diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 78a9d4d..c3465f2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -65,8 +65,8 @@ android { applicationId = "com.prime.player" minSdk = 21 targetSdk = 35 - versionCode = 159 - versionName = "3.0.1" + versionCode = 160 + versionName = "3.0.2" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary = true } // init different config fields. diff --git a/app/src/main/java/com/prime/media/MainActivity.kt b/app/src/main/java/com/prime/media/MainActivity.kt index 1c46fd2..8d713cb 100644 --- a/app/src/main/java/com/prime/media/MainActivity.kt +++ b/app/src/main/java/com/prime/media/MainActivity.kt @@ -206,7 +206,7 @@ class MainActivity : ComponentActivity(), SystemFacade, OnDestinationChangedList val res = toastHostState.showToast( "Restart the app for changes to take effect.", "Restart", - duration = Toast.DURATION_INDEFINITE + priority = Toast.PRIORITY_HIGH ) // Restart the app if the user chooses to if (res == Toast.ACTION_PERFORMED) @@ -266,20 +266,15 @@ class MainActivity : ComponentActivity(), SystemFacade, OnDestinationChangedList @Suppress("UNCHECKED_CAST") override fun getDeviceService(name: String): T = getSystemService(name) as T - override fun showToast( - message: CharSequence, - icon: ImageVector?, - accent: Color, - duration: Int - ) { + override fun showToast(message: CharSequence, icon: ImageVector?, accent: Color, priority: Int) { lifecycleScope.launch { - toastHostState.showToast(message, null, icon, accent, duration) + toastHostState.showToast(message, null, icon, accent, priority) } } - override fun showToast(message: Int, icon: ImageVector?, accent: Color, duration: Int) { + override fun showToast(message: Int, icon: ImageVector?, accent: Color, priority: Int) { lifecycleScope.launch { - toastHostState.showToast(resources.getText2(id = message), null, icon, accent, duration) + toastHostState.showToast(resources.getText2(id = message), null, icon, accent, priority) } } @@ -357,7 +352,7 @@ class MainActivity : ComponentActivity(), SystemFacade, OnDestinationChangedList val res = toastHostState.showToast( message = resources.getText2(R.string.msg_new_update_downloaded), action = resources.getText2(R.string.install), - duration = Toast.DURATION_INDEFINITE, + priority = Toast.PRIORITY_HIGH, accent = Color.MetroGreen, icon = Icons.Outlined.Downloading ) @@ -484,7 +479,7 @@ class MainActivity : ComponentActivity(), SystemFacade, OnDestinationChangedList ), icon = Icons.Outlined.AdsClick, action = getString(R.string.claim).uppercase(), - duration = Toast.DURATION_INDEFINITE, + priority = Toast.PRIORITY_HIGH, accent = Color.MetroGreen2 ) if (result == Toast.ACTION_PERFORMED) { @@ -518,7 +513,7 @@ class MainActivity : ComponentActivity(), SystemFacade, OnDestinationChangedList remaining ), icon = Icons.Outlined.AdsClick, - duration = Toast.DURATION_INDEFINITE, + priority = Toast.PRIORITY_HIGH, accent = Color.MetroGreen, ) } @@ -588,7 +583,7 @@ class MainActivity : ComponentActivity(), SystemFacade, OnDestinationChangedList val result = toastHostState.showToast( info.richDesc, action = info.formattedPrice ?: "N/A", - duration = Toast.DURATION_INDEFINITE + priority = Toast.PRIORITY_CRITICAL ) if (result == Toast.ACTION_PERFORMED) initiatePurchaseFlow(BuildConfig.IAP_NO_ADS) @@ -602,7 +597,7 @@ class MainActivity : ComponentActivity(), SystemFacade, OnDestinationChangedList val result = toastHostState.showToast( info.richDesc, action = info.formattedPrice ?: "N/A", - duration = Toast.DURATION_INDEFINITE + priority = Toast.PRIORITY_CRITICAL ) if (result == Toast.ACTION_PERFORMED) initiatePurchaseFlow(BuildConfig.IAP_CODEX) @@ -616,7 +611,7 @@ class MainActivity : ComponentActivity(), SystemFacade, OnDestinationChangedList val result = toastHostState.showToast( info.richDesc, action = info.formattedPrice ?: getText(R.string.abbr_not_available), - duration = Toast.DURATION_INDEFINITE + priority = Toast.PRIORITY_CRITICAL ) if (result == Toast.ACTION_PERFORMED) initiatePurchaseFlow(BuildConfig.IAP_BUY_ME_COFFEE) @@ -630,7 +625,7 @@ class MainActivity : ComponentActivity(), SystemFacade, OnDestinationChangedList val result = toastHostState.showToast( info.richDesc, action = info.formattedPrice ?: getText(R.string.abbr_not_available), - duration = Toast.DURATION_INDEFINITE + priority = Toast.PRIORITY_CRITICAL ) if (result == Toast.ACTION_PERFORMED) initiatePurchaseFlow(BuildConfig.IAP_TAG_EDITOR_PRO) @@ -645,7 +640,7 @@ class MainActivity : ComponentActivity(), SystemFacade, OnDestinationChangedList val result = toastHostState.showToast( resources.getText2(R.string.msg_promotion_gallery_app), action = resources.getText2(R.string.dive_in), - duration = Toast.DURATION_INDEFINITE, + priority = Toast.PRIORITY_CRITICAL, accent = Color.Amber, icon = Icons.Outlined.GetApp ) @@ -656,8 +651,8 @@ class MainActivity : ComponentActivity(), SystemFacade, OnDestinationChangedList // promo message for widgets. 5 -> { val result = toastHostState.showToast( - "Personalize your app now with in-app widgets!", - duration = Toast.DURATION_INDEFINITE, + resources.getText2(R.string.msg_promo_personalize), + priority = Toast.PRIORITY_CRITICAL, accent = Color.MetroGreen, icon = Icons.Outlined.ColorLens, action = "View" @@ -712,7 +707,7 @@ class MainActivity : ComponentActivity(), SystemFacade, OnDestinationChangedList id = R.string.msg_install_dynamic_module_ss, details.title ), - duration = Toast.DURATION_INDEFINITE, + priority = Toast.PRIORITY_HIGH, action = resources.getText2(R.string.install) ) if (response == Toast.ACTION_PERFORMED) @@ -737,7 +732,7 @@ class MainActivity : ComponentActivity(), SystemFacade, OnDestinationChangedList preferences[KEY_APP_VERSION_CODE] = versionCode showToast( R.string.what_s_new_toast, - duration = Toast.DURATION_INDEFINITE, + priority = Toast.PRIORITY_HIGH, icon = Icons.Outlined.Whatshot ) } diff --git a/app/src/main/java/com/prime/media/common/SystemFacade.kt b/app/src/main/java/com/prime/media/common/SystemFacade.kt index 30ef8e6..1af4e90 100644 --- a/app/src/main/java/com/prime/media/common/SystemFacade.kt +++ b/app/src/main/java/com/prime/media/common/SystemFacade.kt @@ -4,7 +4,6 @@ package com.prime.media.common import android.app.Activity import android.content.Intent -import android.content.pm.PackageManager import android.net.Uri import android.os.Bundle import android.util.Log @@ -24,7 +23,7 @@ import com.prime.media.MainActivity import com.primex.preferences.Key import com.zs.core.paymaster.Purchase import com.zs.core_ui.WindowStyle -import com.zs.core_ui.toast.Duration +import com.zs.core_ui.toast.Priority import com.zs.core_ui.toast.Toast import kotlinx.coroutines.flow.map @@ -126,7 +125,7 @@ interface SystemFacade { message: CharSequence, icon: ImageVector? = null, accent: Color = Color.Unspecified, - @Duration duration: Int = Toast.DURATION_SHORT, + @Priority priority: Int = Toast.PRIORITY_LOW, ) /** @@ -136,7 +135,7 @@ interface SystemFacade { @StringRes message: Int, icon: ImageVector? = null, accent: Color = Color.Unspecified, - @Duration duration: Int = Toast.DURATION_SHORT, + @Priority priority: Int = Toast.PRIORITY_LOW, ) /** @@ -161,12 +160,12 @@ interface SystemFacade { /** * @see com.zs.core_ui.showPlatformToast */ - fun showPlatformToast(message: String, @Duration duration: Int = Toast.DURATION_SHORT) + fun showPlatformToast(message: String, @Priority priority: Int = Toast.PRIORITY_LOW) /** * @see com.zs.core_ui.showPlatformToast */ - fun showPlatformToast(@StringRes message: Int, @Duration duration: Int = Toast.DURATION_SHORT) + fun showPlatformToast(@StringRes message: Int, @Priority priority: Int = Toast.PRIORITY_LOW) /** * Returns the handle to a system-level service by name. diff --git a/app/src/main/java/com/prime/media/impl/KoinViewModel.kt b/app/src/main/java/com/prime/media/impl/KoinViewModel.kt index b89e487..78c55c3 100644 --- a/app/src/main/java/com/prime/media/impl/KoinViewModel.kt +++ b/app/src/main/java/com/prime/media/impl/KoinViewModel.kt @@ -37,7 +37,7 @@ import com.primex.core.OrientRed import com.primex.core.getText2 import com.primex.core.withSpanStyle import com.primex.preferences.Preferences -import com.zs.core_ui.toast.Duration +import com.zs.core_ui.toast.Priority import com.zs.core_ui.toast.Result import com.zs.core_ui.toast.Toast import com.zs.core_ui.toast.ToastHostState @@ -62,34 +62,34 @@ abstract class KoinViewModel : ScopeViewModel() { fun showPlatformToast( @StringRes message: Int, - @Duration duration: Int = Toast.DURATION_SHORT - ) = context.showAndroidToast(message, duration) + @Priority priority: Int = Toast.PRIORITY_LOW + ) = context.showAndroidToast(message, priority) fun showPlatformToast( message: String, - @Duration duration: Int = Toast.DURATION_SHORT - ) = context.showAndroidToast(message, duration) + @Priority priority: Int = Toast.PRIORITY_LOW + ) = context.showAndroidToast(message, priority) suspend fun showToast( message: CharSequence, action: CharSequence? = null, icon: ImageVector? = null, accent: Color = Color.Unspecified, - @Duration duration: Int = if (action == null) Toast.DURATION_SHORT else Toast.DURATION_INDEFINITE - ): @Result Int = toastHostState.showToast(message, action, icon, accent, duration) + @Priority priority: Int = if (action == null) Toast.PRIORITY_LOW else Toast.PRIORITY_HIGH + ): @Result Int = toastHostState.showToast(message, action, icon, accent, priority) suspend fun showToast( @StringRes message: Int, @StringRes action: Int = ResourcesCompat.ID_NULL, icon: ImageVector? = null, accent: Color = Color.Unspecified, - @Duration duration: Int = if (action == ResourcesCompat.ID_NULL) Toast.DURATION_SHORT else Toast.DURATION_INDEFINITE + @Priority priority: Int = if (action == ResourcesCompat.ID_NULL) Toast.PRIORITY_LOW else Toast.PRIORITY_HIGH ): @Result Int = showToast( message = resources.getText2(message), action = if (action == ResourcesCompat.ID_NULL) null else resources.getText2(action), icon = icon, accent = accent, - duration = duration + priority = priority ) fun getText(@StringRes id: Int): CharSequence = resources.getText2(id) @@ -109,7 +109,7 @@ abstract class KoinViewModel : ScopeViewModel() { action = "REPORT", icon = Icons.Outlined.Error, accent = Color.OrientRed, - duration = Toast.DURATION_LONG + priority = Toast.PRIORITY_MEDIUM ) /** diff --git a/app/src/main/java/com/prime/media/impl/PlaylistsViewModel.kt b/app/src/main/java/com/prime/media/impl/PlaylistsViewModel.kt index df2fd8a..479241a 100644 --- a/app/src/main/java/com/prime/media/impl/PlaylistsViewModel.kt +++ b/app/src/main/java/com/prime/media/impl/PlaylistsViewModel.kt @@ -69,7 +69,7 @@ class PlaylistsViewModel(val playlists: Playlists) : KoinViewModel(), PlaylistsV action = "Delete", icon = Icons.Outlined.FolderDelete, accent = Color.RedViolet, - duration = Toast.DURATION_INDEFINITE + priority = Toast.PRIORITY_HIGH ) if (result != Toast.ACTION_PERFORMED) return@launch // Attempt to delete the playlist from the data source (e.g., database). diff --git a/app/src/main/java/com/prime/media/old/console/ConsoleView.kt b/app/src/main/java/com/prime/media/old/console/ConsoleView.kt index 9969e65..862fde4 100644 --- a/app/src/main/java/com/prime/media/old/console/ConsoleView.kt +++ b/app/src/main/java/com/prime/media/old/console/ConsoleView.kt @@ -194,7 +194,7 @@ fun SystemFacade.launchEqualizer(id: Int) { showToast( message = R.string.msg_3rd_party_equalizer_not_found, accent = Color.OrientRed, - duration = Toast.DURATION_SHORT + priority = Toast.PRIORITY_LOW ) } diff --git a/app/src/main/java/com/prime/media/old/directory/playlists/Members.kt b/app/src/main/java/com/prime/media/old/directory/playlists/Members.kt index ac2f309..095ef18 100644 --- a/app/src/main/java/com/prime/media/old/directory/playlists/Members.kt +++ b/app/src/main/java/com/prime/media/old/directory/playlists/Members.kt @@ -24,7 +24,6 @@ import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope import com.prime.media.R import com.prime.media.old.common.Artwork -import com.prime.media.common.composable import com.prime.media.old.common.composable import com.prime.media.old.common.util.addDistinct import com.prime.media.old.common.util.toMediaItem @@ -131,7 +130,7 @@ class MembersViewModel( "Error", icon = Icons.Outlined.Error, accent = Color.Rose, - duration = Toast.DURATION_INDEFINITE + priority = Toast.PRIORITY_HIGH ) }.stateIn(viewModelScope, SharingStarted.Lazily, emptyMap()) diff --git a/app/src/main/java/com/prime/media/old/directory/store/Artists.kt b/app/src/main/java/com/prime/media/old/directory/store/Artists.kt index 021934c..8cbad22 100644 --- a/app/src/main/java/com/prime/media/old/directory/store/Artists.kt +++ b/app/src/main/java/com/prime/media/old/directory/store/Artists.kt @@ -126,7 +126,7 @@ class ArtistsViewModel ( "Error\nSome unknown error occured!.", icon = Icons.Outlined.Error, accent = Color.Rose, - duration = Toast.DURATION_INDEFINITE + priority = Toast.PRIORITY_HIGH ) } .stateIn(viewModelScope, SharingStarted.Lazily, emptyMap()) diff --git a/app/src/main/java/com/prime/media/old/directory/store/Audios.kt b/app/src/main/java/com/prime/media/old/directory/store/Audios.kt index de1edc5..958a867 100644 --- a/app/src/main/java/com/prime/media/old/directory/store/Audios.kt +++ b/app/src/main/java/com/prime/media/old/directory/store/Audios.kt @@ -260,7 +260,7 @@ class AudiosViewModel ( "Error\nSome unknown error occured!. $it", icon = Icons.Outlined.Error, accent = Color.Rose, - duration = Toast.DURATION_INDEFINITE + priority = Toast.PRIORITY_HIGH ) } .stateIn(viewModelScope, SharingStarted.Lazily, emptyMap()) @@ -509,10 +509,10 @@ class AudiosViewModel ( "Delete", icon = Icons.Outlined.WarningAmber, accent = Color.Rose, - Toast.DURATION_INDEFINITE + Toast.PRIORITY_HIGH ) // check if user is interested in deleting the files or not. - if (res == Toast.RESULT_DISMISSED) + if (res == Toast.ACTION_DISMISSED) return@launch // return repository.delete(activity, *uris.toTypedArray(), trash = false) diff --git a/app/src/main/java/com/prime/media/old/directory/store/Folders.kt b/app/src/main/java/com/prime/media/old/directory/store/Folders.kt index a82c604..503a6cd 100644 --- a/app/src/main/java/com/prime/media/old/directory/store/Folders.kt +++ b/app/src/main/java/com/prime/media/old/directory/store/Folders.kt @@ -120,7 +120,7 @@ class FoldersViewModel ( "Error\nSome unknown error occured!. ${it.message}", icon = Icons.Outlined.Error, accent = Color.Rose, - duration = Toast.DURATION_INDEFINITE + priority = Toast.PRIORITY_HIGH ) } .stateIn(viewModelScope, SharingStarted.Lazily, emptyMap()) @@ -134,9 +134,9 @@ class FoldersViewModel ( "Warning\nYou are about to block folder $name", icon = Icons.Outlined.Block, accent = Color.DahliaYellow, - duration = Toast.DURATION_INDEFINITE, + priority = Toast.PRIORITY_HIGH, ) - if (response == Toast.RESULT_DISMISSED) + if (response == Toast.ACTION_DISMISSED) return@launch val result = preferences.block(path) if (result > 0) @@ -144,7 +144,7 @@ class FoldersViewModel ( "$name has been added to block list", icon = Icons.Outlined.Block, accent = Color.Rose, - duration = Toast.DURATION_SHORT, + priority = Toast.PRIORITY_LOW, ) else showToast("Oops! some unknown error has occurred.") diff --git a/app/src/main/java/com/prime/media/old/directory/store/Genres.kt b/app/src/main/java/com/prime/media/old/directory/store/Genres.kt index 1eae3df..df9198b 100644 --- a/app/src/main/java/com/prime/media/old/directory/store/Genres.kt +++ b/app/src/main/java/com/prime/media/old/directory/store/Genres.kt @@ -122,7 +122,7 @@ class GenresViewModel ( "Error\nSome unknown error occured!.", icon = Icons.Outlined.Error, accent = Color.Rose, - duration = Toast.DURATION_INDEFINITE + priority = Toast.PRIORITY_HIGH ) } .stateIn(viewModelScope, SharingStarted.Lazily, emptyMap()) diff --git a/app/src/main/java/com/prime/media/old/impl/SystemDelegate.kt b/app/src/main/java/com/prime/media/old/impl/SystemDelegate.kt index f5175c3..b9c4ab4 100644 --- a/app/src/main/java/com/prime/media/old/impl/SystemDelegate.kt +++ b/app/src/main/java/com/prime/media/old/impl/SystemDelegate.kt @@ -7,11 +7,10 @@ import androidx.annotation.PluralsRes import androidx.annotation.StringRes import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.text.ExperimentalTextApi import androidx.core.content.res.ResourcesCompat import com.primex.core.getQuantityText2 import com.primex.core.getText2 -import com.zs.core_ui.toast.Duration +import com.zs.core_ui.toast.Priority import com.zs.core_ui.toast.Result import com.zs.core_ui.toast.ToastHostState @@ -58,7 +57,7 @@ interface SystemDelegate { action: CharSequence? = null, icon: ImageVector? = null, accent: Color = Color.Unspecified, - @Duration duration: Int = if (action == null) com.zs.core_ui.toast.Toast.DURATION_SHORT else com.zs.core_ui.toast.Toast.DURATION_INDEFINITE + @Priority priority: Int = if (action == null) com.zs.core_ui.toast.Toast.PRIORITY_LOW else com.zs.core_ui.toast.Toast.PRIORITY_HIGH ): @Result Int suspend fun showSnackbar( @@ -66,13 +65,13 @@ interface SystemDelegate { @StringRes action: Int = ResourcesCompat.ID_NULL, icon: ImageVector? = null, accent: Color = Color.Unspecified, - @Duration duration: Int = if (action == ResourcesCompat.ID_NULL) com.zs.core_ui.toast.Toast.DURATION_SHORT else com.zs.core_ui.toast.Toast.DURATION_INDEFINITE + @Priority priority: Int = if (action == ResourcesCompat.ID_NULL) com.zs.core_ui.toast.Toast.PRIORITY_LOW else com.zs.core_ui.toast.Toast.PRIORITY_HIGH ): @Result Int = showSnackbar( message = resources.getText2(message), action = if (action == ResourcesCompat.ID_NULL) null else resources.getText2(action), icon = icon, accent = accent, - duration = duration + priority = priority ) } diff --git a/app/src/main/java/com/prime/media/old/impl/TagEditorViewModel.kt b/app/src/main/java/com/prime/media/old/impl/TagEditorViewModel.kt index 443e8c1..2dfef8c 100644 --- a/app/src/main/java/com/prime/media/old/impl/TagEditorViewModel.kt +++ b/app/src/main/java/com/prime/media/old/impl/TagEditorViewModel.kt @@ -377,7 +377,7 @@ class TagEditorViewModel constructor( viewModelScope.launch { val action = snackbar.showToast("Resetting the file will discard all the changes", action = "Proceed") - if (action == Toast.RESULT_DISMISSED) + if (action == Toast.ACTION_DISMISSED) return@launch // else reset/reinitialize initialize() @@ -441,7 +441,7 @@ class TagEditorViewModel constructor( "Saving the file will overwrite the original", action = "Proceed" ) - if (action == Toast.RESULT_DISMISSED) + if (action == Toast.ACTION_DISMISSED) return@launch val result = runCatching { val cacheDir = ctx.cacheDir.path diff --git a/app/src/main/java/com/prime/media/personalize/Upgrades.kt b/app/src/main/java/com/prime/media/personalize/Upgrades.kt index 747986f..8264079 100644 --- a/app/src/main/java/com/prime/media/personalize/Upgrades.kt +++ b/app/src/main/java/com/prime/media/personalize/Upgrades.kt @@ -29,8 +29,6 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.CutCornerShape -import androidx.compose.material.ButtonDefaults.OutlinedBorderSize import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.Surface import androidx.compose.material.icons.Icons @@ -119,7 +117,7 @@ private fun Upgrade( onClick = { facade.showToast( value.richDesc, - duration = Toast.DURATION_INDEFINITE + priority = Toast.PRIORITY_HIGH ) }, // modifier = Modifier.scale(0.9f) diff --git a/app/src/main/res/drawable/ic_splash.png b/app/src/main/res/drawable/ic_splash.png index cc7ba0d..4a5ca58 100644 Binary files a/app/src/main/res/drawable/ic_splash.png and b/app/src/main/res/drawable/ic_splash.png differ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2a586d7..211793e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -411,12 +411,13 @@ Dive In! Home Error\nOops an unknown error occurred while checking for update. - Playlist\nCraft your own playlist or edit an existing one. + Playlist\nCraft your own playlist or edit an existing one. Remove Play order %1$d\nFiles - %1$s\nLast updated + %1$s\nLast updated Delete Playlist Search - ColorNav\nUse vibrant color to paint navigation bar. + ColorNav\nUse vibrant color to paint navigation bar. + Personalize\nCustomize your app with in-app widgets and change the nav bar accent color. More features coming soon—stay tuned! \ No newline at end of file diff --git a/core-ui/src/main/java/com/zs/core_ui/Utils.kt b/core-ui/src/main/java/com/zs/core_ui/Utils.kt index fce0e02..312b3ea 100644 --- a/core-ui/src/main/java/com/zs/core_ui/Utils.kt +++ b/core-ui/src/main/java/com/zs/core_ui/Utils.kt @@ -5,14 +5,12 @@ import android.content.pm.PackageManager import android.os.Build import android.view.Window import androidx.annotation.StringRes -import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.WindowInsets import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb -import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat import androidx.core.view.WindowInsetsControllerCompat -import com.zs.core_ui.toast.Duration +import com.zs.core_ui.toast.Priority import com.zs.core_ui.toast.Toast import android.widget.Toast as AndroidWidgetToast @@ -40,15 +38,15 @@ fun Context.checkSelfPermissions(values: List) = * This function uses the standard Android Toast class to display a short message to the user. * * @param message The text message to display in the Toast. - * @param duration The duration of the Toast. Must be either [Toast.DURATION_SHORT] or [Toast.DURATION_LONG]. + * @param priority The duration of the Toast. Must be either [Toast.PRIORITY_LOW] or [Toast.PRIORITY_MEDIUM]. */ -fun Context.showPlatformToast(message: String, @Duration duration: Int = Toast.DURATION_SHORT) { +fun Context.showPlatformToast(message: String, @Priority priority: Int = Toast.PRIORITY_LOW) { // Ensure the duration is valid - require(duration == Toast.DURATION_SHORT || duration == Toast.DURATION_LONG) { + require(priority == Toast.PRIORITY_LOW || priority == Toast.PRIORITY_MEDIUM) { "Duration must be either Toast.DURATION_SHORT or Toast.DURATION_LONG" } // Create and show the Toast - val toastDuration = if (duration == Toast.DURATION_SHORT) AndroidWidgetToast.LENGTH_SHORT else AndroidWidgetToast.LENGTH_LONG + val toastDuration = if (priority == Toast.PRIORITY_LOW) AndroidWidgetToast.LENGTH_SHORT else AndroidWidgetToast.LENGTH_LONG AndroidWidgetToast.makeText(this, message, toastDuration).show() } @@ -57,13 +55,13 @@ fun Context.showPlatformToast(message: String, @Duration duration: Int = Toast.D */ fun Context.showPlatformToast( @StringRes message: Int, - @Duration duration: Int = Toast.DURATION_SHORT + @Priority priority: Int = Toast.PRIORITY_LOW ) { - require(duration == Toast.DURATION_SHORT || duration == Toast.DURATION_LONG) { + require(priority == Toast.PRIORITY_LOW || priority == Toast.PRIORITY_MEDIUM) { "Duration must be either Toast.DURATION_SHORT or Toast.DURATION_LONG" } // Create and show the Toast - val toastDuration = if (duration == Toast.DURATION_SHORT) AndroidWidgetToast.LENGTH_SHORT else AndroidWidgetToast.LENGTH_LONG + val toastDuration = if (priority == Toast.PRIORITY_LOW) AndroidWidgetToast.LENGTH_SHORT else AndroidWidgetToast.LENGTH_LONG AndroidWidgetToast.makeText(this, message, toastDuration).show() } diff --git a/core-ui/src/main/java/com/zs/core_ui/toast/Toast.kt b/core-ui/src/main/java/com/zs/core_ui/toast/Toast.kt index 17825ee..ff7d2cd 100644 --- a/core-ui/src/main/java/com/zs/core_ui/toast/Toast.kt +++ b/core-ui/src/main/java/com/zs/core_ui/toast/Toast.kt @@ -80,47 +80,41 @@ import kotlin.coroutines.resume * * @property message The text message to be displayed in the Toast. * @property action Optional label for an action button to be shown in the Toast. - * @property duration The duration for which the Toast should be displayed. See [Toast.DURATION_SHORT], - * [Toast.DURATION_LONG], and [Toast.DURATION_INDEFINITE]. + * @property priority The duration for which the Toast should be displayed. See [Toast.PRIORITY_LOW], + * [Toast.PRIORITY_MEDIUM], [Toast.PRIORITY_HIGH] and [Toast.PRIORITY_CRITICAL]. * @property accent The accent color to be used for this Toast. Defaults to [Color.Unspecified]. * @property icon Optional leading icon to be displayed in the Toast. */ interface Toast { + /** + * Companion object containing constants for Toast priorities and action result codes. + * @property PRIORITY_LOW Show the Toast for a short period of time. + * @property PRIORITY_MEDIUM Show the Toast for a long period of time. + * @property PRIORITY_HIGH Show the Toast indefinitely until explicitly dismissed or the action is clicked. + * @property PRIORITY_CRITICAL Show the Toast indefinitely until explicitly dismissed or the + * action is clicked and also the Toast is in expanded state. + * @property ACTION_PERFORMED Result code indicating the Toast's action was performed. + * @property ACTION_DISMISSED Result code indicating the Toast was dismissed. + */ companion object { - /** - * Show the Toast for a short period of time. - */ - const val DURATION_SHORT = 0 - - /** - * Show the Toast for a long period of time. - */ - const val DURATION_LONG = 1 - - /*** Show the Toast indefinitely until explicitly dismissed or the action is clicked. - */ - const val DURATION_INDEFINITE = 2 - - /** - * Result code indicating the Toast's action was performed. - */ + const val PRIORITY_LOW = 0 + const val PRIORITY_MEDIUM = 1 + const val PRIORITY_HIGH = 2 + const val PRIORITY_CRITICAL = 3 const val ACTION_PERFORMED = 1 - - /** - * Result code indicating the Toast was dismissed. - */ - const val RESULT_DISMISSED = 2 + const val ACTION_DISMISSED = 2 } + val accent: Color get() = Color.Unspecified val icon: ImageVector? val message: CharSequence val action: CharSequence? get() = null - @Duration - val duration: Int + @Priority + val priority: Int /** * Callback invoked when the Toast's action button is clicked. @@ -138,7 +132,7 @@ interface Toast { internal data class Data( override val icon: ImageVector?, override val message: CharSequence, - @Duration override val duration: Int, + @Priority override val priority: Int, override val action: CharSequence?, override val accent: Color, private val continuation: CancellableContinuation, @@ -149,26 +143,26 @@ internal data class Data( } override fun dismiss() { - if (continuation.isActive) continuation.resume(Toast.RESULT_DISMISSED) + if (continuation.isActive) continuation.resume(Toast.ACTION_DISMISSED) } } /** * Annotation for properties representing Toast duration values. */ -@IntDef(Toast.DURATION_LONG, Toast.DURATION_SHORT, Toast.DURATION_INDEFINITE) +@IntDef(Toast.PRIORITY_MEDIUM, Toast.PRIORITY_LOW, Toast.PRIORITY_HIGH) @Target( AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER ) @Retention(AnnotationRetention.SOURCE) @MustBeDocumented -annotation class Duration +annotation class Priority /** * Annotation for properties representing Toast result codes. */ -@IntDef(Toast.ACTION_PERFORMED, Toast.RESULT_DISMISSED) +@IntDef(Toast.ACTION_PERFORMED, Toast.ACTION_DISMISSED) @Target( AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY, AnnotationTarget.TYPE @@ -189,9 +183,9 @@ internal fun Toast.toMillis( hasAction: Boolean, accessibilityManager: AccessibilityManager? ): Long { - val original = when (duration) { - Toast.DURATION_SHORT -> 4000L - Toast.DURATION_LONG -> 10000L + val original = when (priority) { + Toast.PRIORITY_LOW -> 4000L + Toast.PRIORITY_MEDIUM -> 10000L else -> Long.MAX_VALUE } if (accessibilityManager == null) { @@ -231,16 +225,18 @@ internal fun Toast( actionColor: Color = value.accent.takeOrElse { AppTheme.colors.accent }, ) { // State to track if Toast is expanded - var isExpanded: Boolean by remember { mutableStateOf(false) } + val critical = value.priority == Toast.PRIORITY_CRITICAL + var isExpanded: Boolean by remember { mutableStateOf(critical) } // Handle back press to dismiss expanded Toast or the entire Toast // BackHandler(isExpanded) { isExpanded = !isExpanded } // State for swipe-to-dismiss gesture + val dismissState = rememberDismissState( confirmStateChange = { - // Dismiss only if not expanded - if (isExpanded) return@rememberDismissState false + // Dismiss only if not expanded or critical and expanded + if (critical || isExpanded || it == DismissValue.DismissedToEnd) return@rememberDismissState false // Execute action if confirmed - if (it == DismissValue.DismissedToEnd || it == DismissValue.DismissedToStart) value.dismiss() + value.dismiss() true } ) @@ -339,7 +335,7 @@ internal fun Toast( .padding(horizontal = 18.dp) .shadow(6.dp, shape, clip = true) // Toggle expanded state on click - .clickable(indication = null, interactionSource = null, enabled = value.message.length > 100) { + .clickable(indication = null, interactionSource = null, enabled = !critical && value.message.length > 100) { isExpanded = !isExpanded } // Apply border and visual effect if dark theme diff --git a/core-ui/src/main/java/com/zs/core_ui/toast/ToastHostState.kt b/core-ui/src/main/java/com/zs/core_ui/toast/ToastHostState.kt index 962a980..f956b28 100644 --- a/core-ui/src/main/java/com/zs/core_ui/toast/ToastHostState.kt +++ b/core-ui/src/main/java/com/zs/core_ui/toast/ToastHostState.kt @@ -53,7 +53,7 @@ class ToastHostState { * @param action Optional label for an action button to be shown in the Toast. * @param icon Optional leading icon to be displayed in the Toast. * @param accent The accent color to be used for this Toast. - * @param duration The duration for which the Toast should be displayed. + * @param priority The duration for which the Toast should be displayed. * @return A[Result] code indicating whether the Toast was dismissed or its action was performed. */ suspend fun showToast( @@ -61,12 +61,12 @@ class ToastHostState { action: CharSequence? = null, icon: ImageVector? = null, accent: Color = Color.Unspecified, - @Duration duration: Int = if (action == null) Toast.DURATION_SHORT else Toast.DURATION_INDEFINITE + @Priority priority: Int = if (action == null) Toast.PRIORITY_LOW else Toast.PRIORITY_HIGH ): @Result Int { mutex.withLock { try { return suspendCancellableCoroutine { continuation -> - current = Data(icon, message, duration, action, accent, continuation) + current = Data(icon, message, priority, action, accent, continuation) } } finally { current = null