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.LinearLayout
|
||||||
import android.widget.Switch
|
import android.widget.Switch
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import org.json.JSONArray
|
||||||
|
|
||||||
class QuickSendActivity : Activity() {
|
class QuickSendActivity : Activity() {
|
||||||
private lateinit var input: EditText
|
private lateinit var input: EditText
|
||||||
@@ -459,6 +460,7 @@ class QuickSendActivity : Activity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ConnectionService.sendText(text) && (!appendEnter || ConnectionService.sendEnter())) {
|
if (ConnectionService.sendText(text) && (!appendEnter || ConnectionService.sendEnter())) {
|
||||||
|
saveHistory(text)
|
||||||
sendButton.background = roundedDrawable(Color.rgb(22, 163, 74), dp(26).toFloat())
|
sendButton.background = roundedDrawable(Color.rgb(22, 163, 74), dp(26).toFloat())
|
||||||
sendIcon.setImageResource(R.drawable.ic_check_24)
|
sendIcon.setImageResource(R.drawable.ic_check_24)
|
||||||
sendIcon.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN)
|
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() {
|
private fun toggleAppendEnter() {
|
||||||
setAppendEnter(!appendEnter)
|
setAppendEnter(!appendEnter)
|
||||||
}
|
}
|
||||||
@@ -529,5 +570,8 @@ class QuickSendActivity : Activity() {
|
|||||||
companion object {
|
companion object {
|
||||||
private const val PREFS = "FlutterSharedPreferences"
|
private const val PREFS = "FlutterSharedPreferences"
|
||||||
private const val KEY_APPEND_ENTER = "flutter.append_enter"
|
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
|
@override
|
||||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||||
if (state == AppLifecycleState.resumed) {
|
if (state == AppLifecycleState.resumed) {
|
||||||
unawaited(_syncAppendEnterFromPrefs());
|
unawaited(_syncSharedPrefsFromDisk());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +239,7 @@ class _InputSyncPageState extends State<InputSyncPage>
|
|||||||
prefs.getString(_portKey) ?? nativeState.port.toString();
|
prefs.getString(_portKey) ?? nativeState.port.toString();
|
||||||
clearAfterSend = prefs.getBool(_clearAfterSendKey) ?? false;
|
clearAfterSend = prefs.getBool(_clearAfterSendKey) ?? false;
|
||||||
appendEnter = prefs.getBool(_appendEnterKey) ?? false;
|
appendEnter = prefs.getBool(_appendEnterKey) ?? false;
|
||||||
sendHistory = prefs.getStringList(_historyKey) ?? [];
|
sendHistory = _readHistory(prefs);
|
||||||
connection = nativeState;
|
connection = nativeState;
|
||||||
headerExpanded = !nativeState.connected;
|
headerExpanded = !nativeState.connected;
|
||||||
});
|
});
|
||||||
@@ -459,18 +459,45 @@ class _InputSyncPageState extends State<InputSyncPage>
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _syncAppendEnterFromPrefs() async {
|
Future<void> _syncSharedPrefsFromDisk() async {
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
await prefs.reload();
|
await prefs.reload();
|
||||||
final nextAppendEnter = prefs.getBool(_appendEnterKey) ?? false;
|
final nextAppendEnter = prefs.getBool(_appendEnterKey) ?? false;
|
||||||
if (!mounted || nextAppendEnter == appendEnter) {
|
final nextHistory = _readHistory(prefs);
|
||||||
|
if (!mounted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nextAppendEnter != appendEnter ||
|
||||||
|
!_stringListsEqual(nextHistory, sendHistory)) {
|
||||||
setState(() {
|
setState(() {
|
||||||
appendEnter = nextAppendEnter;
|
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) {
|
void _restoreHistory(String text) {
|
||||||
inputController.text = text;
|
inputController.text = text;
|
||||||
|
|||||||
Reference in New Issue
Block a user