From 9f7e0dad52151d23c867ef66f48736a8740fe511 Mon Sep 17 00:00:00 2001 From: xkeyC <3334969096@qq.com> Date: Tue, 5 Nov 2024 22:55:00 +0800 Subject: [PATCH] feat: CommunityInputMethod --- lib/ui/home/home_ui.dart | 38 ++++ lib/ui/home/home_ui_model.dart | 1 + lib/ui/home/home_ui_model.g.dart | 2 +- .../input_method/input_method_dialog_ui.dart | 133 +++++++++++ .../input_method_dialog_ui_model.dart | 117 ++++++++++ .../input_method_dialog_ui_model.freezed.dart | 215 ++++++++++++++++++ .../input_method_dialog_ui_model.g.dart | 28 +++ .../localization/localization_ui_model.dart | 42 +++- .../localization/localization_ui_model.g.dart | 2 +- 9 files changed, 573 insertions(+), 5 deletions(-) create mode 100644 lib/ui/home/input_method/input_method_dialog_ui.dart create mode 100644 lib/ui/home/input_method/input_method_dialog_ui_model.dart create mode 100644 lib/ui/home/input_method/input_method_dialog_ui_model.freezed.dart create mode 100644 lib/ui/home/input_method/input_method_dialog_ui_model.g.dart diff --git a/lib/ui/home/home_ui.dart b/lib/ui/home/home_ui.dart index 2a684d9..f6faf9e 100644 --- a/lib/ui/home/home_ui.dart +++ b/lib/ui/home/home_ui.dart @@ -17,6 +17,7 @@ import 'package:url_launcher/url_launcher_string.dart'; import 'dialogs/home_countdown_dialog_ui.dart'; import 'dialogs/home_md_content_dialog_ui.dart'; import 'home_ui_model.dart'; +import 'input_method/input_method_dialog_ui.dart'; import 'localization/localization_dialog_ui.dart'; import 'localization/localization_ui_model.dart'; @@ -176,6 +177,19 @@ class HomeUI extends HookConsumerWidget { ), )), const SizedBox(width: 12), + Button( + onPressed: () => + _checkAndGoInputMethod(context, homeState, model, ref), + style: ButtonStyle( + backgroundColor: + WidgetStateProperty.resolveWith((_) => Colors.blue), + ), + child: Padding( + padding: const EdgeInsets.all(6), + child: Icon(FluentIcons.keyboard_classic), + ), + ), + const SizedBox(width: 12), Button( onPressed: model.reScanPath, child: const Padding( @@ -841,6 +855,30 @@ class HomeUI extends HookConsumerWidget { return; } } + + void _checkAndGoInputMethod(BuildContext context, HomeUIModelState homeState, + HomeUIModel model, WidgetRef ref) async { + final localizationState = ref.read(localizationUIModelProvider); + if (localizationState.communityInputMethodLanguageData == null) { + showToast(context, "功能维护中,请稍后重试"); + return; + } + if (localizationState.installedCommunityInputMethodSupportVersion == null) { + final userOK = await showConfirmDialogs(context, "未安装社区输入法支持", + Text("是否前往汉化管理安装?\n\n如已安装汉化,请卸载并在重新安装时打开社区输入法支持开关。")); + if (userOK) { + if (!context.mounted) return; + _onMenuTap(context, 'localization', homeState, ref); + } + return; + } + showDialog( + context: context, + builder: (BuildContext context) { + return InputMethodDialogUI(); + }, + ); + } } class _HomeItemData { diff --git a/lib/ui/home/home_ui_model.dart b/lib/ui/home/home_ui_model.dart index d7cb6db..e6cc447 100644 --- a/lib/ui/home/home_ui_model.dart +++ b/lib/ui/home/home_ui_model.dart @@ -338,6 +338,7 @@ class HomeUIModel extends _$HomeUIModel { void onChangeInstallPath(String? value) { if (value == null) return; state = state.copyWith(scInstalledPath: value); + ref.read(localizationUIModelProvider.notifier).onChangeGameInstallPath(value); } doLaunchGame( diff --git a/lib/ui/home/home_ui_model.g.dart b/lib/ui/home/home_ui_model.g.dart index 0638112..52a3124 100644 --- a/lib/ui/home/home_ui_model.g.dart +++ b/lib/ui/home/home_ui_model.g.dart @@ -6,7 +6,7 @@ part of 'home_ui_model.dart'; // RiverpodGenerator // ************************************************************************** -String _$homeUIModelHash() => r'85d3242abb4264a814768a2d5ce108df46df38d9'; +String _$homeUIModelHash() => r'10389d5b134e1ab545b792a814d13a832c2cfc06'; /// See also [HomeUIModel]. @ProviderFor(HomeUIModel) diff --git a/lib/ui/home/input_method/input_method_dialog_ui.dart b/lib/ui/home/input_method/input_method_dialog_ui.dart new file mode 100644 index 0000000..8c834e8 --- /dev/null +++ b/lib/ui/home/input_method/input_method_dialog_ui.dart @@ -0,0 +1,133 @@ +import 'package:fluent_ui/fluent_ui.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:go_router/go_router.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:starcitizen_doctor/ui/home/input_method/input_method_dialog_ui_model.dart'; +import 'package:starcitizen_doctor/widgets/widgets.dart'; + +class InputMethodDialogUI extends HookConsumerWidget { + const InputMethodDialogUI({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final state = ref.watch(inputMethodDialogUIModelProvider); + final model = ref.read(inputMethodDialogUIModelProvider.notifier); + final srcTextCtrl = useTextEditingController(); + final destTextCtrl = useTextEditingController(); + + return ContentDialog( + constraints: BoxConstraints( + maxWidth: MediaQuery.of(context).size.width * .8, + ), + title: makeTitle(context, state, model, destTextCtrl), + content: state.keyMaps == null + ? makeLoading(context) + : Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 12), + InfoBar( + title: Text("使用说明"), + content: Text( + "在上方文本框中输入文字,并将下方转码后的文本复制到游戏的文本框中,即可在聊天频道中发送游戏不支持输入的文字。"), + ), + SizedBox(height: 24), + TextFormBox( + placeholder: "请输入文本...", + controller: srcTextCtrl, + maxLines: 5, + placeholderStyle: + TextStyle(color: Colors.white.withOpacity(.6)), + style: TextStyle(fontSize: 16, color: Colors.white), + onChanged: (str) { + final text = model.onTextChange("src", str); + if (text != null) { + destTextCtrl.text = text; + } + }, + ), + SizedBox(height: 16), + Center( + child: Icon(FluentIcons.down), + ), + SizedBox(height: 16), + TextFormBox( + placeholder: "这里是转码后的文本...", + controller: destTextCtrl, + maxLines: 5, + placeholderStyle: + TextStyle(color: Colors.white.withOpacity(.6)), + style: TextStyle(fontSize: 16, color: Colors.white), + enabled: true, + onChanged: (str) { + // final text = model.onTextChange("dest", str); + // if (text != null) { + // srcTextCtrl.text = text; + // } + }, + ), + SizedBox(height: 32), + Row( + children: [ + Expanded( + child: Text( + textAlign: TextAlign.end, + "*本功能建议仅在非公共频道中使用。若用户选择在公共频道中使用本功能,由此产生的任何后果(包括但不限于被其他玩家举报刷屏等),均由用户自行承担。\n*若该功能被滥用,我们将关闭该功能。", + style: TextStyle( + fontSize: 13, + color: Colors.white.withOpacity(.6), + ), + ), + ) + ], + ), + ], + ), + ); + } + + Widget makeTitle(BuildContext context, InputMethodDialogUIState state, + InputMethodDialogUIModel model, TextEditingController destTextCtrl) { + return Row( + children: [ + IconButton( + icon: const Icon( + FluentIcons.back, + size: 22, + ), + onPressed: () { + context.pop(); + }), + const SizedBox(width: 12), + Text("社区输入法"), + Spacer(), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text( + "自动复制", + style: TextStyle(fontSize: 14), + ), + SizedBox(width: 12), + ToggleSwitch( + checked: state.enableAutoCopy, + onChanged: model.onSwitchAutoCopy), + ], + ), + SizedBox(width: 24), + FilledButton( + child: Padding( + padding: const EdgeInsets.all(6), + child: Icon(FluentIcons.copy), + ), + onPressed: () { + if (destTextCtrl.text.isNotEmpty) { + Clipboard.setData(ClipboardData(text: destTextCtrl.text)); + } + }, + ) + ], + ); + } +} diff --git a/lib/ui/home/input_method/input_method_dialog_ui_model.dart b/lib/ui/home/input_method/input_method_dialog_ui_model.dart new file mode 100644 index 0000000..4011187 --- /dev/null +++ b/lib/ui/home/input_method/input_method_dialog_ui_model.dart @@ -0,0 +1,117 @@ +import 'dart:async'; + +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:hive/hive.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:starcitizen_doctor/common/utils/log.dart'; +import 'package:starcitizen_doctor/ui/home/localization/localization_ui_model.dart'; + +part 'input_method_dialog_ui_model.g.dart'; + +part 'input_method_dialog_ui_model.freezed.dart'; + +@freezed +class InputMethodDialogUIState with _$InputMethodDialogUIState { + factory InputMethodDialogUIState( + Map? keyMaps, + Map? worldMaps, { + @Default(false) bool enableAutoCopy, + }) = _InputMethodDialogUIState; +} + +@riverpod +class InputMethodDialogUIModel extends _$InputMethodDialogUIModel { + @override + InputMethodDialogUIState build() { + state = InputMethodDialogUIState(null, null); + _init(); + return state; + } + + _init() async { + final localizationState = ref.watch(localizationUIModelProvider); + final localizationModel = ref.read(localizationUIModelProvider.notifier); + if (localizationState.installedCommunityInputMethodSupportVersion == null) { + return; + } + final keyMaps = + await localizationModel.getCommunityInputMethodSupportData(); + dPrint("[InputMethodDialogUIModel] keyMapsLen: ${keyMaps?.length}"); + final worldMaps = keyMaps?.map((key, value) => MapEntry(value.trim(), key)); + final appBox = await Hive.openBox("app_conf"); + final enableAutoCopy = appBox.get("enableAutoCopy", defaultValue: false); + state = state.copyWith( + keyMaps: keyMaps, + worldMaps: worldMaps, + enableAutoCopy: enableAutoCopy, + ); + } + + void onSwitchAutoCopy(bool value) async { + final appBox = await Hive.openBox("app_conf"); + appBox.put("enableAutoCopy", value); + state = state.copyWith(enableAutoCopy: value); + } + + String? onTextChange(String type, String str) { + if (state.keyMaps == null || state.worldMaps == null) return null; + StringBuffer sb = StringBuffer(); + final r = RegExp(r'^[a-zA-Z0-9\p{P}\p{S}]+$'); + if (type == "src") { + final map = state.worldMaps!; + // text to code + var leftSafe = true; + for (var c in str.characters) { + if (r.hasMatch((c))) { + if (leftSafe) { + sb.write(c); + } else { + sb.write(" $c"); + } + leftSafe = true; + continue; + } else { + // 特殊字符,开始转码 + final code = map[c.trim()]; + // dPrint("c:$c code: $code"); + if (code != null) { + if (leftSafe) { + sb.write(" "); + } + sb.write("@$code"); + } else { + // 不支持转码,用空格代替 + sb.write(" "); + } + leftSafe = false; + } + } + } + if (sb.toString().trim().isEmpty) { + return ""; + } + final text = "[zh] ${sb.toString()}"; + _handleAutoCopy(text); + return text; + } + + Timer? _autoCopyTimer; + + // 打字结束后的1秒后自动复制,避免频繁复制 + void _handleAutoCopy(String text) { + if (_autoCopyTimer != null) { + _autoCopyTimer?.cancel(); + _autoCopyTimer = null; + } + if (!state.enableAutoCopy) return; + _autoCopyTimer = Timer(const Duration(seconds: 1), () { + if (state.enableAutoCopy) { + dPrint("auto copy: $text"); + Clipboard.setData(ClipboardData(text: text)); + } + }); + } + +} diff --git a/lib/ui/home/input_method/input_method_dialog_ui_model.freezed.dart b/lib/ui/home/input_method/input_method_dialog_ui_model.freezed.dart new file mode 100644 index 0000000..a609001 --- /dev/null +++ b/lib/ui/home/input_method/input_method_dialog_ui_model.freezed.dart @@ -0,0 +1,215 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'input_method_dialog_ui_model.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); + +/// @nodoc +mixin _$InputMethodDialogUIState { + Map? get keyMaps => throw _privateConstructorUsedError; + Map? get worldMaps => throw _privateConstructorUsedError; + bool get enableAutoCopy => throw _privateConstructorUsedError; + + /// Create a copy of InputMethodDialogUIState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $InputMethodDialogUIStateCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $InputMethodDialogUIStateCopyWith<$Res> { + factory $InputMethodDialogUIStateCopyWith(InputMethodDialogUIState value, + $Res Function(InputMethodDialogUIState) then) = + _$InputMethodDialogUIStateCopyWithImpl<$Res, InputMethodDialogUIState>; + @useResult + $Res call( + {Map? keyMaps, + Map? worldMaps, + bool enableAutoCopy}); +} + +/// @nodoc +class _$InputMethodDialogUIStateCopyWithImpl<$Res, + $Val extends InputMethodDialogUIState> + implements $InputMethodDialogUIStateCopyWith<$Res> { + _$InputMethodDialogUIStateCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of InputMethodDialogUIState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? keyMaps = freezed, + Object? worldMaps = freezed, + Object? enableAutoCopy = null, + }) { + return _then(_value.copyWith( + keyMaps: freezed == keyMaps + ? _value.keyMaps + : keyMaps // ignore: cast_nullable_to_non_nullable + as Map?, + worldMaps: freezed == worldMaps + ? _value.worldMaps + : worldMaps // ignore: cast_nullable_to_non_nullable + as Map?, + enableAutoCopy: null == enableAutoCopy + ? _value.enableAutoCopy + : enableAutoCopy // ignore: cast_nullable_to_non_nullable + as bool, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$InputMethodDialogUIStateImplCopyWith<$Res> + implements $InputMethodDialogUIStateCopyWith<$Res> { + factory _$$InputMethodDialogUIStateImplCopyWith( + _$InputMethodDialogUIStateImpl value, + $Res Function(_$InputMethodDialogUIStateImpl) then) = + __$$InputMethodDialogUIStateImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {Map? keyMaps, + Map? worldMaps, + bool enableAutoCopy}); +} + +/// @nodoc +class __$$InputMethodDialogUIStateImplCopyWithImpl<$Res> + extends _$InputMethodDialogUIStateCopyWithImpl<$Res, + _$InputMethodDialogUIStateImpl> + implements _$$InputMethodDialogUIStateImplCopyWith<$Res> { + __$$InputMethodDialogUIStateImplCopyWithImpl( + _$InputMethodDialogUIStateImpl _value, + $Res Function(_$InputMethodDialogUIStateImpl) _then) + : super(_value, _then); + + /// Create a copy of InputMethodDialogUIState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? keyMaps = freezed, + Object? worldMaps = freezed, + Object? enableAutoCopy = null, + }) { + return _then(_$InputMethodDialogUIStateImpl( + freezed == keyMaps + ? _value._keyMaps + : keyMaps // ignore: cast_nullable_to_non_nullable + as Map?, + freezed == worldMaps + ? _value._worldMaps + : worldMaps // ignore: cast_nullable_to_non_nullable + as Map?, + enableAutoCopy: null == enableAutoCopy + ? _value.enableAutoCopy + : enableAutoCopy // ignore: cast_nullable_to_non_nullable + as bool, + )); + } +} + +/// @nodoc + +class _$InputMethodDialogUIStateImpl implements _InputMethodDialogUIState { + _$InputMethodDialogUIStateImpl( + final Map? keyMaps, final Map? worldMaps, + {this.enableAutoCopy = false}) + : _keyMaps = keyMaps, + _worldMaps = worldMaps; + + final Map? _keyMaps; + @override + Map? get keyMaps { + final value = _keyMaps; + if (value == null) return null; + if (_keyMaps is EqualUnmodifiableMapView) return _keyMaps; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(value); + } + + final Map? _worldMaps; + @override + Map? get worldMaps { + final value = _worldMaps; + if (value == null) return null; + if (_worldMaps is EqualUnmodifiableMapView) return _worldMaps; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(value); + } + + @override + @JsonKey() + final bool enableAutoCopy; + + @override + String toString() { + return 'InputMethodDialogUIState(keyMaps: $keyMaps, worldMaps: $worldMaps, enableAutoCopy: $enableAutoCopy)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$InputMethodDialogUIStateImpl && + const DeepCollectionEquality().equals(other._keyMaps, _keyMaps) && + const DeepCollectionEquality() + .equals(other._worldMaps, _worldMaps) && + (identical(other.enableAutoCopy, enableAutoCopy) || + other.enableAutoCopy == enableAutoCopy)); + } + + @override + int get hashCode => Object.hash( + runtimeType, + const DeepCollectionEquality().hash(_keyMaps), + const DeepCollectionEquality().hash(_worldMaps), + enableAutoCopy); + + /// Create a copy of InputMethodDialogUIState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$InputMethodDialogUIStateImplCopyWith<_$InputMethodDialogUIStateImpl> + get copyWith => __$$InputMethodDialogUIStateImplCopyWithImpl< + _$InputMethodDialogUIStateImpl>(this, _$identity); +} + +abstract class _InputMethodDialogUIState implements InputMethodDialogUIState { + factory _InputMethodDialogUIState( + final Map? keyMaps, final Map? worldMaps, + {final bool enableAutoCopy}) = _$InputMethodDialogUIStateImpl; + + @override + Map? get keyMaps; + @override + Map? get worldMaps; + @override + bool get enableAutoCopy; + + /// Create a copy of InputMethodDialogUIState + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$InputMethodDialogUIStateImplCopyWith<_$InputMethodDialogUIStateImpl> + get copyWith => throw _privateConstructorUsedError; +} diff --git a/lib/ui/home/input_method/input_method_dialog_ui_model.g.dart b/lib/ui/home/input_method/input_method_dialog_ui_model.g.dart new file mode 100644 index 0000000..3235c8f --- /dev/null +++ b/lib/ui/home/input_method/input_method_dialog_ui_model.g.dart @@ -0,0 +1,28 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'input_method_dialog_ui_model.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$inputMethodDialogUIModelHash() => + r'48955b06db0b5fdc8ae5e59b93fdd9a95b391487'; + +/// See also [InputMethodDialogUIModel]. +@ProviderFor(InputMethodDialogUIModel) +final inputMethodDialogUIModelProvider = AutoDisposeNotifierProvider< + InputMethodDialogUIModel, InputMethodDialogUIState>.internal( + InputMethodDialogUIModel.new, + name: r'inputMethodDialogUIModelProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$inputMethodDialogUIModelHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef _$InputMethodDialogUIModel + = AutoDisposeNotifier; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/ui/home/localization/localization_ui_model.dart b/lib/ui/home/localization/localization_ui_model.dart index b681931..2e8bfa0 100644 --- a/lib/ui/home/localization/localization_ui_model.dart +++ b/lib/ui/home/localization/localization_ui_model.dart @@ -247,9 +247,6 @@ class LocalizationUIModel extends _$LocalizationUIModel { if (!globalIni.toString().endsWith("\n")) { globalIni.write("\n"); } - if (advanced ?? false) { - globalIni.write("_starcitizen_doctor_localization_advanced=true\n"); - } if (communityInputMethodVersion != null) { globalIni.write( "_starcitizen_doctor_localization_community_input_method_version=$communityInputMethodVersion\n"); @@ -259,6 +256,9 @@ class LocalizationUIModel extends _$LocalizationUIModel { globalIni.write("$line\n"); } } + if (advanced ?? false) { + globalIni.write("_starcitizen_doctor_localization_advanced=true\n"); + } globalIni .write("_starcitizen_doctor_localization_version=$versionName\n"); } @@ -277,6 +277,38 @@ class LocalizationUIModel extends _$LocalizationUIModel { await _updateStatus(); } + Future?> getCommunityInputMethodSupportData() async { + final iniPath = + "${_scDataDir.absolute.path}\\Localization\\${state.selectedLanguage}\\global.ini"; + final iniFile = File(iniPath); + if (!await iniFile.exists()) { + return {}; + } + final iniStringSplit = (await iniFile.readAsString()).split("\n"); + final communityInputMethodSupportData = {}; + var b = false; + for (var i = 0; i < iniStringSplit.length; i++) { + final line = iniStringSplit[i]; + + if (line.trim().startsWith( + "_starcitizen_doctor_localization_community_input_method_version=")) { + b = true; + continue; + } else if (line + .trim() + .startsWith("_starcitizen_doctor_localization_version=")) { + b = false; + return communityInputMethodSupportData; + } else if (b) { + final kv = line.split("="); + if (kv.length == 2) { + communityInputMethodSupportData[kv[0]] = kv[1]; + } + } + } + return null; + } + VoidCallback? doRemoteInstall(BuildContext context, ScLocalizationData value, {bool isEnableCommunityInputMethod = false}) { return () async { @@ -530,4 +562,8 @@ class LocalizationUIModel extends _$LocalizationUIModel { } return updates; } + + Future onChangeGameInstallPath(String value) async { + await _loadData(); + } } diff --git a/lib/ui/home/localization/localization_ui_model.g.dart b/lib/ui/home/localization/localization_ui_model.g.dart index 89926cf..ccbc0a3 100644 --- a/lib/ui/home/localization/localization_ui_model.g.dart +++ b/lib/ui/home/localization/localization_ui_model.g.dart @@ -7,7 +7,7 @@ part of 'localization_ui_model.dart'; // ************************************************************************** String _$localizationUIModelHash() => - r'86e433e1901683ad05b81e34d3b37b9b72c4c786'; + r'b8c893413fa8a314d0fa3b2cfffb63f723226bae'; /// See also [LocalizationUIModel]. @ProviderFor(LocalizationUIModel)