Persist quick send history safely
This commit is contained in:
@@ -21,6 +21,7 @@ import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.Switch
|
||||
import android.widget.TextView
|
||||
import org.json.JSONArray
|
||||
|
||||
class QuickSendActivity : Activity() {
|
||||
private lateinit var input: EditText
|
||||
@@ -459,6 +460,7 @@ class QuickSendActivity : Activity() {
|
||||
}
|
||||
|
||||
if (ConnectionService.sendText(text) && (!appendEnter || ConnectionService.sendEnter())) {
|
||||
saveHistory(text)
|
||||
sendButton.background = roundedDrawable(Color.rgb(22, 163, 74), dp(26).toFloat())
|
||||
sendIcon.setImageResource(R.drawable.ic_check_24)
|
||||
sendIcon.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN)
|
||||
@@ -472,6 +474,45 @@ class QuickSendActivity : Activity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveHistory(text: String) {
|
||||
if (text.trim().isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
val prefs = getSharedPreferences(PREFS, Context.MODE_PRIVATE)
|
||||
val currentHistory = readHistory()
|
||||
val nextHistory = linkedSetOf(text)
|
||||
currentHistory
|
||||
.filter { it != text }
|
||||
.take(MAX_HISTORY_ITEMS - 1)
|
||||
.forEach { nextHistory.add(it) }
|
||||
|
||||
prefs.edit()
|
||||
.putString(KEY_HISTORY, JSON_LIST_PREFIX + JSONArray(nextHistory.toList()).toString())
|
||||
.apply()
|
||||
}
|
||||
|
||||
private fun readHistory(): List<String> {
|
||||
val rawValue = getSharedPreferences(PREFS, Context.MODE_PRIVATE).all[KEY_HISTORY]
|
||||
return when (rawValue) {
|
||||
is String -> decodeHistoryString(rawValue)
|
||||
is Set<*> -> rawValue.filterIsInstance<String>()
|
||||
else -> emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun decodeHistoryString(value: String): List<String> {
|
||||
if (!value.startsWith(JSON_LIST_PREFIX)) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
return runCatching {
|
||||
val array = JSONArray(value.substring(JSON_LIST_PREFIX.length))
|
||||
List(array.length()) { index -> array.optString(index) }
|
||||
.filter { it.isNotEmpty() }
|
||||
}.getOrDefault(emptyList())
|
||||
}
|
||||
|
||||
private fun toggleAppendEnter() {
|
||||
setAppendEnter(!appendEnter)
|
||||
}
|
||||
@@ -529,5 +570,8 @@ class QuickSendActivity : Activity() {
|
||||
companion object {
|
||||
private const val PREFS = "FlutterSharedPreferences"
|
||||
private const val KEY_APPEND_ENTER = "flutter.append_enter"
|
||||
private const val KEY_HISTORY = "flutter.send_history"
|
||||
private const val JSON_LIST_PREFIX = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu!"
|
||||
private const val MAX_HISTORY_ITEMS = 10
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ class _InputSyncPageState extends State<InputSyncPage>
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
if (state == AppLifecycleState.resumed) {
|
||||
unawaited(_syncAppendEnterFromPrefs());
|
||||
unawaited(_syncSharedPrefsFromDisk());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ class _InputSyncPageState extends State<InputSyncPage>
|
||||
prefs.getString(_portKey) ?? nativeState.port.toString();
|
||||
clearAfterSend = prefs.getBool(_clearAfterSendKey) ?? false;
|
||||
appendEnter = prefs.getBool(_appendEnterKey) ?? false;
|
||||
sendHistory = prefs.getStringList(_historyKey) ?? [];
|
||||
sendHistory = _readHistory(prefs);
|
||||
connection = nativeState;
|
||||
headerExpanded = !nativeState.connected;
|
||||
});
|
||||
@@ -459,17 +459,44 @@ class _InputSyncPageState extends State<InputSyncPage>
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _syncAppendEnterFromPrefs() async {
|
||||
Future<void> _syncSharedPrefsFromDisk() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.reload();
|
||||
final nextAppendEnter = prefs.getBool(_appendEnterKey) ?? false;
|
||||
if (!mounted || nextAppendEnter == appendEnter) {
|
||||
final nextHistory = _readHistory(prefs);
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
appendEnter = nextAppendEnter;
|
||||
});
|
||||
if (nextAppendEnter != appendEnter ||
|
||||
!_stringListsEqual(nextHistory, sendHistory)) {
|
||||
setState(() {
|
||||
appendEnter = nextAppendEnter;
|
||||
sendHistory = nextHistory;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bool _stringListsEqual(List<String> left, List<String> right) {
|
||||
if (left.length != right.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var index = 0; index < left.length; index += 1) {
|
||||
if (left[index] != right[index]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
List<String> _readHistory(SharedPreferences prefs) {
|
||||
try {
|
||||
return prefs.getStringList(_historyKey) ?? [];
|
||||
} catch (_) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
void _restoreHistory(String text) {
|
||||
|
||||
Reference in New Issue
Block a user