Compare commits
No commits in common. "65a8f1e6c3c870c7d5dbb04382e35af0bc65f710" and "8a628823e0ad68d40446b0cce5c2353c5ea013a3" have entirely different histories.
65a8f1e6c3
...
8a628823e0
16
README.md
Normal file
16
README.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# surface
|
||||||
|
|
||||||
|
A new Flutter project.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
This project is a starting point for a Flutter application.
|
||||||
|
|
||||||
|
A few resources to get you started if this is your first Flutter project:
|
||||||
|
|
||||||
|
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||||
|
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
||||||
|
|
||||||
|
For help getting started with Flutter development, view the
|
||||||
|
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
||||||
|
samples, guidance on mobile development, and a full API reference.
|
@ -190,13 +190,6 @@
|
|||||||
"settingsNetworkServerPreset": "Present HyperNet Server",
|
"settingsNetworkServerPreset": "Present HyperNet Server",
|
||||||
"settingsNetworkServerPresetDescription": "You can choose one of our preset HyperNet server addresses from the list on the right.",
|
"settingsNetworkServerPresetDescription": "You can choose one of our preset HyperNet server addresses from the list on the right.",
|
||||||
"settingsNetworkServerSaved": "Server address saved.",
|
"settingsNetworkServerSaved": "Server address saved.",
|
||||||
"settingsPerformance": "Performance",
|
|
||||||
"settingsImageQuality": "Image Quality",
|
|
||||||
"settingsImageQualityDescription": "Set the image quality, it will affect the decoding speed of the image.",
|
|
||||||
"settingsImageQualityLowest": "Lowest",
|
|
||||||
"settingsImageQualityLow": "Low",
|
|
||||||
"settingsImageQualityMedium": "Medium",
|
|
||||||
"settingsImageQualityHigh": "High",
|
|
||||||
"settingsMisc": "Misc",
|
"settingsMisc": "Misc",
|
||||||
"settingsMiscAbout": "About",
|
"settingsMiscAbout": "About",
|
||||||
"settingsMiscAboutDescription": "View the version information of Solian.",
|
"settingsMiscAboutDescription": "View the version information of Solian.",
|
||||||
|
@ -188,13 +188,6 @@
|
|||||||
"settingsNetworkServerPreset": "预设的 HyperNet 服务器",
|
"settingsNetworkServerPreset": "预设的 HyperNet 服务器",
|
||||||
"settingsNetworkServerPresetDescription": "你可以在旁边的列表中选择我们提供的预设 HyperNet 服务器地址。",
|
"settingsNetworkServerPresetDescription": "你可以在旁边的列表中选择我们提供的预设 HyperNet 服务器地址。",
|
||||||
"settingsNetworkServerSaved": "服务器地址已保存。",
|
"settingsNetworkServerSaved": "服务器地址已保存。",
|
||||||
"settingsPerformance": "性能",
|
|
||||||
"settingsImageQuality": "图片预览质量",
|
|
||||||
"settingsImageQualityDescription": "设置图片预览质量,会影响图片解码速度。",
|
|
||||||
"settingsImageQualityLowest": "极低",
|
|
||||||
"settingsImageQualityLow": "低",
|
|
||||||
"settingsImageQualityMedium": "中",
|
|
||||||
"settingsImageQualityHigh": "高",
|
|
||||||
"settingsMisc": "杂项",
|
"settingsMisc": "杂项",
|
||||||
"settingsMiscAbout": "关于",
|
"settingsMiscAbout": "关于",
|
||||||
"settingsMiscAboutDescription": "查看 Solian 的版本信息。",
|
"settingsMiscAboutDescription": "查看 Solian 的版本信息。",
|
||||||
|
@ -188,13 +188,6 @@
|
|||||||
"settingsNetworkServerPreset": "預設的 HyperNet 服務器",
|
"settingsNetworkServerPreset": "預設的 HyperNet 服務器",
|
||||||
"settingsNetworkServerPresetDescription": "你可以在旁邊的列表中選擇我們提供的預設 HyperNet 服務器地址。",
|
"settingsNetworkServerPresetDescription": "你可以在旁邊的列表中選擇我們提供的預設 HyperNet 服務器地址。",
|
||||||
"settingsNetworkServerSaved": "服務器地址已保存。",
|
"settingsNetworkServerSaved": "服務器地址已保存。",
|
||||||
"settingsPerformance": "性能",
|
|
||||||
"settingsImageQuality": "圖片預覽質量",
|
|
||||||
"settingsImageQualityDescription": "設置圖片預覽質量,會影響圖片解碼速度。",
|
|
||||||
"settingsImageQualityLowest": "極低",
|
|
||||||
"settingsImageQualityLow": "低",
|
|
||||||
"settingsImageQualityMedium": "中",
|
|
||||||
"settingsImageQualityHigh": "高",
|
|
||||||
"settingsMisc": "雜項",
|
"settingsMisc": "雜項",
|
||||||
"settingsMiscAbout": "關於",
|
"settingsMiscAbout": "關於",
|
||||||
"settingsMiscAboutDescription": "查看 Solian 的版本信息。",
|
"settingsMiscAboutDescription": "查看 Solian 的版本信息。",
|
||||||
@ -448,10 +441,5 @@
|
|||||||
"postImageShareReadMore": "掃描右側 QRCode 查看全文",
|
"postImageShareReadMore": "掃描右側 QRCode 查看全文",
|
||||||
"postImageShareAds": "來 Solar Network 探索更多有趣帖子",
|
"postImageShareAds": "來 Solar Network 探索更多有趣帖子",
|
||||||
"postShare": "分享",
|
"postShare": "分享",
|
||||||
"postShareImage": "分享帖圖",
|
"postShareImage": "分享帖圖"
|
||||||
"appInitializing": "正在初始化",
|
|
||||||
"poweredBy": "由 {} 提供支持",
|
|
||||||
"shareIntent": "分享",
|
|
||||||
"shareIntentDescription": "您想對您分享的內容做些什麼?",
|
|
||||||
"shareIntentPostStory": "發佈動態"
|
|
||||||
}
|
}
|
||||||
|
@ -188,13 +188,6 @@
|
|||||||
"settingsNetworkServerPreset": "預設的 HyperNet 伺服器",
|
"settingsNetworkServerPreset": "預設的 HyperNet 伺服器",
|
||||||
"settingsNetworkServerPresetDescription": "你可以在旁邊的列表中選擇我們提供的預設 HyperNet 伺服器地址。",
|
"settingsNetworkServerPresetDescription": "你可以在旁邊的列表中選擇我們提供的預設 HyperNet 伺服器地址。",
|
||||||
"settingsNetworkServerSaved": "伺服器地址已儲存。",
|
"settingsNetworkServerSaved": "伺服器地址已儲存。",
|
||||||
"settingsPerformance": "效能",
|
|
||||||
"settingsImageQuality": "圖片預覽質量",
|
|
||||||
"settingsImageQualityDescription": "設定圖片預覽質量,會影響圖片解碼速度。",
|
|
||||||
"settingsImageQualityLowest": "極低",
|
|
||||||
"settingsImageQualityLow": "低",
|
|
||||||
"settingsImageQualityMedium": "中",
|
|
||||||
"settingsImageQualityHigh": "高",
|
|
||||||
"settingsMisc": "雜項",
|
"settingsMisc": "雜項",
|
||||||
"settingsMiscAbout": "關於",
|
"settingsMiscAbout": "關於",
|
||||||
"settingsMiscAboutDescription": "檢視 Solian 的版本資訊。",
|
"settingsMiscAboutDescription": "檢視 Solian 的版本資訊。",
|
||||||
@ -448,10 +441,5 @@
|
|||||||
"postImageShareReadMore": "掃描右側 QRCode 檢視全文",
|
"postImageShareReadMore": "掃描右側 QRCode 檢視全文",
|
||||||
"postImageShareAds": "來 Solar Network 探索更多有趣帖子",
|
"postImageShareAds": "來 Solar Network 探索更多有趣帖子",
|
||||||
"postShare": "分享",
|
"postShare": "分享",
|
||||||
"postShareImage": "分享帖圖",
|
"postShareImage": "分享帖圖"
|
||||||
"appInitializing": "正在初始化",
|
|
||||||
"poweredBy": "由 {} 提供支援",
|
|
||||||
"shareIntent": "分享",
|
|
||||||
"shareIntentDescription": "您想對您分享的內容做些什麼?",
|
|
||||||
"shareIntentPostStory": "釋出動態"
|
|
||||||
}
|
}
|
||||||
|
@ -355,7 +355,7 @@ SPEC CHECKSUMS:
|
|||||||
flutter_native_splash: e8a1e01082d97a8099d973f919f57904c925008a
|
flutter_native_splash: e8a1e01082d97a8099d973f919f57904c925008a
|
||||||
flutter_udid: a2482c67a61b9c806ef59dd82ed8d007f1b7ac04
|
flutter_udid: a2482c67a61b9c806ef59dd82ed8d007f1b7ac04
|
||||||
flutter_webrtc: 1a53bd24f97bcfeff512f13699e721897f261563
|
flutter_webrtc: 1a53bd24f97bcfeff512f13699e721897f261563
|
||||||
gal: 6a522c75909f1244732d4596d11d6a2f86ff37a5
|
gal: 61e868295d28fe67ffa297fae6dacebf56fd53e1
|
||||||
GoogleAppMeasurement: 987769c4ca6b968f2479fbcc9fe3ce34af454b8e
|
GoogleAppMeasurement: 987769c4ca6b968f2479fbcc9fe3ce34af454b8e
|
||||||
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||||
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
||||||
|
@ -18,7 +18,6 @@ import 'package:styled_widget/styled_widget.dart';
|
|||||||
import 'package:surface/firebase_options.dart';
|
import 'package:surface/firebase_options.dart';
|
||||||
import 'package:surface/providers/channel.dart';
|
import 'package:surface/providers/channel.dart';
|
||||||
import 'package:surface/providers/chat_call.dart';
|
import 'package:surface/providers/chat_call.dart';
|
||||||
import 'package:surface/providers/config.dart';
|
|
||||||
import 'package:surface/providers/link_preview.dart';
|
import 'package:surface/providers/link_preview.dart';
|
||||||
import 'package:surface/providers/navigation.dart';
|
import 'package:surface/providers/navigation.dart';
|
||||||
import 'package:surface/providers/notification.dart';
|
import 'package:surface/providers/notification.dart';
|
||||||
@ -86,16 +85,13 @@ class SolianApp extends StatelessWidget {
|
|||||||
assetLoader: JsonAssetLoader(),
|
assetLoader: JsonAssetLoader(),
|
||||||
child: MultiProvider(
|
child: MultiProvider(
|
||||||
providers: [
|
providers: [
|
||||||
// System extensions layer
|
|
||||||
Provider(create: (ctx) => HomeWidgetProvider(ctx)),
|
|
||||||
|
|
||||||
// Preferences layer
|
|
||||||
Provider(create: (ctx) => ConfigProvider(ctx)),
|
|
||||||
|
|
||||||
// Display layer
|
// Display layer
|
||||||
ChangeNotifierProvider(create: (_) => ThemeProvider()),
|
ChangeNotifierProvider(create: (_) => ThemeProvider()),
|
||||||
ChangeNotifierProvider(create: (ctx) => NavigationProvider()),
|
ChangeNotifierProvider(create: (ctx) => NavigationProvider()),
|
||||||
|
|
||||||
|
// System extensions layer
|
||||||
|
Provider(create: (ctx) => HomeWidgetProvider(ctx)),
|
||||||
|
|
||||||
// Data layer
|
// Data layer
|
||||||
Provider(create: (ctx) => SnNetworkProvider(ctx)),
|
Provider(create: (ctx) => SnNetworkProvider(ctx)),
|
||||||
Provider(create: (ctx) => UserDirectoryProvider(ctx)),
|
Provider(create: (ctx) => UserDirectoryProvider(ctx)),
|
||||||
@ -166,14 +162,13 @@ class _AppSplashScreen extends StatefulWidget {
|
|||||||
class _AppSplashScreenState extends State<_AppSplashScreen> {
|
class _AppSplashScreenState extends State<_AppSplashScreen> {
|
||||||
bool _isReady = false;
|
bool _isReady = false;
|
||||||
|
|
||||||
|
late StreamSubscription _shareIntentSubscription;
|
||||||
|
|
||||||
Future<void> _initialize() async {
|
Future<void> _initialize() async {
|
||||||
try {
|
try {
|
||||||
final home = context.read<HomeWidgetProvider>();
|
final home = context.read<HomeWidgetProvider>();
|
||||||
await home.initialize();
|
await home.initialize();
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
// The Network initialization must be done after the HomeWidget initialization
|
|
||||||
// The Network initialization will save the server url to the HomeWidget
|
|
||||||
// The Network initialization will also save initialize the Config, so it not need to be initialized again
|
|
||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
await sn.initializeUserAgent();
|
await sn.initializeUserAgent();
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
import 'package:surface/providers/widget.dart';
|
|
||||||
|
|
||||||
const kAtkStoreKey = 'nex_user_atk';
|
|
||||||
const kRtkStoreKey = 'nex_user_rtk';
|
|
||||||
|
|
||||||
const kNetworkServerDefault = 'https://api.sn.solsynth.dev';
|
|
||||||
const kNetworkServerStoreKey = 'app_server_url';
|
|
||||||
|
|
||||||
const Map<String, FilterQuality> kImageQualityLevel = {
|
|
||||||
'settingsImageQualityLowest': FilterQuality.none,
|
|
||||||
'settingsImageQualityLow': FilterQuality.low,
|
|
||||||
'settingsImageQualityMedium': FilterQuality.medium,
|
|
||||||
'settingsImageQualityHigh': FilterQuality.high,
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConfigProvider {
|
|
||||||
late final SharedPreferences prefs;
|
|
||||||
|
|
||||||
late final HomeWidgetProvider _home;
|
|
||||||
|
|
||||||
ConfigProvider(BuildContext context) {
|
|
||||||
_home = context.read<HomeWidgetProvider>();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> initialize() async {
|
|
||||||
prefs = await SharedPreferences.getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
FilterQuality get imageQuality {
|
|
||||||
return kImageQualityLevel.values.elementAtOrNull(prefs.getInt('app_image_quality') ?? 3) ?? FilterQuality.high;
|
|
||||||
}
|
|
||||||
|
|
||||||
String get serverUrl {
|
|
||||||
return prefs.getString(kNetworkServerStoreKey) ?? kNetworkServerDefault;
|
|
||||||
}
|
|
||||||
set serverUrl(String url) {
|
|
||||||
prefs.setString(kNetworkServerStoreKey, url);
|
|
||||||
_home.saveWidgetData("nex_server_url", url);
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,10 +11,15 @@ import 'package:package_info_plus/package_info_plus.dart';
|
|||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:surface/providers/config.dart';
|
|
||||||
import 'package:surface/providers/widget.dart';
|
import 'package:surface/providers/widget.dart';
|
||||||
import 'package:synchronized/synchronized.dart';
|
import 'package:synchronized/synchronized.dart';
|
||||||
|
|
||||||
|
const kAtkStoreKey = 'nex_user_atk';
|
||||||
|
const kRtkStoreKey = 'nex_user_rtk';
|
||||||
|
|
||||||
|
const kNetworkServerDefault = 'https://api.sn.solsynth.dev';
|
||||||
|
const kNetworkServerStoreKey = 'app_server_url';
|
||||||
|
|
||||||
const kNetworkServerDirectory = [
|
const kNetworkServerDirectory = [
|
||||||
('Solar Network', 'https://api.sn.solsynth.dev'),
|
('Solar Network', 'https://api.sn.solsynth.dev'),
|
||||||
('Local', 'http://localhost:8001'),
|
('Local', 'http://localhost:8001'),
|
||||||
@ -24,7 +29,6 @@ class SnNetworkProvider {
|
|||||||
late final Dio client;
|
late final Dio client;
|
||||||
|
|
||||||
late final SharedPreferences _prefs;
|
late final SharedPreferences _prefs;
|
||||||
late final ConfigProvider _config;
|
|
||||||
late final HomeWidgetProvider _home;
|
late final HomeWidgetProvider _home;
|
||||||
|
|
||||||
String? _userAgent;
|
String? _userAgent;
|
||||||
@ -62,12 +66,11 @@ class SnNetworkProvider {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
_config = context.read<ConfigProvider>();
|
SharedPreferences.getInstance().then((prefs) {
|
||||||
_config.initialize().then((_) {
|
_prefs = prefs;
|
||||||
_prefs = _config.prefs;
|
client.options.baseUrl = _prefs.getString(kNetworkServerStoreKey) ?? kNetworkServerDefault;
|
||||||
client.options.baseUrl = _config.serverUrl;
|
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
_home.saveWidgetData("nex_server_url", client.options.baseUrl);
|
_home.saveWidgetData("server_url", client.options.baseUrl);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +197,7 @@ class SnNetworkProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setBaseUrl(String url) {
|
void setBaseUrl(String url) {
|
||||||
_config.serverUrl = url;
|
|
||||||
client.options.baseUrl = url;
|
client.options.baseUrl = url;
|
||||||
|
_home.saveWidgetData("server_url", client.options.baseUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:path/path.dart';
|
import 'package:home_widget/home_widget.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:surface/providers/config.dart';
|
|
||||||
import 'package:surface/providers/sn_network.dart';
|
import 'package:surface/providers/sn_network.dart';
|
||||||
import 'package:surface/providers/widget.dart';
|
import 'package:surface/providers/widget.dart';
|
||||||
import 'package:surface/types/account.dart';
|
import 'package:surface/types/account.dart';
|
||||||
@ -15,12 +14,10 @@ class UserProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
late final SnNetworkProvider _sn;
|
late final SnNetworkProvider _sn;
|
||||||
late final HomeWidgetProvider _home;
|
late final HomeWidgetProvider _home;
|
||||||
late final ConfigProvider _config;
|
|
||||||
|
|
||||||
UserProvider(BuildContext context) {
|
UserProvider(BuildContext context) {
|
||||||
_sn = context.read<SnNetworkProvider>();
|
_sn = context.read<SnNetworkProvider>();
|
||||||
_home = context.read<HomeWidgetProvider>();
|
_home = context.read<HomeWidgetProvider>();
|
||||||
_config = context.read<ConfigProvider>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> get atk async {
|
Future<String?> get atk async {
|
||||||
@ -29,7 +26,8 @@ class UserProvider extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
final value = _config.prefs.getString(kAtkStoreKey);
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
final value = prefs.getString(kAtkStoreKey);
|
||||||
isAuthorized = value != null;
|
isAuthorized = value != null;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
refreshUser().then((value) {
|
refreshUser().then((value) {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:collection/collection.dart';
|
|
||||||
import 'package:dropdown_button2/dropdown_button2.dart';
|
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
@ -12,7 +12,6 @@ import 'package:path_provider/path_provider.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:surface/providers/config.dart';
|
|
||||||
import 'package:surface/providers/sn_network.dart';
|
import 'package:surface/providers/sn_network.dart';
|
||||||
import 'package:surface/providers/theme.dart';
|
import 'package:surface/providers/theme.dart';
|
||||||
import 'package:surface/theme.dart';
|
import 'package:surface/theme.dart';
|
||||||
@ -26,7 +25,7 @@ class SettingsScreen extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _SettingsScreenState extends State<SettingsScreen> {
|
class _SettingsScreenState extends State<SettingsScreen> {
|
||||||
late final SharedPreferences _prefs;
|
SharedPreferences? _prefs;
|
||||||
String _docBasepath = '/';
|
String _docBasepath = '/';
|
||||||
|
|
||||||
final TextEditingController _serverUrlController = TextEditingController();
|
final TextEditingController _serverUrlController = TextEditingController();
|
||||||
@ -40,9 +39,12 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
final config = context.read<ConfigProvider>();
|
SharedPreferences.getInstance().then((prefs) {
|
||||||
_prefs = config.prefs;
|
setState(() {
|
||||||
_serverUrlController.text = config.serverUrl;
|
_prefs = prefs;
|
||||||
|
_serverUrlController.text = prefs.getString(kNetworkServerStoreKey) ?? kNetworkServerDefault;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -58,7 +60,6 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: SingleChildScrollView(
|
body: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
spacing: 16,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Column(
|
Column(
|
||||||
@ -77,7 +78,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
if (image == null) return;
|
if (image == null) return;
|
||||||
|
|
||||||
await File(image.path).copy('$_docBasepath/app_background_image');
|
await File(image.path).copy('$_docBasepath/app_background_image');
|
||||||
_prefs.setBool('has_background_image', true);
|
_prefs?.setBool('has_background_image', true);
|
||||||
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
@ -98,28 +99,29 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
trailing: const Icon(Symbols.chevron_right),
|
trailing: const Icon(Symbols.chevron_right),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
File('$_docBasepath/app_background_image').deleteSync();
|
File('$_docBasepath/app_background_image').deleteSync();
|
||||||
_prefs.remove('has_background_image');
|
_prefs?.remove('has_background_image');
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
CheckboxListTile(
|
if (_prefs != null)
|
||||||
title: Text('settingsThemeMaterial3').tr(),
|
CheckboxListTile(
|
||||||
subtitle: Text('settingsThemeMaterial3Description').tr(),
|
title: Text('settingsThemeMaterial3').tr(),
|
||||||
contentPadding: const EdgeInsets.only(left: 24, right: 17),
|
subtitle: Text('settingsThemeMaterial3Description').tr(),
|
||||||
secondary: const Icon(Symbols.new_releases),
|
contentPadding: const EdgeInsets.only(left: 24, right: 17),
|
||||||
value: _prefs.getBool(kMaterialYouToggleStoreKey) ?? false,
|
secondary: const Icon(Symbols.new_releases),
|
||||||
onChanged: (value) {
|
value: _prefs!.getBool(kMaterialYouToggleStoreKey) ?? false,
|
||||||
setState(() {
|
onChanged: (value) {
|
||||||
_prefs.setBool(
|
setState(() {
|
||||||
kMaterialYouToggleStoreKey,
|
_prefs!.setBool(
|
||||||
value ?? false,
|
kMaterialYouToggleStoreKey,
|
||||||
);
|
value ?? false,
|
||||||
});
|
);
|
||||||
final th = context.watch<ThemeProvider>();
|
});
|
||||||
th.reloadTheme(useMaterial3: value ?? false);
|
final th = context.watch<ThemeProvider>();
|
||||||
},
|
th.reloadTheme(useMaterial3: value ?? false);
|
||||||
),
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Column(
|
Column(
|
||||||
@ -137,7 +139,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
icon: const Icon(Symbols.save),
|
icon: const Icon(Symbols.save),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
sn.setBaseUrl(_serverUrlController.text);
|
sn.setBaseUrl(_serverUrlController.text);
|
||||||
_prefs.setString(
|
_prefs?.setString(
|
||||||
kNetworkServerStoreKey,
|
kNetworkServerStoreKey,
|
||||||
_serverUrlController.text,
|
_serverUrlController.text,
|
||||||
);
|
);
|
||||||
@ -180,7 +182,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
onChanged: (String? value) {
|
onChanged: (String? value) {
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
_serverUrlController.text = value;
|
_serverUrlController.text = value;
|
||||||
_prefs.setString(kNetworkServerStoreKey, value);
|
_prefs?.setString(kNetworkServerStoreKey, value);
|
||||||
context.showSnackbar('settingsNetworkServerSaved'.tr());
|
context.showSnackbar('settingsNetworkServerSaved'.tr());
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
@ -206,56 +208,13 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
trailing: const Icon(Symbols.chevron_right),
|
trailing: const Icon(Symbols.chevron_right),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
_serverUrlController.text = kNetworkServerDefault;
|
_serverUrlController.text = kNetworkServerDefault;
|
||||||
_prefs.remove(kNetworkServerStoreKey);
|
_prefs?.remove(kNetworkServerStoreKey);
|
||||||
context.showSnackbar('settingsNetworkServerSaved'.tr());
|
context.showSnackbar('settingsNetworkServerSaved'.tr());
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text('settingsPerformance').bold().fontSize(17).tr().padding(horizontal: 20, bottom: 4),
|
|
||||||
ListTile(
|
|
||||||
title: Text('settingsImageQuality').tr(),
|
|
||||||
subtitle: Text('settingsImageQualityDescription').tr(),
|
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
|
||||||
leading: const Icon(Symbols.image),
|
|
||||||
trailing: DropdownButtonHideUnderline(
|
|
||||||
child: DropdownButton2<FilterQuality>(
|
|
||||||
value: kImageQualityLevel.values.elementAtOrNull(_prefs.getInt('app_image_quality') ?? 3) ??
|
|
||||||
FilterQuality.high,
|
|
||||||
isExpanded: true,
|
|
||||||
items: kImageQualityLevel.entries
|
|
||||||
.map(
|
|
||||||
(item) => DropdownMenuItem<FilterQuality>(
|
|
||||||
value: item.value,
|
|
||||||
child: Text(item.key).tr().fontSize(14),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.toList(),
|
|
||||||
onChanged: (FilterQuality? value) {
|
|
||||||
if (value == null) return;
|
|
||||||
_prefs.setInt('app_image_quality', kImageQualityLevel.values.toList().indexOf(value));
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
buttonStyleData: const ButtonStyleData(
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: 16,
|
|
||||||
vertical: 5,
|
|
||||||
),
|
|
||||||
height: 40,
|
|
||||||
width: 160,
|
|
||||||
),
|
|
||||||
menuItemStyleData: const MenuItemStyleData(
|
|
||||||
height: 60,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@ -272,7 +231,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
].expand((ele) => [ele, const Gap(16)]).toList(),
|
||||||
).padding(vertical: 20),
|
).padding(vertical: 20),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -6,11 +6,13 @@ import 'package:cross_file/cross_file.dart';
|
|||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
|
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
|
||||||
import 'package:surface/controllers/post_write_controller.dart';
|
import 'package:surface/controllers/post_write_controller.dart';
|
||||||
import 'package:surface/screens/post/post_editor.dart';
|
import 'package:surface/screens/post/post_editor.dart';
|
||||||
|
import 'package:surface/widgets/dialog.dart';
|
||||||
|
|
||||||
class AppSharingListener extends StatefulWidget {
|
class AppSharingListener extends StatefulWidget {
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:responsive_framework/responsive_framework.dart';
|
import 'package:responsive_framework/responsive_framework.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
@ -458,7 +458,6 @@ class _PostBottomAction extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
if (showReactions || showComments)
|
if (showReactions || showComments)
|
||||||
Row(
|
Row(
|
||||||
spacing: 8,
|
|
||||||
children: [
|
children: [
|
||||||
if (showReactions)
|
if (showReactions)
|
||||||
InkWell(
|
InkWell(
|
||||||
@ -524,7 +523,8 @@ class _PostBottomAction extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
].expand((ele) => [ele, const Gap(8)]).toList()
|
||||||
|
..removeLast(),
|
||||||
),
|
),
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: onShare,
|
onTap: onShare,
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:flutter_animate/flutter_animate.dart';
|
import 'package:flutter_animate/flutter_animate.dart';
|
||||||
|
|
||||||
// Keep this import to make the web image render work
|
|
||||||
import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart';
|
import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart';
|
||||||
import 'package:surface/providers/config.dart';
|
|
||||||
|
|
||||||
class UniversalImage extends StatelessWidget {
|
class UniversalImage extends StatelessWidget {
|
||||||
final String url;
|
final String url;
|
||||||
@ -17,7 +15,7 @@ class UniversalImage extends StatelessWidget {
|
|||||||
final bool noProgressIndicator;
|
final bool noProgressIndicator;
|
||||||
final bool noErrorWidget;
|
final bool noErrorWidget;
|
||||||
final double? cacheWidth, cacheHeight;
|
final double? cacheWidth, cacheHeight;
|
||||||
final FilterQuality? filterQuality;
|
final FilterQuality filterQuality;
|
||||||
|
|
||||||
const UniversalImage(
|
const UniversalImage(
|
||||||
this.url, {
|
this.url, {
|
||||||
@ -29,7 +27,7 @@ class UniversalImage extends StatelessWidget {
|
|||||||
this.noErrorWidget = false,
|
this.noErrorWidget = false,
|
||||||
this.cacheWidth,
|
this.cacheWidth,
|
||||||
this.cacheHeight,
|
this.cacheHeight,
|
||||||
this.filterQuality,
|
this.filterQuality = FilterQuality.high,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -39,7 +37,7 @@ class UniversalImage extends StatelessWidget {
|
|||||||
final double? resizeWidth = cacheWidth != null ? (cacheWidth! * devicePixelRatio) : null;
|
final double? resizeWidth = cacheWidth != null ? (cacheWidth! * devicePixelRatio) : null;
|
||||||
|
|
||||||
return Image(
|
return Image(
|
||||||
filterQuality: filterQuality ?? context.read<ConfigProvider>().imageQuality,
|
filterQuality: filterQuality,
|
||||||
image: kIsWeb
|
image: kIsWeb
|
||||||
? UniversalImage.provider(url)
|
? UniversalImage.provider(url)
|
||||||
: ResizeImage(
|
: ResizeImage(
|
||||||
|
@ -289,7 +289,7 @@ SPEC CHECKSUMS:
|
|||||||
flutter_udid: 6b2b89780c3dfeecf0047bdf93f622d6416b1c07
|
flutter_udid: 6b2b89780c3dfeecf0047bdf93f622d6416b1c07
|
||||||
flutter_webrtc: 53c9e1285ab32dfb58afb1e1471416a877e23d7a
|
flutter_webrtc: 53c9e1285ab32dfb58afb1e1471416a877e23d7a
|
||||||
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
||||||
gal: 6a522c75909f1244732d4596d11d6a2f86ff37a5
|
gal: 61e868295d28fe67ffa297fae6dacebf56fd53e1
|
||||||
GoogleAppMeasurement: 987769c4ca6b968f2479fbcc9fe3ce34af454b8e
|
GoogleAppMeasurement: 987769c4ca6b968f2479fbcc9fe3ce34af454b8e
|
||||||
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||||
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
||||||
|
@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 2.1.1+33
|
version: 2.1.1+32
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.5.4
|
sdk: ^3.5.4
|
||||||
|
Loading…
x
Reference in New Issue
Block a user