mirror of
https://github.com/immich-app/immich
synced 2025-06-09 04:09:21 +00:00
feat(mobile): typed translation keys
This commit is contained in:
parent
a9bd651692
commit
b1ab8a610a
61
mobile/bin/generate_keys.dart
Normal file
61
mobile/bin/generate_keys.dart
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
const _kReservedWords = ['continue'];
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
final sourceFile = File('../i18n/en.json');
|
||||||
|
if (!await sourceFile.exists()) {
|
||||||
|
stderr.writeln('Source file does not exist');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final outputDir = Directory('lib/generated');
|
||||||
|
await outputDir.create(recursive: true);
|
||||||
|
|
||||||
|
final outputFile = File('lib/generated/intl_keys.g.dart');
|
||||||
|
await _generate(sourceFile, outputFile);
|
||||||
|
print('Generated ${outputFile.path}');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _generate(File source, File output) async {
|
||||||
|
final content = await source.readAsString();
|
||||||
|
final translations = json.decode(content) as Map<String, dynamic>;
|
||||||
|
|
||||||
|
final buffer = StringBuffer('''
|
||||||
|
// DO NOT EDIT. This is code generated via generate_keys.dart
|
||||||
|
|
||||||
|
abstract class IntlKeys {
|
||||||
|
''');
|
||||||
|
|
||||||
|
_writeKeys(buffer, translations);
|
||||||
|
buffer.writeln('}');
|
||||||
|
|
||||||
|
await output.writeAsString(buffer.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void _writeKeys(
|
||||||
|
StringBuffer buffer,
|
||||||
|
Map<String, dynamic> map, [
|
||||||
|
String prefix = '',
|
||||||
|
]) {
|
||||||
|
for (final entry in map.entries) {
|
||||||
|
final key = entry.key;
|
||||||
|
final value = entry.value;
|
||||||
|
|
||||||
|
if (value is Map<String, dynamic>) {
|
||||||
|
_writeKeys(buffer, value, prefix.isEmpty ? key : '${prefix}_$key');
|
||||||
|
} else {
|
||||||
|
final name = _cleanName(prefix.isEmpty ? key : '${prefix}_$key');
|
||||||
|
final path = prefix.isEmpty ? key : '$prefix.$key'.replaceAll('_', '.');
|
||||||
|
buffer.writeln(' static const $name = \'$path\';');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String _cleanName(String name) {
|
||||||
|
name = name.replaceAll(RegExp(r'[^a-zA-Z0-9_]'), '_');
|
||||||
|
if (RegExp(r'^[0-9]').hasMatch(name)) name = 'k_$name';
|
||||||
|
if (_kReservedWords.contains(name)) name = '${name}_';
|
||||||
|
return name;
|
||||||
|
}
|
2562
mobile/lib/generated/intl_keys.g.dart
generated
Normal file
2562
mobile/lib/generated/intl_keys.g.dart
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||||
import 'package:immich_mobile/extensions/asyncvalue_extensions.dart';
|
import 'package:immich_mobile/extensions/asyncvalue_extensions.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
import 'package:immich_mobile/generated/intl_keys.g.dart';
|
||||||
import 'package:immich_mobile/providers/album/album.provider.dart';
|
import 'package:immich_mobile/providers/album/album.provider.dart';
|
||||||
import 'package:immich_mobile/providers/partner.provider.dart';
|
import 'package:immich_mobile/providers/partner.provider.dart';
|
||||||
import 'package:immich_mobile/providers/search/people.provider.dart';
|
import 'package:immich_mobile/providers/search/people.provider.dart';
|
||||||
@ -41,13 +42,13 @@ class LibraryPage extends ConsumerWidget {
|
|||||||
ActionButton(
|
ActionButton(
|
||||||
onPressed: () => context.pushRoute(const FavoritesRoute()),
|
onPressed: () => context.pushRoute(const FavoritesRoute()),
|
||||||
icon: Icons.favorite_outline_rounded,
|
icon: Icons.favorite_outline_rounded,
|
||||||
label: 'favorites'.tr(),
|
label: IntlKeys.favorites.tr(),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
ActionButton(
|
ActionButton(
|
||||||
onPressed: () => context.pushRoute(const ArchiveRoute()),
|
onPressed: () => context.pushRoute(const ArchiveRoute()),
|
||||||
icon: Icons.archive_outlined,
|
icon: Icons.archive_outlined,
|
||||||
label: 'archived'.tr(),
|
label: IntlKeys.archived.tr(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -58,14 +59,14 @@ class LibraryPage extends ConsumerWidget {
|
|||||||
ActionButton(
|
ActionButton(
|
||||||
onPressed: () => context.pushRoute(const SharedLinkRoute()),
|
onPressed: () => context.pushRoute(const SharedLinkRoute()),
|
||||||
icon: Icons.link_outlined,
|
icon: Icons.link_outlined,
|
||||||
label: 'shared_links'.tr(),
|
label: IntlKeys.shared_links.tr(),
|
||||||
),
|
),
|
||||||
SizedBox(width: trashEnabled ? 8 : 0),
|
SizedBox(width: trashEnabled ? 8 : 0),
|
||||||
trashEnabled
|
trashEnabled
|
||||||
? ActionButton(
|
? ActionButton(
|
||||||
onPressed: () => context.pushRoute(const TrashRoute()),
|
onPressed: () => context.pushRoute(const TrashRoute()),
|
||||||
icon: Icons.delete_outline_rounded,
|
icon: Icons.delete_outline_rounded,
|
||||||
label: 'trash'.tr(),
|
label: IntlKeys.trash.tr(),
|
||||||
)
|
)
|
||||||
: const SizedBox.shrink(),
|
: const SizedBox.shrink(),
|
||||||
],
|
],
|
||||||
@ -133,7 +134,7 @@ class QuickAccessButtons extends ConsumerWidget {
|
|||||||
size: 26,
|
size: 26,
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
'folders'.tr(),
|
IntlKeys.folders.tr(),
|
||||||
style: context.textTheme.titleSmall?.copyWith(
|
style: context.textTheme.titleSmall?.copyWith(
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
@ -146,7 +147,7 @@ class QuickAccessButtons extends ConsumerWidget {
|
|||||||
size: 26,
|
size: 26,
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
'locked_folder'.tr(),
|
IntlKeys.locked_folder.tr(),
|
||||||
style: context.textTheme.titleSmall?.copyWith(
|
style: context.textTheme.titleSmall?.copyWith(
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
@ -159,7 +160,7 @@ class QuickAccessButtons extends ConsumerWidget {
|
|||||||
size: 26,
|
size: 26,
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
'partners'.tr(),
|
IntlKeys.partners.tr(),
|
||||||
style: context.textTheme.titleSmall?.copyWith(
|
style: context.textTheme.titleSmall?.copyWith(
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
@ -275,7 +276,7 @@ class PeopleCollectionCard extends ConsumerWidget {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
'people'.tr(),
|
IntlKeys.people.tr(),
|
||||||
style: context.textTheme.titleSmall?.copyWith(
|
style: context.textTheme.titleSmall?.copyWith(
|
||||||
color: context.colorScheme.onSurface,
|
color: context.colorScheme.onSurface,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -343,7 +344,7 @@ class LocalAlbumsCollectionCard extends HookConsumerWidget {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
'on_this_device'.tr(),
|
IntlKeys.on_this_device.tr(),
|
||||||
style: context.textTheme.titleSmall?.copyWith(
|
style: context.textTheme.titleSmall?.copyWith(
|
||||||
color: context.colorScheme.onSurface,
|
color: context.colorScheme.onSurface,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -404,7 +405,7 @@ class PlacesCollectionCard extends StatelessWidget {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
'places'.tr(),
|
IntlKeys.places.tr(),
|
||||||
style: context.textTheme.titleSmall?.copyWith(
|
style: context.textTheme.titleSmall?.copyWith(
|
||||||
color: context.colorScheme.onSurface,
|
color: context.colorScheme.onSurface,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
|
@ -26,4 +26,6 @@ migration:
|
|||||||
|
|
||||||
translation:
|
translation:
|
||||||
dart run easy_localization:generate -S ../i18n
|
dart run easy_localization:generate -S ../i18n
|
||||||
|
dart run bin/generate_keys.dart
|
||||||
dart format lib/generated/codegen_loader.g.dart
|
dart format lib/generated/codegen_loader.g.dart
|
||||||
|
dart format lib/generated/intl_keys.g.dart
|
Loading…
x
Reference in New Issue
Block a user