From 9e5babec7688d6d72eed033d7146aacda242b9ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lollipopkit=F0=9F=8F=B3=EF=B8=8F=E2=80=8D=E2=9A=A7?= =?UTF-8?q?=EF=B8=8F?= <10864310+lollipopkit@users.noreply.github.com> Date: Wed, 29 Jan 2025 15:10:50 +0800 Subject: [PATCH] opt.: close after saving (#684) --- lib/data/store/setting.dart | 3 ++ lib/generated/l10n/l10n.dart | 6 +++ lib/generated/l10n/l10n_de.dart | 3 ++ lib/generated/l10n/l10n_en.dart | 3 ++ lib/generated/l10n/l10n_es.dart | 3 ++ lib/generated/l10n/l10n_fr.dart | 3 ++ lib/generated/l10n/l10n_id.dart | 3 ++ lib/generated/l10n/l10n_ja.dart | 3 ++ lib/generated/l10n/l10n_nl.dart | 3 ++ lib/generated/l10n/l10n_pt.dart | 3 ++ lib/generated/l10n/l10n_ru.dart | 3 ++ lib/generated/l10n/l10n_tr.dart | 3 ++ lib/generated/l10n/l10n_uk.dart | 3 ++ lib/generated/l10n/l10n_zh.dart | 6 +++ lib/l10n/app_de.arb | 1 + lib/l10n/app_en.arb | 1 + lib/l10n/app_es.arb | 1 + lib/l10n/app_fr.arb | 1 + lib/l10n/app_id.arb | 1 + lib/l10n/app_ja.arb | 1 + lib/l10n/app_nl.arb | 1 + lib/l10n/app_pt.arb | 1 + lib/l10n/app_ru.arb | 1 + lib/l10n/app_tr.arb | 1 + lib/l10n/app_uk.arb | 1 + lib/l10n/app_zh.arb | 1 + lib/l10n/app_zh_tw.arb | 1 + lib/view/page/editor.dart | 92 +++++++++++++++++++++----------- lib/view/page/setting/entry.dart | 54 ++++++++++++------- lib/view/page/storage/local.dart | 15 +++--- lib/view/page/storage/sftp.dart | 24 +++++---- 31 files changed, 181 insertions(+), 65 deletions(-) diff --git a/lib/data/store/setting.dart b/lib/data/store/setting.dart index a1d7160a..81f65c59 100644 --- a/lib/data/store/setting.dart +++ b/lib/data/store/setting.dart @@ -238,6 +238,9 @@ class SettingStore extends HiveStore { /// Run foreground service on Android, if the SSH terminal is running late final fgService = propertyDefault('fgService', false); + /// Close the editor after saving + late final closeAfterSave = propertyDefault('closeAfterSave', false); + // Never show these settings for users // // ------BEGIN------ diff --git a/lib/generated/l10n/l10n.dart b/lib/generated/l10n/l10n.dart index 28361fed..6302534f 100644 --- a/lib/generated/l10n/l10n.dart +++ b/lib/generated/l10n/l10n.dart @@ -212,6 +212,12 @@ abstract class AppLocalizations { /// **'This switch only means the program will try to run in the background. Whether it can run in the background depends on whether the permission is enabled or not. For AOSP-based Android ROMs, please disable \"Battery Optimization\" in this app. For MIUI / HyperOS, please change the power saving policy to \"Unlimited\".'** String get bgRunTip; + /// No description provided for @closeAfterSave. + /// + /// In en, this message translates to: + /// **'Save and close'** + String get closeAfterSave; + /// No description provided for @cmd. /// /// In en, this message translates to: diff --git a/lib/generated/l10n/l10n_de.dart b/lib/generated/l10n/l10n_de.dart index b37de365..124d6886 100644 --- a/lib/generated/l10n/l10n_de.dart +++ b/lib/generated/l10n/l10n_de.dart @@ -54,6 +54,9 @@ class AppLocalizationsDe extends AppLocalizations { @override String get bgRunTip => 'Dieser Schalter bedeutet nur, dass die App versuchen wird, im Hintergrund zu laufen. Ob sie im Hintergrund laufen kann, hängt davon ab, ob die Berechtigungen aktiviert sind oder nicht. Bei nativem Android deaktivieren Sie bitte \"Batterieoptimierung\" in dieser App, und bei miui ändern Sie bitte die Energiesparrichtlinie auf \"Unbegrenzt\".'; + @override + String get closeAfterSave => 'Speichern und schließen'; + @override String get cmd => 'Command'; diff --git a/lib/generated/l10n/l10n_en.dart b/lib/generated/l10n/l10n_en.dart index 4703b278..5728a77c 100644 --- a/lib/generated/l10n/l10n_en.dart +++ b/lib/generated/l10n/l10n_en.dart @@ -54,6 +54,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get bgRunTip => 'This switch only means the program will try to run in the background. Whether it can run in the background depends on whether the permission is enabled or not. For AOSP-based Android ROMs, please disable \"Battery Optimization\" in this app. For MIUI / HyperOS, please change the power saving policy to \"Unlimited\".'; + @override + String get closeAfterSave => 'Save and close'; + @override String get cmd => 'Command'; diff --git a/lib/generated/l10n/l10n_es.dart b/lib/generated/l10n/l10n_es.dart index 338c67ed..50ec68d8 100644 --- a/lib/generated/l10n/l10n_es.dart +++ b/lib/generated/l10n/l10n_es.dart @@ -54,6 +54,9 @@ class AppLocalizationsEs extends AppLocalizations { @override String get bgRunTip => 'Este interruptor solo indica que la aplicación intentará correr en segundo plano, si puede hacerlo o no depende de si tiene el permiso correspondiente. En Android puro, por favor desactiva la “optimización de batería” para esta app, en MIUI por favor cambia la estrategia de ahorro de energía a “Sin restricciones”.'; + @override + String get closeAfterSave => 'Guardar y cerrar'; + @override String get cmd => 'Comando'; diff --git a/lib/generated/l10n/l10n_fr.dart b/lib/generated/l10n/l10n_fr.dart index 5e0e294e..3ef8eaf3 100644 --- a/lib/generated/l10n/l10n_fr.dart +++ b/lib/generated/l10n/l10n_fr.dart @@ -54,6 +54,9 @@ class AppLocalizationsFr extends AppLocalizations { @override String get bgRunTip => 'Cette option signifie seulement que le programme essaiera de s\'exécuter en arrière-plan, que cela soit possible dépend de l\'autorisation activée ou non. Pour Android natif, veuillez désactiver l\'« Optimisation de la batterie » dans cette application, et pour MIUI, veuillez changer la politique d\'économie d\'énergie en « Illimité ».'; + @override + String get closeAfterSave => 'Enregistrer et fermer'; + @override String get cmd => 'Commande'; diff --git a/lib/generated/l10n/l10n_id.dart b/lib/generated/l10n/l10n_id.dart index 127ca3bd..451593b0 100644 --- a/lib/generated/l10n/l10n_id.dart +++ b/lib/generated/l10n/l10n_id.dart @@ -54,6 +54,9 @@ class AppLocalizationsId extends AppLocalizations { @override String get bgRunTip => 'Sakelar ini hanya berarti aplikasi akan mencoba berjalan di latar belakang, apakah aplikasi dapat berjalan di latar belakang tergantung pada apakah izin diaktifkan atau tidak. Untuk Android asli, nonaktifkan \"Pengoptimalan Baterai\" di aplikasi ini, dan untuk miui, ubah kebijakan penghematan daya ke \"Tidak Terbatas\".'; + @override + String get closeAfterSave => 'Simpan dan tutup'; + @override String get cmd => 'Memerintah'; diff --git a/lib/generated/l10n/l10n_ja.dart b/lib/generated/l10n/l10n_ja.dart index 52739c6c..491c9cd9 100644 --- a/lib/generated/l10n/l10n_ja.dart +++ b/lib/generated/l10n/l10n_ja.dart @@ -54,6 +54,9 @@ class AppLocalizationsJa extends AppLocalizations { @override String get bgRunTip => 'このスイッチはプログラムがバックグラウンドで実行を試みることを意味しますが、実際にバックグラウンドで実行できるかどうかは、権限が有効になっているかに依存します。AOSPベースのAndroid ROMでは、このアプリの「バッテリー最適化」をオフにしてください。MIUIでは、省エネモードを「無制限」に変更してください。'; + @override + String get closeAfterSave => '保存して閉じる'; + @override String get cmd => 'コマンド'; diff --git a/lib/generated/l10n/l10n_nl.dart b/lib/generated/l10n/l10n_nl.dart index e32d5ace..4f5bdd36 100644 --- a/lib/generated/l10n/l10n_nl.dart +++ b/lib/generated/l10n/l10n_nl.dart @@ -54,6 +54,9 @@ class AppLocalizationsNl extends AppLocalizations { @override String get bgRunTip => 'Deze schakelaar betekent alleen dat het programma zal proberen op de achtergrond uit te voeren, of het in de achtergrond kan worden uitgevoerd, hangt af van of de toestemming is ingeschakeld of niet. Voor native Android, schakel \"Batterijoptimalisatie\" uit in deze app, en voor miui, wijzig de energiebesparingsbeleid naar \"Onbeperkt\".'; + @override + String get closeAfterSave => 'Opslaan en sluiten'; + @override String get cmd => 'Opdracht'; diff --git a/lib/generated/l10n/l10n_pt.dart b/lib/generated/l10n/l10n_pt.dart index 0f6bb792..dd76d318 100644 --- a/lib/generated/l10n/l10n_pt.dart +++ b/lib/generated/l10n/l10n_pt.dart @@ -54,6 +54,9 @@ class AppLocalizationsPt extends AppLocalizations { @override String get bgRunTip => 'Este interruptor indica que o programa tentará rodar em segundo plano, mas a capacidade de fazer isso depende das permissões concedidas. No Android nativo, desative a \'Otimização de bateria\' para este app, no MIUI, altere a estratégia de economia de energia para \'Sem restrições\'.'; + @override + String get closeAfterSave => 'Salvar e fechar'; + @override String get cmd => 'Comando'; diff --git a/lib/generated/l10n/l10n_ru.dart b/lib/generated/l10n/l10n_ru.dart index 7bf19cca..1e0bd505 100644 --- a/lib/generated/l10n/l10n_ru.dart +++ b/lib/generated/l10n/l10n_ru.dart @@ -54,6 +54,9 @@ class AppLocalizationsRu extends AppLocalizations { @override String get bgRunTip => 'Этот переключатель означает, что программа будет пытаться работать в фоновом режиме, но фактическое выполнение зависит от того, включено ли разрешение. Для нативного Android отключите «Оптимизацию батареи» для этого приложения, для MIUI измените контроль активности на «Нет ограничений».'; + @override + String get closeAfterSave => 'Сохранить и закрыть'; + @override String get cmd => 'Команда'; diff --git a/lib/generated/l10n/l10n_tr.dart b/lib/generated/l10n/l10n_tr.dart index be193930..71962485 100644 --- a/lib/generated/l10n/l10n_tr.dart +++ b/lib/generated/l10n/l10n_tr.dart @@ -54,6 +54,9 @@ class AppLocalizationsTr extends AppLocalizations { @override String get bgRunTip => 'Bu anahtar yalnızca programın arka planda çalışmayı deneyeceğini ifade eder. Arka planda çalışıp çalışamayacağı, iznin etkinleştirilip etkinleştirilmediğine bağlıdır. AOSP tabanlı Android ROM\'larda, bu uygulamada \"Pil Optimizasyonunu\" devre dışı bırakın. MIUI / HyperOS için, güç tasarrufu politikasını \"Sınırsız\" olarak değiştirin.'; + @override + String get closeAfterSave => 'Kaydet ve kapat'; + @override String get cmd => 'Komut'; diff --git a/lib/generated/l10n/l10n_uk.dart b/lib/generated/l10n/l10n_uk.dart index 6fd83b4a..5d815266 100644 --- a/lib/generated/l10n/l10n_uk.dart +++ b/lib/generated/l10n/l10n_uk.dart @@ -54,6 +54,9 @@ class AppLocalizationsUk extends AppLocalizations { @override String get bgRunTip => 'Цей перемикач лише вказує на те, що програма намагатиметься працювати у фоновому режимі. Чи може вона працювати у фоновому режимі, залежить від прав доступу. Для AOSP-орієнтованих Android ROM, будь ласка, вимкніть \"Оптимізацію акумулятора\" в цьому додатку. Для MIUI / HyperOS, будь ласка, змініть політику економії енергії на \"Нескінченна\".'; + @override + String get closeAfterSave => 'Зберегти та закрити'; + @override String get cmd => 'Команда'; diff --git a/lib/generated/l10n/l10n_zh.dart b/lib/generated/l10n/l10n_zh.dart index 7d758dac..deb96ff8 100644 --- a/lib/generated/l10n/l10n_zh.dart +++ b/lib/generated/l10n/l10n_zh.dart @@ -54,6 +54,9 @@ class AppLocalizationsZh extends AppLocalizations { @override String get bgRunTip => '此开关只代表程序会尝试在后台运行,具体能否后台运行取决于是否开启了权限。原生 Android 请关闭本 App 的“电池优化”,MIUI / HyperOS 请修改省电策略为“无限制”。'; + @override + String get closeAfterSave => '保存后关闭'; + @override String get cmd => '命令'; @@ -756,6 +759,9 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { @override String get bgRunTip => '此開關只代表程式會嘗試在後台運行,具體能否在後臺運行取決於是否開啟了權限。 原生 Android 請關閉本 App 的“電池優化”,MIUI / HyperOS 請修改省電策略為“無限制”。'; + @override + String get closeAfterSave => '儲存後關閉'; + @override String get cmd => '命令'; diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 4c5ce99d..76d60134 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -16,6 +16,7 @@ "battery": "Batterie", "bgRun": "Hintergrundaktualisierung", "bgRunTip": "Dieser Schalter bedeutet nur, dass die App versuchen wird, im Hintergrund zu laufen. Ob sie im Hintergrund laufen kann, hängt davon ab, ob die Berechtigungen aktiviert sind oder nicht. Bei nativem Android deaktivieren Sie bitte \"Batterieoptimierung\" in dieser App, und bei miui ändern Sie bitte die Energiesparrichtlinie auf \"Unbegrenzt\".", + "closeAfterSave": "Speichern und schließen", "cmd": "Command", "collapseUITip": "Ob lange Listen in der Benutzeroberfläche standardmäßig eingeklappt werden sollen oder nicht", "conn": "Verbindung", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index a818067f..e1817e81 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -16,6 +16,7 @@ "battery": "Battery", "bgRun": "Run in background", "bgRunTip": "This switch only means the program will try to run in the background. Whether it can run in the background depends on whether the permission is enabled or not. For AOSP-based Android ROMs, please disable \"Battery Optimization\" in this app. For MIUI / HyperOS, please change the power saving policy to \"Unlimited\".", + "closeAfterSave": "Save and close", "cmd": "Command", "collapseUITip": "Whether to collapse long lists present in the UI by default", "conn": "Connection", diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index d01fc937..66049009 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -16,6 +16,7 @@ "battery": "Batería", "bgRun": "Ejecución en segundo plano", "bgRunTip": "Este interruptor solo indica que la aplicación intentará correr en segundo plano, si puede hacerlo o no depende de si tiene el permiso correspondiente. En Android puro, por favor desactiva la “optimización de batería” para esta app, en MIUI por favor cambia la estrategia de ahorro de energía a “Sin restricciones”.", + "closeAfterSave": "Guardar y cerrar", "cmd": "Comando", "collapseUITip": "¿Colapsar por defecto las listas largas en la UI?", "conn": "Conectar", diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index 4eb9415c..49e1b60b 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -16,6 +16,7 @@ "battery": "Batterie", "bgRun": "Exécution en arrière-plan", "bgRunTip": "Cette option signifie seulement que le programme essaiera de s'exécuter en arrière-plan, que cela soit possible dépend de l'autorisation activée ou non. Pour Android natif, veuillez désactiver l'« Optimisation de la batterie » dans cette application, et pour MIUI, veuillez changer la politique d'économie d'énergie en « Illimité ».", + "closeAfterSave": "Enregistrer et fermer", "cmd": "Commande", "collapseUITip": "Indique si les longues listes présentées dans l'interface utilisateur doivent être réduites par défaut.", "conn": "Connexion", diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb index 507804da..78158478 100644 --- a/lib/l10n/app_id.arb +++ b/lib/l10n/app_id.arb @@ -16,6 +16,7 @@ "battery": "Baterai", "bgRun": "Jalankan di Backgroud", "bgRunTip": "Sakelar ini hanya berarti aplikasi akan mencoba berjalan di latar belakang, apakah aplikasi dapat berjalan di latar belakang tergantung pada apakah izin diaktifkan atau tidak. Untuk Android asli, nonaktifkan \"Pengoptimalan Baterai\" di aplikasi ini, dan untuk miui, ubah kebijakan penghematan daya ke \"Tidak Terbatas\".", + "closeAfterSave": "Simpan dan tutup", "cmd": "Memerintah", "collapseUITip": "Apakah akan menciutkan daftar panjang yang ada di UI secara default atau tidak", "conn": "Koneksi", diff --git a/lib/l10n/app_ja.arb b/lib/l10n/app_ja.arb index c30b9bb2..f78eabc5 100644 --- a/lib/l10n/app_ja.arb +++ b/lib/l10n/app_ja.arb @@ -16,6 +16,7 @@ "battery": "バッテリー", "bgRun": "バックグラウンド実行", "bgRunTip": "このスイッチはプログラムがバックグラウンドで実行を試みることを意味しますが、実際にバックグラウンドで実行できるかどうかは、権限が有効になっているかに依存します。AOSPベースのAndroid ROMでは、このアプリの「バッテリー最適化」をオフにしてください。MIUIでは、省エネモードを「無制限」に変更してください。", + "closeAfterSave": "保存して閉じる", "cmd": "コマンド", "collapseUITip": "UIの長いリストをデフォルトで折りたたむかどうか", "conn": "接続", diff --git a/lib/l10n/app_nl.arb b/lib/l10n/app_nl.arb index a2558360..d1ff8319 100644 --- a/lib/l10n/app_nl.arb +++ b/lib/l10n/app_nl.arb @@ -16,6 +16,7 @@ "battery": "Batterij", "bgRun": "Uitvoeren op de achtergrond", "bgRunTip": "Deze schakelaar betekent alleen dat het programma zal proberen op de achtergrond uit te voeren, of het in de achtergrond kan worden uitgevoerd, hangt af van of de toestemming is ingeschakeld of niet. Voor native Android, schakel \"Batterijoptimalisatie\" uit in deze app, en voor miui, wijzig de energiebesparingsbeleid naar \"Onbeperkt\".", + "closeAfterSave": "Opslaan en sluiten", "cmd": "Opdracht", "collapseUITip": "Of lange lijsten in de UI standaard moeten worden ingeklapt", "conn": "Verbinding", diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index 82c56865..c21aa033 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -16,6 +16,7 @@ "battery": "Bateria", "bgRun": "Execução em segundo plano", "bgRunTip": "Este interruptor indica que o programa tentará rodar em segundo plano, mas a capacidade de fazer isso depende das permissões concedidas. No Android nativo, desative a 'Otimização de bateria' para este app, no MIUI, altere a estratégia de economia de energia para 'Sem restrições'.", + "closeAfterSave": "Salvar e fechar", "cmd": "Comando", "collapseUITip": "Deve colapsar listas longas na UI por padrão?", "conn": "Conectar", diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index 9fad74ce..000f0156 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -16,6 +16,7 @@ "battery": "Батарея", "bgRun": "Работа в фоновом режиме", "bgRunTip": "Этот переключатель означает, что программа будет пытаться работать в фоновом режиме, но фактическое выполнение зависит от того, включено ли разрешение. Для нативного Android отключите «Оптимизацию батареи» для этого приложения, для MIUI измените контроль активности на «Нет ограничений».", + "closeAfterSave": "Сохранить и закрыть", "cmd": "Команда", "collapseUITip": "Свернуть длинные списки в UI по умолчанию", "conn": "Подключение", diff --git a/lib/l10n/app_tr.arb b/lib/l10n/app_tr.arb index 5b39834a..be2db192 100644 --- a/lib/l10n/app_tr.arb +++ b/lib/l10n/app_tr.arb @@ -16,6 +16,7 @@ "battery": "Pil", "bgRun": "Arka planda çalıştır", "bgRunTip": "Bu anahtar yalnızca programın arka planda çalışmayı deneyeceğini ifade eder. Arka planda çalışıp çalışamayacağı, iznin etkinleştirilip etkinleştirilmediğine bağlıdır. AOSP tabanlı Android ROM'larda, bu uygulamada \"Pil Optimizasyonunu\" devre dışı bırakın. MIUI / HyperOS için, güç tasarrufu politikasını \"Sınırsız\" olarak değiştirin.", + "closeAfterSave": "Kaydet ve kapat", "cmd": "Komut", "collapseUITip": "UI'daki uzun listeleri varsayılan olarak gizleyip gizlememeyi belirler", "conn": "Bağlantı", diff --git a/lib/l10n/app_uk.arb b/lib/l10n/app_uk.arb index 19207cf4..6c2e7569 100644 --- a/lib/l10n/app_uk.arb +++ b/lib/l10n/app_uk.arb @@ -16,6 +16,7 @@ "battery": "Акумулятор", "bgRun": "Запуск у фоновому режимі", "bgRunTip": "Цей перемикач лише вказує на те, що програма намагатиметься працювати у фоновому режимі. Чи може вона працювати у фоновому режимі, залежить від прав доступу. Для AOSP-орієнтованих Android ROM, будь ласка, вимкніть \"Оптимізацію акумулятора\" в цьому додатку. Для MIUI / HyperOS, будь ласка, змініть політику економії енергії на \"Нескінченна\".", + "closeAfterSave": "Зберегти та закрити", "cmd": "Команда", "collapseUITip": "Сховати довгі списки, що є у UI за замовчуванням", "conn": "З'єднання", diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 300dfc49..37ef674b 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -16,6 +16,7 @@ "battery": "电池", "bgRun": "后台运行", "bgRunTip": "此开关只代表程序会尝试在后台运行,具体能否后台运行取决于是否开启了权限。原生 Android 请关闭本 App 的“电池优化”,MIUI / HyperOS 请修改省电策略为“无限制”。", + "closeAfterSave": "保存后关闭", "cmd": "命令", "collapseUITip": "是否默认折叠 UI 中的长列表", "conn": "连接", diff --git a/lib/l10n/app_zh_tw.arb b/lib/l10n/app_zh_tw.arb index 09b37da1..38daa83d 100644 --- a/lib/l10n/app_zh_tw.arb +++ b/lib/l10n/app_zh_tw.arb @@ -16,6 +16,7 @@ "battery": "電池", "bgRun": "後台運行", "bgRunTip": "此開關只代表程式會嘗試在後台運行,具體能否在後臺運行取決於是否開啟了權限。 原生 Android 請關閉本 App 的“電池優化”,MIUI / HyperOS 請修改省電策略為“無限制”。", + "closeAfterSave": "儲存後關閉", "cmd": "命令", "collapseUITip": "是否預設折疊 UI 中存在的長列表", "conn": "連接", diff --git a/lib/view/page/editor.dart b/lib/view/page/editor.dart index e07756eb..b96d193c 100644 --- a/lib/view/page/editor.dart +++ b/lib/view/page/editor.dart @@ -11,17 +11,17 @@ import 'package:flutter_highlight/themes/monokai.dart'; import 'package:server_box/core/extension/context/locale.dart'; import 'package:server_box/data/res/highlight.dart'; import 'package:server_box/data/res/store.dart'; +import 'package:server_box/data/store/setting.dart'; import 'package:server_box/view/widget/two_line_text.dart'; +enum EditorPageRetType { path, text } + final class EditorPageRet { - /// If edit text, this includes the edited result - final String? result; + final EditorPageRetType typ; + final String val; - /// Indicates whether it's ok to edit existing file - final bool? editExistedOk; - - const EditorPageRet({this.result, this.editExistedOk}); + const EditorPageRet(this.typ, this.val); } final class EditorPageArgs { @@ -38,11 +38,14 @@ final class EditorPageArgs { final String? title; + final void Function(BuildContext, EditorPageRet) onSave; + const EditorPageArgs({ this.path, this.text, this.langCode, this.title, + required this.onSave, }); } @@ -51,7 +54,7 @@ class EditorPage extends StatefulWidget { const EditorPage({super.key, this.args}); - static const route = AppRoute( + static const route = AppRoute( page: EditorPage.new, path: '/editor', ); @@ -69,6 +72,7 @@ class _EditorPageState extends State { TextStyle(fontSize: Stores.setting.editorFontSize.fetch()); String? _langCode; + var _saved = false; @override void dispose() { @@ -99,10 +103,16 @@ class _EditorPageState extends State { @override Widget build(BuildContext context) { - return Scaffold( - backgroundColor: _codeTheme['root']?.backgroundColor, - appBar: _buildAppBar(), - body: _buildBody(), + return PopScope( + canPop: false, + onPopInvokedWithResult: (didPop, result) { + _pop(); + }, + child: Scaffold( + backgroundColor: _codeTheme['root']?.backgroundColor, + appBar: _buildAppBar(), + body: _buildBody(), + ), ); } @@ -136,25 +146,7 @@ class _EditorPageState extends State { IconButton( icon: const Icon(Icons.save), tooltip: l10n.save, - onPressed: () async { - // If path is not null, then it's a file editor - // save the text and return true to pop the page - final path = widget.args?.path; - if (path != null) { - final (res, _) = await context.showLoadingDialog( - fn: () => File(path).writeAsString(_controller.text), - ); - if (res == null) { - context.showSnackBar(libL10n.fail); - return; - } - context.pop(const EditorPageRet(editExistedOk: true)); - return; - } - // else it's a text editor - // return the text to the previous page - context.pop(EditorPageRet(result: _controller.text)); - }, + onPressed: _onSave, ) ], ); @@ -210,4 +202,44 @@ extension on _EditorPageState { _controller.text = text; } } + + void _onSave() async { + // If path is not null, then it's a file editor + final path = widget.args?.path; + if (path != null) { + final (res, _) = await context.showLoadingDialog( + fn: () => File(path).writeAsString(_controller.text), + ); + if (res == null) { + context.showSnackBar(libL10n.fail); + return; + } + final ret = EditorPageRet(EditorPageRetType.path, path); + widget.args?.onSave(context, ret); + _saved = true; + + final pop_ = SettingStore.instance.closeAfterSave.fetch(); + if (pop_) _pop(); + return; + } + // it's a text editor + final ret = EditorPageRet(EditorPageRetType.text, _controller.text); + widget.args?.onSave(context, ret); + _saved = true; + + final pop_ = SettingStore.instance.closeAfterSave.fetch(); + if (pop_) _pop(); + } + + void _pop() async { + if (!_saved) { + final ret = await context.showRoundDialog( + title: libL10n.attention, + child: Text(libL10n.askContinue(libL10n.exit)), + actions: Btnx.cancelOk, + ); + if (ret != true) return; + } + context.pop(); + } } diff --git a/lib/view/page/setting/entry.dart b/lib/view/page/setting/entry.dart index 78627889..925fb3ff 100644 --- a/lib/view/page/setting/entry.dart +++ b/lib/view/page/setting/entry.dart @@ -305,6 +305,7 @@ final class _AppSettingsPageState extends State { _buildEditorTheme(), _buildEditorDarkTheme(), _buildEditorHighlight(), + _buildEditorCloseAfterEdit(), ].map((e) => CardX(child: e)).toList(), ); } @@ -1329,32 +1330,49 @@ final class _AppSettingsPageState extends State { final map = await Stores.setting.getAllMap(includeInternalKeys: true); final keys = map.keys; + void onSave(BuildContext context, EditorPageRet ret) { + if (ret.typ != EditorPageRetType.text) { + context.showRoundDialog( + title: libL10n.fail, + child: Text(l10n.invalid), + ); + return; + } + try { + final newSettings = json.decode(ret.val) as Map; + Stores.setting.box.putAll(newSettings); + final newKeys = newSettings.keys; + final removedKeys = keys.where((e) => !newKeys.contains(e)); + for (final key in removedKeys) { + Stores.setting.box.delete(key); + } + } catch (e, trace) { + context.showRoundDialog( + title: libL10n.error, + child: Text('${l10n.save}:\n$e'), + ); + Loggers.app.warning('Update json settings failed', e, trace); + } + } + /// Encode [map] to String with indent `\t` final text = jsonIndentEncoder.convert(map); - final ret = await EditorPage.route.go( + await EditorPage.route.go( context, args: EditorPageArgs( text: text, langCode: 'json', title: libL10n.setting, + onSave: onSave, ), ); - final result = ret?.result; - if (result == null) return; - try { - final newSettings = json.decode(result) as Map; - Stores.setting.box.putAll(newSettings); - final newKeys = newSettings.keys; - final removedKeys = keys.where((e) => !newKeys.contains(e)); - for (final key in removedKeys) { - Stores.setting.box.delete(key); - } - } catch (e, trace) { - context.showRoundDialog( - title: libL10n.error, - child: Text('${l10n.save}:\n$e'), - ); - Loggers.app.warning('Update json settings failed', e, trace); - } + } + + Widget _buildEditorCloseAfterEdit() { + return ListTile( + leading: const Icon(MingCute.edit_fill), + title: Text(l10n.closeAfterSave), + trailing: StoreSwitch(prop: _setting.closeAfterSave), + ); } } diff --git a/lib/view/page/storage/local.dart b/lib/view/page/storage/local.dart index 396d87e0..0cdbdfa1 100644 --- a/lib/view/page/storage/local.dart +++ b/lib/view/page/storage/local.dart @@ -217,14 +217,17 @@ class _LocalFilePageState extends State ); return; } - final ret = await EditorPage.route.go( + + await EditorPage.route.go( context, - args: EditorPageArgs(path: file.absolute.path), + args: EditorPageArgs( + path: file.absolute.path, + onSave: (context, _) { + context.showSnackBar(l10n.saved); + setState(() {}); + }, + ), ); - if (ret?.editExistedOk == true) { - context.showSnackBar(l10n.saved); - setState(() {}); - } }, ), Btn.tile( diff --git a/lib/view/page/storage/sftp.dart b/lib/view/page/storage/sftp.dart index d54535fb..57a6ad1a 100644 --- a/lib/view/page/storage/sftp.dart +++ b/lib/view/page/storage/sftp.dart @@ -317,19 +317,21 @@ class _SftpPageState extends State with AfterLayoutMixin { ); if (suc == null || err != null) return; - final ret = await EditorPage.route.go( + await EditorPage.route.go( context, - args: EditorPageArgs(path: localPath), + args: EditorPageArgs( + path: localPath, + onSave: (context, _) { + SftpProvider.add(SftpReq( + req.spi, + remotePath, + localPath, + SftpReqType.upload, + )); + context.showSnackBar(l10n.added2List); + }, + ), ); - if (ret?.editExistedOk == true) { - SftpProvider.add(SftpReq( - req.spi, - remotePath, - localPath, - SftpReqType.upload, - )); - context.showSnackBar(l10n.added2List); - } } void _download(SftpName name) {