1
0
forked from firka/firka

fix: use proper settings api for l10n

This commit is contained in:
2025-08-15 13:31:55 +02:00
parent 72a538f3c5
commit 55540cce90
4 changed files with 423 additions and 52 deletions

View File

@@ -26,6 +26,16 @@ const AppSettingsModelSchema = CollectionSchema(
id: 1,
name: r'valueDouble',
type: IsarType.double,
),
r'valueIndex': PropertySchema(
id: 2,
name: r'valueIndex',
type: IsarType.long,
),
r'valueString': PropertySchema(
id: 3,
name: r'valueString',
type: IsarType.string,
)
},
estimateSize: _appSettingsModelEstimateSize,
@@ -48,6 +58,12 @@ int _appSettingsModelEstimateSize(
Map<Type, List<int>> allOffsets,
) {
var bytesCount = offsets.last;
{
final value = object.valueString;
if (value != null) {
bytesCount += 3 + value.length * 3;
}
}
return bytesCount;
}
@@ -59,6 +75,8 @@ void _appSettingsModelSerialize(
) {
writer.writeBool(offsets[0], object.valueBool);
writer.writeDouble(offsets[1], object.valueDouble);
writer.writeLong(offsets[2], object.valueIndex);
writer.writeString(offsets[3], object.valueString);
}
AppSettingsModel _appSettingsModelDeserialize(
@@ -71,6 +89,8 @@ AppSettingsModel _appSettingsModelDeserialize(
object.id = id;
object.valueBool = reader.readBoolOrNull(offsets[0]);
object.valueDouble = reader.readDoubleOrNull(offsets[1]);
object.valueIndex = reader.readLongOrNull(offsets[2]);
object.valueString = reader.readStringOrNull(offsets[3]);
return object;
}
@@ -85,6 +105,10 @@ P _appSettingsModelDeserializeProp<P>(
return (reader.readBoolOrNull(offset)) as P;
case 1:
return (reader.readDoubleOrNull(offset)) as P;
case 2:
return (reader.readLongOrNull(offset)) as P;
case 3:
return (reader.readStringOrNull(offset)) as P;
default:
throw IsarError('Unknown property with id $propertyId');
}
@@ -369,6 +393,234 @@ extension AppSettingsModelQueryFilter
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueIndexIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'valueIndex',
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueIndexIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'valueIndex',
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueIndexEqualTo(int? value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'valueIndex',
value: value,
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueIndexGreaterThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'valueIndex',
value: value,
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueIndexLessThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'valueIndex',
value: value,
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueIndexBetween(
int? lower,
int? upper, {
bool includeLower = true,
bool includeUpper = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'valueIndex',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueStringIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'valueString',
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueStringIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'valueString',
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueStringEqualTo(
String? value, {
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'valueString',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueStringGreaterThan(
String? value, {
bool include = false,
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'valueString',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueStringLessThan(
String? value, {
bool include = false,
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'valueString',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueStringBetween(
String? lower,
String? upper, {
bool includeLower = true,
bool includeUpper = true,
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'valueString',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueStringStartsWith(
String value, {
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.startsWith(
property: r'valueString',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueStringEndsWith(
String value, {
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.endsWith(
property: r'valueString',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueStringContains(String value, {bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.contains(
property: r'valueString',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueStringMatches(String pattern, {bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.matches(
property: r'valueString',
wildcard: pattern,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueStringIsEmpty() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'valueString',
value: '',
));
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterFilterCondition>
valueStringIsNotEmpty() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
property: r'valueString',
value: '',
));
});
}
}
extension AppSettingsModelQueryObject
@@ -406,6 +658,34 @@ extension AppSettingsModelQuerySortBy
return query.addSortBy(r'valueDouble', Sort.desc);
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterSortBy>
sortByValueIndex() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'valueIndex', Sort.asc);
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterSortBy>
sortByValueIndexDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'valueIndex', Sort.desc);
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterSortBy>
sortByValueString() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'valueString', Sort.asc);
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterSortBy>
sortByValueStringDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'valueString', Sort.desc);
});
}
}
extension AppSettingsModelQuerySortThenBy
@@ -450,6 +730,34 @@ extension AppSettingsModelQuerySortThenBy
return query.addSortBy(r'valueDouble', Sort.desc);
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterSortBy>
thenByValueIndex() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'valueIndex', Sort.asc);
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterSortBy>
thenByValueIndexDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'valueIndex', Sort.desc);
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterSortBy>
thenByValueString() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'valueString', Sort.asc);
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QAfterSortBy>
thenByValueStringDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'valueString', Sort.desc);
});
}
}
extension AppSettingsModelQueryWhereDistinct
@@ -467,6 +775,20 @@ extension AppSettingsModelQueryWhereDistinct
return query.addDistinctBy(r'valueDouble');
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QDistinct>
distinctByValueIndex() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'valueIndex');
});
}
QueryBuilder<AppSettingsModel, AppSettingsModel, QDistinct>
distinctByValueString({bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'valueString', caseSensitive: caseSensitive);
});
}
}
extension AppSettingsModelQueryProperty
@@ -489,4 +811,17 @@ extension AppSettingsModelQueryProperty
return query.addPropertyName(r'valueDouble');
});
}
QueryBuilder<AppSettingsModel, int?, QQueryOperations> valueIndexProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'valueIndex');
});
}
QueryBuilder<AppSettingsModel, String?, QQueryOperations>
valueStringProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'valueString');
});
}
}

