Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In-App update #1563

Merged
merged 10 commits into from
Dec 6, 2023
34 changes: 29 additions & 5 deletions app/src/main/java/com/infomaniak/mail/ui/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,11 @@ import com.infomaniak.lib.core.utils.SentryLog
import com.infomaniak.lib.core.utils.Utils
import com.infomaniak.lib.core.utils.Utils.toEnumOrThrow
import com.infomaniak.lib.core.utils.UtilsUi.openUrl
import com.infomaniak.lib.stores.checkUpdateIsAvailable
import com.infomaniak.lib.stores.launchInAppReview
import com.infomaniak.lib.stores.StoreUtils.checkStalledUpdate
import com.infomaniak.lib.stores.StoreUtils.checkUpdateIsAvailable
import com.infomaniak.lib.stores.StoreUtils.initAppUpdateManager
import com.infomaniak.lib.stores.StoreUtils.launchInAppReview
import com.infomaniak.lib.stores.StoreUtils.unregisterAppUpdateListener
import com.infomaniak.mail.BuildConfig
import com.infomaniak.mail.MatomoMail.trackDestination
import com.infomaniak.mail.MatomoMail.trackEvent
Expand Down Expand Up @@ -113,6 +116,10 @@ class MainActivity : BaseActivity() {
}
}

private val inAppUpdateResultLauncher = registerForActivityResult(StartIntentSenderForResult()) { result ->
localSettings.isUserWantingUpdates = result.resultCode == RESULT_OK
}

@Inject
lateinit var draftsActionsWorkerScheduler: DraftsActionsWorker.Scheduler

Expand Down Expand Up @@ -176,6 +183,8 @@ class MainActivity : BaseActivity() {
loadCurrentMailbox()

permissionUtils.requestMainPermissionsIfNeeded()

initAppUpdateManager()
}

