Skip to content

Commit e8c8dbb

Browse files
anhanh11001iamareebjamal
authored andcommitted
fix: Improve AttendeeFragment (#1890)
Details: - Set up more logically time display of event - Remove card type selector as it doesn't matter that much. Stripe automatically determine card type based on card number provided - Hide billing information for free tickets - Show pop up message for "required fields should be filled" - Remove confirm dialog on ordering ticket (based on Eventbrite)
1 parent 2b39b06 commit e8c8dbb

File tree

7 files changed

+59
-139
lines changed

7 files changed

+59
-139
lines changed

app/src/main/java/org/fossasia/openevent/general/attendees/AttendeeFragment.kt

Lines changed: 50 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ import kotlinx.android.synthetic.main.fragment_attendee.view.accept
4141
import kotlinx.android.synthetic.main.fragment_attendee.view.amount
4242
import kotlinx.android.synthetic.main.fragment_attendee.view.attendeeInformation
4343
import kotlinx.android.synthetic.main.fragment_attendee.view.attendeeRecycler
44-
import kotlinx.android.synthetic.main.fragment_attendee.view.cardSelector
4544
import kotlinx.android.synthetic.main.fragment_attendee.view.eventName
4645
import kotlinx.android.synthetic.main.fragment_attendee.view.offlinePayment
4746
import kotlinx.android.synthetic.main.fragment_attendee.view.offlinePaymentDescription
@@ -50,10 +49,8 @@ import kotlinx.android.synthetic.main.fragment_attendee.view.monthText
5049
import kotlinx.android.synthetic.main.fragment_attendee.view.moreAttendeeInformation
5150
import kotlinx.android.synthetic.main.fragment_attendee.view.paymentSelector
5251
import kotlinx.android.synthetic.main.fragment_attendee.view.paymentSelectorContainer
53-
import kotlinx.android.synthetic.main.fragment_attendee.view.progressBarAttendee
5452
import kotlinx.android.synthetic.main.fragment_attendee.view.qty
5553
import kotlinx.android.synthetic.main.fragment_attendee.view.register
56-
import kotlinx.android.synthetic.main.fragment_attendee.view.selectCard
5754
import kotlinx.android.synthetic.main.fragment_attendee.view.signOut
5855
import kotlinx.android.synthetic.main.fragment_attendee.view.stripePayment
5956
import kotlinx.android.synthetic.main.fragment_attendee.view.ticketDetails
@@ -67,6 +64,7 @@ import kotlinx.android.synthetic.main.fragment_attendee.view.acceptCheckbox
6764
import kotlinx.android.synthetic.main.fragment_attendee.view.countryPicker
6865
import kotlinx.android.synthetic.main.fragment_attendee.view.countryPickerContainer
6966
import kotlinx.android.synthetic.main.fragment_attendee.view.billingInfoContainer
67+
import kotlinx.android.synthetic.main.fragment_attendee.view.billingInfoCheckboxSection
7068
import kotlinx.android.synthetic.main.fragment_attendee.view.billingEnabledCheckbox
7169
import kotlinx.android.synthetic.main.fragment_attendee.view.city
7270
import kotlinx.android.synthetic.main.fragment_attendee.view.company
@@ -102,6 +100,7 @@ import org.fossasia.openevent.general.utils.nullToEmpty
102100
import org.koin.androidx.viewmodel.ext.android.viewModel
103101
import org.fossasia.openevent.general.ComplexBackPressFragment
104102
import org.fossasia.openevent.general.utils.Utils.setToolbar
103+
import org.fossasia.openevent.general.utils.Utils.show
105104
import org.fossasia.openevent.general.utils.setRequired
106105
import org.fossasia.openevent.general.utils.checkEmpty
107106
import org.fossasia.openevent.general.utils.checkValidEmail
@@ -157,15 +156,11 @@ class AttendeeFragment : Fragment(), ComplexBackPressFragment {
157156
rootView.longSnackbar(it)
158157
})
159158

