mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 15:24:35 +01:00
fix & opt
fix: cant ping when launch page is ping fix: button text color not primaryColor opt: getting primaryColor
This commit is contained in:
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -5,5 +5,8 @@
|
|||||||
},
|
},
|
||||||
"search.exclude": {
|
"search.exclude": {
|
||||||
"**/.fvm": true
|
"**/.fvm": true
|
||||||
}
|
},
|
||||||
|
"git.ignoredRepositories": [
|
||||||
|
".fvm"
|
||||||
|
],
|
||||||
}
|
}
|
||||||
@@ -356,7 +356,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 201;
|
CURRENT_PROJECT_VERSION = 205;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@@ -364,7 +364,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.201;
|
MARKETING_VERSION = 1.0.205;
|
||||||
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";
|
||||||
@@ -486,7 +486,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 201;
|
CURRENT_PROJECT_VERSION = 205;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@@ -494,7 +494,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.201;
|
MARKETING_VERSION = 1.0.205;
|
||||||
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";
|
||||||
@@ -510,7 +510,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 201;
|
CURRENT_PROJECT_VERSION = 205;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@@ -518,7 +518,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.201;
|
MARKETING_VERSION = 1.0.205;
|
||||||
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";
|
||||||
|
|||||||
92
lib/app.dart
92
lib/app.dart
@@ -1,13 +1,14 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
import 'package:toolbox/core/extension/colorx.dart';
|
|
||||||
import 'package:toolbox/data/res/build_data.dart';
|
|
||||||
import 'package:toolbox/data/store/setting.dart';
|
|
||||||
import 'package:toolbox/generated/l10n.dart';
|
|
||||||
import 'package:toolbox/locator.dart';
|
|
||||||
import 'package:toolbox/view/page/home.dart';
|
|
||||||
|
|
||||||
|
import '/core/extension/colorx.dart';
|
||||||
import 'core/utils/ui.dart';
|
import 'core/utils/ui.dart';
|
||||||
|
import 'data/res/build_data.dart';
|
||||||
|
import 'data/res/color.dart';
|
||||||
|
import 'data/store/setting.dart';
|
||||||
|
import 'generated/l10n.dart';
|
||||||
|
import 'locator.dart';
|
||||||
|
import 'view/page/home.dart';
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
class MyApp extends StatelessWidget {
|
||||||
const MyApp({Key? key}) : super(key: key);
|
const MyApp({Key? key}) : super(key: key);
|
||||||
@@ -17,12 +18,31 @@ class MyApp extends StatelessWidget {
|
|||||||
setTransparentNavigationBar(context);
|
setTransparentNavigationBar(context);
|
||||||
return ValueListenableBuilder<int>(
|
return ValueListenableBuilder<int>(
|
||||||
valueListenable: locator<SettingStore>().primaryColor.listenable(),
|
valueListenable: locator<SettingStore>().primaryColor.listenable(),
|
||||||
builder: (_, value, __) {
|
builder: (_, colorValue, __) {
|
||||||
final primaryColor = Color(value);
|
primaryColor = Color(colorValue);
|
||||||
|
|
||||||
final textStyle = TextStyle(color: primaryColor);
|
final textStyle = TextStyle(color: primaryColor);
|
||||||
final materialColor = primaryColor.materialStateColor;
|
final materialColor = primaryColor.materialStateColor;
|
||||||
final materialColorAlpha =
|
final materialColorAlpha =
|
||||||
primaryColor.withOpacity(0.7).materialStateColor;
|
primaryColor.withOpacity(0.7).materialStateColor;
|
||||||
|
final fabTheme =
|
||||||
|
FloatingActionButtonThemeData(backgroundColor: primaryColor);
|
||||||
|
final switchTheme = SwitchThemeData(
|
||||||
|
thumbColor: materialColor,
|
||||||
|
trackColor: materialColorAlpha,
|
||||||
|
);
|
||||||
|
final appBarTheme = AppBarTheme(backgroundColor: primaryColor);
|
||||||
|
final iconTheme = IconThemeData(color: primaryColor);
|
||||||
|
final inputDecorationTheme = InputDecorationTheme(
|
||||||
|
labelStyle: textStyle,
|
||||||
|
focusedBorder: UnderlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: primaryColor),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
final radioTheme = RadioThemeData(
|
||||||
|
fillColor: materialColor,
|
||||||
|
);
|
||||||
|
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
localizationsDelegates: const [
|
localizationsDelegates: const [
|
||||||
S.delegate,
|
S.delegate,
|
||||||
@@ -31,50 +51,30 @@ class MyApp extends StatelessWidget {
|
|||||||
supportedLocales: S.delegate.supportedLocales,
|
supportedLocales: S.delegate.supportedLocales,
|
||||||
title: BuildData.name,
|
title: BuildData.name,
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
|
useMaterial3: false,
|
||||||
primaryColor: primaryColor,
|
primaryColor: primaryColor,
|
||||||
appBarTheme: AppBarTheme(backgroundColor: primaryColor),
|
primarySwatch: primaryColor.materialColor,
|
||||||
floatingActionButtonTheme:
|
appBarTheme: appBarTheme,
|
||||||
FloatingActionButtonThemeData(backgroundColor: primaryColor),
|
floatingActionButtonTheme: fabTheme,
|
||||||
iconTheme: IconThemeData(color: primaryColor),
|
iconTheme: iconTheme,
|
||||||
primaryIconTheme: IconThemeData(color: primaryColor),
|
primaryIconTheme: iconTheme,
|
||||||
switchTheme: SwitchThemeData(
|
switchTheme: switchTheme,
|
||||||
thumbColor: materialColor,
|
inputDecorationTheme: inputDecorationTheme,
|
||||||
trackColor: materialColorAlpha,
|
radioTheme: radioTheme,
|
||||||
),
|
|
||||||
buttonTheme: ButtonThemeData(splashColor: primaryColor),
|
|
||||||
inputDecorationTheme: InputDecorationTheme(
|
|
||||||
labelStyle: textStyle,
|
|
||||||
focusedBorder: UnderlineInputBorder(
|
|
||||||
borderSide: BorderSide(color: primaryColor),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
radioTheme: RadioThemeData(
|
|
||||||
fillColor: materialColor,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
darkTheme: ThemeData.dark().copyWith(
|
darkTheme: ThemeData.dark().copyWith(
|
||||||
|
useMaterial3: false,
|
||||||
primaryColor: primaryColor,
|
primaryColor: primaryColor,
|
||||||
floatingActionButtonTheme:
|
floatingActionButtonTheme: fabTheme,
|
||||||
FloatingActionButtonThemeData(backgroundColor: primaryColor),
|
iconTheme: iconTheme,
|
||||||
iconTheme: IconThemeData(color: primaryColor),
|
primaryIconTheme: iconTheme,
|
||||||
primaryIconTheme: IconThemeData(color: primaryColor),
|
switchTheme: switchTheme,
|
||||||
switchTheme: SwitchThemeData(
|
inputDecorationTheme: inputDecorationTheme,
|
||||||
thumbColor: materialColor,
|
radioTheme: radioTheme,
|
||||||
trackColor: materialColorAlpha,
|
|
||||||
),
|
|
||||||
buttonTheme: ButtonThemeData(splashColor: primaryColor),
|
|
||||||
inputDecorationTheme: InputDecorationTheme(
|
|
||||||
labelStyle: textStyle,
|
|
||||||
focusedBorder: UnderlineInputBorder(
|
|
||||||
borderSide: BorderSide(color: primaryColor),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
radioTheme: RadioThemeData(
|
|
||||||
fillColor: materialColor,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
home: MyHomePage(primaryColor: primaryColor),
|
home: MyHomePage(primaryColor: primaryColor),
|
||||||
);
|
);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,4 +24,17 @@ extension ColorX on Color {
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaterialColor get materialColor => MaterialColor(value, {
|
||||||
|
50: withOpacity(0.05),
|
||||||
|
100: withOpacity(0.1),
|
||||||
|
200: withOpacity(0.2),
|
||||||
|
300: withOpacity(0.3),
|
||||||
|
400: withOpacity(0.4),
|
||||||
|
500: withOpacity(0.5),
|
||||||
|
600: withOpacity(0.6),
|
||||||
|
700: withOpacity(0.7),
|
||||||
|
800: withOpacity(0.8),
|
||||||
|
900: withOpacity(0.9),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,10 +56,17 @@ Future<void> doUpdate(BuildContext context, {bool force = false}) async {
|
|||||||
final s = S.of(context);
|
final s = S.of(context);
|
||||||
|
|
||||||
if (update.min > BuildData.build) {
|
if (update.min > BuildData.build) {
|
||||||
showRoundDialog(context, s.attention, Text(s.updateTipTooLow(newest)), [
|
showRoundDialog(
|
||||||
|
context,
|
||||||
|
s.attention,
|
||||||
|
Text(s.updateTipTooLow(newest)),
|
||||||
|
[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => _doUpdate(update, context, s), child: Text(s.ok))
|
onPressed: () => _doUpdate(update, context, s),
|
||||||
]);
|
child: Text(s.ok),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,14 +80,19 @@ Future<void> doUpdate(BuildContext context, {bool force = false}) async {
|
|||||||
|
|
||||||
Future<void> _doUpdate(AppUpdate update, BuildContext context, S s) async {
|
Future<void> _doUpdate(AppUpdate update, BuildContext context, S s) async {
|
||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
await RUpgrade.upgrade(update.android,
|
await RUpgrade.upgrade(
|
||||||
fileName: update.android.split('/').last, isAutoRequestInstall: true);
|
update.android,
|
||||||
|
fileName: update.android.split('/').last,
|
||||||
|
isAutoRequestInstall: true,
|
||||||
|
);
|
||||||
} else if (Platform.isIOS) {
|
} else if (Platform.isIOS) {
|
||||||
await RUpgrade.upgradeFromAppStore('1586449703');
|
await RUpgrade.upgradeFromAppStore('1586449703');
|
||||||
} else {
|
} else {
|
||||||
showRoundDialog(context, s.attention, Text(s.platformNotSupportUpdate), [
|
showRoundDialog(context, s.attention, Text(s.platformNotSupportUpdate), [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(), child: Text(s.ok))
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
child: Text(s.ok),
|
||||||
|
)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
lib/data/model/app/dynamic_color.dart
Normal file
15
lib/data/model/app/dynamic_color.dart
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
import '../../../core/utils/ui.dart';
|
||||||
|
|
||||||
|
class DynamicColor {
|
||||||
|
/// 白天模式显示的颜色
|
||||||
|
Color light;
|
||||||
|
|
||||||
|
/// 暗黑模式显示的颜色
|
||||||
|
Color dark;
|
||||||
|
|
||||||
|
DynamicColor(this.light, this.dark);
|
||||||
|
|
||||||
|
Color resolve(BuildContext context) => isDarkMode(context) ? dark : light;
|
||||||
|
}
|
||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
class BuildData {
|
class BuildData {
|
||||||
static const String name = "ServerBox";
|
static const String name = "ServerBox";
|
||||||
static const int build = 203;
|
static const int build = 205;
|
||||||
static const String engine =
|
static const String engine =
|
||||||
"Flutter 3.7.0 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision b06b8b2710 (8 days ago) • 2023-01-23 16:55:55 -0800\nEngine • revision b24591ed32\nTools • Dart 2.19.0 • DevTools 2.20.1\n";
|
"Flutter 3.7.0 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision b06b8b2710 (8 days ago) • 2023-01-23 16:55:55 -0800\nEngine • revision b24591ed32\nTools • Dart 2.19.0 • DevTools 2.20.1\n";
|
||||||
static const String buildAt = "2023-02-01 12:58:12.944187";
|
static const String buildAt = "2023-02-01 14:57:28.662965";
|
||||||
static const int modifications = 13;
|
static const int modifications = 5;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:toolbox/data/store/setting.dart';
|
||||||
|
import 'package:toolbox/locator.dart';
|
||||||
|
|
||||||
import '../../core/utils/ui.dart';
|
import '../model/app/dynamic_color.dart';
|
||||||
|
|
||||||
class DynamicColor {
|
Color primaryColor = Color(locator<SettingStore>().primaryColor.fetch()!);
|
||||||
/// 白天模式显示的颜色
|
|
||||||
Color light;
|
|
||||||
|
|
||||||
/// 暗黑模式显示的颜色
|
final contentColor = DynamicColor(Colors.black87, Colors.white70);
|
||||||
Color dark;
|
final bgColor = DynamicColor(Colors.white, Colors.black);
|
||||||
|
|
||||||
DynamicColor(this.light, this.dark);
|
|
||||||
|
|
||||||
resolve(BuildContext context) => isDarkMode(context) ? dark : light;
|
|
||||||
}
|
|
||||||
|
|
||||||
final mainColor = DynamicColor(Colors.black87, Colors.white70);
|
|
||||||
final progressColor = DynamicColor(Colors.grey.shade100, Colors.white10);
|
final progressColor = DynamicColor(Colors.grey.shade100, Colors.white10);
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
import 'package:toolbox/data/provider/app.dart';
|
|
||||||
import 'package:toolbox/data/provider/pkg.dart';
|
|
||||||
import 'package:toolbox/data/provider/debug.dart';
|
|
||||||
import 'package:toolbox/data/provider/docker.dart';
|
|
||||||
import 'package:toolbox/data/provider/private_key.dart';
|
|
||||||
import 'package:toolbox/data/provider/server.dart';
|
|
||||||
import 'package:toolbox/data/provider/sftp_download.dart';
|
|
||||||
import 'package:toolbox/data/provider/snippet.dart';
|
|
||||||
import 'package:toolbox/data/service/app.dart';
|
|
||||||
import 'package:toolbox/data/store/docker.dart';
|
|
||||||
import 'package:toolbox/data/store/private_key.dart';
|
|
||||||
import 'package:toolbox/data/store/server.dart';
|
|
||||||
import 'package:toolbox/data/store/setting.dart';
|
|
||||||
import 'package:toolbox/data/store/snippet.dart';
|
|
||||||
|
|
||||||
|
import 'data/provider/app.dart';
|
||||||
|
import 'data/provider/debug.dart';
|
||||||
|
import 'data/provider/docker.dart';
|
||||||
|
import 'data/provider/pkg.dart';
|
||||||
|
import 'data/provider/private_key.dart';
|
||||||
|
import 'data/provider/server.dart';
|
||||||
|
import 'data/provider/sftp_download.dart';
|
||||||
|
import 'data/provider/snippet.dart';
|
||||||
import 'data/provider/virtual_keyboard.dart';
|
import 'data/provider/virtual_keyboard.dart';
|
||||||
|
import 'data/service/app.dart';
|
||||||
|
import 'data/store/docker.dart';
|
||||||
|
import 'data/store/private_key.dart';
|
||||||
|
import 'data/store/server.dart';
|
||||||
|
import 'data/store/setting.dart';
|
||||||
|
import 'data/store/snippet.dart';
|
||||||
|
|
||||||
GetIt locator = GetIt.instance;
|
GetIt locator = GetIt.instance;
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'dart:convert';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:toolbox/data/res/color.dart';
|
||||||
|
|
||||||
import '../../core/extension/colorx.dart';
|
import '../../core/extension/colorx.dart';
|
||||||
import '../../core/utils/ui.dart';
|
import '../../core/utils/ui.dart';
|
||||||
@@ -15,7 +16,6 @@ import '../../data/store/setting.dart';
|
|||||||
import '../../data/store/snippet.dart';
|
import '../../data/store/snippet.dart';
|
||||||
import '../../generated/l10n.dart';
|
import '../../generated/l10n.dart';
|
||||||
import '../../locator.dart';
|
import '../../locator.dart';
|
||||||
import '../widget/primary_color.dart';
|
|
||||||
|
|
||||||
const backupFormatVersion = 1;
|
const backupFormatVersion = 1;
|
||||||
|
|
||||||
@@ -68,14 +68,12 @@ class BackupPage extends StatelessWidget {
|
|||||||
|
|
||||||
Widget _buildCard(String text, IconData icon, MediaQueryData media,
|
Widget _buildCard(String text, IconData icon, MediaQueryData media,
|
||||||
FutureOr Function() onTap) {
|
FutureOr Function() onTap) {
|
||||||
return PrimaryColor(
|
final textColor = primaryColor.isBrightColor ? Colors.black : Colors.white;
|
||||||
builder: ((context, pColor) {
|
|
||||||
final textColor = pColor.isBrightColor ? Colors.black : Colors.white;
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(37), color: pColor),
|
borderRadius: BorderRadius.circular(37), color: primaryColor),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 7, horizontal: 17),
|
padding: const EdgeInsets.symmetric(vertical: 7, horizontal: 17),
|
||||||
child: Row(
|
child: Row(
|
||||||
@@ -93,8 +91,6 @@ class BackupPage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _showExportDialog(BuildContext context, S s) async {
|
Future<void> _showExportDialog(BuildContext context, S s) async {
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import '../../core/utils/ui.dart';
|
import '../../core/utils/ui.dart';
|
||||||
|
import '../../data/res/color.dart';
|
||||||
import '../../generated/l10n.dart';
|
import '../../generated/l10n.dart';
|
||||||
import '../widget/input_field.dart';
|
import '../widget/input_field.dart';
|
||||||
import '../widget/primary_color.dart';
|
|
||||||
import '../widget/round_rect_card.dart';
|
import '../widget/round_rect_card.dart';
|
||||||
|
|
||||||
class ConvertPage extends StatefulWidget {
|
class ConvertPage extends StatefulWidget {
|
||||||
@@ -105,7 +105,6 @@ class _ConvertPageState extends State<ConvertPage>
|
|||||||
'URL $encode',
|
'URL $encode',
|
||||||
'URL $decode'
|
'URL $decode'
|
||||||
];
|
];
|
||||||
return PrimaryColor(builder: (context, primaryColor) {
|
|
||||||
return RoundRectCard(
|
return RoundRectCard(
|
||||||
ExpansionTile(
|
ExpansionTile(
|
||||||
tilePadding: const EdgeInsets.only(left: 7, right: 27),
|
tilePadding: const EdgeInsets.only(left: 7, right: 27),
|
||||||
@@ -113,26 +112,21 @@ class _ConvertPageState extends State<ConvertPage>
|
|||||||
title: Row(
|
title: Row(
|
||||||
children: [
|
children: [
|
||||||
TextButton(
|
TextButton(
|
||||||
style: ButtonStyle(
|
|
||||||
foregroundColor: MaterialStateProperty.all(primaryColor)),
|
|
||||||
child: Icon(Icons.change_circle, semanticLabel: _s.upsideDown),
|
child: Icon(Icons.change_circle, semanticLabel: _s.upsideDown),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
final temp = _textEditingController.text;
|
final temp = _textEditingController.text;
|
||||||
_textEditingController.text =
|
_textEditingController.text = _textEditingControllerResult.text;
|
||||||
_textEditingControllerResult.text;
|
|
||||||
_textEditingControllerResult.text = temp;
|
_textEditingControllerResult.text = temp;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
style: ButtonStyle(
|
|
||||||
foregroundColor: MaterialStateProperty.all(primaryColor),
|
|
||||||
),
|
|
||||||
child: Icon(Icons.copy, semanticLabel: _s.copy),
|
child: Icon(Icons.copy, semanticLabel: _s.copy),
|
||||||
onPressed: () => Clipboard.setData(
|
onPressed: () => Clipboard.setData(
|
||||||
ClipboardData(
|
ClipboardData(
|
||||||
text: _textEditingControllerResult.text == ''
|
text: _textEditingControllerResult.text == ''
|
||||||
? ' '
|
? ' '
|
||||||
: _textEditingControllerResult.text),
|
: _textEditingControllerResult.text,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
@@ -150,7 +144,8 @@ class _ConvertPageState extends State<ConvertPage>
|
|||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16.0,
|
fontSize: 16.0,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: primaryColor),
|
color: primaryColor,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
_s.currentMode,
|
_s.currentMode,
|
||||||
@@ -176,7 +171,6 @@ class _ConvertPageState extends State<ConvertPage>
|
|||||||
.toList(),
|
.toList(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildResult() {
|
Widget _buildResult() {
|
||||||
|
|||||||
@@ -190,7 +190,9 @@ class _DockerManagePageState extends State<DockerManagePage> {
|
|||||||
if (_textController.text == '') {
|
if (_textController.text == '') {
|
||||||
showRoundDialog(context, _s.attention, Text(_s.fieldMustNotEmpty), [
|
showRoundDialog(context, _s.attention, Text(_s.fieldMustNotEmpty), [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(), child: Text(_s.ok)),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
child: Text(_s.ok),
|
||||||
|
),
|
||||||
]);
|
]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import '../../core/analysis.dart';
|
|||||||
import '../../core/route.dart';
|
import '../../core/route.dart';
|
||||||
import '../../core/update.dart';
|
import '../../core/update.dart';
|
||||||
import '../../core/utils/ui.dart';
|
import '../../core/utils/ui.dart';
|
||||||
|
import '../../data/model/app/dynamic_color.dart';
|
||||||
import '../../data/model/app/navigation_item.dart';
|
import '../../data/model/app/navigation_item.dart';
|
||||||
import '../../data/provider/server.dart';
|
import '../../data/provider/server.dart';
|
||||||
import '../../data/res/build_data.dart';
|
import '../../data/res/build_data.dart';
|
||||||
@@ -28,6 +29,9 @@ import 'setting.dart';
|
|||||||
import 'sftp/downloaded.dart';
|
import 'sftp/downloaded.dart';
|
||||||
import 'snippet/list.dart';
|
import 'snippet/list.dart';
|
||||||
|
|
||||||
|
final _bottomItemOverlayColor =
|
||||||
|
DynamicColor(Colors.black.withOpacity(0.07), Colors.white12);
|
||||||
|
|
||||||
class MyHomePage extends StatefulWidget {
|
class MyHomePage extends StatefulWidget {
|
||||||
const MyHomePage({Key? key, required this.primaryColor}) : super(key: key);
|
const MyHomePage({Key? key, required this.primaryColor}) : super(key: key);
|
||||||
final Color primaryColor;
|
final Color primaryColor;
|
||||||
@@ -112,7 +116,7 @@ class _MyHomePageState extends State<MyHomePage>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildItem(int idx, NavigationItem item, bool isSelected) {
|
Widget _buildBottomItem(int idx, NavigationItem item, bool isSelected) {
|
||||||
final width = _width / tabItems.length;
|
final width = _width / tabItems.length;
|
||||||
return AnimatedContainer(
|
return AnimatedContainer(
|
||||||
duration: const Duration(milliseconds: 377),
|
duration: const Duration(milliseconds: 377),
|
||||||
@@ -121,9 +125,7 @@ class _MyHomePageState extends State<MyHomePage>
|
|||||||
width: isSelected ? width : width - 17,
|
width: isSelected ? width : width - 17,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: isSelected
|
color: isSelected
|
||||||
? isDarkMode(context)
|
? _bottomItemOverlayColor.resolve(context)
|
||||||
? Colors.white12
|
|
||||||
: Colors.black.withOpacity(0.07)
|
|
||||||
: Colors.transparent,
|
: Colors.transparent,
|
||||||
borderRadius: const BorderRadius.all(
|
borderRadius: const BorderRadius.all(
|
||||||
Radius.circular(50),
|
Radius.circular(50),
|
||||||
@@ -156,7 +158,8 @@ class _MyHomePageState extends State<MyHomePage>
|
|||||||
children: tabItems.map(
|
children: tabItems.map(
|
||||||
(item) {
|
(item) {
|
||||||
int itemIndex = tabItems.indexOf(item);
|
int itemIndex = tabItems.indexOf(item);
|
||||||
return _buildItem(itemIndex, item, _selectIndex == itemIndex);
|
return _buildBottomItem(
|
||||||
|
itemIndex, item, _selectIndex == itemIndex,);
|
||||||
},
|
},
|
||||||
).toList(),
|
).toList(),
|
||||||
),
|
),
|
||||||
@@ -179,7 +182,6 @@ class _MyHomePageState extends State<MyHomePage>
|
|||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
'${BuildData.name}\n$_versionStr',
|
'${BuildData.name}\n$_versionStr',
|
||||||
style: TextStyle(color: widget.primaryColor),
|
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -225,11 +227,6 @@ class _MyHomePageState extends State<MyHomePage>
|
|||||||
_s.feedback,
|
_s.feedback,
|
||||||
Text(_s.feedbackOnGithub),
|
Text(_s.feedbackOnGithub),
|
||||||
[
|
[
|
||||||
TextButton(
|
|
||||||
onPressed: () => Clipboard.setData(
|
|
||||||
const ClipboardData(text: issueUrl)),
|
|
||||||
child: Text(_s.copy),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => openUrl(issueUrl),
|
onPressed: () => openUrl(issueUrl),
|
||||||
child: Text(_s.feedback),
|
child: Text(_s.feedback),
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:after_layout/after_layout.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import '../../core/extension/uint8list.dart';
|
import '../../core/extension/uint8list.dart';
|
||||||
import '../../core/utils/ui.dart';
|
import '../../core/utils/ui.dart';
|
||||||
import '../../data/model/server/ping_result.dart';
|
import '../../data/model/server/ping_result.dart';
|
||||||
import '../../data/provider/server.dart';
|
import '../../data/provider/server.dart';
|
||||||
|
import '../../data/res/color.dart';
|
||||||
import '../../data/res/font_style.dart';
|
import '../../data/res/font_style.dart';
|
||||||
import '../../generated/l10n.dart';
|
import '../../generated/l10n.dart';
|
||||||
import '../../locator.dart';
|
import '../../locator.dart';
|
||||||
import '../widget/input_field.dart';
|
import '../widget/input_field.dart';
|
||||||
import '../widget/primary_color.dart';
|
|
||||||
import '../widget/round_rect_card.dart';
|
import '../widget/round_rect_card.dart';
|
||||||
|
|
||||||
final doaminReg =
|
final doaminReg =
|
||||||
@@ -25,7 +28,7 @@ class PingPage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _PingPageState extends State<PingPage>
|
class _PingPageState extends State<PingPage>
|
||||||
with AutomaticKeepAliveClientMixin {
|
with AutomaticKeepAliveClientMixin, AfterLayoutMixin {
|
||||||
late TextEditingController _textEditingController;
|
late TextEditingController _textEditingController;
|
||||||
late MediaQueryData _media;
|
late MediaQueryData _media;
|
||||||
final List<PingResult> _results = [];
|
final List<PingResult> _results = [];
|
||||||
@@ -54,10 +57,13 @@ class _PingPageState extends State<PingPage>
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 13),
|
const SizedBox(height: 13),
|
||||||
buildInput(context, _textEditingController,
|
buildInput(
|
||||||
|
context,
|
||||||
|
_textEditingController,
|
||||||
hint: s.inputDomainHere,
|
hint: s.inputDomainHere,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
onSubmitted: (_) => doPing()),
|
onSubmitted: (_) => doPing(),
|
||||||
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: _media.size.height * 0.6,
|
height: _media.size.height * 0.6,
|
||||||
@@ -67,7 +73,8 @@ class _PingPageState extends State<PingPage>
|
|||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final result = _results[index];
|
final result = _results[index];
|
||||||
return _buildResultItem(result);
|
return _buildResultItem(result);
|
||||||
}),
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -89,12 +96,9 @@ class _PingPageState extends State<PingPage>
|
|||||||
Widget _buildResultItem(PingResult result) {
|
Widget _buildResultItem(PingResult result) {
|
||||||
final unknown = s.unknown;
|
final unknown = s.unknown;
|
||||||
final ms = s.ms;
|
final ms = s.ms;
|
||||||
return PrimaryColor(
|
|
||||||
builder: ((context, primaryColor) {
|
|
||||||
return RoundRectCard(
|
return RoundRectCard(
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding:
|
contentPadding: const EdgeInsets.symmetric(vertical: 7, horizontal: 17),
|
||||||
const EdgeInsets.symmetric(vertical: 7, horizontal: 17),
|
|
||||||
title: Text(
|
title: Text(
|
||||||
result.serverName,
|
result.serverName,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
@@ -116,8 +120,6 @@ class _PingPageState extends State<PingPage>
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String _buildPingSummary(PingResult result, String unknown, String ms) {
|
String _buildPingSummary(PingResult result, String unknown, String ms) {
|
||||||
@@ -169,4 +171,10 @@ class _PingPageState extends State<PingPage>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool get wantKeepAlive => true;
|
bool get wantKeepAlive => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<FutureOr<void>> afterFirstLayout(BuildContext context) async {
|
||||||
|
await _serverProvider.loadLocalData();
|
||||||
|
await _serverProvider.refreshData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,9 @@ class _PkgManagePageState extends State<PkgManagePage>
|
|||||||
Text(_s.fieldMustNotEmpty),
|
Text(_s.fieldMustNotEmpty),
|
||||||
[
|
[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(), child: Text(_s.ok)),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
child: Text(_s.ok),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
@@ -112,7 +114,8 @@ class _PkgManagePageState extends State<PkgManagePage>
|
|||||||
child: Text(
|
child: Text(
|
||||||
_s.ok,
|
_s.ok,
|
||||||
style: const TextStyle(color: Colors.red),
|
style: const TextStyle(color: Colors.red),
|
||||||
)),
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
return _textController.text.trim();
|
return _textController.text.trim();
|
||||||
@@ -206,7 +209,8 @@ class _PkgManagePageState extends State<PkgManagePage>
|
|||||||
child: Text(_s.updateAll),
|
child: Text(_s.updateAll),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
apt.upgrade();
|
apt.upgrade();
|
||||||
}),
|
},
|
||||||
|
),
|
||||||
...apt.upgradeable!.map((e) => _buildUpdateItem(e, apt)).toList()
|
...apt.upgradeable!.map((e) => _buildUpdateItem(e, apt)).toList()
|
||||||
]
|
]
|
||||||
: [
|
: [
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ class _PrivateKeyListState extends State<PrivateKeysListPage> {
|
|||||||
trailing: TextButton(
|
trailing: TextButton(
|
||||||
onPressed: () => AppRoute(
|
onPressed: () => AppRoute(
|
||||||
PrivateKeyEditPage(info: key.infos[idx]),
|
PrivateKeyEditPage(info: key.infos[idx]),
|
||||||
'private key edit page')
|
'private key edit page',
|
||||||
.go(context),
|
).go(context),
|
||||||
child: Text(_s.edit),
|
child: Text(_s.edit),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import '../../../data/res/sizedbox.dart';
|
|||||||
import '../../../data/store/setting.dart';
|
import '../../../data/store/setting.dart';
|
||||||
import '../../../generated/l10n.dart';
|
import '../../../generated/l10n.dart';
|
||||||
import '../../../locator.dart';
|
import '../../../locator.dart';
|
||||||
import '../../widget/primary_color.dart';
|
|
||||||
import '../../widget/round_rect_card.dart';
|
import '../../widget/round_rect_card.dart';
|
||||||
|
|
||||||
class ServerDetailPage extends StatefulWidget {
|
class ServerDetailPage extends StatefulWidget {
|
||||||
@@ -174,14 +173,12 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
|||||||
Widget _buildProgress(double percent) {
|
Widget _buildProgress(double percent) {
|
||||||
if (percent > 100) percent = 100;
|
if (percent > 100) percent = 100;
|
||||||
final percentWithinOne = percent / 100;
|
final percentWithinOne = percent / 100;
|
||||||
return PrimaryColor(builder: (context, primaryColor) {
|
|
||||||
return LinearProgressIndicator(
|
return LinearProgressIndicator(
|
||||||
value: percentWithinOne,
|
value: percentWithinOne,
|
||||||
minHeight: 7,
|
minHeight: 7,
|
||||||
backgroundColor: progressColor.resolve(context),
|
backgroundColor: progressColor.resolve(context),
|
||||||
color: primaryColor,
|
color: primaryColor,
|
||||||
);
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildUpTimeAndSys(ServerStatus ss) {
|
Widget _buildUpTimeAndSys(ServerStatus ss) {
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ import '../../../data/model/server/private_key_info.dart';
|
|||||||
import '../../../data/model/server/server_private_info.dart';
|
import '../../../data/model/server/server_private_info.dart';
|
||||||
import '../../../data/provider/private_key.dart';
|
import '../../../data/provider/private_key.dart';
|
||||||
import '../../../data/provider/server.dart';
|
import '../../../data/provider/server.dart';
|
||||||
|
import '../../../data/res/color.dart';
|
||||||
import '../../../data/res/font_style.dart';
|
import '../../../data/res/font_style.dart';
|
||||||
import '../../../data/store/private_key.dart';
|
import '../../../data/store/private_key.dart';
|
||||||
import '../../../generated/l10n.dart';
|
import '../../../generated/l10n.dart';
|
||||||
import '../../../locator.dart';
|
import '../../../locator.dart';
|
||||||
import '../../widget/input_decoration.dart';
|
import '../../widget/input_decoration.dart';
|
||||||
import '../../widget/primary_color.dart';
|
|
||||||
import '../private_key/edit.dart';
|
import '../private_key/edit.dart';
|
||||||
|
|
||||||
class ServerEditPage extends StatefulWidget {
|
class ServerEditPage extends StatefulWidget {
|
||||||
@@ -200,7 +200,6 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
return PrimaryColor(builder: ((context, primaryColor) {
|
|
||||||
return ExpansionTile(
|
return ExpansionTile(
|
||||||
textColor: primaryColor,
|
textColor: primaryColor,
|
||||||
iconColor: primaryColor,
|
iconColor: primaryColor,
|
||||||
@@ -212,7 +211,6 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
|
|||||||
),
|
),
|
||||||
children: tiles,
|
children: tiles,
|
||||||
);
|
);
|
||||||
}));
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: const SizedBox()
|
: const SizedBox()
|
||||||
@@ -234,10 +232,12 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
|
|||||||
[
|
[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(false),
|
onPressed: () => Navigator.of(context).pop(false),
|
||||||
child: Text(_s.ok)),
|
child: Text(_s.ok),
|
||||||
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(true),
|
onPressed: () => Navigator.of(context).pop(true),
|
||||||
child: Text(_s.cancel))
|
child: Text(_s.cancel),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
barrierDismiss: false,
|
barrierDismiss: false,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import '../../../data/model/server/server_private_info.dart';
|
|||||||
import '../../../data/model/server/server_status.dart';
|
import '../../../data/model/server/server_status.dart';
|
||||||
import '../../../data/provider/server.dart';
|
import '../../../data/provider/server.dart';
|
||||||
import '../../../data/provider/snippet.dart';
|
import '../../../data/provider/snippet.dart';
|
||||||
|
import '../../../data/res/color.dart';
|
||||||
import '../../../data/res/font_style.dart';
|
import '../../../data/res/font_style.dart';
|
||||||
import '../../../data/res/menu.dart';
|
import '../../../data/res/menu.dart';
|
||||||
import '../../../data/res/url.dart';
|
import '../../../data/res/url.dart';
|
||||||
@@ -19,7 +20,6 @@ import '../../../generated/l10n.dart';
|
|||||||
import '../../../locator.dart';
|
import '../../../locator.dart';
|
||||||
import '../../widget/dropdown_menu.dart';
|
import '../../widget/dropdown_menu.dart';
|
||||||
import '../../widget/picker.dart';
|
import '../../widget/picker.dart';
|
||||||
import '../../widget/primary_color.dart';
|
|
||||||
import '../../widget/round_rect_card.dart';
|
import '../../widget/round_rect_card.dart';
|
||||||
import '../../widget/url_text.dart';
|
import '../../widget/url_text.dart';
|
||||||
import '../docker.dart';
|
import '../docker.dart';
|
||||||
@@ -162,7 +162,11 @@ class _ServerPageState extends State<ServerPage>
|
|||||||
? GestureDetector(
|
? GestureDetector(
|
||||||
onTap: () => showRoundDialog(
|
onTap: () => showRoundDialog(
|
||||||
context, _s.error, Text(ss.failedInfo ?? ''), []),
|
context, _s.error, Text(ss.failedInfo ?? ''), []),
|
||||||
child: Text(_s.clickSee, style: style, textScaleFactor: 1.0,))
|
child: Text(
|
||||||
|
_s.clickSee,
|
||||||
|
style: style,
|
||||||
|
textScaleFactor: 1.0,
|
||||||
|
))
|
||||||
: Text(topRightStr, style: style, textScaleFactor: 1.0),
|
: Text(topRightStr, style: style, textScaleFactor: 1.0),
|
||||||
const SizedBox(width: 9),
|
const SizedBox(width: 9),
|
||||||
_buildSSHBtn(spi),
|
_buildSSHBtn(spi),
|
||||||
@@ -352,16 +356,12 @@ class _ServerPageState extends State<ServerPage>
|
|||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
Center(
|
Center(
|
||||||
child: PrimaryColor(
|
child: CircleChart(
|
||||||
builder: (context, primaryColor) {
|
|
||||||
return CircleChart(
|
|
||||||
progressColor: primaryColor,
|
progressColor: primaryColor,
|
||||||
progressNumber: percent,
|
progressNumber: percent,
|
||||||
maxNumber: 100,
|
maxNumber: 100,
|
||||||
width: 53,
|
width: 53,
|
||||||
height: 53,
|
height: 53,
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
@@ -415,8 +415,7 @@ class _ServerPageState extends State<ServerPage>
|
|||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
final result =
|
final result = await _serverProvider.runSnippet(id, snippet);
|
||||||
await locator<ServerProvider>().runSnippet(id, snippet);
|
|
||||||
showRoundDialog(
|
showRoundDialog(
|
||||||
context,
|
context,
|
||||||
_s.result,
|
_s.result,
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ import '../../core/utils/ui.dart';
|
|||||||
import '../../data/provider/app.dart';
|
import '../../data/provider/app.dart';
|
||||||
import '../../data/provider/server.dart';
|
import '../../data/provider/server.dart';
|
||||||
import '../../data/res/build_data.dart';
|
import '../../data/res/build_data.dart';
|
||||||
|
import '../../data/res/color.dart';
|
||||||
import '../../data/res/font_style.dart';
|
import '../../data/res/font_style.dart';
|
||||||
import '../../data/res/tab.dart';
|
import '../../data/res/tab.dart';
|
||||||
import '../../data/store/setting.dart';
|
import '../../data/store/setting.dart';
|
||||||
import '../../generated/l10n.dart';
|
import '../../generated/l10n.dart';
|
||||||
import '../../locator.dart';
|
import '../../locator.dart';
|
||||||
import '../widget/primary_color.dart';
|
|
||||||
import '../widget/round_rect_card.dart';
|
import '../widget/round_rect_card.dart';
|
||||||
|
|
||||||
class SettingPage extends StatefulWidget {
|
class SettingPage extends StatefulWidget {
|
||||||
@@ -56,19 +56,15 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(_s.setting),
|
title: Text(_s.setting),
|
||||||
),
|
),
|
||||||
body: PrimaryColor(
|
body: ListView(
|
||||||
builder: (context, primaryColor) {
|
|
||||||
return ListView(
|
|
||||||
padding: const EdgeInsets.all(17),
|
padding: const EdgeInsets.all(17),
|
||||||
children: [
|
children: [
|
||||||
_buildAppColorPreview(primaryColor),
|
_buildAppColorPreview(),
|
||||||
_buildUpdateInterval(primaryColor),
|
_buildUpdateInterval(),
|
||||||
_buildCheckUpdate(),
|
_buildCheckUpdate(),
|
||||||
_buildLaunchPage(primaryColor),
|
_buildLaunchPage(),
|
||||||
_buildDistLogoSwitch(),
|
_buildDistLogoSwitch(),
|
||||||
].map((e) => RoundRectCard(e)).toList(),
|
].map((e) => RoundRectCard(e)).toList(),
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -113,9 +109,9 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildUpdateInterval(Color priColor) {
|
Widget _buildUpdateInterval() {
|
||||||
return ExpansionTile(
|
return ExpansionTile(
|
||||||
textColor: priColor,
|
textColor: primaryColor,
|
||||||
title: Text(
|
title: Text(
|
||||||
_s.updateServerStatusInterval,
|
_s.updateServerStatusInterval,
|
||||||
style: textSize13,
|
style: textSize13,
|
||||||
@@ -128,8 +124,8 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
trailing: Text('${_updateInterval.toInt()} ${_s.second}'),
|
trailing: Text('${_updateInterval.toInt()} ${_s.second}'),
|
||||||
children: [
|
children: [
|
||||||
Slider(
|
Slider(
|
||||||
thumbColor: priColor,
|
thumbColor: primaryColor,
|
||||||
activeColor: priColor.withOpacity(0.7),
|
activeColor: primaryColor.withOpacity(0.7),
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 10,
|
max: 10,
|
||||||
value: _updateInterval,
|
value: _updateInterval,
|
||||||
@@ -162,12 +158,12 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildAppColorPreview(Color priColor) {
|
Widget _buildAppColorPreview() {
|
||||||
return ExpansionTile(
|
return ExpansionTile(
|
||||||
textColor: priColor,
|
textColor: primaryColor,
|
||||||
trailing: ClipOval(
|
trailing: ClipOval(
|
||||||
child: Container(
|
child: Container(
|
||||||
color: priColor,
|
color: primaryColor,
|
||||||
height: 27,
|
height: 27,
|
||||||
width: 27,
|
width: 27,
|
||||||
),
|
),
|
||||||
@@ -176,17 +172,18 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
_s.appPrimaryColor,
|
_s.appPrimaryColor,
|
||||||
style: textSize13,
|
style: textSize13,
|
||||||
),
|
),
|
||||||
children: [_buildAppColorPicker(priColor), _buildColorPickerConfirmBtn()],
|
children: [_buildAppColorPicker(), _buildColorPickerConfirmBtn()],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildAppColorPicker(Color selected) {
|
Widget _buildAppColorPicker() {
|
||||||
return MaterialColorPicker(
|
return MaterialColorPicker(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
onColorChange: (Color color) {
|
onColorChange: (Color color) {
|
||||||
_selectedColorValue = color.value;
|
_selectedColorValue = color.value;
|
||||||
},
|
},
|
||||||
selectedColor: selected);
|
selectedColor: primaryColor,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildColorPickerConfirmBtn() {
|
Widget _buildColorPickerConfirmBtn() {
|
||||||
@@ -199,9 +196,10 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildLaunchPage(Color priColor) {
|
Widget _buildLaunchPage() {
|
||||||
return ExpansionTile(
|
return ExpansionTile(
|
||||||
textColor: priColor,
|
childrenPadding: const EdgeInsets.only(left: 17, right: 7),
|
||||||
|
textColor: primaryColor,
|
||||||
title: Text(
|
title: Text(
|
||||||
_s.launchPage,
|
_s.launchPage,
|
||||||
style: textSize13,
|
style: textSize13,
|
||||||
@@ -222,7 +220,7 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
tabTitleName(context, tabs.indexOf(e)),
|
tabTitleName(context, tabs.indexOf(e)),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
color: _theme.textTheme.bodyMedium!.color!.withAlpha(177)),
|
color: _theme.textTheme.bodyMedium!.color!.withAlpha(177),),
|
||||||
),
|
),
|
||||||
trailing: _buildRadio(tabs.indexOf(e)),
|
trailing: _buildRadio(tabs.indexOf(e)),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -152,7 +152,8 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
|
|||||||
[
|
[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: Text(_s.cancel)),
|
child: Text(_s.cancel),
|
||||||
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
file.deleteSync();
|
file.deleteSync();
|
||||||
@@ -177,7 +178,8 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
|
|||||||
[
|
[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: (() => Navigator.of(context).pop()),
|
onPressed: (() => Navigator.of(context).pop()),
|
||||||
child: Text(_s.close))
|
child: Text(_s.close),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,7 +114,8 @@ class _SFTPPageState extends State<SFTPPage> {
|
|||||||
[
|
[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: Text(_s.close))
|
child: Text(_s.close),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
icon: const Icon(Icons.add),
|
icon: const Icon(Icons.add),
|
||||||
@@ -141,7 +142,8 @@ class _SFTPPageState extends State<SFTPPage> {
|
|||||||
[
|
[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: Text(_s.cancel))
|
child: Text(_s.cancel),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -278,7 +280,8 @@ class _SFTPPageState extends State<SFTPPage> {
|
|||||||
[
|
[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: Text(_s.cancel))
|
child: Text(_s.cancel),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -291,7 +294,8 @@ class _SFTPPageState extends State<SFTPPage> {
|
|||||||
[
|
[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: Text(_s.cancel)),
|
child: Text(_s.cancel),
|
||||||
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
@@ -329,7 +333,8 @@ class _SFTPPageState extends State<SFTPPage> {
|
|||||||
[
|
[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: const Text('Cancel')),
|
child: const Text('Cancel'),
|
||||||
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_status.client!.remove(file.filename);
|
_status.client!.remove(file.filename);
|
||||||
@@ -372,7 +377,8 @@ class _SFTPPageState extends State<SFTPPage> {
|
|||||||
[
|
[
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: Text(_s.ok)),
|
child: Text(_s.ok),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:toolbox/data/res/color.dart';
|
||||||
import 'package:xterm/xterm.dart';
|
import 'package:xterm/xterm.dart';
|
||||||
|
|
||||||
import '../../core/utils/ui.dart';
|
import '../../core/utils/ui.dart';
|
||||||
@@ -15,7 +16,6 @@ import '../../data/provider/virtual_keyboard.dart';
|
|||||||
import '../../data/res/terminal_theme.dart';
|
import '../../data/res/terminal_theme.dart';
|
||||||
import '../../data/res/virtual_key.dart';
|
import '../../data/res/virtual_key.dart';
|
||||||
import '../../locator.dart';
|
import '../../locator.dart';
|
||||||
import '../widget/primary_color.dart';
|
|
||||||
|
|
||||||
class SSHPage extends StatefulWidget {
|
class SSHPage extends StatefulWidget {
|
||||||
final ServerPrivateInfo spi;
|
final ServerPrivateInfo spi;
|
||||||
@@ -156,15 +156,13 @@ class _SSHPageState extends State<SSHPage> {
|
|||||||
color: isDark ? Colors.white : Colors.black,
|
color: isDark ? Colors.white : Colors.black,
|
||||||
size: 17,
|
size: 17,
|
||||||
)
|
)
|
||||||
: PrimaryColor(builder: (context, color) {
|
: Text(
|
||||||
return Text(
|
|
||||||
item.text,
|
item.text,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: selected ? color : Colors.black,
|
color: selected ? primaryColor : null,
|
||||||
fontSize: 17,
|
fontSize: 17,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
|
||||||
|
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../data/res/color.dart';
|
||||||
import '../../data/res/menu.dart';
|
import '../../data/res/menu.dart';
|
||||||
import '../../generated/l10n.dart';
|
import '../../generated/l10n.dart';
|
||||||
import 'primary_color.dart';
|
|
||||||
|
|
||||||
class DropdownBtnItem {
|
class DropdownBtnItem {
|
||||||
final String text;
|
final String text;
|
||||||
@@ -15,12 +15,10 @@ class DropdownBtnItem {
|
|||||||
|
|
||||||
Widget build(S s) => Row(
|
Widget build(S s) => Row(
|
||||||
children: [
|
children: [
|
||||||
PrimaryColor(builder: (context, primaryColor) {
|
Icon(
|
||||||
return Icon(
|
|
||||||
icon,
|
icon,
|
||||||
color: primaryColor,
|
color: primaryColor,
|
||||||
);
|
),
|
||||||
}),
|
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 10,
|
width: 10,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'primary_color.dart';
|
import '../../data/res/color.dart';
|
||||||
|
|
||||||
InputDecoration buildDecoration(String label,
|
InputDecoration buildDecoration(String label,
|
||||||
{TextStyle? textStyle, IconData? icon, String? hint}) {
|
{TextStyle? textStyle, IconData? icon, String? hint}) {
|
||||||
@@ -8,11 +8,9 @@ InputDecoration buildDecoration(String label,
|
|||||||
labelText: label,
|
labelText: label,
|
||||||
labelStyle: textStyle,
|
labelStyle: textStyle,
|
||||||
hintText: hint,
|
hintText: hint,
|
||||||
icon: PrimaryColor(builder: (context, primaryColor) {
|
icon: Icon(
|
||||||
return Icon(
|
|
||||||
icon,
|
icon,
|
||||||
color: primaryColor,
|
color: primaryColor,
|
||||||
);
|
),
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import '../../data/store/setting.dart';
|
|
||||||
import '../../locator.dart';
|
|
||||||
|
|
||||||
final _primaryColor = locator<SettingStore>().primaryColor.listenable();
|
|
||||||
|
|
||||||
class PrimaryColor extends StatelessWidget {
|
|
||||||
final Widget Function(BuildContext context, Color primaryColor) builder;
|
|
||||||
|
|
||||||
const PrimaryColor({Key? key, required this.builder}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return ValueListenableBuilder<int>(
|
|
||||||
builder: (context, c, child) => builder(context, Color(c)),
|
|
||||||
valueListenable: _primaryColor,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:toolbox/data/res/color.dart';
|
||||||
|
|
||||||
import '../../core/utils/ui.dart';
|
import '../../core/utils/ui.dart';
|
||||||
|
|
||||||
const regUrl =
|
final _reg = RegExp(
|
||||||
r"(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]*";
|
r"(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]*");
|
||||||
|
|
||||||
|
const _textStyle = TextStyle();
|
||||||
|
|
||||||
class UrlText extends StatelessWidget {
|
class UrlText extends StatelessWidget {
|
||||||
final String text;
|
final String text;
|
||||||
@@ -12,18 +15,17 @@ class UrlText extends StatelessWidget {
|
|||||||
final TextAlign? textAlign;
|
final TextAlign? textAlign;
|
||||||
final TextStyle style;
|
final TextStyle style;
|
||||||
|
|
||||||
const UrlText(
|
const UrlText({
|
||||||
{Key? key,
|
Key? key,
|
||||||
required this.text,
|
required this.text,
|
||||||
this.replace,
|
this.replace,
|
||||||
this.textAlign,
|
this.textAlign,
|
||||||
this.style = const TextStyle()})
|
this.style = _textStyle,
|
||||||
: super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
List<InlineSpan> _getTextSpans(bool isDarkMode) {
|
List<InlineSpan> _getTextSpans(Color c) {
|
||||||
List<InlineSpan> widgets = <InlineSpan>[];
|
List<InlineSpan> widgets = <InlineSpan>[];
|
||||||
final reg = RegExp(regUrl);
|
Iterable<Match> matches = _reg.allMatches(text);
|
||||||
Iterable<Match> matches = reg.allMatches(text);
|
|
||||||
List<_ResultMatch> resultMatches = <_ResultMatch>[];
|
List<_ResultMatch> resultMatches = <_ResultMatch>[];
|
||||||
int start = 0;
|
int start = 0;
|
||||||
|
|
||||||
@@ -54,16 +56,22 @@ class UrlText extends StatelessWidget {
|
|||||||
|
|
||||||
for (var result in resultMatches) {
|
for (var result in resultMatches) {
|
||||||
if (result.isUrl) {
|
if (result.isUrl) {
|
||||||
widgets.add(_LinkTextSpan(
|
widgets.add(
|
||||||
|
_LinkTextSpan(
|
||||||
replace: replace ?? result.text,
|
replace: replace ?? result.text,
|
||||||
text: result.text,
|
text: result.text,
|
||||||
style: style.copyWith(color: Colors.blue)));
|
style: style.copyWith(color: primaryColor),
|
||||||
|
),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
widgets.add(TextSpan(
|
widgets.add(
|
||||||
|
TextSpan(
|
||||||
text: result.text,
|
text: result.text,
|
||||||
style: style.copyWith(
|
style: style.copyWith(
|
||||||
color: isDarkMode ? Colors.white : Colors.black,
|
color: c,
|
||||||
)));
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return widgets;
|
return widgets;
|
||||||
@@ -73,7 +81,7 @@ class UrlText extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return RichText(
|
return RichText(
|
||||||
textAlign: textAlign ?? TextAlign.start,
|
textAlign: textAlign ?? TextAlign.start,
|
||||||
text: TextSpan(children: _getTextSpans(isDarkMode(context))),
|
text: TextSpan(children: _getTextSpans(contentColor.resolve(context))),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,7 +94,8 @@ class _LinkTextSpan extends TextSpan {
|
|||||||
recognizer: TapGestureRecognizer()
|
recognizer: TapGestureRecognizer()
|
||||||
..onTap = () {
|
..onTap = () {
|
||||||
openUrl(text);
|
openUrl(text);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ResultMatch {
|
class _ResultMatch {
|
||||||
|
|||||||
Reference in New Issue
Block a user