Skip to content

Commit 64fdffd

Browse files
author
thelimitbreaker
committed
Merge branch 'development' of https://github.com/fossasia/open-event-android into feature/autocomplete-place
2 parents 2949185 + 4f10acf commit 64fdffd

37 files changed

+1415
-395
lines changed

app/build.gradle

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ android {
6666
packagingOptions {
6767
pickFirst 'kotlin/**'
6868
}
69+
lintOptions {
70+
disable 'MissingTranslation'
71+
}
72+
androidExtensions {
73+
experimental = true
74+
}
6975
}
7076

7177
spotless {
@@ -82,18 +88,18 @@ repositories {
8288
}
8389

8490
dependencies {
85-
def lifecycle_version = "2.1.0-alpha02"
91+
def lifecycle_version = "2.1.0-alpha03"
8692
def koin_version = "1.0.2"
87-
def roomVersion = '2.1.0-alpha04'
93+
def roomVersion = "2.1.0-alpha04"
8894
def ktx_version = "1.0.0"
8995
def ktx2_version = "2.0.0"
9096

9197
implementation fileTree(dir: 'libs', include: ['*.jar'])
9298
implementation 'androidx.multidex:multidex:2.0.1'
93-
implementation 'androidx.appcompat:appcompat:1.1.0-alpha02'
99+
implementation 'androidx.appcompat:appcompat:1.1.0-alpha03'
94100
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha3'
95101
implementation 'androidx.cardview:cardview:1.0.0'
96-
implementation 'androidx.recyclerview:recyclerview:1.1.0-alpha02'
102+
implementation 'androidx.recyclerview:recyclerview:1.1.0-alpha03'
97103
implementation 'com.google.android.material:material:1.1.0-alpha04'
98104
implementation "androidx.browser:browser:1.0.0"
99105
implementation 'androidx.exifinterface:exifinterface:1.0.0'
@@ -130,7 +136,7 @@ dependencies {
130136

131137
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.9.8"
132138
implementation 'com.github.jasminb:jsonapi-converter:0.9'
133-
implementation 'com.squareup.okhttp3:logging-interceptor:3.13.1'
139+
implementation 'com.squareup.okhttp3:logging-interceptor:3.14.0'
134140
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
135141
implementation 'com.squareup.retrofit2:converter-jackson:2.5.0'
136142

@@ -152,8 +158,14 @@ dependencies {
152158
implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
153159

154160
//Navigation
155-
implementation 'android.arch.navigation:navigation-fragment-ktx:1.0.0-rc02'
156-
implementation 'android.arch.navigation:navigation-ui-ktx:1.0.0-rc02'
161+
implementation 'android.arch.navigation:navigation-fragment-ktx:1.0.0'
162+
implementation 'android.arch.navigation:navigation-ui-ktx:1.0.0'
163+
164+
// Stetho
165+
debugImplementation 'com.facebook.stetho:stetho:1.5.1'
166+
debugImplementation 'com.facebook.stetho:stetho-okhttp3:1.5.0'
167+
releaseImplementation 'com.github.iamareebjamal:stetho-noop:1.2.1'
168+
testImplementation 'com.github.iamareebjamal:stetho-noop:1.2.1'
157169

158170
//Mapbox SDK plugins
159171
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-places-v7:0.7.0'

app/src/main/java/org/fossasia/openevent/general/OpenEventGeneral.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ package org.fossasia.openevent.general
22

33
import android.content.Context
44
import androidx.multidex.MultiDexApplication
5+
import com.facebook.stetho.Stetho
56
import com.jakewharton.threetenabp.AndroidThreeTen
67
import org.fossasia.openevent.general.di.apiModule
78
import org.fossasia.openevent.general.di.commonModule
89
import org.fossasia.openevent.general.di.databaseModule
910
import org.fossasia.openevent.general.di.flavorSpecificModule
11+
import org.fossasia.openevent.general.di.fragmentsModule
1012
import org.fossasia.openevent.general.di.networkModule
1113
import org.fossasia.openevent.general.di.viewModelModule
1214
import org.koin.android.ext.android.startKoin
@@ -24,9 +26,19 @@ class OpenEventGeneral : MultiDexApplication() {
2426
super.onCreate()
2527
appContext = applicationContext
2628
startKoin(this, listOf(
27-
commonModule, apiModule, viewModelModule, networkModule, databaseModule, flavorSpecificModule
29+
commonModule,
30+
apiModule,
31+
viewModelModule,
32+
networkModule,
33+
databaseModule,
34+
flavorSpecificModule,
35+
fragmentsModule
2836
))
2937
Timber.plant(Timber.DebugTree())
3038
AndroidThreeTen.init(applicationContext)
39+
40+
if (BuildConfig.DEBUG) {
41+
Stetho.initializeWithDefaults(this)
42+
}
3143
}
3244
}

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

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package org.fossasia.openevent.general.attendees
22

33
import android.app.AlertDialog
4+
import android.content.Context
45
import android.content.pm.PackageManager
56
import android.os.Bundle
7+
import android.telephony.TelephonyManager
68
import android.text.Editable
79
import android.text.Spannable
810
import android.text.SpannableStringBuilder
@@ -32,7 +34,6 @@ import com.stripe.android.TokenCallback
3234
import com.stripe.android.model.Card
3335
import com.stripe.android.model.Token
3436
import kotlinx.android.synthetic.main.fragment_attendee.cardNumber
35-
import kotlinx.android.synthetic.main.fragment_attendee.country
3637
import kotlinx.android.synthetic.main.fragment_attendee.cvc
3738
import kotlinx.android.synthetic.main.fragment_attendee.email
3839
import kotlinx.android.synthetic.main.fragment_attendee.firstName
@@ -45,7 +46,6 @@ import kotlinx.android.synthetic.main.fragment_attendee.view.amount
4546
import kotlinx.android.synthetic.main.fragment_attendee.view.attendeeInformation
4647
import kotlinx.android.synthetic.main.fragment_attendee.view.attendeeRecycler
4748
import kotlinx.android.synthetic.main.fragment_attendee.view.cardSelector
48-
import kotlinx.android.synthetic.main.fragment_attendee.view.countryArea
4949
import kotlinx.android.synthetic.main.fragment_attendee.view.eventName
5050
import kotlinx.android.synthetic.main.fragment_attendee.view.month
5151
import kotlinx.android.synthetic.main.fragment_attendee.view.monthText
@@ -65,6 +65,8 @@ import kotlinx.android.synthetic.main.fragment_attendee.view.year
6565
import kotlinx.android.synthetic.main.fragment_attendee.view.yearText
6666
import kotlinx.android.synthetic.main.fragment_attendee.view.cardNumber
6767
import kotlinx.android.synthetic.main.fragment_attendee.view.acceptCheckbox
68+
import kotlinx.android.synthetic.main.fragment_attendee.view.countryPicker
69+
import kotlinx.android.synthetic.main.fragment_attendee.view.countryPickerContainer
6870
import org.fossasia.openevent.general.R
6971
import org.fossasia.openevent.general.attendees.forms.CustomForm
7072
import org.fossasia.openevent.general.event.Event
@@ -216,6 +218,14 @@ class AttendeeFragment : Fragment() {
216218

217219
attendeeViewModel.initializeSpinner()
218220

221+
ArrayAdapter.createFromResource(
222+
requireContext(), R.array.country_arrays,
223+
android.R.layout.simple_spinner_dropdown_item
224+
).also { adapter ->
225+
rootView.countryPicker.adapter = adapter
226+
autoSetCurrentCountry()
227+
}
228+
219229
rootView.cardNumber.addTextChangedListener(object : TextWatcher {
220230
override fun afterTextChanged(s: Editable?) {
221231
}
@@ -239,6 +249,9 @@ class AttendeeFragment : Fragment() {
239249
Utils.cardType.AMERICAN_EXPRESS -> 1
240250
Utils.cardType.MASTER_CARD -> 2
241251
Utils.cardType.VISA -> 3
252+
Utils.cardType.DISCOVER -> 4
253+
Utils.cardType.DINERS_CLUB -> 5
254+
Utils.cardType.UNIONPAY -> 6
242255
else -> 0
243256
}
244257
}
@@ -306,15 +319,21 @@ class AttendeeFragment : Fragment() {
306319
})
307320

308321
rootView.view.setOnClickListener {
309-
if (rootView.view.text == "(view)") {
310-
rootView.ticketDetails.visibility = View.VISIBLE
311-
rootView.view.text = "(hide)"
322+
val currentVisibility: Boolean? = attendeeViewModel.ticketDetailsVisibility.value
323+
if (currentVisibility == null) {
324+
attendeeViewModel.ticketDetailsVisibility.value = false
312325
} else {
313-
rootView.ticketDetails.visibility = View.GONE
314-
rootView.view.text = "(view)"
326+
attendeeViewModel.ticketDetailsVisibility.value = !currentVisibility
315327
}
316328
}
317329

330+
attendeeViewModel.ticketDetailsVisibility
331+
.nonNull()
332+
.observe(this, Observer {
333+
rootView.view.text = if (it) getString(R.string.hide) else getString(R.string.view)
334+
rootView.ticketDetails.visibility = if (it) View.VISIBLE else View.GONE
335+
})
336+
318337
attendeeViewModel.message
319338
.nonNull()
320339
.observe(this, Observer {
@@ -366,7 +385,7 @@ class AttendeeFragment : Fragment() {
366385
.nonNull()
367386
.observe(this, Observer {
368387
if (singleTicket) {
369-
rootView.countryArea.visibility = if (it) View.VISIBLE else View.GONE
388+
rootView.countryPickerContainer.visibility = if (it) View.VISIBLE else View.GONE
370389
}
371390
})
372391

@@ -443,7 +462,7 @@ class AttendeeFragment : Fragment() {
443462
}
444463

445464
if (attendeeViewModel.areAttendeeEmailsValid(attendees)) {
446-
val country = if (country.text.isEmpty()) country.text.toString() else null
465+
val country = rootView.countryPicker.selectedItem.toString()
447466
attendeeViewModel.createAttendees(attendees, country, paymentOptions[selectedPaymentOption])
448467

449468
attendeeViewModel.isAttendeeCreated.observe(this, Observer { isAttendeeCreated ->
@@ -483,7 +502,7 @@ class AttendeeFragment : Fragment() {
483502

484503
private fun sendToken() {
485504
val card = Card(cardNumber.text.toString(), expiryMonth, expiryYear.toInt(), cvc.text.toString())
486-
card.addressCountry = country.text.toString()
505+
card.addressCountry = rootView.countryPicker.selectedItem.toString()
487506
card.addressZip = postalCode.text.toString()
488507

489508
if (card.brand != null && card.brand != "Unknown")
@@ -569,4 +588,13 @@ class AttendeeFragment : Fragment() {
569588
val index = identifierList.indexOf(identifier)
570589
return if (index == -1) "" else index.let { editTextList[it] }.text.toString()
571590
}
591+
592+
private fun autoSetCurrentCountry() {
593+
val telephonyManager: TelephonyManager = activity?.getSystemService(Context.TELEPHONY_SERVICE)
594+
as TelephonyManager
595+
val currentCountryCode = telephonyManager.networkCountryIso
596+
val countryCodes = resources.getStringArray(R.array.country_code_arrays)
597+
val countryIndex = countryCodes.indexOf(currentCountryCode.toUpperCase())
598+
if (countryIndex != -1) rootView.countryPicker.setSelection(countryIndex)
599+
}
572600
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class AttendeeViewModel(
5757
private val mutableQtyList = MutableLiveData<ArrayList<Int>>()
5858
val qtyList: LiveData<ArrayList<Int>> = mutableQtyList
5959
val paymentCompleted = MutableLiveData<Boolean>()
60+
val ticketDetailsVisibility = MutableLiveData<Boolean>()
6061
private val mutableTickets = MutableLiveData<MutableList<Ticket>>()
6162
val tickets: LiveData<MutableList<Ticket>> = mutableTickets
6263
private val mutableForms = MutableLiveData<List<CustomForm>>()
@@ -109,6 +110,9 @@ class AttendeeViewModel(
109110
cardType.add("Pay by American Express")
110111
cardType.add("Pay by MasterCard")
111112
cardType.add("Pay by Visa")
113+
cardType.add("Pay by Discover")
114+
cardType.add("Pay by Diners Club")
115+
cardType.add("Pay by UnionPay")
112116
}
113117

114118
fun updatePaymentSelectorVisibility(ticketIdAndQty: List<Pair<Int, Int>>?) {

app/src/main/java/org/fossasia/openevent/general/auth/EditProfileFragment.kt

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ import android.content.Intent
77
import android.content.pm.PackageManager
88
import android.graphics.Bitmap
99
import android.graphics.BitmapFactory
10+
import android.net.Uri
1011
import android.os.Bundle
1112
import android.util.Base64
1213
import android.view.LayoutInflater
1314
import android.view.MenuItem
1415
import android.view.View
1516
import android.view.ViewGroup
1617
import androidx.appcompat.app.AppCompatActivity
18+
import androidx.core.content.ContextCompat
1719
import androidx.core.view.isVisible
1820
import androidx.fragment.app.Fragment
1921
import androidx.lifecycle.Observer
@@ -70,7 +72,7 @@ class EditProfileFragment : Fragment() {
7072
if (rootView.lastName.text.isBlank()) {
7173
rootView.lastName.setText(userLastName)
7274
}
73-
if (!imageUrl.isEmpty()) {
75+
if (!imageUrl.isEmpty() && !avatarUpdated) {
7476
val drawable = requireDrawable(requireContext(), R.drawable.ic_account_circle_grey)
7577
Picasso.get()
7678
.load(imageUrl)
@@ -79,6 +81,16 @@ class EditProfileFragment : Fragment() {
7981
.into(rootView.profilePhoto)
8082
}
8183
})
84+
profileViewModel.avatarPicked.observe(this, Observer {
85+
if (it != null) {
86+
Picasso.get()
87+
.load(Uri.parse(it))
88+
.placeholder(requireDrawable(requireContext(), R.drawable.ic_account_circle_grey))
89+
.transform(CircleTransform())
90+
.into(rootView.profilePhoto)
91+
this.avatarUpdated = true
92+
}
93+
})
8294
profileViewModel.fetchProfile()
8395

8496
editProfileViewModel.progress
@@ -87,6 +99,9 @@ class EditProfileFragment : Fragment() {
8799
rootView.progressBar.isVisible = it
88100
})
89101

102+
permissionGranted = (ContextCompat.checkSelfPermission(requireContext(),
103+
Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
104+
90105
rootView.profilePhoto.setOnClickListener {
91106
if (permissionGranted) {
92107
showFileChooser()
@@ -132,6 +147,7 @@ class EditProfileFragment : Fragment() {
132147
.transform(CircleTransform())
133148
.into(rootView.profilePhoto)
134149
avatarUpdated = true
150+
profileViewModel.avatarPicked.value = imageUri.toString()
135151
}
136152
}
137153

app/src/main/java/org/fossasia/openevent/general/auth/ProfileViewModel.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class ProfileViewModel(private val authService: AuthService) : ViewModel() {
1919
val user: LiveData<User> = mutableUser
2020
private val mutableError = SingleLiveEvent<String>()
2121
val error: LiveData<String> = mutableError
22+
val avatarPicked = MutableLiveData<String>()
2223

2324
fun isLoggedIn() = authService.isLoggedIn()
2425

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.fossasia.openevent.general.common
2+
3+
import androidx.recyclerview.widget.DiffUtil
4+
import org.fossasia.openevent.general.event.Event
5+
6+
/**
7+
* The DiffUtil ItemCallback class for the [Event] model class.
8+
* This enables proper diffing of items in Recycler Views using [DiffUtil]
9+
*/
10+
class EventsDiffCallback : DiffUtil.ItemCallback<Event>() {
11+
12+
override fun areItemsTheSame(oldItem: Event, newItem: Event): Boolean {
13+
return oldItem.id == newItem.id
14+
}
15+
16+
override fun areContentsTheSame(oldItem: Event, newItem: Event): Boolean {
17+
return oldItem == newItem
18+
}
19+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package org.fossasia.openevent.general.common
2+
3+
import org.fossasia.openevent.general.event.Event
4+
5+
/**
6+
* The callback interface for Event item clicks
7+
*/
8+
interface EventClickListener {
9+
/**
10+
* The function to be invoked when an event item is clicked
11+
*
12+
* @param eventID The ID of the clicked event
13+
*/
14+
fun onClick(eventID: Long)
15+
}
16+
17+
/**
18+
* The callback interface for Favorite FAB clicks
19+
*/
20+
interface FavoriteFabClickListener {
21+
/**
22+
* The function to be invoked when the fab is clicked
23+
*
24+
* @param event The event object for which the fab was clicked
25+
* @param itemPosition The position of the event object in the adapter
26+
*/
27+
fun onClick(event: Event, itemPosition: Int)
28+
}
29+
30+
/**
31+
* The callback interface for Share FAB clicks
32+
*/
33+
interface ShareFabClickListener {
34+
/**
35+
* The function to be invoked when the fab is clicked
36+
*
37+
* @param event The event object for which the fab was clicked
38+
*/
39+
fun onClick(event: Event)
40+
}

0 commit comments

Comments
 (0)