159+
val progressDialog = Utils.progressDialog(context, getString(R.string.creating_order_message))
160160
attendeeViewModel.progress
161161
.nonNull()
162162
.observe(viewLifecycleOwner, Observer {
163-
rootView.progressBarAttendee.isVisible = it
164-
rootView.register.isEnabled = !it
165-
rootView.register.text = if (!it) getString(R.string.register) else ""
166-
rootView.register.backgroundTintList =
167-
if (it) resources.getColorStateList(R.color.grey)
168-
else resources.getColorStateList(R.color.colorAccent)
163+
progressDialog.show(it)
169164
})
170165

171166
rootView.sameBuyerCheckBox.setOnCheckedChangeListener { _, isChecked ->
@@ -190,7 +185,6 @@ class AttendeeFragment : Fragment(), ComplexBackPressFragment {
190185
setupBillingInfo()
191186
setupCountryOptions()
192187
setupCardNumber()
193-
setupCardType()
194188
setupMonthOptions()
195189
setupYearOptions()
196190
setupTermsAndCondition()
@@ -214,7 +208,6 @@ class AttendeeFragment : Fragment(), ComplexBackPressFragment {
214208
override fun onResume() {
215209
super.onResume()
216210
if (!isNetworkConnected(context)) {
217-
rootView.progressBarAttendee.isVisible = false
218211
rootView.attendeeScrollView.longSnackbar(getString(R.string.no_internet_connection_message))
219212
}
220213
}
@@ -324,8 +317,9 @@ class AttendeeFragment : Fragment(), ComplexBackPressFragment {
324317
.nonNull()
325318
.observe(viewLifecycleOwner, Observer {
326319
totalAmount = it
327-
rootView.paymentSelectorContainer.visibility = if (it > 0) View.VISIBLE else View.GONE
328-
rootView.countryPickerContainer.visibility = if (it > 0) View.VISIBLE else View.GONE
320+
rootView.paymentSelectorContainer.isVisible = it > 0
321+
rootView.countryPickerContainer.isVisible = it > 0
322+
rootView.billingInfoCheckboxSection.isVisible = it > 0
329323
rootView.amount.text = "Total: ${attendeeViewModel.paymentCurrency}$it"
330324
})
331325

@@ -534,32 +528,18 @@ class AttendeeFragment : Fragment(), ComplexBackPressFragment {
534528

535529
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
536530
if (s == null || s.length < 3) {
537-
setCardSelectorAndError(0, visibility = true, error = false)
531+
setCardSelectorAndError(false)
538532
return
539533
}
540534
val card = Utils.getCardType(s.toString())
541535
if (card == Utils.cardType.NONE) {
542-
setCardSelectorAndError(0, visibility = true, error = true)
536+
setCardSelectorAndError(true)
543537
return
544538
}
545-
546-
val pos: Int = card.let {
547-
when (it) {
548-
Utils.cardType.AMERICAN_EXPRESS -> 1
549-
Utils.cardType.MASTER_CARD -> 2
550-
Utils.cardType.VISA -> 3
551-
Utils.cardType.DISCOVER -> 4
552-
Utils.cardType.DINERS_CLUB -> 5
553-
Utils.cardType.UNIONPAY -> 6
554-
else -> 0
555-
}
556-
}
557-
setCardSelectorAndError(pos, visibility = false, error = false)
539+
setCardSelectorAndError(false)
558540
}
559541

560-
private fun setCardSelectorAndError(pos: Int, visibility: Boolean, error: Boolean) {
561-
rootView.cardSelector.setSelection(pos, true)
562-
rootView.cardSelector.isVisible = visibility
542+
private fun setCardSelectorAndError(error: Boolean) {
563543
if (error) {
564544
rootView.cardNumber.error = "Invalid card number"
565545
return
@@ -627,29 +607,6 @@ class AttendeeFragment : Fragment(), ComplexBackPressFragment {
627607
rootView.year.setSelection(attendeeViewModel.yearSelectedPosition)
628608
}
629609

630-
private fun setupCardType() {
631-
val cardType = ArrayList<String>()
632-
cardType.add(getString(R.string.american_express_pay_message))
633-
cardType.add(getString(R.string.mastercard_pay_message))
634-
cardType.add(getString(R.string.visa_pay_message))
635-
cardType.add(getString(R.string.discover_pay_message))
636-
cardType.add(getString(R.string.diners_pay_message))
637-
cardType.add(getString(R.string.unionpay_pay_message))
638-
639-
rootView.cardSelector.adapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_dropdown_item,
640-
cardType)
641-
rootView.cardSelector.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
642-
override fun onNothingSelected(p0: AdapterView<*>?) { /* Do nothing */ }
643-
644-
override fun onItemSelected(p0: AdapterView<*>?, p1: View?, pos: Int, p3: Long) {
645-
attendeeViewModel.cardTypePosition = pos
646-
rootView.selectCard.text = cardType[pos]
647-
}
648-
}
649-
650-
rootView.cardSelector.setSelection(attendeeViewModel.cardTypePosition)
651-
}
652-
653610
private fun setupTermsAndCondition() {
654611
val paragraph = SpannableStringBuilder()
655612
val startText = getString(R.string.start_text)
@@ -742,37 +699,30 @@ class AttendeeFragment : Fragment(), ComplexBackPressFragment {
742699
return@setOnClickListener
743700
}
744701

745-
if (!checkRequiredFields()) return@setOnClickListener
702+
if (!checkRequiredFields()) {
703+
rootView.snackbar(R.string.fill_required_fields_message)
704+
return@setOnClickListener
705+
}
746706

747707
if (attendeeViewModel.totalAmount.value != 0F && !checkPaymentOptions()) return@setOnClickListener
748708

749-
val builder = AlertDialog.Builder(requireContext())
750-
builder.setTitle(R.string.confirmation_dialog)
751-
752-
builder.setPositiveButton(android.R.string.yes) { _, _ ->
753-
val attendees = attendeeViewModel.attendees
754-
755-
if (attendeeViewModel.areAttendeeEmailsValid(attendees)) {
756-
val country = rootView.countryPicker.selectedItem.toString()
757-
val paymentOption =
758-
if (totalAmount != 0F) getPaymentMode(rootView.paymentSelector.selectedItem.toString())
759-
else PAYMENT_MODE_FREE
760-
val company = rootView.company.text.toString()
761-
val city = rootView.city.text.toString()
762-
val taxId = rootView.taxId.text.toString()
763-
val address = rootView.address.text.toString()
764-
val postalCode = rootView.postalCode.text.toString()
765-
attendeeViewModel.createAttendees(attendees, country, company, taxId, address,
766-
city, postalCode, paymentOption)
767-
} else {
768-
rootView.attendeeScrollView.longSnackbar(getString(R.string.invalid_email_address_message))
769-
}
770-
}
771-
772-
builder.setNegativeButton(android.R.string.no) { _, _ ->
773-
rootView.snackbar(getString(R.string.order_not_completed))
709+
val attendees = attendeeViewModel.attendees
710+
711+
if (attendeeViewModel.areAttendeeEmailsValid(attendees)) {
712+
val country = rootView.countryPicker.selectedItem.toString()
713+
val paymentOption =
714+
if (totalAmount != 0F) getPaymentMode(rootView.paymentSelector.selectedItem.toString())
715+
else PAYMENT_MODE_FREE
716+
val company = rootView.company.text.toString()
717+
val city = rootView.city.text.toString()
718+
val taxId = rootView.taxId.text.toString()
719+
val address = rootView.address.text.toString()
720+
val postalCode = rootView.postalCode.text.toString()
721+
attendeeViewModel.createAttendees(attendees, country, company, taxId, address,
722+
city, postalCode, paymentOption)
723+
} else {
724+
rootView.attendeeScrollView.longSnackbar(getString(R.string.invalid_email_address_message))
774725
}
775-
builder.show()
776726
}
777727

778728
attendeeViewModel.isAttendeeCreated.observe(viewLifecycleOwner, Observer { isAttendeeCreated ->
@@ -820,9 +770,6 @@ class AttendeeFragment : Fragment(), ComplexBackPressFragment {
820770
val card = Card(rootView.cardNumber.text.toString(), attendeeViewModel.monthSelectedPosition,
821771
attendeeViewModel.yearSelectedPosition, rootView.cvc.text.toString())
822772

823-
if (card.brand != null && card.brand != "Unknown")
824-
rootView.selectCard.text = "Pay by ${card.brand}"
825-
826773
val validDetails: Boolean? = card.validateCard()
827774
if (validDetails != null && !validDetails)
828775
rootView.snackbar(getString(R.string.invalid_card_data_message))
@@ -848,12 +795,25 @@ class AttendeeFragment : Fragment(), ComplexBackPressFragment {
848795
attendeeViewModel.paymentCurrency = Currency.getInstance(event.paymentCurrency).symbol
849796
ticketsRecyclerAdapter.setCurrency(attendeeViewModel.paymentCurrency)
850797

851-
rootView.eventName.text = "${event.name} - ${EventUtils.getFormattedDate(startsAt)}"
852-
rootView.time.text = dateString.append(EventUtils.getFormattedDate(startsAt))
853-
.append(" - ")
854-
.append(EventUtils.getFormattedDate(endsAt))
855-
.append("")
856-
.append(EventUtils.getFormattedTime(startsAt))
798+
rootView.eventName.text = event.name
799+
800+
val startDate = EventUtils.getFormattedDate(startsAt)
801+
val endDate = EventUtils.getFormattedDate(endsAt)
802+
dateString.append(startDate)
803+
if (startDate == endDate) {
804+
dateString.append("")
805+
.append(EventUtils.getFormattedTime(startsAt))
806+
.append(" - ")
807+
.append(EventUtils.getFormattedTime(endsAt))
808+
} else {
809+
dateString.append(" - ")
810+
.append(EventUtils.getFormattedTime(startsAt))
811+
.append("")
812+
.append(endDate)
813+
.append(" - ")
814+
.append(EventUtils.getFormattedTime(endsAt))
815+
}
816+
rootView.time.text = dateString
857817
}
858818

859819
private fun loadUserUI(user: User) {

app/src/main/java/org/fossasia/openevent/general/attendees/AttendeeViewModel.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ class AttendeeViewModel(
9595
var singleTicket = false
9696
var monthSelectedPosition: Int = 0
9797
var yearSelectedPosition: Int = 0
98-
var cardTypePosition: Int = 0
9998
var identifierList = ArrayList<String>()
10099
var editTextList = ArrayList<EditText>()
101100
var paymentCurrency: String = ""

app/src/main/java/org/fossasia/openevent/general/utils/Utils.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,13 @@ object Utils {
5757
return connectivityManager?.activeNetworkInfo != null
5858
}
5959

60-
fun progressDialog(context: Context?): ProgressDialog {
60+
fun progressDialog(
61+
context: Context?,
62+
message: String? = context?.resources?.getString(R.string.loading_message)
63+
): ProgressDialog {
6164
val dialog = ProgressDialog(context)
6265
dialog.setCancelable(false)
63-
dialog.setMessage("Loading...")
66+
dialog.setMessage(message)
6467
return dialog
6568
}
6669

app/src/main/res/layout/fragment_attendee.xml

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@
303303
tools:listitem="@layout/item_attendee" />
304304

305305
<RelativeLayout
306+
android:id="@+id/billingInfoCheckboxSection"
306307
android:layout_width="match_parent"
307308
android:layout_height="wrap_content">
308309
<TextView
@@ -489,38 +490,6 @@
489490
android:layout_height="wrap_content"/>
490491
</com.google.android.material.textfield.TextInputLayout>
491492

492-
<TextView
493-
android:layout_width="wrap_content"
494-
android:layout_height="wrap_content"
495-
android:layout_marginBottom="@dimen/layout_margin_medium"
496-
android:layout_marginTop="@dimen/layout_margin_large"
497-
android:text="@string/card_type"
498-
android:textSize="@dimen/text_size_large" />
499-
500-
<LinearLayout
501-
android:layout_width="match_parent"
502-
android:layout_height="wrap_content"
503-
android:layout_weight="1"
504-
android:background="@drawable/filled_border"
505-
android:gravity="center"
506-
android:orientation="horizontal">
507-
508-
<TextView
509-
android:id="@+id/selectCard"
510-
android:layout_width="wrap_content"
511-
android:layout_height="@dimen/spinner_width"
512-
android:layout_weight="0.8"
513-
android:gravity="center"
514-
android:textSize="@dimen/text_size_large" />
515-
516-
<androidx.appcompat.widget.AppCompatSpinner
517-
android:id="@+id/cardSelector"
518-
android:layout_width="@dimen/spinner_width"
519-
android:layout_height="@dimen/spinner_width"
520-
android:layout_marginLeft="@dimen/layout_margin_medium"
521-
android:spinnerMode="dialog" />
522-
</LinearLayout>
523-
524493
<TextView
525494
android:layout_width="wrap_content"
526495
android:layout_height="wrap_content"
@@ -627,18 +596,7 @@
627596
android:layout_marginEnd="@dimen/details_margin_small"
628597
android:layout_marginTop="@dimen/layout_margin_large"
629598
android:layout_marginBottom="@dimen/layout_margin_large"
630-
android:enabled="false"
631599
android:text="@string/register"/>
632-
633-
<ProgressBar
634-
android:layout_centerInParent="true"
635-
android:id="@+id/progressBarAttendee"
636-
android:layout_width="@dimen/spinner_height"
637-
android:layout_height="@dimen/spinner_width"
638-
android:elevation="@dimen/card_elevation"
639-
android:padding="@dimen/padding_small"
640-
android:visibility="gone"
641-
tools:visibility="visible"/>
642600
</RelativeLayout>
643601

644602
</LinearLayout>

app/src/main/res/values-bn-rIN/strings.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,6 @@
172172
<string name="sign_in_canceled">সিগণ ইন ক্যানসেল!</string>
173173
<string name="sign_up_success">সিগণ উপ সাফল্য!</string>
174174
<string name="cannot_fetch_location">অবস্থান আনা যাচ্ছে না!</string>
175-
<string name="confirmation_dialog">আপনি কি অর্ডার কন্ফার্ম করতে চান?</string>
176175
<string name="order_not_completed">অর্ডার কমপ্লিট হয়নি!</string>
177176

178177
<!--welcome fragment-->

app/src/main/res/values-vi/strings.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@
150150
<string name="timeZone_title">Sử dụng múi giờ của sự kiện.</string>
151151
<string name="timeZone_summary">Múi giờ của bạn sẽ được sử dụng khi khóa lại.</string>
152152
<string name="hide">(giấu)</string>
153-
<string name="confirmation_dialog">Bạn có chắc chắn để khẳng định trình tự?</string>
154153
<string name="order_not_completed">Để không hoàn thành!</string>
155154
<string name="country">Quốc Gia</string>
156155
<string name="visit_website">truy cập trang web</string>

app/src/main/res/values/strings.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@
263263
<string name="create_attendee_success_message">Attendees created successfully!</string>
264264
<string name="create_attendee_fail_message">Unable to create Attendee!</string>
265265
<string name="fill_all_fields_message">Please fill in all the fields</string>
266+
<string name="fill_required_fields_message">Please fill in all the required fields</string>
266267
<string name="free">free</string>
267268
<string name="order_success_message">Order created successfully!</string>
268269
<string name="order_fail_message">Unable to create Order!</string>
@@ -282,7 +283,6 @@
282283
<string name="sign_in_canceled">Sign In canceled!</string>
283284
<string name="sign_up_success">Sign Up Success!</string>
284285
<string name="cannot_fetch_location">Cannot fetch location!</string>
285-
<string name="confirmation_dialog">Are you sure to confirm the order?</string>
286286
<string name="order_not_completed">Order not completed!</string>
287287
<string name="removed_from_liked">Removed %1$s from liked events</string>
288288
<string name="undo">Undo</string>
@@ -411,5 +411,7 @@
411411
<string name="no_speaker_profile_created_message">You haven\'t created any speaker profile</string>
412412
<string name="create_speaker_fail_message">Fail on creating speaker profile</string>
413413
<string name="update_speaker_fail_message">Fail on updating speaker profile</string>
414+
<string name="loading_message">Loading...</string>
415+
<string name="creating_order_message">Creating order...</string>
414416

415417
</resources>

0 commit comments

Comments
 (0)