mirror of
https://github.com/yogeshpaliyal/KeyPass.git
synced 2026-01-12 09:20:14 -06:00
feat: batch actions (#1062)
This commit is contained in:
committed by
GitHub
parent
7831511ed6
commit
35cae1f1b0
@@ -20,6 +20,7 @@ import com.yogeshpaliyal.common.dbhelper.restoreBackup
|
||||
import com.yogeshpaliyal.common.utils.BACKUP_KEY_LENGTH
|
||||
import com.yogeshpaliyal.keypass.R
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.Action
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.BatchActions
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.RestoreAccountsAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.ToastAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.UpdateDialogAction
|
||||
@@ -68,9 +69,13 @@ fun RestoreKeyPassBackupDialog(
|
||||
restoreBackup(keyphrase, context.contentResolver, selectedFile)
|
||||
|
||||
if (result != null) {
|
||||
dispatchAction(RestoreAccountsAction(result))
|
||||
dispatchAction(UpdateDialogAction(null))
|
||||
dispatchAction(ToastAction(R.string.backup_restored))
|
||||
dispatchAction(
|
||||
BatchActions(
|
||||
RestoreAccountsAction(result),
|
||||
UpdateDialogAction(null),
|
||||
ToastAction(R.string.backup_restored)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
dispatchAction(ToastAction(R.string.invalid_keyphrase))
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.yogeshpaliyal.keypass.ui.commonComponents.DefaultBottomAppBar
|
||||
import com.yogeshpaliyal.keypass.ui.commonComponents.KeyPassInputField
|
||||
import com.yogeshpaliyal.keypass.ui.nav.LocalUserSettings
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.Action
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.BatchActions
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.GoBackAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.ToastAction
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -54,8 +55,7 @@ fun PasswordHintScreen() {
|
||||
Button(modifier = Modifier.fillMaxWidth(1f), onClick = {
|
||||
coroutineScope.launch {
|
||||
context.setPasswordHint(passwordHint)
|
||||
dispatchAction(ToastAction(R.string.hint_change_success))
|
||||
dispatchAction(GoBackAction)
|
||||
dispatchAction(BatchActions(GoBackAction, ToastAction(R.string.hint_change_success)))
|
||||
}
|
||||
}) {
|
||||
Text(text = stringResource(id = R.string.change_app_hint))
|
||||
@@ -64,8 +64,7 @@ fun PasswordHintScreen() {
|
||||
OutlinedButton(modifier = Modifier.fillMaxWidth(1f), onClick = {
|
||||
coroutineScope.launch {
|
||||
context.setPasswordHint(null)
|
||||
dispatchAction(ToastAction(R.string.hint_removed_success))
|
||||
dispatchAction(GoBackAction)
|
||||
dispatchAction(BatchActions(GoBackAction, ToastAction(R.string.hint_removed_success)))
|
||||
}
|
||||
}) {
|
||||
Text(text = stringResource(id = R.string.remove_app_hint))
|
||||
|
||||
@@ -1,22 +1,16 @@
|
||||
package com.yogeshpaliyal.keypass.ui.redux
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.yogeshpaliyal.keypass.R
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.BatchActions
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.BottomSheetAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.CopyToClipboard
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.GoBackAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.NavigationAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.RestoreAccountsAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.StateUpdateAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.ToastAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.ToastActionStr
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.UpdateContextAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.UpdateDialogAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.UpdateViewModalAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.middlewares.intentNavigationMiddleware
|
||||
import com.yogeshpaliyal.keypass.ui.redux.middlewares.utilityMiddleware
|
||||
import com.yogeshpaliyal.keypass.ui.redux.states.BottomSheetState
|
||||
import com.yogeshpaliyal.keypass.ui.redux.states.KeyPassState
|
||||
import com.yogeshpaliyal.keypass.ui.redux.states.ScreenState
|
||||
@@ -32,7 +26,17 @@ object KeyPassRedux {
|
||||
fun getLastScreen() = arrPages.lastOrNull()
|
||||
|
||||
private val reducer: Reducer<KeyPassState> = { state, action ->
|
||||
when (action) {
|
||||
if (action is BatchActions) {
|
||||
action.actions.fold(state) { acc, act ->
|
||||
handleAction(act, acc)
|
||||
}
|
||||
} else {
|
||||
handleAction(action, state)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleAction(action: Any, state: KeyPassState): KeyPassState {
|
||||
return when (action) {
|
||||
is NavigationAction -> {
|
||||
if (action.clearBackStack) {
|
||||
arrPages.clear()
|
||||
@@ -49,43 +53,10 @@ object KeyPassRedux {
|
||||
state.copy(currentScreen = action.state)
|
||||
}
|
||||
|
||||
is CopyToClipboard -> {
|
||||
state.context?.let {
|
||||
val clipboard = ContextCompat.getSystemService(
|
||||
it,
|
||||
ClipboardManager::class.java
|
||||
)
|
||||
val clip = ClipData.newPlainText("KeyPass", action.password)
|
||||
clipboard?.setPrimaryClip(clip)
|
||||
|
||||
Toast.makeText(
|
||||
it,
|
||||
R.string.copied_to_clipboard,
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
}
|
||||
state
|
||||
}
|
||||
|
||||
is UpdateContextAction -> {
|
||||
state.copy(context = action.context)
|
||||
}
|
||||
|
||||
is ToastAction -> {
|
||||
state.context?.let {
|
||||
Toast.makeText(it, action.text, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
state
|
||||
}
|
||||
|
||||
is ToastActionStr -> {
|
||||
state.context?.let {
|
||||
Toast.makeText(it, action.text, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
state
|
||||
}
|
||||
|
||||
is GoBackAction -> {
|
||||
val lastItem = arrPages.removeLastOrNull()
|
||||
if (lastItem != null) {
|
||||
@@ -104,6 +75,7 @@ object KeyPassRedux {
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
is UpdateDialogAction -> {
|
||||
state.copy(dialog = action.dialogState)
|
||||
}
|
||||
@@ -125,6 +97,6 @@ object KeyPassRedux {
|
||||
createStore(
|
||||
reducer,
|
||||
generateDefaultState(),
|
||||
applyMiddleware(intentNavigationMiddleware)
|
||||
applyMiddleware(utilityMiddleware, intentNavigationMiddleware)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,12 +8,45 @@ import com.yogeshpaliyal.keypass.ui.redux.states.ScreenState
|
||||
|
||||
sealed interface Action
|
||||
|
||||
/**
|
||||
* Batch Multiples Actions to send to ingest in one go
|
||||
*/
|
||||
class BatchActions(vararg val actions: Action) : Action
|
||||
|
||||
/**
|
||||
* Used to update context value in redux store
|
||||
*/
|
||||
class UpdateContextAction(val context: Context?) : Action
|
||||
|
||||
/**
|
||||
* Used to update ViewModal in redux store
|
||||
*/
|
||||
class UpdateViewModalAction(val viewModal: DashboardViewModel?) : Action
|
||||
|
||||
/**
|
||||
* Used to navigate from 1 state to another
|
||||
* @param state: ScreenState New State where to navigate
|
||||
* @param clearBackStack: Boolean Clear BackStack or not
|
||||
*/
|
||||
data class NavigationAction(val state: ScreenState, val clearBackStack: Boolean = false) : Action
|
||||
|
||||
/**
|
||||
* Used to send Accounts list which we want to restore
|
||||
*/
|
||||
data class RestoreAccountsAction(val accounts: List<AccountModel>) : Action
|
||||
|
||||
/**
|
||||
* Used to update Screen State in redux store
|
||||
*/
|
||||
data class StateUpdateAction(val state: ScreenState) : Action
|
||||
|
||||
/**
|
||||
* used to update dialog state of the app
|
||||
* @param dialogState: DialogState? New Dialog State or send null to dismiss the dialog
|
||||
*/
|
||||
data class UpdateDialogAction(val dialogState: DialogState? = null) : Action
|
||||
|
||||
/**
|
||||
* Used to go back to previous screen
|
||||
*/
|
||||
object GoBackAction : Action
|
||||
|
||||
@@ -3,6 +3,9 @@ package com.yogeshpaliyal.keypass.ui.redux.actions
|
||||
import android.os.Bundle
|
||||
import com.yogeshpaliyal.keypass.ui.redux.BottomSheetRoutes
|
||||
|
||||
/**
|
||||
* Bottom Sheet action to open bottom sheet for different routes
|
||||
*/
|
||||
sealed class BottomSheetAction(
|
||||
val route: String,
|
||||
val globalIsBottomSheetOpen: Boolean,
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package com.yogeshpaliyal.keypass.ui.redux.actions
|
||||
|
||||
/**
|
||||
* Intent Navigation actions, used to navigate to different activities
|
||||
* handled in {@link IntentNavigationMiddleware}
|
||||
*/
|
||||
sealed interface IntentNavigation : Action {
|
||||
object GeneratePassword : IntentNavigation
|
||||
object BackupActivity : IntentNavigation
|
||||
object ShareApp : IntentNavigation
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package com.yogeshpaliyal.keypass.ui.redux.actions
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import com.yogeshpaliyal.keypass.R
|
||||
|
||||
data class ToastAction(@StringRes val text: Int) : Action
|
||||
data class ToastActionStr(val text: String) : Action
|
||||
data class CopyToClipboard(val password: String) : Action
|
||||
interface UtilityAction : Action
|
||||
|
||||
object GoBackAction : Action
|
||||
data class ToastAction(@StringRes val text: Int) : UtilityAction
|
||||
data class ToastActionStr(val text: String) : UtilityAction
|
||||
data class CopyToClipboard(val password: String, @StringRes val successMessage: Int = R.string.copied_to_clipboard) : UtilityAction
|
||||
|
||||
@@ -4,23 +4,35 @@ import android.content.Intent
|
||||
import com.yogeshpaliyal.keypass.BuildConfig
|
||||
import com.yogeshpaliyal.keypass.R
|
||||
import com.yogeshpaliyal.keypass.ui.generate.GeneratePasswordActivity
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.BatchActions
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.IntentNavigation
|
||||
import com.yogeshpaliyal.keypass.ui.redux.states.KeyPassState
|
||||
import org.reduxkotlin.Store
|
||||
import org.reduxkotlin.middleware
|
||||
|
||||
/**
|
||||
* Middleware to handle intent navigation
|
||||
*/
|
||||
val intentNavigationMiddleware = middleware<KeyPassState> { store, next, action ->
|
||||
val state = store.state
|
||||
if (action is BatchActions) {
|
||||
action.actions.forEach {
|
||||
store.handleAction(it, state)
|
||||
}
|
||||
} else {
|
||||
store.handleAction(action, state)
|
||||
}
|
||||
|
||||
next(action)
|
||||
}
|
||||
|
||||
private fun Store<KeyPassState>.handleAction(action: Any, state: KeyPassState) {
|
||||
when (action) {
|
||||
is IntentNavigation.GeneratePassword -> {
|
||||
val intent = Intent(state.context, GeneratePasswordActivity::class.java)
|
||||
state.context?.startActivity(intent)
|
||||
}
|
||||
|
||||
is IntentNavigation.BackupActivity -> {
|
||||
// BackupActivity.start(state.context)
|
||||
}
|
||||
|
||||
is IntentNavigation.ShareApp -> {
|
||||
val sendIntent = Intent()
|
||||
sendIntent.action = Intent.ACTION_SEND
|
||||
@@ -37,5 +49,4 @@ val intentNavigationMiddleware = middleware<KeyPassState> { store, next, action
|
||||
)
|
||||
}
|
||||
}
|
||||
next(action)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.yogeshpaliyal.keypass.ui.redux.middlewares
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.BatchActions
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.CopyToClipboard
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.ToastAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.ToastActionStr
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.UtilityAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.states.KeyPassState
|
||||
import org.reduxkotlin.Store
|
||||
import org.reduxkotlin.middleware
|
||||
|
||||
/**
|
||||
* Middle ware to handle utility functions like copy to clipboard and toast
|
||||
*/
|
||||
val utilityMiddleware = middleware<KeyPassState> { store, next, action ->
|
||||
val state = store.state
|
||||
if (action is BatchActions) {
|
||||
action.actions.forEach {
|
||||
store.handleAction(it, state)
|
||||
}
|
||||
} else {
|
||||
store.handleAction(action, state)
|
||||
}
|
||||
next(action)
|
||||
}
|
||||
|
||||
private fun Store<KeyPassState>.handleAction(action: Any, state: KeyPassState) {
|
||||
if (action is UtilityAction) {
|
||||
when (action) {
|
||||
is ToastActionStr -> {
|
||||
state.context?.let {
|
||||
Toast.makeText(it, action.text, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
is ToastAction -> {
|
||||
state.context?.let {
|
||||
Toast.makeText(it, action.text, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
is CopyToClipboard -> {
|
||||
state.context?.let {
|
||||
val clipboard = ContextCompat.getSystemService(
|
||||
it,
|
||||
ClipboardManager::class.java
|
||||
)
|
||||
val clip = ClipData.newPlainText("KeyPass", action.password)
|
||||
clipboard?.setPrimaryClip(clip)
|
||||
dispatch(ToastAction(action.successMessage))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user