This commit is contained in:
parent
e9107a7f62
commit
089fe1f8df
11
assets/i18n/de_DE.json
Normal file
11
assets/i18n/de_DE.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"settings_title": "Einstellungen",
|
||||||
|
"settings_language": "Sprache",
|
||||||
|
"settings_drawer_title": "Drawer per Geste öffnen",
|
||||||
|
"settings_drawer_subtitle": "Wähle, ob der Drawer mit einer Wischgeste geschlossen/geöffnet werden kann.",
|
||||||
|
"settings_numberofcolumns_title": "Spaltenanzahl",
|
||||||
|
"settings_numberofcolumns_columns": "@count Spalten",
|
||||||
|
"settings_pageanimation_title": "Seitenwechselanimation",
|
||||||
|
"settings_cache_title": "Cache leeren",
|
||||||
|
"settings_cache_clear_button": "Leeren"
|
||||||
|
}
|
11
assets/i18n/en_US.json
Normal file
11
assets/i18n/en_US.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"settings_title": "Settings",
|
||||||
|
"settings_language": "Language",
|
||||||
|
"settings_drawer_title": "Open drawer with gesture",
|
||||||
|
"settings_drawer_subtitle": "Choose whether the drawer can be closed/opened with a swipe gesture.",
|
||||||
|
"settings_numberofcolumns_title": "Number of columns",
|
||||||
|
"settings_numberofcolumns_columns": "@count columns",
|
||||||
|
"settings_pageanimation_title": "Page change animation",
|
||||||
|
"settings_cache_title": "Clear Cache",
|
||||||
|
"settings_cache_clear_button": "Clear"
|
||||||
|
}
|
11
assets/i18n/fr_FR.json
Normal file
11
assets/i18n/fr_FR.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"settings_title": "Paramètres",
|
||||||
|
"settings_language": "Langue",
|
||||||
|
"settings_drawer_title": "Ouvrir le tiroir avec un geste",
|
||||||
|
"settings_drawer_subtitle": "Choisissez si le tiroir peut être ouvert/fermé avec un geste de balayage.",
|
||||||
|
"settings_numberofcolumns_title": "Nombre de colonnes",
|
||||||
|
"settings_numberofcolumns_columns": "@count colonnes",
|
||||||
|
"settings_pageanimation_title": "Animation de changement de page",
|
||||||
|
"settings_cache_title": "Vider le cache",
|
||||||
|
"settings_cache_clear_button": "Vider"
|
||||||
|
}
|
11
assets/i18n/nl_NL.json
Normal file
11
assets/i18n/nl_NL.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"settings_title": "Instellingen",
|
||||||
|
"settings_language": "Taal",
|
||||||
|
"settings_drawer_title": "Lade openen met een gebaar",
|
||||||
|
"settings_drawer_subtitle": "Kies of de lade geopend/gesloten kan worden met een veeggebaar.",
|
||||||
|
"settings_numberofcolumns_title": "Aantal kolommen",
|
||||||
|
"settings_numberofcolumns_columns": "@count kolommen",
|
||||||
|
"settings_pageanimation_title": "Pagina-overgangsanimatie",
|
||||||
|
"settings_cache_title": "Cache wissen",
|
||||||
|
"settings_cache_clear_button": "Wissen"
|
||||||
|
}
|
61
lib/controller/localization_controller.dart
Normal file
61
lib/controller/localization_controller.dart
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:encrypt_shared_preferences/provider.dart';
|
||||||
|
|
||||||
|
class MyTranslations extends Translations {
|
||||||
|
static final MyTranslations instance = MyTranslations._internal();
|
||||||
|
MyTranslations._internal();
|
||||||
|
|
||||||
|
static final Map<String, Map<String, String>> _translations = {};
|
||||||
|
|
||||||
|
static Future<void> loadTranslations() async {
|
||||||
|
final locales = ['en_US', 'de_DE', 'fr_FR', 'nl_NL'];
|
||||||
|
for (final locale in locales) {
|
||||||
|
final String jsonString = await rootBundle.loadString('assets/i18n/$locale.json');
|
||||||
|
final Map<String, dynamic> jsonMap = json.decode(jsonString);
|
||||||
|
_translations[locale] = jsonMap.map((key, value) => MapEntry(key, value.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, Map<String, String>> get keys => _translations;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LocalizationController extends GetxController {
|
||||||
|
final EncryptedSharedPreferencesAsync storage =
|
||||||
|
EncryptedSharedPreferencesAsync.getInstance();
|
||||||
|
Rx<Locale> currentLocale = const Locale('en', 'US').obs;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
super.onInit();
|
||||||
|
loadLocale();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> loadLocale() async {
|
||||||
|
String? savedLocale = await storage.getString(
|
||||||
|
'locale',
|
||||||
|
defaultValue: 'en_US',
|
||||||
|
);
|
||||||
|
if (savedLocale != null && savedLocale.isNotEmpty) {
|
||||||
|
final List<String> parts = savedLocale.split('_');
|
||||||
|
currentLocale.value = parts.length == 2
|
||||||
|
? Locale(parts[0], parts[1])
|
||||||
|
: Locale(parts[0]);
|
||||||
|
Get.locale = currentLocale.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> changeLocale(Locale newLocale) async {
|
||||||
|
currentLocale.value = newLocale;
|
||||||
|
Get.updateLocale(newLocale);
|
||||||
|
await storage.setString(
|
||||||
|
'locale',
|
||||||
|
'${newLocale.languageCode}_${newLocale.countryCode}',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:encrypt_shared_preferences/provider.dart';
|
import 'package:encrypt_shared_preferences/provider.dart';
|
||||||
import 'package:f0ckapp/utils/animatedtransition.dart';
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import 'package:f0ckapp/utils/animatedtransition.dart';
|
||||||
import 'package:f0ckapp/service/media_service.dart';
|
import 'package:f0ckapp/service/media_service.dart';
|
||||||
import 'package:f0ckapp/models/media_item.dart';
|
import 'package:f0ckapp/models/media_item.dart';
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:encrypt_shared_preferences/provider.dart';
|
import 'package:encrypt_shared_preferences/provider.dart';
|
||||||
|
|
||||||
|
import 'package:f0ckapp/controller/localization_controller.dart';
|
||||||
import 'package:f0ckapp/utils/appversion.dart';
|
import 'package:f0ckapp/utils/appversion.dart';
|
||||||
import 'package:f0ckapp/controller/theme_controller.dart';
|
import 'package:f0ckapp/controller/theme_controller.dart';
|
||||||
import 'package:f0ckapp/controller/media_controller.dart';
|
import 'package:f0ckapp/controller/media_controller.dart';
|
||||||
@ -14,13 +15,21 @@ void main() async {
|
|||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||||
await EncryptedSharedPreferencesAsync.initialize('VokTnbAbemBUa2j9');
|
await EncryptedSharedPreferencesAsync.initialize('VokTnbAbemBUa2j9');
|
||||||
|
await MyTranslations.loadTranslations();
|
||||||
await AppVersion.init();
|
await AppVersion.init();
|
||||||
Get.put(MediaController());
|
Get.put(MediaController());
|
||||||
|
LocalizationController localizationController = Get.put(LocalizationController());
|
||||||
final ThemeController themeController = Get.put(ThemeController());
|
final ThemeController themeController = Get.put(ThemeController());
|
||||||
|
|
||||||
|
Get.addTranslations(MyTranslations.instance.keys);
|
||||||
|
Get.locale = localizationController.currentLocale.value;
|
||||||
|
|
||||||
|
//Locale systemLocale = WidgetsBinding.instance.platformDispatcher.locale;
|
||||||
|
|
||||||
runApp(
|
runApp(
|
||||||
Obx(
|
Obx(
|
||||||
() => MaterialApp(
|
() => MaterialApp(
|
||||||
|
locale: Get.locale,
|
||||||
navigatorKey: Get.key,
|
navigatorKey: Get.key,
|
||||||
theme: themeController.currentTheme.value,
|
theme: themeController.currentTheme.value,
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:f0ckapp/utils/animatedtransition.dart';
|
|
||||||
import 'package:f0ckapp/utils/smartrefreshindicator.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
@ -10,6 +8,8 @@ import 'package:get/get.dart';
|
|||||||
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
|
|
||||||
|
import 'package:f0ckapp/utils/animatedtransition.dart';
|
||||||
|
import 'package:f0ckapp/utils/smartrefreshindicator.dart';
|
||||||
import 'package:f0ckapp/controller/media_controller.dart';
|
import 'package:f0ckapp/controller/media_controller.dart';
|
||||||
import 'package:f0ckapp/models/media_item.dart';
|
import 'package:f0ckapp/models/media_item.dart';
|
||||||
import 'package:f0ckapp/screens/media_grid.dart';
|
import 'package:f0ckapp/screens/media_grid.dart';
|
||||||
@ -151,7 +151,11 @@ class _DetailViewState extends State<DetailView> {
|
|||||||
title: Text('f0ck #${currentItem.id.toString()}'),
|
title: Text('f0ck #${currentItem.id.toString()}'),
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
icon: const Icon(Icons.arrow_back),
|
icon: const Icon(Icons.arrow_back),
|
||||||
onPressed: () => Get.back(),
|
onPressed: () {
|
||||||
|
Navigator.canPop(context)
|
||||||
|
? Get.back()
|
||||||
|
: Get.offAllNamed('/');
|
||||||
|
}
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import 'package:f0ckapp/utils/animatedtransition.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
import 'package:f0ckapp/controller/media_controller.dart';
|
import 'package:f0ckapp/controller/media_controller.dart';
|
||||||
|
import 'package:f0ckapp/controller/localization_controller.dart';
|
||||||
|
import 'package:f0ckapp/utils/animatedtransition.dart';
|
||||||
|
|
||||||
class SettingsPage extends StatefulWidget {
|
class SettingsPage extends StatefulWidget {
|
||||||
const SettingsPage({super.key});
|
const SettingsPage({super.key});
|
||||||
@ -14,7 +15,8 @@ class SettingsPage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _SettingsPageState extends State<SettingsPage> {
|
class _SettingsPageState extends State<SettingsPage> {
|
||||||
final MediaController controller = Get.find<MediaController>();
|
final MediaController controller = Get.find();
|
||||||
|
final LocalizationController localizationController = Get.find();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -24,12 +26,12 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||||||
SliverAppBar(
|
SliverAppBar(
|
||||||
floating: false,
|
floating: false,
|
||||||
pinned: true,
|
pinned: true,
|
||||||
title: const Text('Settings'),
|
title: Text('settings_title'.tr),
|
||||||
),
|
),
|
||||||
SliverList(
|
SliverList(
|
||||||
delegate: SliverChildListDelegate([
|
delegate: SliverChildListDelegate([
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text("Spaltenanzahl"),
|
title: Text('settings_numberofcolumns_title'.tr),
|
||||||
trailing: Obx(
|
trailing: Obx(
|
||||||
() => DropdownButton<int>(
|
() => DropdownButton<int>(
|
||||||
value: controller.crossAxisCount.value,
|
value: controller.crossAxisCount.value,
|
||||||
@ -38,7 +40,13 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||||||
items: [0, 3, 4, 5].map((int value) {
|
items: [0, 3, 4, 5].map((int value) {
|
||||||
return DropdownMenuItem<int>(
|
return DropdownMenuItem<int>(
|
||||||
value: value,
|
value: value,
|
||||||
child: Text(value == 0 ? 'auto' : '$value Spalten'),
|
child: Text(
|
||||||
|
value == 0
|
||||||
|
? 'auto'
|
||||||
|
: 'settings_numberofcolumns_columns'.trParams({
|
||||||
|
'count': value.toString(),
|
||||||
|
}),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
onChanged: (int? newValue) async {
|
onChanged: (int? newValue) async {
|
||||||
@ -52,7 +60,7 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text("Seitenwechselanimation"),
|
title: Text('settings_pageanimation_title'.tr),
|
||||||
trailing: Obx(
|
trailing: Obx(
|
||||||
() => DropdownButton<PageTransition>(
|
() => DropdownButton<PageTransition>(
|
||||||
value: controller.transitionType.value,
|
value: controller.transitionType.value,
|
||||||
@ -94,10 +102,8 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||||||
|
|
||||||
const Divider(),
|
const Divider(),
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
title: const Text("Drawer per Geste öffnen"),
|
title: Text('settings_drawer_title'.tr),
|
||||||
subtitle: const Text(
|
subtitle: Text('settings_drawer_subtitle'.tr),
|
||||||
"Wähle, ob der Drawer mit einer Wischgeste geschlossen/ geöffnet werden kann.",
|
|
||||||
),
|
|
||||||
value: controller.drawerSwipeEnabled.value,
|
value: controller.drawerSwipeEnabled.value,
|
||||||
onChanged: (bool value) async {
|
onChanged: (bool value) async {
|
||||||
await controller.setDrawerSwipeEnabled(value);
|
await controller.setDrawerSwipeEnabled(value);
|
||||||
@ -106,17 +112,50 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text("Cache löschen"),
|
title: Text('settings_language'.tr),
|
||||||
|
trailing: Obx(
|
||||||
|
() => DropdownButton<Locale>(
|
||||||
|
value: localizationController.currentLocale.value,
|
||||||
|
dropdownColor: const Color.fromARGB(255, 43, 43, 43),
|
||||||
|
iconEnabledColor: Colors.white,
|
||||||
|
items: const [
|
||||||
|
DropdownMenuItem<Locale>(
|
||||||
|
value: Locale('en', 'US'),
|
||||||
|
child: Text('English'),
|
||||||
|
),
|
||||||
|
DropdownMenuItem<Locale>(
|
||||||
|
value: Locale('de', 'DE'),
|
||||||
|
child: Text('Deutsch'),
|
||||||
|
),
|
||||||
|
DropdownMenuItem<Locale>(
|
||||||
|
value: Locale('fr', 'FR'),
|
||||||
|
child: Text('Français'),
|
||||||
|
),
|
||||||
|
DropdownMenuItem<Locale>(
|
||||||
|
value: Locale('nl', 'NL'),
|
||||||
|
child: Text('Nederlands'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
onChanged: (Locale? newLocale) async {
|
||||||
|
if (newLocale != null) {
|
||||||
|
await localizationController.changeLocale(newLocale);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
ListTile(
|
||||||
|
title: Text('settings_cache_title'.tr),
|
||||||
trailing: ElevatedButton(
|
trailing: ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await DefaultCacheManager().emptyCache();
|
await DefaultCacheManager().emptyCache();
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
Get.snackbar('', 'der Cache wurde geleert.');
|
Get.snackbar('', 'der Cache wurde geleert.');
|
||||||
},
|
},
|
||||||
child: const Text("Löschen"),
|
child: Text('settings_cache_clear_button'.tr),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -18,7 +18,7 @@ Widget buildAnimatedTransition({
|
|||||||
switch (controller.transitionType.value) {
|
switch (controller.transitionType.value) {
|
||||||
case PageTransition.opacity:
|
case PageTransition.opacity:
|
||||||
return Opacity(
|
return Opacity(
|
||||||
opacity: Curves.easeOut.transform(1 - value.abs().clamp(0.0, 40.0)),
|
opacity: Curves.easeOut.transform(1 - value.abs().clamp(0.0, 1.0)),
|
||||||
child: Transform(transform: Matrix4.identity(), child: child),
|
child: Transform(transform: Matrix4.identity(), child: child),
|
||||||
);
|
);
|
||||||
case PageTransition.scale:
|
case PageTransition.scale:
|
||||||
@ -48,4 +48,3 @@ Widget buildAnimatedTransition({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,8 +1,8 @@
|
|||||||
import 'package:f0ckapp/screens/settings_screen.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import 'package:f0ckapp/screens/settings_screen.dart';
|
||||||
import 'package:f0ckapp/controller/theme_controller.dart';
|
import 'package:f0ckapp/controller/theme_controller.dart';
|
||||||
import 'package:f0ckapp/utils/appversion.dart';
|
import 'package:f0ckapp/utils/appversion.dart';
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 1.3.1+57
|
version: 1.3.2+58
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.9.0-100.2.beta
|
sdk: ^3.9.0-100.2.beta
|
||||||
@ -63,6 +63,7 @@ flutter:
|
|||||||
# To add assets to your application, add an assets section, like this:
|
# To add assets to your application, add an assets section, like this:
|
||||||
assets:
|
assets:
|
||||||
- assets/images/
|
- assets/images/
|
||||||
|
- assets/i18n/
|
||||||
- pubspec.yaml
|
- pubspec.yaml
|
||||||
# - images/a_dot_burr.jpeg
|
# - images/a_dot_burr.jpeg
|
||||||
# - images/a_dot_ham.jpeg
|
# - images/a_dot_ham.jpeg
|
||||||
|
Loading…
x
Reference in New Issue
Block a user