From 70d2c69e0dff17639822b96f930739eec3300fbf Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Sat, 24 Feb 2024 00:20:38 -0600 Subject: [PATCH 1/4] Fixed TimerTask calling while app is in the background --- .../main/java/org/hackillinois/android/API.kt | 4 +-- .../android/repository/ShopRepository.kt | 1 - .../android/view/profile/ProfileFragment.kt | 20 ++++++++--- .../android/view/shop/ShopFragment.kt | 10 ++++++ .../android/viewmodel/ProfileViewModel.kt | 29 +++++++++++---- .../android/viewmodel/ShopViewModel.kt | 35 ++++++++++++++----- 6 files changed, 75 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/org/hackillinois/android/API.kt b/app/src/main/java/org/hackillinois/android/API.kt index 57aaec7ed..81ede45f9 100644 --- a/app/src/main/java/org/hackillinois/android/API.kt +++ b/app/src/main/java/org/hackillinois/android/API.kt @@ -64,7 +64,7 @@ interface API { // SHOP - @GET("shop/") + @GET("shop/v2/") suspend fun shop(): List @POST("shop/item/buy/") @@ -92,7 +92,7 @@ interface API { @PUT("user/unfollow/") fun unfollowEvent(@Body eventId: EventId): Call - @GET("user/qr/") + @GET("user/v2-qr/") suspend fun qrCode(): QR @PUT("user/scan-event/") diff --git a/app/src/main/java/org/hackillinois/android/repository/ShopRepository.kt b/app/src/main/java/org/hackillinois/android/repository/ShopRepository.kt index 18d64ac71..688b0f0c3 100644 --- a/app/src/main/java/org/hackillinois/android/repository/ShopRepository.kt +++ b/app/src/main/java/org/hackillinois/android/repository/ShopRepository.kt @@ -24,7 +24,6 @@ class ShopRepository { GlobalScope.launch(Dispatchers.IO) { try { val shop = App.getAPI().shop() - Log.d("SHOP REFRESH ALL", shop.toString()) shopDao.clearTableAndInsertShopItems(shop) } catch (e: Exception) { Log.e("SHOP REFRESH ALL", e.toString()) diff --git a/app/src/main/java/org/hackillinois/android/view/profile/ProfileFragment.kt b/app/src/main/java/org/hackillinois/android/view/profile/ProfileFragment.kt index 31c1ad0f8..cb0296d2e 100644 --- a/app/src/main/java/org/hackillinois/android/view/profile/ProfileFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/profile/ProfileFragment.kt @@ -40,6 +40,16 @@ class ProfileFragment : Fragment() { private var pro = false private var userRoles: Roles? = null + override fun onPause() { + super.onPause() + profileViewModel.stopTimer() + } + + override fun onResume() { + super.onResume() + profileViewModel.startTimer() + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -65,13 +75,13 @@ class ProfileFragment : Fragment() { // set up LiveData observers profileViewModel.currentProfileLiveData.observe( this@ProfileFragment, - Observer { updateProfileUI(it) }, + Observer { updateProfileUI(it) } ) profileViewModel.qr.observe( this@ProfileFragment, Observer { updateQrView(it) - }, + } ) profileViewModel.roles.observe( this@ProfileFragment, @@ -81,13 +91,13 @@ class ProfileFragment : Fragment() { pro = it.isPro() updateProTag() } - }, + } ) profileViewModel.ranking.observe( this@ProfileFragment, Observer { updateRanking(it) - }, + } ) // do view creation here if attendee @@ -175,4 +185,4 @@ class ProfileFragment : Fragment() { val prefString = context.getString(R.string.authorization_pref_file_key) return context.getSharedPreferences(prefString, Context.MODE_PRIVATE).getString("provider", "") ?: "" == "google" } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt index 6050d0b27..fe0e1f2e4 100644 --- a/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/shop/ShopFragment.kt @@ -42,6 +42,16 @@ class ShopFragment : Fragment() { // Merch tab is default selected private var showingMerch: Boolean = true + override fun onPause() { + super.onPause() + shopViewModel.stopTimer() + } + + override fun onResume() { + super.onResume() + shopViewModel.startTimer() + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/org/hackillinois/android/viewmodel/ProfileViewModel.kt b/app/src/main/java/org/hackillinois/android/viewmodel/ProfileViewModel.kt index b15c67108..ef10518fc 100644 --- a/app/src/main/java/org/hackillinois/android/viewmodel/ProfileViewModel.kt +++ b/app/src/main/java/org/hackillinois/android/viewmodel/ProfileViewModel.kt @@ -24,6 +24,7 @@ class ProfileViewModel : ViewModel() { var ranking: MutableLiveData = MutableLiveData() lateinit var roles: LiveData lateinit var timerObj: Timer + private var isTimerRunning = false fun init() { this.roles = rolesRepository.fetch() @@ -32,21 +33,35 @@ class ProfileViewModel : ViewModel() { currentProfileLiveData = profileRepository.fetchProfile() // Initial qr code fetching qr = qrRepository.fetch() + startTimer() + } + fun startTimer() { // should refresh QR code every 15 seconds using Timer() class - timerObj = Timer() - val timerTaskObj: TimerTask = object : TimerTask() { - override fun run() { - qr = qrRepository.fetch() + if (!isTimerRunning) { + timerObj = Timer() + val timerTaskObj: TimerTask = object : TimerTask() { + override fun run() { + qr = qrRepository.fetch() + } } + // Runs TimerTask every 15 seconds, with a 0 second delay upon the call of init(). + timerObj.scheduleAtFixedRate(timerTaskObj, 0, 15000) + isTimerRunning = true + } + } + + fun stopTimer() { + if (isTimerRunning && ::timerObj.isInitialized) { + timerObj.cancel() + isTimerRunning = false } - // Runs TimerTask every 15 seconds, with a 0 second delay upon the call of init(). - timerObj.scheduleAtFixedRate(timerTaskObj, 0, 15000) } override fun onCleared() { super.onCleared() - timerObj.cancel() + Log.d("OnCleared", "QR") + stopTimer() } private fun fetchRanking() { diff --git a/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt b/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt index 93dd98516..e3e3f0568 100644 --- a/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt +++ b/app/src/main/java/org/hackillinois/android/viewmodel/ShopViewModel.kt @@ -17,29 +17,46 @@ class ShopViewModel : ViewModel() { lateinit var profileLiveData: LiveData lateinit var timerObj: Timer + private var isTimerRunning = false + private var isAttendee = true - fun init(isAttendee: Boolean) { + fun init(inIsAttendee: Boolean) { // initial fetch shopLiveData = shopRepository.fetchShop() + isAttendee = inIsAttendee if (isAttendee) { profileLiveData = profileRepository.fetchProfile() } + startTimer() + } + + fun startTimer() { // runs TimerTask every 10 seconds to fetch profile and shop data - timerObj = Timer() - val timerTaskObj: TimerTask = object : TimerTask() { - override fun run() { - shopLiveData = shopRepository.fetchShop() - if (isAttendee) { - profileLiveData = profileRepository.fetchProfile() + if (!isTimerRunning) { + timerObj = Timer() + val timerTaskObj: TimerTask = object : TimerTask() { + override fun run() { + shopLiveData = shopRepository.fetchShop() + if (isAttendee) { + profileLiveData = profileRepository.fetchProfile() + } } } + timerObj.scheduleAtFixedRate(timerTaskObj, 0, 10000) + isTimerRunning = true + } + } + + fun stopTimer() { + if (isTimerRunning && ::timerObj.isInitialized) { + timerObj.cancel() + isTimerRunning = false } - timerObj.scheduleAtFixedRate(timerTaskObj, 0, 10000) } override fun onCleared() { super.onCleared() - timerObj.cancel() + stopTimer() } } From 80f0453e14b3a83250068733009bce82d3b9fd4d Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Sat, 24 Feb 2024 00:22:32 -0600 Subject: [PATCH 2/4] Update app version --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9430e1493..616a9d9a2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -24,8 +24,8 @@ android { applicationId "org.hackillinois.android" minSdkVersion 23 targetSdkVersion 33 - versionCode 60 - versionName "2024.2.2" + versionCode 61 + versionName "2024.3.0" multiDexEnabled true testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true From a3c6c732b187c2d1549fa604a0739e2a7ffd5f86 Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Sat, 24 Feb 2024 00:23:02 -0600 Subject: [PATCH 3/4] fix ktlint error --- .../org/hackillinois/android/view/profile/ProfileFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/hackillinois/android/view/profile/ProfileFragment.kt b/app/src/main/java/org/hackillinois/android/view/profile/ProfileFragment.kt index cb0296d2e..e561298ab 100644 --- a/app/src/main/java/org/hackillinois/android/view/profile/ProfileFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/profile/ProfileFragment.kt @@ -185,4 +185,4 @@ class ProfileFragment : Fragment() { val prefString = context.getString(R.string.authorization_pref_file_key) return context.getSharedPreferences(prefString, Context.MODE_PRIVATE).getString("provider", "") ?: "" == "google" } -} \ No newline at end of file +} From 8c4c61904c6c6b2d991426cba4fd592d543acd33 Mon Sep 17 00:00:00 2001 From: Leah Ludwikowski Date: Sat, 24 Feb 2024 00:39:57 -0600 Subject: [PATCH 4/4] Only call profileViewModel if attendee --- .../android/view/profile/ProfileFragment.kt | 14 ++++++++++++-- .../android/viewmodel/ProfileViewModel.kt | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/hackillinois/android/view/profile/ProfileFragment.kt b/app/src/main/java/org/hackillinois/android/view/profile/ProfileFragment.kt index e561298ab..d8cd596cf 100644 --- a/app/src/main/java/org/hackillinois/android/view/profile/ProfileFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/profile/ProfileFragment.kt @@ -42,12 +42,16 @@ class ProfileFragment : Fragment() { override fun onPause() { super.onPause() - profileViewModel.stopTimer() + if (isAttendee()) { + profileViewModel.stopTimer() + } } override fun onResume() { super.onResume() - profileViewModel.startTimer() + if (isAttendee()) { + profileViewModel.startTimer() + } } override fun onCreate(savedInstanceState: Bundle?) { @@ -185,4 +189,10 @@ class ProfileFragment : Fragment() { val prefString = context.getString(R.string.authorization_pref_file_key) return context.getSharedPreferences(prefString, Context.MODE_PRIVATE).getString("provider", "") ?: "" == "google" } + + private fun isAttendee(): Boolean { + val context = requireActivity().applicationContext + val prefString = context.getString(R.string.authorization_pref_file_key) + return context.getSharedPreferences(prefString, Context.MODE_PRIVATE).getString("provider", "") ?: "" == "github" + } } diff --git a/app/src/main/java/org/hackillinois/android/viewmodel/ProfileViewModel.kt b/app/src/main/java/org/hackillinois/android/viewmodel/ProfileViewModel.kt index ef10518fc..6a7f38fa5 100644 --- a/app/src/main/java/org/hackillinois/android/viewmodel/ProfileViewModel.kt +++ b/app/src/main/java/org/hackillinois/android/viewmodel/ProfileViewModel.kt @@ -42,6 +42,7 @@ class ProfileViewModel : ViewModel() { timerObj = Timer() val timerTaskObj: TimerTask = object : TimerTask() { override fun run() { + Log.d("QR FETCH", "...") qr = qrRepository.fetch() } }