diff --git a/java/src/org/futo/inputmethod/latin/uix/Action.kt b/java/src/org/futo/inputmethod/latin/uix/Action.kt index 1b6f2556f1..cde0e41ef3 100644 --- a/java/src/org/futo/inputmethod/latin/uix/Action.kt +++ b/java/src/org/futo/inputmethod/latin/uix/Action.kt @@ -105,6 +105,7 @@ interface KeyboardManagerForAction { fun copyToClipboard(cut: Boolean = false) fun pasteFromClipboard() + fun dismissQuickClips() // Returns null if the current IME is not of this kind. // TODO: In the future make an IMEActionInterface for correctness diff --git a/java/src/org/futo/inputmethod/latin/uix/QuickClip.kt b/java/src/org/futo/inputmethod/latin/uix/QuickClip.kt index aeb88e8e23..bc9d61e153 100644 --- a/java/src/org/futo/inputmethod/latin/uix/QuickClip.kt +++ b/java/src/org/futo/inputmethod/latin/uix/QuickClip.kt @@ -215,6 +215,13 @@ object QuickClip { timeOfDismissal = System.currentTimeMillis() } + // Invalidate the cached QuickClip state. This must be called when clipboard items + // are removed or pruned so that deleted items no longer appear as QuickClip suggestions. + fun invalidateCache() { + cachedPreviousItem = null + cachedPreviousState = null + } + private fun getStateForItem(validUntil: Long, mimeTypes: List, item: ClipData.Item, isSensitive: Boolean): QuickClipState? { val texts = mutableListOf() val currTexts = mutableSetOf() diff --git a/java/src/org/futo/inputmethod/latin/uix/UixManager.kt b/java/src/org/futo/inputmethod/latin/uix/UixManager.kt index 831f0ff540..347b56fc29 100644 --- a/java/src/org/futo/inputmethod/latin/uix/UixManager.kt +++ b/java/src/org/futo/inputmethod/latin/uix/UixManager.kt @@ -512,6 +512,10 @@ class UixActionKeyboardManager(val uixManager: UixManager, val latinIME: LatinIM uixManager.dismissQuickClips() } + override fun dismissQuickClips() { + uixManager.dismissQuickClips() + } + override fun getSizingCalculator(): KeyboardSizingCalculator = latinIME.sizingCalculator diff --git a/java/src/org/futo/inputmethod/latin/uix/actions/ClipboardHistoryAction.kt b/java/src/org/futo/inputmethod/latin/uix/actions/ClipboardHistoryAction.kt index 48b1add48f..6dd419192f 100644 --- a/java/src/org/futo/inputmethod/latin/uix/actions/ClipboardHistoryAction.kt +++ b/java/src/org/futo/inputmethod/latin/uix/actions/ClipboardHistoryAction.kt @@ -65,6 +65,7 @@ import org.futo.inputmethod.latin.R import org.futo.inputmethod.latin.common.Constants import org.futo.inputmethod.latin.uix.Action import org.futo.inputmethod.latin.uix.ActionWindow +import org.futo.inputmethod.latin.uix.QuickClip import org.futo.inputmethod.latin.uix.DialogRequestItem import org.futo.inputmethod.latin.uix.PersistentActionState import org.futo.inputmethod.latin.uix.PersistentStateInitialization @@ -380,14 +381,15 @@ class ClipboardHistoryManager(val context: Context, val coroutineScope: Lifecycl val numHoursToKeep = context.getSetting(ClipboardHistoryTimeToKeep) val numItemsToKeep = context.getSetting(ClipboardHistoryItemsToKeep) val minimumTimestamp = System.currentTimeMillis() - (numHoursToKeep * 60L * 60L * 1000L) - clipboardHistory.removeAll { + val removedByTime = clipboardHistory.removeAll { (!it.pinned) && (it.timestamp < minimumTimestamp) } // Remove duplicates of entries, if any appeared // Duplicates will have same timestamp, same text, etc val set = clipboardHistory.toSet() - if(set.size < clipboardHistory.size) { + val hadDuplicates = set.size < clipboardHistory.size + if(hadDuplicates) { clipboardHistory.clear() clipboardHistory.addAll(set) } @@ -395,14 +397,21 @@ class ClipboardHistoryManager(val context: Context, val coroutineScope: Lifecycl val maxItems = numItemsToKeep val numUnpinnedItems = clipboardHistory.filter { !it.pinned }.size + var removedByLimit = false val numItemsToRemove = numUnpinnedItems - maxItems if(numItemsToRemove > 0) { for(i in 0 until numItemsToRemove) { val idx = clipboardHistory.indexOfFirst { !it.pinned } if(idx == -1) break clipboardHistory.removeAt(idx) + removedByLimit = true } } + + // Invalidate QuickClip cache if any items were removed during pruning + if(removedByTime || hadDuplicates || removedByLimit) { + QuickClip.invalidateCache() + } } var saveClipboardLoadJob: Job? = null @@ -598,6 +607,11 @@ ${if(clipboardFileSwap.exists()) { clipboardFileSwap.readText() } else { "File d } } clipboardHistory.removeAll { it == item } + + // Invalidate QuickClip cache so removed items no longer appear as suggestions + QuickClip.invalidateCache() + QuickClip.markQuickClipDismissed() + saveClipboard() } @@ -695,6 +709,7 @@ val ClipboardHistoryAction = Action( clipboardHistoryManager.onRemove(it) } } + manager.dismissQuickClips() }, ), {} @@ -841,6 +856,7 @@ val ClipboardHistoryAction = Action( context.getString(R.string.action_clipboard_manager_remove_item) ) { clipboardHistoryManager.onRemove(it) + manager.dismissQuickClips() manager.performHapticAndAudioFeedback(Constants.CODE_TAB, view) } )