Skip to content

Commit

Permalink
settings: Support export/import color settings
Browse files Browse the repository at this point in the history
  • Loading branch information
calcitem committed Oct 4, 2024
1 parent 8254468 commit 81d5eb0
Show file tree
Hide file tree
Showing 60 changed files with 1,047 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import 'dart:convert';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hive_flutter/adapters.dart';
import 'package:hive_flutter/hive_flutter.dart' show Box;

Expand Down Expand Up @@ -115,6 +117,161 @@ class AppearanceSettingsPage extends StatelessWidget {
builder: (_) => const _PieceImagePicker(),
);

Future<void> importColorSettings(BuildContext context) async {
final String strImport = S.of(context).import;
final String strClose = S.of(context).close;
final String strImported = S.of(context).imported;
final String strInvalidFormat = S.of(context).pleaseCopyJsonToClipboard;

// Get clipboard data
final ClipboardData? data = await Clipboard.getData('text/plain');
if (data == null || data.text == null) {
rootScaffoldMessengerKey.currentState!.showSnackBar(
SnackBar(
content: Text(strInvalidFormat),
),
);
return;
}

// Check if clipboard content contains only ASCII characters
final String clipboardText = data.text!;
if (!isAscii(clipboardText)) {
// If content is not ASCII, show a SnackBar with the invalid format message
rootScaffoldMessengerKey.currentState!.showSnackBar(
SnackBar(
content: Text(strInvalidFormat),
),
);
return;
}

try {
// Try to parse the clipboard content as JSON
final Map<String, dynamic> json =
jsonDecode(clipboardText) as Map<String, dynamic>;
final Widget importButton = TextButton(
child: Text(
strImport,
style: TextStyle(
fontSize: AppTheme.textScaler.scale(AppTheme.largeFontSize),
),
),
onPressed: () async {
final ColorSettings colorSettings = ColorSettings.fromJson(json);
DB().colorSettings = colorSettings;

rootScaffoldMessengerKey.currentState!.showSnackBarClear(strImported);

if (!context.mounted) {
return;
}
Navigator.pop(context);
},
);

final Widget closeButton = TextButton(
child: Text(
strClose,
style: TextStyle(
fontSize: AppTheme.textScaler.scale(AppTheme.largeFontSize),
),
),
onPressed: () => Navigator.pop(context),
);

final AlertDialog alert = AlertDialog(
title: Text(
strImport,
style: TextStyle(
fontSize: AppTheme.textScaler.scale(AppTheme.largeFontSize),
),
),
// Show content if it's valid JSON
content: Text(
clipboardText,
textDirection: TextDirection.ltr,
),
actions: <Widget>[importButton, closeButton],
scrollable: true,
);

if (!context.mounted) {
return;
}

showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
} catch (e) {
// If parsing fails (not valid JSON), show a SnackBar with the invalid format message
rootScaffoldMessengerKey.currentState!.showSnackBar(
SnackBar(
content: Text(strInvalidFormat),
),
);
}
}

// Function to check if a string contains only ASCII characters
bool isAscii(String text) {
return text.codeUnits.every((int unit) => unit <= 127);
}

void exportColorSettings(BuildContext context) {
final String json = jsonEncode(DB().colorSettings.toJson());
final String content = json;
final Widget copyButton = TextButton(
child: Text(
S.of(context).copy,
style: TextStyle(
fontSize: AppTheme.textScaler.scale(AppTheme.largeFontSize),
),
),
onPressed: () {
Clipboard.setData(ClipboardData(text: content));
rootScaffoldMessengerKey.currentState!
.showSnackBarClear(S.of(context).copiedToClipboard);
Navigator.pop(context);
},
);

final Widget closeButton = TextButton(
child: Text(
S.of(context).close,
style: TextStyle(
fontSize: AppTheme.textScaler.scale(AppTheme.largeFontSize),
),
),
onPressed: () => Navigator.pop(context),
);

final AlertDialog alert = AlertDialog(
title: Text(
S.of(context).export,
style: TextStyle(
fontSize: AppTheme.textScaler.scale(AppTheme.largeFontSize),
),
),
content: Text(
content,
textDirection: TextDirection.ltr,
),
actions: <Widget>[copyButton, closeButton],
scrollable: true,
);

showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}

