✨ Base url
This commit is contained in:
		| @@ -98,5 +98,8 @@ | ||||
|   "settingsNetworkServer": "HyperNet Server", | ||||
|   "settingsNetworkServerDescription": "Set the HyperNet server address, choose ours or build your own.", | ||||
|   "settingsNetworkServerReset": "Reset to Official Server", | ||||
|   "settingsNetworkServerResetDescription": "Reset to the official server address of Solar Network." | ||||
|   "settingsNetworkServerResetDescription": "Reset to the official server address of Solar Network.", | ||||
|   "settingsNetworkServerPreset": "Present HyperNet Server", | ||||
|   "settingsNetworkServerPresetDescription": "You can choose one of our preset HyperNet server addresses from the list on the right.", | ||||
|   "settingsNetworkServerSaved": "Server address saved." | ||||
| } | ||||
|   | ||||
| @@ -98,5 +98,8 @@ | ||||
|   "settingsNetworkServer": "HyperNet 服务器", | ||||
|   "settingsNetworkServerDescription": "设置 HyperNet 服务器地址,选择我们提供的,或者自己搭建。", | ||||
|   "settingsNetworkServerReset": "重设为官方服务器", | ||||
|   "settingsNetworkServerResetDescription": "重设为 Solar Network 的服务器地址。" | ||||
|   "settingsNetworkServerResetDescription": "重设为 Solar Network 的服务器地址。", | ||||
|   "settingsNetworkServerPreset": "预设的 HyperNet 服务器", | ||||
|   "settingsNetworkServerPresetDescription": "你可以在旁边的列表中选择我们提供的预设 HyperNet 服务器地址。", | ||||
|   "settingsNetworkServerSaved": "服务器地址已保存。" | ||||
| } | ||||
|   | ||||
| @@ -4,25 +4,30 @@ import 'dart:developer'; | ||||
| import 'package:dio/dio.dart'; | ||||
| import 'package:dio_smart_retry/dio_smart_retry.dart'; | ||||
| import 'package:flutter_secure_storage/flutter_secure_storage.dart'; | ||||
| import 'package:shared_preferences/shared_preferences.dart'; | ||||
| import 'package:surface/providers/adapters/sn_network_universal.dart'; | ||||
|  | ||||
| const kUseLocalNetwork = true; | ||||
|  | ||||
| const kAtkStoreKey = 'nex_user_atk'; | ||||
| const kRtkStoreKey = 'nex_user_rtk'; | ||||
|  | ||||
| const kNetworkServerDefault = 'https://api.sn-next.solsynth.dev'; | ||||
| const kNetworkServerStoreKey = 'app_server_url'; | ||||
|  | ||||
| const kNetworkServerDirectory = [ | ||||
|   ('SN Preview', 'https://api.sn-next.solsynth.dev'), | ||||
|   ('SN Stable', 'https://api.sn.solsynth.dev'), | ||||
|   ('Local', 'http://localhost:8001'), | ||||
| ]; | ||||
|  | ||||
| class SnNetworkProvider { | ||||
|   late Dio client; | ||||
|  | ||||
|   late final SharedPreferences _prefs; | ||||
|   late final FlutterSecureStorage _storage = FlutterSecureStorage(); | ||||
|  | ||||
|   SnNetworkProvider() { | ||||
|     client = Dio(); | ||||
|  | ||||
|     client.options.baseUrl = kUseLocalNetwork | ||||
|         ? 'http://localhost:8001' | ||||
|         : 'https://api.sn.solsynth.dev'; | ||||
|  | ||||
|     client.interceptors.add(RetryInterceptor( | ||||
|       dio: client, | ||||
|       retries: 3, | ||||
| @@ -86,6 +91,12 @@ class SnNetworkProvider { | ||||
|     ); | ||||
|  | ||||
|     client = addClientAdapter(client); | ||||
|  | ||||
|     SharedPreferences.getInstance().then((prefs) { | ||||
|       _prefs = prefs; | ||||
|       client.options.baseUrl = | ||||
|           _prefs.getString(kNetworkServerStoreKey) ?? kNetworkServerDefault; | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   String getAttachmentUrl(String ky) { | ||||
| @@ -112,9 +123,7 @@ class SnNetworkProvider { | ||||
|     if (rtk == null) return null; | ||||
|  | ||||
|     final dio = Dio(); | ||||
|     dio.options.baseUrl = kUseLocalNetwork | ||||
|         ? 'http://localhost:8001' | ||||
|         : 'https://api.sn.solsynth.dev'; | ||||
|     dio.options.baseUrl = client.options.baseUrl; | ||||
|  | ||||
|     final resp = await dio.post('/cgi/id/auth/token', data: { | ||||
|       'grant_type': 'refresh_token', | ||||
| @@ -127,4 +136,8 @@ class SnNetworkProvider { | ||||
|  | ||||
|     return atk; | ||||
|   } | ||||
|  | ||||
|   void setBaseUrl(String url) { | ||||
|     client.options.baseUrl = url; | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import 'dart:io'; | ||||
|  | ||||
| import 'package:dropdown_button2/dropdown_button2.dart'; | ||||
| import 'package:easy_localization/easy_localization.dart'; | ||||
| import 'package:flutter/foundation.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| @@ -10,8 +11,10 @@ import 'package:path_provider/path_provider.dart'; | ||||
| import 'package:provider/provider.dart'; | ||||
| import 'package:shared_preferences/shared_preferences.dart'; | ||||
| import 'package:styled_widget/styled_widget.dart'; | ||||
| import 'package:surface/providers/sn_network.dart'; | ||||
| import 'package:surface/providers/theme.dart'; | ||||
| import 'package:surface/theme.dart'; | ||||
| import 'package:surface/widgets/dialog.dart'; | ||||
| import 'package:surface/widgets/navigation/app_scaffold.dart'; | ||||
|  | ||||
| class SettingsScreen extends StatefulWidget { | ||||
| @@ -25,6 +28,8 @@ class _SettingsScreenState extends State<SettingsScreen> { | ||||
|   SharedPreferences? _prefs; | ||||
|   String _docBasepath = '/'; | ||||
|  | ||||
|   final TextEditingController _serverUrlController = TextEditingController(); | ||||
|  | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
| @@ -37,12 +42,22 @@ class _SettingsScreenState extends State<SettingsScreen> { | ||||
|     SharedPreferences.getInstance().then((prefs) { | ||||
|       setState(() { | ||||
|         _prefs = prefs; | ||||
|         _serverUrlController.text = | ||||
|             prefs.getString(kNetworkServerStoreKey) ?? kNetworkServerDefault; | ||||
|       }); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   void dispose() { | ||||
|     _serverUrlController.dispose(); | ||||
|     super.dispose(); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     final sn = context.read<SnNetworkProvider>(); | ||||
|  | ||||
|     return AppScaffold( | ||||
|       body: SingleChildScrollView( | ||||
|         child: Column( | ||||
| @@ -127,6 +142,95 @@ class _SettingsScreenState extends State<SettingsScreen> { | ||||
|                     .fontSize(17) | ||||
|                     .tr() | ||||
|                     .padding(horizontal: 20), | ||||
|                 TextField( | ||||
|                   controller: _serverUrlController, | ||||
|                   decoration: InputDecoration( | ||||
|                     border: const OutlineInputBorder(), | ||||
|                     labelText: 'settingsNetworkServer'.tr(), | ||||
|                     helperText: 'settingsNetworkServerDescription'.tr(), | ||||
|                     prefixIcon: const Icon(Symbols.dns), | ||||
|                     suffixIcon: IconButton( | ||||
|                       icon: const Icon(Symbols.save), | ||||
|                       onPressed: () { | ||||
|                         sn.setBaseUrl(_serverUrlController.text); | ||||
|                         _prefs?.setString( | ||||
|                           kNetworkServerStoreKey, | ||||
|                           _serverUrlController.text, | ||||
|                         ); | ||||
|                         context.showSnackbar('settingsNetworkServerSaved'.tr()); | ||||
|                         setState(() {}); | ||||
|                       }, | ||||
|                     ), | ||||
|                   ), | ||||
|                   onTapOutside: (_) => | ||||
|                       FocusManager.instance.primaryFocus?.unfocus(), | ||||
|                 ).padding(horizontal: 16, top: 8, bottom: 4), | ||||
|                 ListTile( | ||||
|                   title: Text('settingsNetworkServerPreset').tr(), | ||||
|                   subtitle: Text('settingsNetworkServerPresetDescription').tr(), | ||||
|                   contentPadding: const EdgeInsets.symmetric(horizontal: 24), | ||||
|                   leading: const Icon(Symbols.lists), | ||||
|                   trailing: DropdownButtonHideUnderline( | ||||
|                     child: DropdownButton2<String>( | ||||
|                       isExpanded: true, | ||||
|                       items: [ | ||||
|                         ...kNetworkServerDirectory, | ||||
|                         if (!kNetworkServerDirectory | ||||
|                             .map((ele) => ele.$2) | ||||
|                             .contains(_serverUrlController.text)) | ||||
|                           ('Custom', _serverUrlController.text), | ||||
|                       ] | ||||
|                           .map( | ||||
|                             (item) => DropdownMenuItem<String>( | ||||
|                               value: item.$2, | ||||
|                               child: Column( | ||||
|                                 mainAxisSize: MainAxisSize.max, | ||||
|                                 mainAxisAlignment: MainAxisAlignment.center, | ||||
|                                 crossAxisAlignment: CrossAxisAlignment.start, | ||||
|                                 children: [ | ||||
|                                   Text(item.$1).fontSize(14), | ||||
|                                   Text(item.$2, overflow: TextOverflow.ellipsis) | ||||
|                                       .fontSize(11) | ||||
|                                 ], | ||||
|                               ), | ||||
|                             ), | ||||
|                           ) | ||||
|                           .toList(), | ||||
|                       value: _serverUrlController.text, | ||||
|                       onChanged: (String? value) { | ||||
|                         if (value == null) return; | ||||
|                         _serverUrlController.text = value; | ||||
|                         _prefs?.setString(kNetworkServerStoreKey, value); | ||||
|                         context.showSnackbar('settingsNetworkServerSaved'.tr()); | ||||
|                         setState(() {}); | ||||
|                       }, | ||||
|                       buttonStyleData: const ButtonStyleData( | ||||
|                         padding: EdgeInsets.symmetric( | ||||
|                           horizontal: 16, | ||||
|                           vertical: 5, | ||||
|                         ), | ||||
|                         height: 40, | ||||
|                         width: 140, | ||||
|                       ), | ||||
|                       menuItemStyleData: const MenuItemStyleData( | ||||
|                         height: 60, | ||||
|                       ), | ||||
|                     ), | ||||
|                   ), | ||||
|                 ), | ||||
|                 ListTile( | ||||
|                   title: Text('settingsNetworkServerReset').tr(), | ||||
|                   subtitle: Text('settingsNetworkServerResetDescription').tr(), | ||||
|                   contentPadding: const EdgeInsets.symmetric(horizontal: 24), | ||||
|                   leading: const Icon(Symbols.reset_wrench), | ||||
|                   trailing: const Icon(Symbols.chevron_right), | ||||
|                   onTap: () { | ||||
|                     _serverUrlController.text = kNetworkServerDefault; | ||||
|                     _prefs?.remove(kNetworkServerStoreKey); | ||||
|                     context.showSnackbar('settingsNetworkServerSaved'.tr()); | ||||
|                     setState(() {}); | ||||
|                   }, | ||||
|                 ), | ||||
|               ], | ||||
|             ), | ||||
|           ].expand((ele) => [ele, const Gap(16)]).toList(), | ||||
|   | ||||
| @@ -34,7 +34,7 @@ class PostItem extends StatelessWidget { | ||||
|  | ||||
| class _PostBottomAction extends StatelessWidget { | ||||
|   final SnPost data; | ||||
|   const _PostBottomAction({super.key, required this.data}); | ||||
|   const _PostBottomAction({required this.data}); | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user