mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
tidy: settings page
This commit is contained in:
@@ -586,7 +586,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 561;
|
CURRENT_PROJECT_VERSION = 562;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||||
@@ -594,7 +594,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.561;
|
MARKETING_VERSION = 1.0.562;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
@@ -718,7 +718,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 561;
|
CURRENT_PROJECT_VERSION = 562;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||||
@@ -726,7 +726,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.561;
|
MARKETING_VERSION = 1.0.562;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
@@ -744,7 +744,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 561;
|
CURRENT_PROJECT_VERSION = 562;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||||
@@ -752,7 +752,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.561;
|
MARKETING_VERSION = 1.0.562;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
@@ -773,7 +773,7 @@
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 561;
|
CURRENT_PROJECT_VERSION = 562;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -786,7 +786,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.561;
|
MARKETING_VERSION = 1.0.562;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
||||||
@@ -812,7 +812,7 @@
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 561;
|
CURRENT_PROJECT_VERSION = 562;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -825,7 +825,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.561;
|
MARKETING_VERSION = 1.0.562;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
@@ -848,7 +848,7 @@
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 561;
|
CURRENT_PROJECT_VERSION = 562;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -861,7 +861,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.561;
|
MARKETING_VERSION = 1.0.562;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
@@ -884,7 +884,7 @@
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 561;
|
CURRENT_PROJECT_VERSION = 562;
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
@@ -896,7 +896,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.561;
|
MARKETING_VERSION = 1.0.562;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
||||||
@@ -925,7 +925,7 @@
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 561;
|
CURRENT_PROJECT_VERSION = 562;
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
@@ -937,7 +937,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.561;
|
MARKETING_VERSION = 1.0.562;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
||||||
PRODUCT_NAME = ServerBox;
|
PRODUCT_NAME = ServerBox;
|
||||||
@@ -963,7 +963,7 @@
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 561;
|
CURRENT_PROJECT_VERSION = 562;
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
@@ -975,7 +975,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.561;
|
MARKETING_VERSION = 1.0.562;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
||||||
PRODUCT_NAME = ServerBox;
|
PRODUCT_NAME = ServerBox;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "E39515C62AB5AD62003602C1"
|
BlueprintIdentifier = "E39515C62AB5AD62003602C1"
|
||||||
BuildableName = "WatchApp.app"
|
BuildableName = "ServerBox.app"
|
||||||
BlueprintName = "WatchApp"
|
BlueprintName = "WatchApp"
|
||||||
ReferencedContainer = "container:Runner.xcodeproj">
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "E39515C62AB5AD62003602C1"
|
BlueprintIdentifier = "E39515C62AB5AD62003602C1"
|
||||||
BuildableName = "WatchApp.app"
|
BuildableName = "ServerBox.app"
|
||||||
BlueprintName = "WatchApp"
|
BlueprintName = "WatchApp"
|
||||||
ReferencedContainer = "container:Runner.xcodeproj">
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "E39515C62AB5AD62003602C1"
|
BlueprintIdentifier = "E39515C62AB5AD62003602C1"
|
||||||
BuildableName = "WatchApp.app"
|
BuildableName = "ServerBox.app"
|
||||||
BlueprintName = "WatchApp"
|
BlueprintName = "WatchApp"
|
||||||
ReferencedContainer = "container:Runner.xcodeproj">
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ struct StatusWidget_Previews: PreviewProvider {
|
|||||||
|
|
||||||
struct StatusLoader {
|
struct StatusLoader {
|
||||||
static func fetch(completion: @escaping (Result<Status, Error>) -> Void) {
|
static func fetch(completion: @escaping (Result<Status, Error>) -> Void) {
|
||||||
guard let url = url, url.count < 12 else {
|
guard let url = url, url.count >= 12 else {
|
||||||
completion(.failure(NSError(domain: domain, code: 0, userInfo: [NSLocalizedDescriptionKey: "https://github.com/lollipopkit/server_box_monitor/wiki"])))
|
completion(.failure(NSError(domain: domain, code: 0, userInfo: [NSLocalizedDescriptionKey: "https://github.com/lollipopkit/server_box_monitor/wiki"])))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -109,7 +109,7 @@ struct StatusLoader {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
|
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
|
||||||
guard error == nil else {
|
if error != nil {
|
||||||
completion(.failure(error!))
|
completion(.failure(error!))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -117,8 +117,7 @@ struct StatusLoader {
|
|||||||
completion(.failure(NSError(domain: domain, code: 2, userInfo: [NSLocalizedDescriptionKey: "empty network data."])))
|
completion(.failure(NSError(domain: domain, code: 2, userInfo: [NSLocalizedDescriptionKey: "empty network data."])))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let result = getStatus(fromData: data)
|
switch getStatus(fromData: data) {
|
||||||
switch result {
|
|
||||||
case .success(let status):
|
case .success(let status):
|
||||||
completion(.success(status))
|
completion(.success(status))
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
@@ -129,58 +128,36 @@ struct StatusLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static func getStatus(fromData data: Foundation.Data) -> Result<Status, Error> {
|
static func getStatus(fromData data: Foundation.Data) -> Result<Status, Error> {
|
||||||
let jsonAll = try! JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]
|
let jsonAll = try! JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] ?? [:]
|
||||||
let code = jsonAll["code"] as! Int
|
let code = jsonAll["code"] as? Int ?? 1
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
default:
|
default:
|
||||||
let msg = jsonAll["msg"] as! String? ?? ""
|
let msg = jsonAll["msg"] as? String ?? ""
|
||||||
return .failure(NSError(domain: domain, code: code, userInfo: [NSLocalizedDescriptionKey: msg]))
|
return .failure(NSError(domain: domain, code: code, userInfo: [NSLocalizedDescriptionKey: msg]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let json = jsonAll["data"] as! [String: Any]
|
let json = jsonAll["data"] as? [String: Any] ?? [:]
|
||||||
let name = json["name"] as! String
|
let name = json["name"] as? String ?? ""
|
||||||
let disk = json["disk"] as! String
|
let disk = json["disk"] as? String ?? ""
|
||||||
let cpu = json["cpu"] as! String
|
let cpu = json["cpu"] as? String ?? ""
|
||||||
let mem = json["mem"] as! String
|
let mem = json["mem"] as? String ?? ""
|
||||||
let net = json["net"] as! String
|
let net = json["net"] as? String ?? ""
|
||||||
return .success(Status(name: name, cpu: cpu, mem: mem, disk: disk, net: net))
|
return .success(Status(name: name, cpu: cpu, mem: mem, disk: disk, net: net))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func dynamicUIColor(color: DynamicColor) -> UIColor {
|
|
||||||
if #available(iOS 13, *) { // 版本号大于等于13
|
|
||||||
return UIColor { (traitCollection: UITraitCollection) -> UIColor in
|
|
||||||
return traitCollection.userInterfaceStyle == UIUserInterfaceStyle.dark ?
|
|
||||||
color.dark : color.light
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return color.light
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DynamicColor {
|
|
||||||
let dark: UIColor
|
|
||||||
let light: UIColor
|
|
||||||
}
|
|
||||||
|
|
||||||
let bgColor = DynamicColor(dark: UIColor(.black), light: UIColor(.white))
|
|
||||||
let textColor = DynamicColor(dark: UIColor(.white), light: UIColor(.black))
|
|
||||||
|
|
||||||
private func dynamicColor(color: DynamicColor) -> Color {
|
|
||||||
return Color.init(dynamicUIColor(color: color))
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DetailItem: View {
|
struct DetailItem: View {
|
||||||
let icon: String
|
let icon: String
|
||||||
let text: String
|
let text: String
|
||||||
let color: Color
|
let color: Color
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack(spacing: 7.7) {
|
HStack(spacing: 6.7) {
|
||||||
Image(systemName: icon).resizable().foregroundColor(color).frame(width: 11, height: 11, alignment: .center)
|
Image(systemName: icon).resizable().foregroundColor(color).frame(width: 11, height: 11, alignment: .center)
|
||||||
Text(text)
|
Text(text)
|
||||||
.font(.system(.caption2, design: .monospaced))
|
.font(.system(size: 11, design: .monospaced))
|
||||||
.foregroundColor(color)
|
.foregroundColor(color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,13 @@ import 'package:toolbox/view/page/ping.dart';
|
|||||||
import 'package:toolbox/view/page/private_key/edit.dart';
|
import 'package:toolbox/view/page/private_key/edit.dart';
|
||||||
import 'package:toolbox/view/page/private_key/list.dart';
|
import 'package:toolbox/view/page/private_key/list.dart';
|
||||||
import 'package:toolbox/view/page/server/detail.dart';
|
import 'package:toolbox/view/page/server/detail.dart';
|
||||||
|
import 'package:toolbox/view/page/setting/android.dart';
|
||||||
|
import 'package:toolbox/view/page/setting/ios.dart';
|
||||||
import 'package:toolbox/view/page/ssh_term.dart';
|
import 'package:toolbox/view/page/ssh_term.dart';
|
||||||
import 'package:toolbox/view/page/setting/virt_key.dart';
|
import 'package:toolbox/view/page/setting/virt_key.dart';
|
||||||
import 'package:toolbox/view/page/storage/local.dart';
|
import 'package:toolbox/view/page/storage/local.dart';
|
||||||
|
|
||||||
import '../data/model/server/snippet.dart';
|
import '../data/model/server/snippet.dart';
|
||||||
import '../view/page/convert.dart';
|
|
||||||
import '../view/page/debug.dart';
|
import '../view/page/debug.dart';
|
||||||
import '../view/page/editor.dart';
|
import '../view/page/editor.dart';
|
||||||
import '../view/page/full_screen.dart';
|
import '../view/page/full_screen.dart';
|
||||||
@@ -143,10 +144,6 @@ class AppRoute {
|
|||||||
return AppRoute(BackupPage(key: key), 'backup');
|
return AppRoute(BackupPage(key: key), 'backup');
|
||||||
}
|
}
|
||||||
|
|
||||||
static AppRoute convert({Key? key}) {
|
|
||||||
return AppRoute(ConvertPage(key: key), 'convert');
|
|
||||||
}
|
|
||||||
|
|
||||||
static AppRoute debug({Key? key}) {
|
static AppRoute debug({Key? key}) {
|
||||||
return AppRoute(DebugPage(key: key), 'debug');
|
return AppRoute(DebugPage(key: key), 'debug');
|
||||||
}
|
}
|
||||||
@@ -191,7 +188,7 @@ class AppRoute {
|
|||||||
return AppRoute(ProcessPage(key: key, spi: spi), 'process');
|
return AppRoute(ProcessPage(key: key, spi: spi), 'process');
|
||||||
}
|
}
|
||||||
|
|
||||||
static AppRoute setting({Key? key}) {
|
static AppRoute settings({Key? key}) {
|
||||||
return AppRoute(SettingPage(key: key), 'setting');
|
return AppRoute(SettingPage(key: key), 'setting');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,4 +199,12 @@ class AppRoute {
|
|||||||
static AppRoute serverDetailOrder({Key? key}) {
|
static AppRoute serverDetailOrder({Key? key}) {
|
||||||
return AppRoute(ServerDetailOrderPage(key: key), 'server_detail_order');
|
return AppRoute(ServerDetailOrderPage(key: key), 'server_detail_order');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static AppRoute iosSettings({Key? key}) {
|
||||||
|
return AppRoute(IOSSettingsPage(key: key), 'ios_setting');
|
||||||
|
}
|
||||||
|
|
||||||
|
static AppRoute androidSettings({Key? key}) {
|
||||||
|
return AppRoute(AndroidSettingsPage(key: key), 'android_setting');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,38 @@ enum PlatformType {
|
|||||||
web,
|
web,
|
||||||
fuchsia,
|
fuchsia,
|
||||||
unknown;
|
unknown;
|
||||||
|
|
||||||
|
String get prettyName {
|
||||||
|
switch (this) {
|
||||||
|
case PlatformType.android:
|
||||||
|
return 'Android';
|
||||||
|
case PlatformType.ios:
|
||||||
|
return 'iOS';
|
||||||
|
case PlatformType.linux:
|
||||||
|
return 'Linux';
|
||||||
|
case PlatformType.macos:
|
||||||
|
return 'macOS';
|
||||||
|
case PlatformType.windows:
|
||||||
|
return 'Windows';
|
||||||
|
case PlatformType.web:
|
||||||
|
return 'Web';
|
||||||
|
case PlatformType.fuchsia:
|
||||||
|
return 'Fuchsia';
|
||||||
|
case PlatformType.unknown:
|
||||||
|
return 'Unknown';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether has platform specific settings.
|
||||||
|
bool get hasSettings {
|
||||||
|
switch (this) {
|
||||||
|
case PlatformType.android:
|
||||||
|
case PlatformType.ios:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final _p = () {
|
final _p = () {
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
class BuildData {
|
class BuildData {
|
||||||
static const String name = "ServerBox";
|
static const String name = "ServerBox";
|
||||||
static const int build = 561;
|
static const int build = 562;
|
||||||
static const String engine = "3.13.2";
|
static const String engine = "3.13.2";
|
||||||
static const String buildAt = "2023-09-17 00:01:27";
|
static const String buildAt = "2023-09-17 00:26:50";
|
||||||
static const int modifications = 8;
|
static const int modifications = 2;
|
||||||
static const int script = 15;
|
static const int script = 15;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,5 +36,6 @@ class GithubIds {
|
|||||||
'xgzxmytx',
|
'xgzxmytx',
|
||||||
'wind057',
|
'wind057',
|
||||||
'a1564471347',
|
'a1564471347',
|
||||||
|
'fanzhebufan1',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,188 +0,0 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
|
||||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
|
||||||
import 'package:toolbox/data/res/ui.dart';
|
|
||||||
import 'package:toolbox/view/widget/value_notifier.dart';
|
|
||||||
|
|
||||||
import '../widget/custom_appbar.dart';
|
|
||||||
import '../widget/input_field.dart';
|
|
||||||
import '../widget/popup_menu.dart';
|
|
||||||
import '../widget/round_rect_card.dart';
|
|
||||||
|
|
||||||
class ConvertPage extends StatefulWidget {
|
|
||||||
const ConvertPage({Key? key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
_ConvertPageState createState() => _ConvertPageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ConvertPageState extends State<ConvertPage>
|
|
||||||
with AutomaticKeepAliveClientMixin {
|
|
||||||
late TextEditingController _textEditingController;
|
|
||||||
late TextEditingController _textEditingControllerResult;
|
|
||||||
late MediaQueryData _media;
|
|
||||||
late S _s;
|
|
||||||
|
|
||||||
final _typeOptionIndex = ValueNotifier(0);
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_textEditingController = TextEditingController(text: '');
|
|
||||||
_textEditingControllerResult = TextEditingController(text: '');
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void didChangeDependencies() {
|
|
||||||
super.didChangeDependencies();
|
|
||||||
_media = MediaQuery.of(context);
|
|
||||||
_s = S.of(context)!;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
_textEditingController.dispose();
|
|
||||||
_textEditingControllerResult.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
super.build(context);
|
|
||||||
return Scaffold(
|
|
||||||
appBar: CustomAppBar(
|
|
||||||
title: Text(_s.convert),
|
|
||||||
),
|
|
||||||
body: SingleChildScrollView(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 7),
|
|
||||||
controller: ScrollController(),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
UIs.height13,
|
|
||||||
_buildInputTop(),
|
|
||||||
_buildMiddleBtns(),
|
|
||||||
_buildResult(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
floatingActionButton: FloatingActionButton(
|
|
||||||
onPressed: () {
|
|
||||||
try {
|
|
||||||
_textEditingControllerResult.text = doConvert();
|
|
||||||
FocusScope.of(context).requestFocus(FocusNode());
|
|
||||||
} catch (e) {
|
|
||||||
context.showSnackBar('Error: \n$e');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tooltip: _s.convert,
|
|
||||||
child: const Icon(Icons.send),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
String doConvert() {
|
|
||||||
final text = _textEditingController.text.trim();
|
|
||||||
switch (_typeOptionIndex.value) {
|
|
||||||
case 0:
|
|
||||||
return utf8.decode(base64.decode(text));
|
|
||||||
case 1:
|
|
||||||
return base64.encode(utf8.encode(text));
|
|
||||||
case 2:
|
|
||||||
return Uri.encodeFull(text);
|
|
||||||
case 3:
|
|
||||||
return Uri.decodeFull(text);
|
|
||||||
default:
|
|
||||||
return _s.unkownConvertMode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildInputTop() {
|
|
||||||
return SizedBox(
|
|
||||||
height: _media.size.height * 0.33,
|
|
||||||
child: Input(controller: _textEditingController),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildMiddleBtns() {
|
|
||||||
final decode = _s.decode;
|
|
||||||
final encode = _s.encode;
|
|
||||||
final List<String> typeOption = [
|
|
||||||
'Base64 $decode',
|
|
||||||
'Base64 $encode',
|
|
||||||
'URL $encode',
|
|
||||||
'URL $decode'
|
|
||||||
];
|
|
||||||
final items = typeOption
|
|
||||||
.map(
|
|
||||||
(e) => PopupMenuItem(value: typeOption.indexOf(e), child: Text(e)),
|
|
||||||
)
|
|
||||||
.toList();
|
|
||||||
return RoundRectCard(
|
|
||||||
ListTile(
|
|
||||||
contentPadding: const EdgeInsets.only(right: 17),
|
|
||||||
title: Row(
|
|
||||||
children: [
|
|
||||||
TextButton(
|
|
||||||
child: Icon(Icons.change_circle, semanticLabel: _s.upsideDown),
|
|
||||||
onPressed: () {
|
|
||||||
final temp = _textEditingController.text;
|
|
||||||
_textEditingController.text = _textEditingControllerResult.text;
|
|
||||||
_textEditingControllerResult.text = temp;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
TextButton(
|
|
||||||
child: Icon(Icons.copy, semanticLabel: _s.copy),
|
|
||||||
onPressed: () => Clipboard.setData(
|
|
||||||
ClipboardData(
|
|
||||||
text: _textEditingControllerResult.text == ''
|
|
||||||
? ''
|
|
||||||
: _textEditingControllerResult.text,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
trailing: ValueBuilder(
|
|
||||||
listenable: _typeOptionIndex,
|
|
||||||
build: () => PopupMenu<int>(
|
|
||||||
items: items,
|
|
||||||
initialValue: _typeOptionIndex.value,
|
|
||||||
onSelected: (p0) {
|
|
||||||
_typeOptionIndex.value = p0;
|
|
||||||
},
|
|
||||||
child: Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
typeOption[_typeOptionIndex.value],
|
|
||||||
textScaleFactor: 1.0,
|
|
||||||
textAlign: TextAlign.right,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Colors.grey,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Icon(Icons.keyboard_arrow_down, color: Colors.grey)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildResult() {
|
|
||||||
return SizedBox(
|
|
||||||
height: _media.size.height * 0.33,
|
|
||||||
child: Input(controller: _textEditingControllerResult),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool get wantKeepAlive => true;
|
|
||||||
}
|
|
||||||
@@ -120,7 +120,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
|
|||||||
|
|
||||||
Widget _buildSettingBtn() {
|
Widget _buildSettingBtn() {
|
||||||
return IconButton(
|
return IconButton(
|
||||||
onPressed: () => AppRoute.setting().go(context),
|
onPressed: () => AppRoute.settings().go(context),
|
||||||
icon: const Icon(Icons.settings, color: Colors.grey));
|
icon: const Icon(Icons.settings, color: Colors.grey));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ class _HomePageState extends State<HomePage>
|
|||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.settings),
|
leading: const Icon(Icons.settings),
|
||||||
title: Text(_s.setting),
|
title: Text(_s.setting),
|
||||||
onTap: () => AppRoute.setting().go(context),
|
onTap: () => AppRoute.settings().go(context),
|
||||||
onLongPress: _onLongPressSetting,
|
onLongPress: _onLongPressSetting,
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
@@ -246,11 +246,6 @@ class _HomePageState extends State<HomePage>
|
|||||||
title: Text(_s.files),
|
title: Text(_s.files),
|
||||||
onTap: () => AppRoute.localStorage().go(context),
|
onTap: () => AppRoute.localStorage().go(context),
|
||||||
),
|
),
|
||||||
ListTile(
|
|
||||||
leading: const Icon(Icons.code),
|
|
||||||
title: Text(_s.convert),
|
|
||||||
onTap: () => AppRoute.convert().go(context),
|
|
||||||
),
|
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.import_export),
|
leading: const Icon(Icons.import_export),
|
||||||
title: Text(_s.backupAndRestore),
|
title: Text(_s.backupAndRestore),
|
||||||
|
|||||||
113
lib/view/page/setting/android.dart
Normal file
113
lib/view/page/setting/android.dart
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:toolbox/core/extension/context/common.dart';
|
||||||
|
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||||
|
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||||
|
import 'package:toolbox/data/res/store.dart';
|
||||||
|
import 'package:toolbox/view/widget/custom_appbar.dart';
|
||||||
|
import 'package:toolbox/view/widget/input_field.dart';
|
||||||
|
import 'package:toolbox/view/widget/round_rect_card.dart';
|
||||||
|
import 'package:toolbox/view/widget/store_switch.dart';
|
||||||
|
|
||||||
|
class AndroidSettingsPage extends StatefulWidget {
|
||||||
|
const AndroidSettingsPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_AndroidSettingsPageState createState() => _AndroidSettingsPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AndroidSettingsPageState extends State<AndroidSettingsPage> {
|
||||||
|
late S _s;
|
||||||
|
late SharedPreferences _sp;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
_s = S.of(context)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
SharedPreferences.getInstance().then((value) => _sp = value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: CustomAppBar(
|
||||||
|
title: const Text('Android'),
|
||||||
|
),
|
||||||
|
body: ListView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 17),
|
||||||
|
children: [
|
||||||
|
_buildBgRun(),
|
||||||
|
_buildAndroidWidgetSharedPreference(),
|
||||||
|
].map((e) => RoundRectCard(e)).toList(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildBgRun() {
|
||||||
|
return ListTile(
|
||||||
|
title: Text(_s.bgRun),
|
||||||
|
trailing: StoreSwitch(prop: Stores.setting.bgRun),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _saveWidgetSP(String data, Map<String, String> old) {
|
||||||
|
context.pop();
|
||||||
|
try {
|
||||||
|
final map = Map<String, String>.from(json.decode(data));
|
||||||
|
final keysDel = old.keys.toSet().difference(map.keys.toSet());
|
||||||
|
for (final key in keysDel) {
|
||||||
|
_sp.remove(key);
|
||||||
|
}
|
||||||
|
map.forEach((key, value) {
|
||||||
|
_sp.setString(key, value);
|
||||||
|
});
|
||||||
|
context.showSnackBar(_s.success);
|
||||||
|
} catch (e) {
|
||||||
|
context.showSnackBar(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildAndroidWidgetSharedPreference() {
|
||||||
|
return ListTile(
|
||||||
|
title: Text(_s.homeWidgetUrlConfig),
|
||||||
|
trailing: const Icon(Icons.keyboard_arrow_right),
|
||||||
|
onTap: () {
|
||||||
|
final data = <String, String>{};
|
||||||
|
_sp.getKeys().forEach((key) {
|
||||||
|
final val = _sp.getString(key);
|
||||||
|
if (val != null) {
|
||||||
|
data[key] = val;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
final ctrl = TextEditingController(text: json.encode(data));
|
||||||
|
context.showRoundDialog(
|
||||||
|
title: Text(_s.homeWidgetUrlConfig),
|
||||||
|
child: Input(
|
||||||
|
autoFocus: true,
|
||||||
|
controller: ctrl,
|
||||||
|
label: 'JSON',
|
||||||
|
type: TextInputType.visiblePassword,
|
||||||
|
maxLines: 7,
|
||||||
|
onSubmitted: (p0) => _saveWidgetSP(p0, data),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
_saveWidgetSP(ctrl.text, data);
|
||||||
|
},
|
||||||
|
child: Text(_s.ok),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:flutter_highlight/theme_map.dart';
|
import 'package:flutter_highlight/theme_map.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
import 'package:toolbox/core/build_mode.dart';
|
|
||||||
import 'package:toolbox/core/extension/colorx.dart';
|
import 'package:toolbox/core/extension/colorx.dart';
|
||||||
import 'package:toolbox/core/extension/context/common.dart';
|
import 'package:toolbox/core/extension/context/common.dart';
|
||||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||||
@@ -15,11 +12,8 @@ import 'package:toolbox/core/extension/context/dialog.dart';
|
|||||||
import 'package:toolbox/core/extension/stringx.dart';
|
import 'package:toolbox/core/extension/stringx.dart';
|
||||||
import 'package:toolbox/core/utils/platform/auth.dart';
|
import 'package:toolbox/core/utils/platform/auth.dart';
|
||||||
import 'package:toolbox/core/utils/platform/base.dart';
|
import 'package:toolbox/core/utils/platform/base.dart';
|
||||||
import 'package:toolbox/data/res/logger.dart';
|
|
||||||
import 'package:toolbox/data/res/misc.dart';
|
|
||||||
import 'package:toolbox/data/res/provider.dart';
|
import 'package:toolbox/data/res/provider.dart';
|
||||||
import 'package:toolbox/data/res/store.dart';
|
import 'package:toolbox/data/res/store.dart';
|
||||||
import 'package:watch_connectivity/watch_connectivity.dart';
|
|
||||||
|
|
||||||
import '../../../core/persistant_store.dart';
|
import '../../../core/persistant_store.dart';
|
||||||
import '../../../core/route.dart';
|
import '../../../core/route.dart';
|
||||||
@@ -59,9 +53,6 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
final _setting = Stores.setting;
|
final _setting = Stores.setting;
|
||||||
|
|
||||||
late S _s;
|
late S _s;
|
||||||
late SharedPreferences _sp;
|
|
||||||
|
|
||||||
final wc = WatchConnectivity();
|
|
||||||
|
|
||||||
final _selectedColorValue = ValueNotifier(0);
|
final _selectedColorValue = ValueNotifier(0);
|
||||||
final _nightMode = ValueNotifier(0);
|
final _nightMode = ValueNotifier(0);
|
||||||
@@ -75,7 +66,6 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
final _keyboardType = ValueNotifier(0);
|
final _keyboardType = ValueNotifier(0);
|
||||||
final _rotateQuarter = ValueNotifier(0);
|
final _rotateQuarter = ValueNotifier(0);
|
||||||
final _netViewType = ValueNotifier(NetViewType.speed);
|
final _netViewType = ValueNotifier(NetViewType.speed);
|
||||||
final _pushToken = ValueNotifier<String?>(null);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didChangeDependencies() {
|
void didChangeDependencies() {
|
||||||
@@ -103,7 +93,6 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
_keyboardType.value = _setting.keyboardType.fetch();
|
_keyboardType.value = _setting.keyboardType.fetch();
|
||||||
_rotateQuarter.value = _setting.fullScreenRotateQuarter.fetch();
|
_rotateQuarter.value = _setting.fullScreenRotateQuarter.fetch();
|
||||||
_netViewType.value = _setting.netViewType.fetch();
|
_netViewType.value = _setting.netViewType.fetch();
|
||||||
SharedPreferences.getInstance().then((value) => _sp = value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -112,8 +101,8 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
appBar: CustomAppBar(
|
appBar: CustomAppBar(
|
||||||
title: Text(_s.setting),
|
title: Text(_s.setting),
|
||||||
actions: [
|
actions: [
|
||||||
InkWell(
|
IconButton(
|
||||||
onTap: () => context.showRoundDialog(
|
onPressed: () => context.showRoundDialog(
|
||||||
title: Text(_s.attention),
|
title: Text(_s.attention),
|
||||||
child: Text(_s.sureDelete(_s.all)),
|
child: Text(_s.sureDelete(_s.all)),
|
||||||
actions: [
|
actions: [
|
||||||
@@ -127,26 +116,26 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
onDoubleTap: () => context.showRoundDialog(
|
// onDoubleTap: () => context.showRoundDialog(
|
||||||
title: Text(_s.attention),
|
// title: Text(_s.attention),
|
||||||
child: Text(_s.sureDelete(_s.all)),
|
// child: Text(_s.sureDelete(_s.all)),
|
||||||
actions: [
|
// actions: [
|
||||||
TextButton(
|
// TextButton(
|
||||||
onPressed: () {
|
// onPressed: () {
|
||||||
Stores.docker.box.deleteFromDisk();
|
// Stores.docker.box.deleteFromDisk();
|
||||||
Stores.server.box.deleteFromDisk();
|
// Stores.server.box.deleteFromDisk();
|
||||||
Stores.setting.box.deleteFromDisk();
|
// Stores.setting.box.deleteFromDisk();
|
||||||
Stores.history.box.deleteFromDisk();
|
// Stores.history.box.deleteFromDisk();
|
||||||
Stores.snippet.box.deleteFromDisk();
|
// Stores.snippet.box.deleteFromDisk();
|
||||||
Stores.key.box.deleteFromDisk();
|
// Stores.key.box.deleteFromDisk();
|
||||||
context.pop();
|
// context.pop();
|
||||||
context.showSnackBar(_s.success);
|
// context.showSnackBar(_s.success);
|
||||||
},
|
// },
|
||||||
child: Text(_s.ok, style: const TextStyle(color: Colors.red)),
|
// child: Text(_s.ok, style: const TextStyle(color: Colors.red)),
|
||||||
),
|
// ),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
child: const Icon(Icons.delete),
|
icon: const Icon(Icons.delete),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -189,17 +178,12 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
//_buildLaunchPage(),
|
//_buildLaunchPage(),
|
||||||
_buildCheckUpdate(),
|
_buildCheckUpdate(),
|
||||||
];
|
];
|
||||||
if (isAndroid) {
|
|
||||||
children.add(_buildBgRun());
|
|
||||||
children.add(_buildAndroidWidgetSharedPreference());
|
|
||||||
}
|
|
||||||
if (BioAuth.isPlatformSupported) {
|
if (BioAuth.isPlatformSupported) {
|
||||||
children.add(_buildBioAuth());
|
children.add(_buildBioAuth());
|
||||||
}
|
}
|
||||||
if (isIOS) {
|
/// Platform specific settings
|
||||||
if (BuildMode.isRelease) children.add(_buildPushToken());
|
if (platform.hasSettings) {
|
||||||
children.add(_buildAutoUpdateHomeWidget());
|
children.add(_buildPlatformSetting(platform));
|
||||||
children.add(_buildWatchApp());
|
|
||||||
}
|
}
|
||||||
return Column(
|
return Column(
|
||||||
children: children.map((e) => RoundRectCard(e)).toList(),
|
children: children.map((e) => RoundRectCard(e)).toList(),
|
||||||
@@ -221,7 +205,6 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
children: [
|
children: [
|
||||||
_buildMoveOutServerFuncBtns(),
|
_buildMoveOutServerFuncBtns(),
|
||||||
_buildServerOrder(),
|
_buildServerOrder(),
|
||||||
_buildServerDetailOrder(),
|
|
||||||
_buildNetViewType(),
|
_buildNetViewType(),
|
||||||
_buildUpdateInterval(),
|
_buildUpdateInterval(),
|
||||||
_buildMaxRetry(),
|
_buildMaxRetry(),
|
||||||
@@ -523,42 +506,6 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildPushToken() {
|
|
||||||
return ListTile(
|
|
||||||
title: Text(
|
|
||||||
_s.pushToken,
|
|
||||||
),
|
|
||||||
trailing: IconButton(
|
|
||||||
icon: const Icon(Icons.copy),
|
|
||||||
alignment: Alignment.centerRight,
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
onPressed: () {
|
|
||||||
if (_pushToken.value != null) {
|
|
||||||
copy2Clipboard(_pushToken.value!);
|
|
||||||
context.showSnackBar(_s.success);
|
|
||||||
} else {
|
|
||||||
context.showSnackBar(_s.getPushTokenFailed);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
subtitle: FutureWidget<String?>(
|
|
||||||
future: getToken(),
|
|
||||||
loading: Text(_s.gettingToken),
|
|
||||||
error: (error, trace) => Text('${_s.error}: $error'),
|
|
||||||
noData: Text(_s.nullToken),
|
|
||||||
success: (text) {
|
|
||||||
_pushToken.value = text;
|
|
||||||
return Text(
|
|
||||||
text ?? _s.nullToken,
|
|
||||||
style: UIs.textGrey,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
maxLines: 1,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildFont() {
|
Widget _buildFont() {
|
||||||
final fontName = getFileName(_setting.fontPath.fetch());
|
final fontName = getFileName(_setting.fontPath.fetch());
|
||||||
return ListTile(
|
return ListTile(
|
||||||
@@ -612,13 +559,6 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
context.showSnackBar(_s.failed);
|
context.showSnackBar(_s.failed);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBgRun() {
|
|
||||||
return ListTile(
|
|
||||||
title: Text(_s.bgRun),
|
|
||||||
trailing: StoreSwitch(prop: _setting.bgRun),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildTermFontSize() {
|
Widget _buildTermFontSize() {
|
||||||
return ValueBuilder(
|
return ValueBuilder(
|
||||||
listenable: _termFontSize,
|
listenable: _termFontSize,
|
||||||
@@ -891,59 +831,6 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _saveWidgetSP(String data, Map<String, String> old) {
|
|
||||||
context.pop();
|
|
||||||
try {
|
|
||||||
final map = Map<String, String>.from(json.decode(data));
|
|
||||||
final keysDel = old.keys.toSet().difference(map.keys.toSet());
|
|
||||||
for (final key in keysDel) {
|
|
||||||
_sp.remove(key);
|
|
||||||
}
|
|
||||||
map.forEach((key, value) {
|
|
||||||
_sp.setString(key, value);
|
|
||||||
});
|
|
||||||
context.showSnackBar(_s.success);
|
|
||||||
} catch (e) {
|
|
||||||
context.showSnackBar(e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildAndroidWidgetSharedPreference() {
|
|
||||||
return ListTile(
|
|
||||||
title: Text(_s.homeWidgetUrlConfig),
|
|
||||||
trailing: const Icon(Icons.keyboard_arrow_right),
|
|
||||||
onTap: () {
|
|
||||||
final data = <String, String>{};
|
|
||||||
_sp.getKeys().forEach((key) {
|
|
||||||
final val = _sp.getString(key);
|
|
||||||
if (val != null) {
|
|
||||||
data[key] = val;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
final ctrl = TextEditingController(text: json.encode(data));
|
|
||||||
context.showRoundDialog(
|
|
||||||
title: Text(_s.homeWidgetUrlConfig),
|
|
||||||
child: Input(
|
|
||||||
autoFocus: true,
|
|
||||||
controller: ctrl,
|
|
||||||
label: 'JSON',
|
|
||||||
type: TextInputType.visiblePassword,
|
|
||||||
maxLines: 7,
|
|
||||||
onSubmitted: (p0) => _saveWidgetSP(p0, data),
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () {
|
|
||||||
_saveWidgetSP(ctrl.text, data);
|
|
||||||
},
|
|
||||||
child: Text(_s.ok),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildNetViewType() {
|
Widget _buildNetViewType() {
|
||||||
final items = NetViewType.values
|
final items = NetViewType.values
|
||||||
.map((e) => PopupMenuItem(
|
.map((e) => PopupMenuItem(
|
||||||
@@ -975,14 +862,6 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildAutoUpdateHomeWidget() {
|
|
||||||
return ListTile(
|
|
||||||
title: Text(_s.autoUpdateHomeWidget),
|
|
||||||
subtitle: Text(_s.whenOpenApp, style: UIs.textGrey),
|
|
||||||
trailing: StoreSwitch(prop: _setting.autoUpdateHomeWidget),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildDeleteServers() {
|
Widget _buildDeleteServers() {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(_s.deleteServers),
|
title: Text(_s.deleteServers),
|
||||||
@@ -1026,17 +905,28 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
|
|
||||||
Widget _buildServerOrder() {
|
Widget _buildServerOrder() {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
|
title: Text(_s.serverOrder),
|
||||||
|
subtitle: Text('${_s.serverOrder} / ${_s.serverDetailOrder}',
|
||||||
|
style: UIs.textGrey),
|
||||||
|
trailing: const Icon(Icons.keyboard_arrow_right),
|
||||||
|
onTap: () => context.showRoundDialog(
|
||||||
|
title: Text(_s.choose),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
ListTile(
|
||||||
title: Text(_s.serverOrder),
|
title: Text(_s.serverOrder),
|
||||||
trailing: const Icon(Icons.keyboard_arrow_right),
|
trailing: const Icon(Icons.keyboard_arrow_right),
|
||||||
onTap: () => AppRoute.serverOrder().go(context),
|
onTap: () => AppRoute.serverOrder().go(context),
|
||||||
);
|
),
|
||||||
}
|
ListTile(
|
||||||
|
|
||||||
Widget _buildServerDetailOrder() {
|
|
||||||
return ListTile(
|
|
||||||
title: Text(_s.serverDetailOrder),
|
title: Text(_s.serverDetailOrder),
|
||||||
trailing: const Icon(Icons.keyboard_arrow_right),
|
trailing: const Icon(Icons.keyboard_arrow_right),
|
||||||
onTap: () => AppRoute.serverDetailOrder().go(context),
|
onTap: () => AppRoute.serverDetailOrder().go(context),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1148,59 +1038,22 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildWatchApp() {
|
Widget _buildPlatformSetting(PlatformType type) {
|
||||||
return FutureWidget<Map<String, dynamic>?>(
|
|
||||||
future: () async {
|
|
||||||
if (!await wc.isPaired) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return await wc.applicationContext;
|
|
||||||
}(),
|
|
||||||
loading: UIs.centerLoading,
|
|
||||||
error: (e, trace) {
|
|
||||||
Loggers.app.warning('WatchOS error', e, trace);
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: const Text('Watch app'),
|
title: Text('${type.prettyName} ${_s.setting}'),
|
||||||
subtitle: Text('${_s.error}: $e', style: UIs.textGrey),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
success: (ctx) {
|
|
||||||
if (ctx == null) {
|
|
||||||
return ListTile(
|
|
||||||
title: const Text('Watch app'),
|
|
||||||
subtitle: Text(_s.watchNotPaired, style: UIs.textGrey),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return ListTile(
|
|
||||||
title: const Text('Watch app'),
|
|
||||||
trailing: const Icon(Icons.keyboard_arrow_right),
|
trailing: const Icon(Icons.keyboard_arrow_right),
|
||||||
onTap: () async => _onTapWatchApp(ctx),
|
onTap: () {
|
||||||
);
|
switch (type) {
|
||||||
|
case PlatformType.android:
|
||||||
|
AppRoute.androidSettings().go(context);
|
||||||
|
break;
|
||||||
|
case PlatformType.ios:
|
||||||
|
AppRoute.iosSettings().go(context);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
noData: UIs.placeholder,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onTapWatchApp(Map<String, dynamic> map) async {
|
|
||||||
/// Encode [map] to String with indent `\t`
|
|
||||||
final text = Miscs.jsonEncoder.convert(map);
|
|
||||||
final result = await AppRoute.editor(
|
|
||||||
text: text,
|
|
||||||
langCode: 'json',
|
|
||||||
title: 'Watch app',
|
|
||||||
).go(context);
|
|
||||||
if (result == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
final newCtx = json.decode(result) as Map<String, dynamic>;
|
|
||||||
await wc.updateApplicationContext(newCtx);
|
|
||||||
} catch (e, trace) {
|
|
||||||
context.showRoundDialog(
|
|
||||||
title: Text(_s.error),
|
|
||||||
child: Text('${_s.save}:\n$e'),
|
|
||||||
);
|
|
||||||
Loggers.app.warning('Update watch config failed', e, trace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
155
lib/view/page/setting/ios.dart
Normal file
155
lib/view/page/setting/ios.dart
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||||
|
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||||
|
import 'package:toolbox/core/route.dart';
|
||||||
|
import 'package:toolbox/core/utils/misc.dart';
|
||||||
|
import 'package:toolbox/data/res/logger.dart';
|
||||||
|
import 'package:toolbox/data/res/misc.dart';
|
||||||
|
import 'package:toolbox/data/res/store.dart';
|
||||||
|
import 'package:toolbox/data/res/ui.dart';
|
||||||
|
import 'package:toolbox/view/widget/custom_appbar.dart';
|
||||||
|
import 'package:toolbox/view/widget/future_widget.dart';
|
||||||
|
import 'package:toolbox/view/widget/round_rect_card.dart';
|
||||||
|
import 'package:toolbox/view/widget/store_switch.dart';
|
||||||
|
import 'package:watch_connectivity/watch_connectivity.dart';
|
||||||
|
|
||||||
|
class IOSSettingsPage extends StatefulWidget {
|
||||||
|
const IOSSettingsPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_IOSSettingsPageState createState() => _IOSSettingsPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _IOSSettingsPageState extends State<IOSSettingsPage> {
|
||||||
|
late S _s;
|
||||||
|
|
||||||
|
final _pushToken = ValueNotifier<String?>(null);
|
||||||
|
|
||||||
|
final wc = WatchConnectivity();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
_s = S.of(context)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: CustomAppBar(
|
||||||
|
title: const Text('iOS'),
|
||||||
|
),
|
||||||
|
body: ListView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 17),
|
||||||
|
children: [
|
||||||
|
_buildPushToken(),
|
||||||
|
_buildAutoUpdateHomeWidget(),
|
||||||
|
_buildWatchApp(),
|
||||||
|
].map((e) => RoundRectCard(e)).toList(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPushToken() {
|
||||||
|
return ListTile(
|
||||||
|
title: Text(
|
||||||
|
_s.pushToken,
|
||||||
|
),
|
||||||
|
trailing: IconButton(
|
||||||
|
icon: const Icon(Icons.copy),
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
onPressed: () {
|
||||||
|
if (_pushToken.value != null) {
|
||||||
|
copy2Clipboard(_pushToken.value!);
|
||||||
|
context.showSnackBar(_s.success);
|
||||||
|
} else {
|
||||||
|
context.showSnackBar(_s.getPushTokenFailed);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
subtitle: FutureWidget<String?>(
|
||||||
|
future: getToken(),
|
||||||
|
loading: Text(_s.gettingToken),
|
||||||
|
error: (error, trace) => Text('${_s.error}: $error'),
|
||||||
|
noData: Text(_s.nullToken),
|
||||||
|
success: (text) {
|
||||||
|
_pushToken.value = text;
|
||||||
|
return Text(
|
||||||
|
text ?? _s.nullToken,
|
||||||
|
style: UIs.textGrey,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 1,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildAutoUpdateHomeWidget() {
|
||||||
|
return ListTile(
|
||||||
|
title: Text(_s.autoUpdateHomeWidget),
|
||||||
|
subtitle: Text(_s.whenOpenApp, style: UIs.textGrey),
|
||||||
|
trailing: StoreSwitch(prop: Stores.setting.autoUpdateHomeWidget),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildWatchApp() {
|
||||||
|
return FutureWidget<Map<String, dynamic>?>(
|
||||||
|
future: () async {
|
||||||
|
if (!await wc.isPaired) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return await wc.applicationContext;
|
||||||
|
}(),
|
||||||
|
loading: UIs.centerLoading,
|
||||||
|
error: (e, trace) {
|
||||||
|
Loggers.app.warning('WatchOS error', e, trace);
|
||||||
|
return ListTile(
|
||||||
|
title: const Text('Watch app'),
|
||||||
|
subtitle: Text('${_s.error}: $e', style: UIs.textGrey),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
success: (ctx) {
|
||||||
|
if (ctx == null) {
|
||||||
|
return ListTile(
|
||||||
|
title: const Text('Watch app'),
|
||||||
|
subtitle: Text(_s.watchNotPaired, style: UIs.textGrey),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return ListTile(
|
||||||
|
title: const Text('Watch app'),
|
||||||
|
trailing: const Icon(Icons.keyboard_arrow_right),
|
||||||
|
onTap: () async => _onTapWatchApp(ctx),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
noData: UIs.placeholder,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onTapWatchApp(Map<String, dynamic> map) async {
|
||||||
|
/// Encode [map] to String with indent `\t`
|
||||||
|
final text = Miscs.jsonEncoder.convert(map);
|
||||||
|
final result = await AppRoute.editor(
|
||||||
|
text: text,
|
||||||
|
langCode: 'json',
|
||||||
|
title: 'Watch app',
|
||||||
|
).go(context);
|
||||||
|
if (result == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
final newCtx = json.decode(result) as Map<String, dynamic>;
|
||||||
|
await wc.updateApplicationContext(newCtx);
|
||||||
|
} catch (e, trace) {
|
||||||
|
context.showRoundDialog(
|
||||||
|
title: Text(_s.error),
|
||||||
|
child: Text('${_s.save}:\n$e'),
|
||||||
|
);
|
||||||
|
Loggers.app.warning('Update watch config failed', e, trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -50,7 +50,7 @@ class _ServerDetailOrderPageState extends State<ServerDetailOrderPage> {
|
|||||||
property: Stores.setting.detailCardOrder,
|
property: Stores.setting.detailCardOrder,
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 3),
|
padding: const EdgeInsets.all(17),
|
||||||
buildDefaultDragHandles: false,
|
buildDefaultDragHandles: false,
|
||||||
itemBuilder: (_, index) => _buildItem(index, _cardsOrder[index]),
|
itemBuilder: (_, index) => _buildItem(index, _cardsOrder[index]),
|
||||||
itemCount: _cardsOrder.length,
|
itemCount: _cardsOrder.length,
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ class _ServerOrderPageState extends State<ServerOrderPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody() {
|
Widget _buildBody() {
|
||||||
|
if (Providers.server.serverOrder.isEmpty) {
|
||||||
|
return Center(child: Text(_s.noServerAvailable));
|
||||||
|
}
|
||||||
return ReorderableListView.builder(
|
return ReorderableListView.builder(
|
||||||
footer: const SizedBox(height: 77),
|
footer: const SizedBox(height: 77),
|
||||||
onReorder: (oldIndex, newIndex) => setState(() {
|
onReorder: (oldIndex, newIndex) => setState(() {
|
||||||
|
|||||||
@@ -476,9 +476,9 @@
|
|||||||
baseConfigurationReference = C1C758C41C4E208965A68933 /* Pods-RunnerTests.debug.xcconfig */;
|
baseConfigurationReference = C1C758C41C4E208965A68933 /* Pods-RunnerTests.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CURRENT_PROJECT_VERSION = 561;
|
CURRENT_PROJECT_VERSION = 562;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0.561;
|
MARKETING_VERSION = 1.0.562;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
|
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@@ -491,9 +491,9 @@
|
|||||||
baseConfigurationReference = 15AF97DF993E8968098D6EBE /* Pods-RunnerTests.release.xcconfig */;
|
baseConfigurationReference = 15AF97DF993E8968098D6EBE /* Pods-RunnerTests.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CURRENT_PROJECT_VERSION = 561;
|
CURRENT_PROJECT_VERSION = 562;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0.561;
|
MARKETING_VERSION = 1.0.562;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
|
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@@ -506,9 +506,9 @@
|
|||||||
baseConfigurationReference = 7CFA7DE7FABA75685DFB6948 /* Pods-RunnerTests.profile.xcconfig */;
|
baseConfigurationReference = 7CFA7DE7FABA75685DFB6948 /* Pods-RunnerTests.profile.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CURRENT_PROJECT_VERSION = 561;
|
CURRENT_PROJECT_VERSION = 562;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0.561;
|
MARKETING_VERSION = 1.0.562;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
|
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
|||||||
Reference in New Issue
Block a user