private fun observeNetworkStatus() {
Expand Down Expand Up @@ -318,6 +327,8 @@ class MainActivity : BaseActivity() {
super.onResume()
playServicesUtils.checkPlayServices(this)

checkStalledUpdate()

if (binding.drawerLayout.isOpen) colorSystemBarsWithMenuDrawer()
}

Expand Down Expand Up @@ -350,6 +361,7 @@ class MainActivity : BaseActivity() {

override fun onStop() {
descriptionDialog.resetLoadingAndDismiss()
unregisterAppUpdateListener()
super.onStop()
}

Expand Down Expand Up @@ -449,11 +461,23 @@ class MainActivity : BaseActivity() {
}
}

private fun initAppUpdateManager() {
initAppUpdateManager(
context = this,
onInstall = { mainViewModel.canInstallUpdate.value = true },
)
}

private fun showUpdateAvailable() = with(localSettings) {
if (isUserWantingUpdates || (appLaunches != 0 && appLaunches % 10 == 0)) {
checkUpdateIsAvailable(BuildConfig.APPLICATION_ID, BuildConfig.VERSION_CODE) { updateIsAvailable ->
if (updateIsAvailable) navController.navigate(R.id.updateAvailableBottomSheetDialog)
}
checkUpdateIsAvailable(
appId = BuildConfig.APPLICATION_ID,
versionCode = BuildConfig.VERSION_CODE,
inAppResultLauncher = inAppUpdateResultLauncher,
onFDroidResult = { updateIsAvailable ->
if (updateIsAvailable) navController.navigate(R.id.updateAvailableBottomSheetDialog)
},
)
}
}

Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/com/infomaniak/mail/ui/MainViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class MainViewModel @Inject constructor(
val flushFolderTrigger = SingleLiveEvent<Unit>()
val newFolderResultTrigger = MutableLiveData<Unit>()
val reportPhishingTrigger = SingleLiveEvent<Unit>()
val canInstallUpdate = MutableLiveData(false)

val snackBarManager by lazy { SnackBarManager() }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import com.ernestoyaquello.dragdropswiperecyclerview.listener.OnListScrollListen
import com.infomaniak.lib.core.MatomoCore.TrackerAction
import com.infomaniak.lib.core.utils.*
import com.infomaniak.lib.core.utils.Utils
import com.infomaniak.lib.stores.StoreUtils
import com.infomaniak.mail.MatomoMail.trackEvent
import com.infomaniak.mail.MatomoMail.trackMenuDrawerEvent
import com.infomaniak.mail.MatomoMail.trackMultiSelectionEvent
Expand Down Expand Up @@ -160,6 +161,7 @@ class ThreadListFragment : Fragment(), SwipeRefreshLayout.OnRefreshListener {
observeContacts()
observerDraftsActionsCompletedWorks()
observeFlushFolderTrigger()
observeUpdateInstall()
}.getOrDefault(Unit)

private fun navigateFromNotificationToNewMessage() {
Expand Down Expand Up @@ -569,6 +571,23 @@ class ThreadListFragment : Fragment(), SwipeRefreshLayout.OnRefreshListener {
mainViewModel.flushFolderTrigger.observe(viewLifecycleOwner) { descriptionDialog.resetLoadingAndDismiss() }
}

private fun observeUpdateInstall() = with(binding) {
mainViewModel.canInstallUpdate.observe(viewLifecycleOwner) { isUpdateDownloaded ->
installUpdateGroup.isVisible = isUpdateDownloaded
installUpdate.setOnClickListener {
trackEvent("inAppUpdate", "installUpdate")
mainViewModel.canInstallUpdate.value = false

StoreUtils.installDownloadedUpdate {
Sentry.captureException(it)
// This avoid the user being instantly reprompted to download update
localSettings.isUserWantingUpdates = false
mainViewModel.snackBarManager.setValue(getString(RCore.string.errorUpdateInstall))
}
}
}
}

private fun observerDraftsActionsCompletedWorks() {

fun observeDraftsActions() {
Expand Down
26 changes: 26 additions & 0 deletions app/src/main/res/drawable/ic_app_update.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Infomaniak Mail - Android
~ Copyright (C) 2023 Infomaniak Network SA
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000"
android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z" />
</vector>
63 changes: 55 additions & 8 deletions app/src/main/res/layout/fragment_thread_list.xml
Original file line number Diff line number Diff line change
Expand Up @@ -193,15 +193,62 @@
android:layout_height="wrap_content"
android:nestedScrollingEnabled="true">

<com.ernestoyaquello.dragdropswiperecyclerview.DragDropSwipeRecyclerView
android:id="@+id/threadsList"
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="@dimen/recyclerViewPaddingBottom"
app:behind_swiped_item_icon_margin="@dimen/marginStandard"
tools:listitem="@layout/cardview_thread_item"
tools:visibility="gone" />
android:layout_height="match_parent">

<TextView
android:id="@+id/updateDownloadedText"
style="@style/BodySmall"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/marginStandardMedium"
android:layout_marginTop="@dimen/marginStandardMedium"
android:text="@string/updateReadyTitle"
app:layout_constraintEnd_toStartOf="@+id/installUpdate"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<com.google.android.material.button.MaterialButton
android:id="@+id/installUpdate"
style="@style/TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/buttonInstall"
app:icon="@drawable/ic_app_update"
app:iconPadding="@dimen/marginStandardSmall"
app:iconSize="@dimen/marginStandardMedium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<com.google.android.material.divider.MaterialDivider
android:id="@+id/installUpdateDivider"
android:layout_width="match_parent"
android:layout_height="1dp"
app:dividerColor="@color/divider"
app:layout_constraintTop_toBottomOf="@id/installUpdate" />

<androidx.constraintlayout.widget.Group
android:id="@+id/installUpdateGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="installUpdate, installUpdateDivider, updateDownloadedText"
tools:visibility="visible" />

<com.ernestoyaquello.dragdropswiperecyclerview.DragDropSwipeRecyclerView
android:id="@+id/threadsList"
android:layout_width="match_parent"
android:layout_height="0dp"
android:clipToPadding="false"
android:paddingBottom="@dimen/recyclerViewPaddingBottom"
app:behind_swiped_item_icon_margin="@dimen/marginStandard"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/installUpdateDivider"
tools:listitem="@layout/cardview_thread_item"
tools:visibility="gone" />

</androidx.constraintlayout.widget.ConstraintLayout>

<com.infomaniak.mail.ui.main.EmptyStateView
android:id="@+id/emptyStateView"
Expand Down