View File

@@ -5,14 +5,14 @@ import 'package:firka/ui/widget/firka_icon.dart';
import 'package:isar/isar.dart';
import 'package:majesticons_flutter/majesticons_flutter.dart';
const bellRing = 1_001;
const rounding1 = 1_002;
const rounding2 = 1_003;
const rounding3 = 1_004;
const rounding4 = 1_005;
const classAvgOnGraph = 1_006;
const leftHandedMode = 1_007;
const language = 1_008;
const bellRing = 1001;
const rounding1 = 1002;
const rounding2 = 1003;
const rounding3 = 1004;
const rounding4 = 1005;
const classAvgOnGraph = 1006;
const leftHandedMode = 1007;
const language = 1008;
class SettingsStore {
LinkedHashMap<String, SettingsItem> items = LinkedHashMap.of({});
@@ -81,13 +81,13 @@ class SettingsStore {
Future<void> save(IsarCollection<AppSettingsModel> model) async {
for (var item in items.values) {
item.save(model);
await item.save(model);
}
}
Future<void> load(IsarCollection<AppSettingsModel> model) async {
for (var item in items.values) {
item.load(model);
await item.load(model);
}
}
}
@@ -97,6 +97,10 @@ extension SettingExt on LinkedHashMap<String, SettingsItem> {
return (this[key] as SettingsGroup).children;
}
LinkedHashMap<String, SettingsItem> subGroup(String key) {
return (this[key] as SettingsSubGroup).children;
}
String string(String key) {
return (this[key] as SettingsString).value;
}
@@ -129,9 +133,9 @@ class SettingsItem {
SettingsItem(this.key, this.iconType, this.iconData);
void save(IsarCollection<AppSettingsModel> model) {}
Future<void> save(IsarCollection<AppSettingsModel> model) async {}
void load(IsarCollection<AppSettingsModel> model) {}
Future<void> load(IsarCollection<AppSettingsModel> model) async {}
}
class SettingsGroup implements SettingsItem {
@@ -146,16 +150,16 @@ class SettingsGroup implements SettingsItem {
SettingsGroup(this.key, this.children);
@override
void load(IsarCollection<AppSettingsModel> model) {
Future<void> load(IsarCollection<AppSettingsModel> model) async {
for (var item in children.values) {
item.load(model);
await item.load(model);
}
}
@override
void save(IsarCollection<AppSettingsModel> model) {
Future<void> save(IsarCollection<AppSettingsModel> model) async {
for (var item in children.values) {
item.save(model);
await item.save(model);
}
}
}
@@ -174,16 +178,16 @@ class SettingsSubGroup implements SettingsItem {
this.key, this.iconType, this.iconData, this.title, this.children);
@override
void load(IsarCollection<AppSettingsModel> model) {
Future<void> load(IsarCollection<AppSettingsModel> model) async {
for (var item in children.values) {
item.load(model);
await item.load(model);
}
}
@override
void save(IsarCollection<AppSettingsModel> model) {
Future<void> save(IsarCollection<AppSettingsModel> model) async {
for (var item in children.values) {
item.save(model);
await item.save(model);
}
}
}
@@ -200,10 +204,10 @@ class SettingsPadding implements SettingsItem {
SettingsPadding(this.key, this.padding);
@override
void load(IsarCollection<AppSettingsModel> model) {}
Future<void> load(IsarCollection<AppSettingsModel> model) async {}
@override
void save(IsarCollection<AppSettingsModel> model) {}
Future<void> save(IsarCollection<AppSettingsModel> model) async {}
}
class SettingsHeader implements SettingsItem {
@@ -218,10 +222,10 @@ class SettingsHeader implements SettingsItem {
SettingsHeader(this.key, this.title);
@override
void load(IsarCollection<AppSettingsModel> model) {}
Future<void> load(IsarCollection<AppSettingsModel> model) async {}
@override
void save(IsarCollection<AppSettingsModel> model) {}
Future<void> save(IsarCollection<AppSettingsModel> model) async {}
}
class SettingsHeaderSmall implements SettingsItem {
@@ -236,10 +240,10 @@ class SettingsHeaderSmall implements SettingsItem {
SettingsHeaderSmall(this.key, this.title);
@override
void load(IsarCollection<AppSettingsModel> model) {}
Future<void> load(IsarCollection<AppSettingsModel> model) async {}
@override
void save(IsarCollection<AppSettingsModel> model) {}
Future<void> save(IsarCollection<AppSettingsModel> model) async {}
}
class SettingsSubtitle implements SettingsItem {
@@ -254,10 +258,10 @@ class SettingsSubtitle implements SettingsItem {
SettingsSubtitle(this.key, this.title);
@override
void load(IsarCollection<AppSettingsModel> model) {}
Future<void> load(IsarCollection<AppSettingsModel> model) async {}
@override
void save(IsarCollection<AppSettingsModel> model) {}
Future<void> save(IsarCollection<AppSettingsModel> model) async {}
}
class SettingsBoolean implements SettingsItem {
@@ -275,8 +279,8 @@ class SettingsBoolean implements SettingsItem {
this.key, this.iconType, this.iconData, this.title, this.defaultValue);
@override
void load(IsarCollection<AppSettingsModel> model) {
var v = model.getSync(key);
Future<void> load(IsarCollection<AppSettingsModel> model) async {
var v = await model.get(key);
if (v == null || v.valueBool == null) {
value = defaultValue;
} else {
@@ -285,12 +289,12 @@ class SettingsBoolean implements SettingsItem {
}
@override
void save(IsarCollection<AppSettingsModel> model) {
Future<void> save(IsarCollection<AppSettingsModel> model) async {
var v = AppSettingsModel();
v.id = key;
v.valueBool = value;
model.put(v);
await model.put(v);
}
}
@@ -309,22 +313,22 @@ class SettingsItemsRadio implements SettingsItem {
this.key, this.iconType, this.iconData, this.values, this.defaultIndex);
@override
void load(IsarCollection<AppSettingsModel> model) {
var v = model.getSync(key);
Future<void> load(IsarCollection<AppSettingsModel> model) async {
var v = await model.get(key);
if (v == null || v.valueIndex == null) {
activeIndex = v!.valueIndex!;
} else {
activeIndex = defaultIndex;
} else {
activeIndex = v.valueIndex!;
}
}
@override
void save(IsarCollection<AppSettingsModel> model) {
Future<void> save(IsarCollection<AppSettingsModel> model) async {
var v = AppSettingsModel();
v.id = key;
v.valueIndex = activeIndex;
model.put(v);
await model.put(v);
}
}
@@ -343,8 +347,8 @@ class SettingsDouble implements SettingsItem {
this.key, this.iconType, this.iconData, this.title, this.defaultValue);
@override
void load(IsarCollection<AppSettingsModel> model) {
var v = model.getSync(key);
Future<void> load(IsarCollection<AppSettingsModel> model) async {
var v = await model.get(key);
if (v == null || v.valueDouble == null) {
value = defaultValue;
} else {
@@ -353,12 +357,12 @@ class SettingsDouble implements SettingsItem {
}
@override
void save(IsarCollection<AppSettingsModel> model) {
Future<void> save(IsarCollection<AppSettingsModel> model) async {
var v = AppSettingsModel();
v.id = key;
v.valueDouble = value;
model.put(v);
await model.put(v);
}
}
@@ -377,8 +381,8 @@ class SettingsString implements SettingsItem {
this.key, this.iconType, this.iconData, this.title, this.defaultValue);
@override
void load(IsarCollection<AppSettingsModel> model) {
var v = model.getSync(key);
Future<void> load(IsarCollection<AppSettingsModel> model) async {
var v = await model.get(key);
if (v == null || v.valueString == null) {
value = defaultValue;
} else {
@@ -387,11 +391,11 @@ class SettingsString implements SettingsItem {
}
@override
void save(IsarCollection<AppSettingsModel> model) {
Future<void> save(IsarCollection<AppSettingsModel> model) async {
var v = AppSettingsModel();
v.id = key;
v.valueString = value;
model.put(v);
await model.put(v);
}
}

View File

@@ -1,5 +1,6 @@
import 'dart:async';
import 'dart:io';
import 'dart:ui' as ui;
import 'package:dio/dio.dart';
import 'package:firka/helpers/api/client/kreta_client.dart';
@@ -28,6 +29,8 @@ import 'package:watch_connectivity/watch_connectivity.dart';
import 'helpers/db/models/homework_cache_model.dart';
import 'l10n/app_localizations.dart';
import 'l10n/app_localizations_de.dart';
import 'l10n/app_localizations_en.dart';
Isar? isarInit;
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
@@ -86,6 +89,34 @@ Future<AppInitialization> initializeApp() async {
l10n: AppLocalizationsHu(),
);
await init.settings.load(init.isar.appSettingsModels);
switch ((init.settings.group("settings").subGroup("application")["language"]
as SettingsItemsRadio)
.activeIndex) {
case 1: // hu
init.l10n = AppLocalizationsHu();
break;
case 2: // en
init.l10n = AppLocalizationsEn();
break;
case 3: // de
init.l10n = AppLocalizationsDe();
break;
default: // auto
switch (ui.window.locale.languageCode) {
case 'hu':
init.l10n = AppLocalizationsHu();
break;
case 'en':
init.l10n = AppLocalizationsEn();
break;
case 'de':
init.l10n = AppLocalizationsDe();
break;
}
break;
}
resetOldTimeTableCache(isar);
resetOldHomeworkCache(isar);

View File

@@ -120,13 +120,13 @@ class _SettingsScreenState extends State<SettingsScreen> {
Switch(
value: item.value,
activeColor: appStyle.colors.accent,
onChanged: (v) {
onChanged: (v) async {
setState(() {
item.value = v;
});
widget.data.isar.writeTxn(() async {
item.save(widget.data.isar.appSettingsModels);
await widget.data.isar.writeTxn(() async {
await item.save(widget.data.isar.appSettingsModels);
});
})
],
@@ -147,14 +147,15 @@ class _SettingsScreenState extends State<SettingsScreen> {
(Set<WidgetState> states) {
return appStyle.colors.secondary;
}),
onChanged: (_) {
onChanged: (_) async {
setState(() {
item.activeIndex = i;
});
widget.data.isar.writeTxn(() async {
item.save(widget.data.isar.appSettingsModels);
await widget.data.isar.writeTxn(() async {
await item.save(widget.data.isar.appSettingsModels);
});
debugPrint('Settings saved');
})
]));
}