void langCallback(
BuildContext context,
DisplaySettings displaySettings, [
Expand Down Expand Up @@ -287,6 +444,14 @@ class AppearanceSettingsPage extends StatelessWidget {
analysisToolbarIconColor: val,
),
),
SettingsListTile(
titleString: S.of(context).importColorSettings,
onTap: () => importColorSettings(context),
),
SettingsListTile(
titleString: S.of(context).exportColorSettings,
onTap: () => exportColorSettings(context),
),
],
);
}
Expand Down
16 changes: 15 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_af.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1541,5 +1541,19 @@
"focusOnBlockingPaths_Detail": "Tydens spesifieke fases van die spel, prioritiseer om die teenstander se beweging te belemmer eerder as om rye van drie te vorm. In plaas daarvan om te fokus op die verwydering van stukke deur rye van drie te voltooi, mik die KI daarna om die teenstander tydens hierdie fases vas te keer, sodat hulle nie kan beweeg nie en 'n oorwinning deur uitputting verseker. Hierdie fase-spesifieke strategie blokkeer nie aktief die teenstander se rye van drie nie.",
"@focusOnBlockingPaths_Detail": {},
"pieceImage": "Stukkieprentjie",
"@pieceImage": {}
"@pieceImage": {},
"importColorSettings": "Kleurinstellings invoer",
"@importColorSettings": {},
"exportColorSettings": "Kleurinstellings uitvoer",
"@exportColorSettings": {},
"import": "Invoer",
"@import": {},
"export": "Uitvoer",
"@export": {},
"pleaseCopyJsonToClipboard": "Kopieer asseblief eers die JSON-formaatinstellings na die knipbord.",
"@pleaseCopyJsonToClipboard": {},
"copiedToClipboard": "Na knipbord gekopieer.",
"@copiedToClipboard": {},
"imported": "Geïmporteer.",
"@imported": {}
}
16 changes: 15 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_ar.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1443,5 +1443,19 @@
"focusOnBlockingPaths_Detail": "خلال مراحل محددة من اللعبة، قدِّم الأولوية لإعاقة حركة الخصم على تشكيل الطواحين. بدلاً من التركيز على إزالة القطع عبر إكمال الطواحين، تهدف الذكاء الاصطناعي إلى محاصرة الخصم خلال هذه المراحل، مما يجعله غير قادر على التحرك وضمان الفوز من خلال الإنهاك بدلاً من اللعب العدواني. هذه الاستراتيجية المحددة بالمرحلة لا تعيق طواحين الخصم بنشاط.",
"@focusOnBlockingPaths_Detail": {},
"pieceImage": "صورة قطعة الشطرنج",
"@pieceImage": {}
"@pieceImage": {},
"importColorSettings": "استيراد إعدادات الألوان",
"@importColorSettings": {},
"exportColorSettings": "تصدير إعدادات الألوان",
"@exportColorSettings": {},
"import": "استيراد",
"@import": {},
"export": "تصدير",
"@export": {},
"pleaseCopyJsonToClipboard": "يرجى نسخ إعدادات تنسيق JSON إلى الحافظة أولاً.",
"@pleaseCopyJsonToClipboard": {},
"copiedToClipboard": "تم النسخ إلى الحافظة.",
"@copiedToClipboard": {},
"imported": "تم الاستيراد.",
"@imported": {}
}
16 changes: 15 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_az.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1541,5 +1541,19 @@
"focusOnBlockingPaths_Detail": "Rəqibin hərəkətini maneə törətməyə üstünlük verin, üçlüyü formalaşdırmaqdan daha çox. Üçlü yaratmaqla parçaları çıxarmağa yönəlmək əvəzinə, AI rəqibi tələyə salmağa çalışır, onları hərəkətsiz vəziyyətə gətirir və aqressiv oyundan çox tükəndirməklə qalib gəlir. Bu strategiya rəqibin üçlü yaratmasına aktiv şəkildə mane olmur.",
"@focusOnBlockingPaths_Detail": {},
"pieceImage": "Fiqur şəkli",
"@pieceImage": {}
"@pieceImage": {},
"importColorSettings": "Rəng ayarlarını idxal edin",
"@importColorSettings": {},
"exportColorSettings": "Rəng ayarlarını ixrac edin",
"@exportColorSettings": {},
"import": "İdxal",
"@import": {},
"export": "İxrac",
"@export": {},
"pleaseCopyJsonToClipboard": "Zəhmət olmasa əvvəlcə JSON formatlı parametrləri mübadilə buferinə kopyalayın.",
"@pleaseCopyJsonToClipboard": {},
"copiedToClipboard": "Mübadilə buferinə kopyalandı.",
"@copiedToClipboard": {},
"imported": "İdxal edildi.",
"@imported": {}
}
16 changes: 15 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_be.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1541,5 +1541,19 @@
"focusOnBlockingPaths_Detail": "Перавага аддаецца перашкодзе руху суперніка, а не фарміраванню тройкі. Замест таго, каб засяродзіцца на выдаленні фігур шляхам завяршэння тройкі, ШІ імкнецца паставіць суперніка ў тупік, не дазваляючы яму рухацца і забяспечваючы перамогу праз стратэгію знясілення, а не агрэсіўную гульню. Гэтая стратэгія не блакуе актыўна тройкі суперніка.",
"@focusOnBlockingPaths_Detail": {},
"pieceImage": "Выява фігуры",
"@pieceImage": {}
"@pieceImage": {},
"importColorSettings": "Імпартаваць налады колеру",
"@importColorSettings": {},
"exportColorSettings": "Экспартаваць налады колеру",
"@exportColorSettings": {},
"import": "Імпарт",
"@import": {},
"export": "Экспарт",
"@export": {},
"pleaseCopyJsonToClipboard": "Калі ласка, спачатку скапіруйце налады фармату JSON у буфер абмену.",
"@pleaseCopyJsonToClipboard": {},
"copiedToClipboard": "Скапіравана ў буфер абмену.",
"@copiedToClipboard": {},
"imported": "Імпартавана.",
"@imported": {}
}
16 changes: 15 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_bg.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1443,5 +1443,19 @@
"focusOnBlockingPaths_Detail": "Приоритизирайте блокирането на движението на противника вместо формирането на тройки. Вместо да се фокусирате върху премахването на фигури чрез завършване на тройки, AI цели да вкара противника в капан, като го направи неспособен да се движи и да осигури победа чрез изтощение, а не чрез агресивна игра. Тази стратегия не блокира активно тройките на противника.",
"@focusOnBlockingPaths_Detail": {},
"pieceImage": "Изображение на фигура",
"@pieceImage": {}
"@pieceImage": {},
"importColorSettings": "Импортиране на настройки за цвят",
"@importColorSettings": {},
"exportColorSettings": "Експортиране на настройки за цвят",
"@exportColorSettings": {},
"import": "Импорт",
"@import": {},
"export": "Експорт",
"@export": {},
"pleaseCopyJsonToClipboard": "Моля, първо копирайте настройките за формат JSON в клипборда.",
"@pleaseCopyJsonToClipboard": {},
"copiedToClipboard": "Копирано в клипборда.",
"@copiedToClipboard": {},
"imported": "Импортирано.",
"@imported": {}
}
16 changes: 15 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_bn.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1443,5 +1443,19 @@
"focusOnBlockingPaths_Detail": "মিল তৈরি করার পরিবর্তে প্রতিপক্ষের গতিকে বাধা দেওয়ার উপর অগ্রাধিকার দিন। মিল সম্পূর্ণ করার মাধ্যমে টুকরোগুলি অপসারণের উপর মনোযোগ দেওয়ার পরিবর্তে, AI প্রতিপক্ষকে আটকে রাখার চেষ্টা করে, তাদের অক্ষম করে রাখে এবং আক্রমণাত্মক খেলার পরিবর্তে দীর্ঘমেয়াদী কৌশলে বিজয় নিশ্চিত করে। এই কৌশলটি প্রতিপক্ষের মিলগুলিকে সক্রিয়ভাবে ব্লক করে না।",
"@focusOnBlockingPaths_Detail": {},
"pieceImage": "ছবি টুকরা",
"@pieceImage": {}
"@pieceImage": {},
"importColorSettings": "রঙের সেটিংস আমদানি করুন",
"@importColorSettings": {},
"exportColorSettings": "রঙের সেটিংস রপ্তানি করুন",
"@exportColorSettings": {},
"import": "আমদানি",
"@import": {},
"export": "রপ্তানি",
"@export": {},
"pleaseCopyJsonToClipboard": "দয়া করে প্রথমে JSON ফরম্যাটের সেটিংসগুলো ক্লিপবোর্ডে কপি করুন।",
"@pleaseCopyJsonToClipboard": {},
"copiedToClipboard": "ক্লিপবোর্ডে কপি করা হয়েছে।",
"@copiedToClipboard": {},
"imported": "আমদানি করা হয়েছে।",
"@imported": {}
}
16 changes: 15 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_bs.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1443,5 +1443,19 @@
"focusOnBlockingPaths_Detail": "Prioritet dajte ometanju kretanja protivnika umjesto formiranja tri u nizu. Umjesto da se fokusira na uklanjanje figura dovršavanjem tri u nizu, AI nastoji da uhvati protivnika u zamku, onemogućavajući mu kretanje i osiguravajući pobjedu kroz iscrpljivanje umjesto agresivne igre. Ova strategija ne blokira aktivno protivničke tri u nizu.",
"@focusOnBlockingPaths_Detail": {},
"pieceImage": "Slika figure",
"@pieceImage": {}
"@pieceImage": {},
"importColorSettings": "Uvezi postavke boja",
"@importColorSettings": {},
"exportColorSettings": "Izvezi postavke boja",
"@exportColorSettings": {},
"import": "Uvoz",
"@import": {},
"export": "Izvoz",
"@export": {},
"pleaseCopyJsonToClipboard": "Molimo prvo kopirajte postavke JSON formata u međuspremnik.",
"@pleaseCopyJsonToClipboard": {},
"copiedToClipboard": "Kopirano u međuspremnik.",
"@copiedToClipboard": {},
"imported": "Uvezeno.",
"@imported": {}
}
16 changes: 15 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_cs.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1443,5 +1443,19 @@
"focusOnBlockingPaths_Detail": "V určitých fázích hry prioritizujte bránění pohybu soupeře před tvořením mlýnů. Místo zaměření se na odstraňování figurek dokončováním mlýnů, AI se v těchto fázích snaží chytit soupeře do pasti, znemožnit mu pohyb a zajistit vítězství opotřebováním místo agresivní hry. Tato strategie specifická pro dané fáze aktivně neblokuje soupeřovy mlýny.",
"@focusOnBlockingPaths_Detail": {},
"pieceImage": "Obraz figurky",
"@pieceImage": {}
"@pieceImage": {},
"importColorSettings": "Importovat nastavení barev",
"@importColorSettings": {},
"exportColorSettings": "Exportovat nastavení barev",
"@exportColorSettings": {},
"import": "Import",
"@import": {},
"export": "Export",
"@export": {},
"pleaseCopyJsonToClipboard": "Nejprve prosím zkopírujte nastavení formátu JSON do schránky.",
"@pleaseCopyJsonToClipboard": {},
"copiedToClipboard": "Zkopírováno do schránky.",
"@copiedToClipboard": {},
"imported": "Importováno.",
"@imported": {}
}
16 changes: 15 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_da.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1443,5 +1443,19 @@
"focusOnBlockingPaths_Detail": "Prioriter at hindre modstanderens bevægelser over at danne møller. I stedet for at fokusere på at fjerne brikker ved at fuldføre møller, sigter AI på at fange modstanderen, så de ikke kan bevæge sig og sikre en sejr gennem udmattelse snarere end aggressivt spil. Denne strategi blokerer ikke aktivt modstanderens møller.",
"@focusOnBlockingPaths_Detail": {},
"pieceImage": "Brikbillede",
"@pieceImage": {}
"@pieceImage": {},
"importColorSettings": "Importér farveindstillinger",
"@importColorSettings": {},
"exportColorSettings": "Eksporter farveindstillinger",
"@exportColorSettings": {},
"import": "Importér",
"@import": {},
"export": "Eksportér",
"@export": {},
"pleaseCopyJsonToClipboard": "Kopier venligst JSON-formatindstillingerne til udklipsholderen først.",
"@pleaseCopyJsonToClipboard": {},
"copiedToClipboard": "Kopieret til udklipsholder.",
"@copiedToClipboard": {},
"imported": "Importeret.",
"@imported": {}
}
Loading

0 comments on commit 81d5eb0

Please sign in to comment.