diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart index a81a047b4..9ca9039f0 100644 --- a/flutter/lib/main.dart +++ b/flutter/lib/main.dart @@ -39,7 +39,7 @@ class App extends StatelessWidget { primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), - home: !isAndroid ? WebHomePage() : HomePage(), + home: !isAndroid ? WebHomePage() : HomePage(key: homeKey), navigatorObservers: [ FirebaseAnalyticsObserver(analytics: analytics), FlutterSmartDialog.observer diff --git a/flutter/lib/pages/chat_page.dart b/flutter/lib/pages/chat_page.dart index af940a29e..527f2a8c6 100644 --- a/flutter/lib/pages/chat_page.dart +++ b/flutter/lib/pages/chat_page.dart @@ -6,8 +6,6 @@ import 'package:provider/provider.dart'; import '../models/model.dart'; import 'home_page.dart'; -ChatPage chatPage = ChatPage(); - class ChatPage extends StatelessWidget implements PageShape { @override final title = translate("Chat"); diff --git a/flutter/lib/pages/home_page.dart b/flutter/lib/pages/home_page.dart index 371aa3f64..fbf4fa0d2 100644 --- a/flutter/lib/pages/home_page.dart +++ b/flutter/lib/pages/home_page.dart @@ -12,6 +12,8 @@ abstract class PageShape extends Widget { final List appBarActions = []; } +final homeKey = GlobalKey<_HomePageState>(); + class HomePage extends StatefulWidget { HomePage({Key? key}) : super(key: key); @@ -23,12 +25,23 @@ class _HomePageState extends State { var _selectedIndex = 0; final List _pages = []; + void refreshPages() { + setState(() { + initPages(); + }); + } + @override void initState() { super.initState(); + initPages(); + } + + void initPages() { + _pages.clear(); _pages.add(ConnectionPage()); if (isAndroid) { - _pages.addAll([chatPage, ServerPage()]); + _pages.addAll([ChatPage(), ServerPage()]); } _pages.add(SettingsPage()); } diff --git a/flutter/lib/pages/settings_page.dart b/flutter/lib/pages/settings_page.dart index ea92a72ca..bb1238494 100644 --- a/flutter/lib/pages/settings_page.dart +++ b/flutter/lib/pages/settings_page.dart @@ -146,6 +146,12 @@ class _SettingsState extends State with WidgetsBindingObserver { leading: Icon(Icons.cloud), onPressed: (context) { showServerSettings(); + }), + SettingsTile.navigation( + title: Text(translate('Language')), + leading: Icon(Icons.translate), + onPressed: (context) { + showLanguageSettings(); }) ]), SettingsSection( @@ -185,6 +191,42 @@ void showServerSettings() { showServerSettingsWithValue(id, relay, key, api); } +void showLanguageSettings() { + try { + final langs = json.decode(FFI.getByName('langs')) as List; + var lang = FFI.getByName('local_option', 'lang'); + DialogManager.show((setState, close) { + final setLang = (v) { + if (lang != v) { + setState(() { + lang = v; + }); + final msg = Map() + ..['name'] = 'lang' + ..['value'] = v; + FFI.setByName('local_option', json.encode(msg)); + homeKey.currentState?.refreshPages(); + Future.delayed(Duration(milliseconds: 200), close); + } + }; + return CustomAlertDialog( + title: SizedBox.shrink(), + content: Column( + children: [ + getRadio('Default', '', lang, setLang), + Divider(color: MyTheme.border), + ] + + langs.map((e) { + final key = e[0] as String; + final name = e[1] as String; + return getRadio(name, key, lang, setLang); + }).toList(), + ), + actions: []); + }, backDismiss: true, clickMaskDismiss: true); + } catch (_e) {} +} + void showAbout() { DialogManager.show((setState, close) { return CustomAlertDialog( diff --git a/flutter/lib/widgets/overlay.dart b/flutter/lib/widgets/overlay.dart index 276c175f9..b2ee54410 100644 --- a/flutter/lib/widgets/overlay.dart +++ b/flutter/lib/widgets/overlay.dart @@ -27,7 +27,7 @@ class DraggableChatWindow extends StatelessWidget { height: height, builder: (_, onPanUpdate) { return isIOS - ? chatPage + ? ChatPage() : Scaffold( resizeToAvoidBottomInset: false, appBar: CustomAppBar( @@ -68,7 +68,7 @@ class DraggableChatWindow extends StatelessWidget { ), ), ), - body: chatPage, + body: ChatPage(), ); }); } diff --git a/src/mobile_ffi.rs b/src/mobile_ffi.rs index ef2a986eb..b9ef571bb 100644 --- a/src/mobile_ffi.rs +++ b/src/mobile_ffi.rs @@ -113,6 +113,14 @@ unsafe extern "C" fn get_by_name(name: *const c_char, arg: *const c_char) -> *co res = Session::get_option(arg); } } + "local_option" => { + if let Ok(arg) = arg.to_str() { + res = LocalConfig::get_option(arg); + } + } + "langs" => { + res = crate::lang::LANGS.to_string(); + } // File Action "get_home_dir" => { res = fs::get_home_as_string(); @@ -311,6 +319,15 @@ unsafe extern "C" fn set_by_name(name: *const c_char, value: *const c_char) { } } } + "local_option" => { + if let Ok(m) = serde_json::from_str::>(value) { + if let Some(name) = m.get("name") { + if let Some(value) = m.get("value") { + LocalConfig::set_option(name.to_owned(), value.to_owned()); + } + } + } + } "input_os_password" => { Session::input_os_password(value.to_owned(), true); }