This commit is contained in:
lollipopkit
2023-09-13 14:28:02 +08:00
parent 6c84d2f52b
commit 278d5984b2
55 changed files with 528 additions and 481 deletions

View File

@@ -1,7 +1,7 @@
import 'package:dynamic_color/dynamic_color.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/core/extension/locale.dart';
import 'core/utils/ui.dart';

View File

@@ -0,0 +1,11 @@
import 'package:flutter/material.dart';
extension ContextX on BuildContext {
void pop<T extends Object?>([T? result]) {
Navigator.of(this).pop<T>(result);
}
bool get canPop => Navigator.of(this).canPop();
bool get isDark => Theme.of(this).brightness == Brightness.dark;
}

View File

@@ -1,55 +1,14 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/view/widget/rebuild.dart';
import 'package:toolbox/core/extension/context/common.dart';
import '../../data/model/server/snippet.dart';
import '../../data/provider/snippet.dart';
import '../../data/res/ui.dart';
import '../../locator.dart';
import '../../view/widget/input_field.dart';
import '../../view/widget/picker.dart';
import '../route.dart';
extension ContextX on BuildContext {
void pop<T extends Object?>([T? result]) {
Navigator.of(this).pop<T>(result);
}
bool get canPop => Navigator.of(this).canPop();
bool get isDark => Theme.of(this).brightness == Brightness.dark;
}
extension SnackBarX on BuildContext {
void showSnackBar(String text) =>
ScaffoldMessenger.of(this).showSnackBar(SnackBar(
content: Text(text),
behavior: SnackBarBehavior.floating,
));
void showSnackBarWithAction(
String content,
String action,
GestureTapCallback onTap,
) {
ScaffoldMessenger.of(this).showSnackBar(SnackBar(
content: Text(content),
behavior: SnackBarBehavior.floating,
action: SnackBarAction(
label: action,
onPressed: onTap,
),
));
}
void showRestartSnackbar({String? btn, String? msg}) {
showSnackBarWithAction(
msg ?? 'Need restart to take effect',
btn ?? 'Restart',
() => RebuildWidget.restartApp(this),
);
}
}
import '../../../data/model/server/snippet.dart';
import '../../../data/provider/snippet.dart';
import '../../../data/res/ui.dart';
import '../../../locator.dart';
import '../../../view/widget/input_field.dart';
import '../../../view/widget/picker.dart';
import '../../route.dart';
extension DialogX on BuildContext {
Future<T?> showRoundDialog<T>({
@@ -74,7 +33,7 @@ extension DialogX on BuildContext {
void showLoadingDialog({bool barrierDismiss = false}) {
showRoundDialog(
child: centerSizedLoading,
child: UIs.centerSizedLoading,
barrierDismiss: barrierDismiss,
);
}

View File

@@ -0,0 +1,33 @@
import 'package:flutter/material.dart';
import 'package:toolbox/view/widget/rebuild.dart';
extension SnackBarX on BuildContext {
void showSnackBar(String text) =>
ScaffoldMessenger.of(this).showSnackBar(SnackBar(
content: Text(text),
behavior: SnackBarBehavior.floating,
));
void showSnackBarWithAction(
String content,
String action,
GestureTapCallback onTap,
) {
ScaffoldMessenger.of(this).showSnackBar(SnackBar(
content: Text(content),
behavior: SnackBarBehavior.floating,
action: SnackBarAction(
label: action,
onPressed: onTap,
),
));
}
void showRestartSnackbar({String? btn, String? msg}) {
showSnackBarWithAction(
msg ?? 'Need restart to take effect',
btn ?? 'Restart',
() => RebuildWidget.restartApp(this),
);
}
}

View File

@@ -3,7 +3,7 @@ import 'dart:async';
import 'package:dartssh2/dartssh2.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/stringx.dart';
import 'package:toolbox/core/extension/uint8list.dart';
@@ -70,7 +70,7 @@ extension SSHClientX on SSHClient {
if (isRequestingPwd) return;
isRequestingPwd = true;
if (data.contains('[sudo] password for ')) {
final user = pwdRequestWithUserReg.firstMatch(data)?.group(1);
final user = Miscs.pwdRequestWithUserReg.firstMatch(data)?.group(1);
if (context == null) return;
final pwd = await context.showPwdDialog(user);
if (pwd == null || pwd.isEmpty) {

View File

@@ -4,7 +4,9 @@ import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:r_upgrade/r_upgrade.dart';
import 'package:toolbox/core/extension/context.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/model/app/update.dart';
import 'package:toolbox/data/res/logger.dart';
import 'package:toolbox/data/res/path.dart';
@@ -103,10 +105,8 @@ Future<void> _doUpdate(AppUpdate update, BuildContext context, S? s) async {
// rmdir Download
Future<void> _rmDownloadApks() async {
if (!isAndroid) return;
final dlDir = Directory(await _dlDir);
final dlDir = Directory(await Paths.dl);
if (await dlDir.exists()) {
await dlDir.delete(recursive: true);
}
}
Future<String> get _dlDir async => joinPath(await docDir, 'Download');

View File

@@ -29,7 +29,7 @@ class ICloud {
final completer = Completer<ICloudErr?>();
await ICloudStorage.upload(
containerId: _containerId,
filePath: localPath ?? '${await docDir}/$relativePath',
filePath: localPath ?? '${await Paths.doc}/$relativePath',
destinationRelativePath: relativePath,
onProgress: (stream) {
stream.listen(
@@ -73,7 +73,7 @@ class ICloud {
await ICloudStorage.download(
containerId: _containerId,
relativePath: relativePath,
destinationFilePath: localPath ?? '${await docDir}/$relativePath',
destinationFilePath: localPath ?? '${await Paths.doc}/$relativePath',
onProgress: (stream) {
stream.listen(
null,
@@ -122,7 +122,7 @@ class ICloud {
}
}));
final docPath = await docDir;
final docPath = await Paths.doc;
/// compare files in iCloud and local
mission.addAll(allFiles.map((file) async {
@@ -176,7 +176,7 @@ class ICloud {
static Future<void> syncDb() async {
if (!isIOS && !isMacOS) return;
final docPath = await docDir;
final docPath = await Paths.doc;
final dir = Directory(docPath);
final files = await dir.list().toList();
// filter out non-hive(db) files

View File

@@ -70,7 +70,7 @@ class Backup {
static Future<void> backup() async {
final result = _diyEncrtpt(json.encode(Backup.loadFromStore()));
await File(await backupPath).writeAsString(result);
await File(await Paths.bak).writeAsString(result);
}
Future<void> restore() async {

View File

@@ -1,6 +1,5 @@
import 'package:flutter/widgets.dart';
import '../../../core/extension/context.dart';
import 'package:toolbox/core/extension/context/common.dart';
class DynamicColor {
/// 白天模式显示的颜色

View File

@@ -1,7 +1,8 @@
import '../../res/build_data.dart';
import '../../res/server_cmd.dart';
import '../server/system.dart';
const seperator = 'SrvBoxSep';
const _cmdDivider = '\necho $seperator\n\t';
const _serverBoxDir = r'$HOME/.config/server_box';

View File

@@ -20,7 +20,7 @@ Conn? parseConn(String raw) {
final idx = lines.lastWhere((element) => element.startsWith('Tcp:'),
orElse: () => '');
if (idx != '') {
final vals = idx.split(numReg);
final vals = idx.split(Miscs.numReg);
return Conn(
maxConn: vals[5].i,
active: vals[6].i,

View File

@@ -27,7 +27,7 @@ List<Disk> parseDisk(String raw) {
if (item.isEmpty) {
continue;
}
final vals = item.split(numReg);
final vals = item.split(Miscs.numReg);
if (vals.length == 1) {
pathCache = vals[0];
continue;

View File

@@ -93,7 +93,7 @@ class Proc {
@override
String toString() {
return jsonEncoder.convert(toJson());
return Miscs.jsonEncoder.convert(toJson());
}
String get binary {

View File

@@ -52,9 +52,9 @@ class DebugProvider extends ChangeNotifier {
void _addWidget(Widget widget) {
widgets.add(widget);
widgets.add(height13);
if (widgets.length > maxDebugLogLines) {
widgets.removeRange(0, widgets.length - maxDebugLogLines);
widgets.add(UIs.height13);
if (widgets.length > Miscs.maxDebugLogLines) {
widgets.removeRange(0, widgets.length - Miscs.maxDebugLogLines);
}
notifyListeners();
}

View File

@@ -12,8 +12,6 @@ import 'package:toolbox/data/res/logger.dart';
import 'package:toolbox/data/store/docker.dart';
import 'package:toolbox/locator.dart';
import '../res/server_cmd.dart';
final _dockerNotFound = RegExp(r'command not found|Unknown command');
final _versionReg = RegExp(r'(Version:)\s+([0-9]+\.[0-9]+\.[0-9]+)');
// eg: `Docker Engine - Community`

View File

@@ -14,7 +14,6 @@ import '../model/server/server_private_info.dart';
import '../model/server/server_status_update_req.dart';
import '../model/server/snippet.dart';
import '../model/server/try_limiter.dart';
import '../res/server_cmd.dart';
import '../res/status.dart';
import '../store/server.dart';
import '../store/setting.dart';

View File

@@ -4,6 +4,8 @@ import '../model/app/dynamic_color.dart';
late Color primaryColor;
const contentColor = DynamicColor(Colors.black87, Colors.white70);
const bgColor = DynamicColor(Colors.white, Colors.black);
const progressColor = DynamicColor(Colors.black12, Colors.white10);
class DynamicColors {
static const content = DynamicColor(Colors.black87, Colors.white70);
static const bg = DynamicColor(Colors.white, Colors.black);
static const progress = DynamicColor(Colors.black12, Colors.white10);
}

View File

@@ -2,8 +2,9 @@ import 'dart:ui';
import 'package:toolbox/data/model/ssh/virtual_key.dart';
class Defaults {
// default server details page cards order
const defaultDetailCardOrder = [
static const detailCardOrder = [
'uptime',
'cpu',
'mem',
@@ -13,7 +14,7 @@ const defaultDetailCardOrder = [
'temp'
];
const defaultDiskIgnorePath = [
static const diskIgnorePath = [
'udev',
'tmpfs',
'devtmpfs',
@@ -22,7 +23,7 @@ const defaultDiskIgnorePath = [
'none',
];
const defaultSSHVirtKeys = [
static const sshVirtKeys = [
VirtKey.esc,
VirtKey.alt,
VirtKey.home,
@@ -39,11 +40,12 @@ const defaultSSHVirtKeys = [
VirtKey.ime,
];
const defaultPrimaryColor = Color.fromARGB(255, 145, 58, 31);
static const primaryColor = Color.fromARGB(255, 145, 58, 31);
const defaultLaunchPageIdx = 0;
static const launchPageIdx = 0;
const defaultUpdateInterval = 3;
static const updateInterval = 3;
const defaultEditorTheme = 'a11y-light';
const defaultEditorDarkTheme = 'monokai';
static const editorTheme = 'a11y-light';
static const editorDarkTheme = 'monokai';
}

View File

@@ -0,0 +1,38 @@
import 'package:toolbox/data/model/app/github_id.dart';
class GithubIds {
// Thanks
// If you want to change the url, please open an issue.
static const contributors = <GhId>{
'its-tom',
'RainSunMe',
'kalashnikov',
'azkadev',
'calvinweb',
'Liloupar'
};
static const participants = <GhId>{
'jaychoubaby',
'fecture',
'Tao173',
'QingAnLe',
'wxdjs',
'Aeorq',
'allonmymind',
'Yuuki-Rin',
'LittleState',
'karuboniru',
'whosphp',
'Climit',
'dianso',
'Jasondeepny',
'kaliwell',
'ymxkiss',
'Ealrang',
'hange33',
'yuchen1204',
'xgzxmytx',
'wind057',
'a1564471347',
};
}

View File

@@ -1,4 +1,3 @@
import 'package:highlight/highlight_core.dart';
import 'package:highlight/languages/accesslog.dart';
import 'package:highlight/languages/awk.dart';
import 'package:highlight/languages/bash.dart';
@@ -33,9 +32,10 @@ import 'package:highlight/languages/vim.dart';
import 'package:highlight/languages/xml.dart';
import 'package:highlight/languages/yaml.dart';
// KEY: fileNameSuffix
// VAL: highlight
final suffix2HighlightMap = {
class Highlights {
/// - KEY: fileNameSuffix
/// - VAL: highlight
static final all = {
'dart': dart,
'go': go,
'rust': rust,
@@ -72,13 +72,8 @@ final suffix2HighlightMap = {
'plaintext': plaintext,
};
extension HighlightString on String? {
Mode? get highlight {
return suffix2HighlightMap[highlightCode];
}
String? get highlightCode {
if (this == null) return null;
return this!.split('.').last;
static String? getCode(String? fileName) {
if (fileName == null) return null;
return fileName.split('.').last;
}
}

View File

@@ -2,61 +2,26 @@ import 'dart:convert';
import 'package:flutter/services.dart';
import '../model/app/github_id.dart';
class Miscs {
/// RegExp for number
final numReg = RegExp(r'\s{1,}');
static final numReg = RegExp(r'\s{1,}');
/// RegExp for password request
final pwdRequestWithUserReg = RegExp(r'\[sudo\] password for (.+):');
static final pwdRequestWithUserReg = RegExp(r'\[sudo\] password for (.+):');
/// Private Key max allowed size is 20kb
const privateKeyMaxSize = 20 * 1024;
static const privateKeyMaxSize = 20 * 1024;
// Editor max allowed size is 1mb
const editorMaxSize = 1024 * 1024;
static const editorMaxSize = 1024 * 1024;
/// Max debug log lines
const maxDebugLogLines = 100;
static const maxDebugLogLines = 100;
/// Method Channels
const pkgName = 'tech.lolli.toolbox';
const bgRunChannel = MethodChannel('$pkgName/app_retain');
const homeWidgetChannel = MethodChannel('$pkgName/home_widget');
static const pkgName = 'tech.lolli.toolbox';
static const bgRunChannel = MethodChannel('$pkgName/app_retain');
static const homeWidgetChannel = MethodChannel('$pkgName/home_widget');
// Thanks
// If you want to change the url, please open an issue.
const contributors = <GhId>{
'its-tom',
'RainSunMe',
'kalashnikov',
'azkadev',
'calvinweb',
'Liloupar'
};
const participants = <GhId>{
'jaychoubaby',
'fecture',
'Tao173',
'QingAnLe',
'wxdjs',
'Aeorq',
'allonmymind',
'Yuuki-Rin',
'LittleState',
'karuboniru',
'whosphp',
'Climit',
'dianso',
'Jasondeepny',
'kaliwell',
'ymxkiss',
'Ealrang',
'hange33',
'yuchen1204',
'xgzxmytx',
'wind057',
'a1564471347',
};
const jsonEncoder = JsonEncoder.withIndent(' ');
static const jsonEncoder = JsonEncoder.withIndent(' ');
}

View File

@@ -3,11 +3,12 @@ import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:toolbox/core/utils/platform.dart';
String? _docDir;
String? _sftpDir;
String? _fontDir;
class Paths {
static String? _docDir;
static String? _sftpDir;
static String? _fontDir;
Future<String> get docDir async {
static Future<String> get doc async {
if (_docDir != null) {
return _docDir!;
}
@@ -24,24 +25,27 @@ Future<String> get docDir async {
return dir.path;
}
Future<String> get sftpDir async {
static Future<String> get sftp async {
if (_sftpDir != null) {
return _sftpDir!;
}
_sftpDir = '${await docDir}/sftp';
_sftpDir = '${await doc}/sftp';
final dir = Directory(_sftpDir!);
await dir.create(recursive: true);
return _sftpDir!;
}
Future<String> get fontDir async {
static Future<String> get font async {
if (_fontDir != null) {
return _fontDir!;
}
_fontDir = '${await docDir}/font';
_fontDir = '${await doc}/font';
final dir = Directory(_fontDir!);
await dir.create(recursive: true);
return _fontDir!;
}
Future<String> get backupPath async => '${await docDir}/srvbox_bak.json';
static Future<String> get bak async => '${await doc}/srvbox_bak.json';
static Future<String> get dl async => joinPath(await doc, 'dl');
}

View File

@@ -1 +0,0 @@
const seperator = 'SrvBoxSep';

View File

@@ -1,39 +1,41 @@
import 'package:flutter/material.dart';
class UIs {
/// Font style
const textSize9Grey = TextStyle(color: Colors.grey, fontSize: 9);
const textSize11 = TextStyle(fontSize: 11);
const textSize11Grey = TextStyle(color: Colors.grey, fontSize: 11);
const textSize13 = TextStyle(fontSize: 13);
const textSize13Bold = TextStyle(fontSize: 13, fontWeight: FontWeight.bold);
const textSize13Grey = TextStyle(color: Colors.grey, fontSize: 13);
const textSize15 = TextStyle(fontSize: 15);
const textSize18 = TextStyle(fontSize: 18);
const textSize27 = TextStyle(fontSize: 27);
const grey = TextStyle(color: Colors.grey);
const textRed = TextStyle(color: Colors.red);
static const textSize9Grey = TextStyle(color: Colors.grey, fontSize: 9);
static const textSize11 = TextStyle(fontSize: 11);
static const textSize11Grey = TextStyle(color: Colors.grey, fontSize: 11);
static const textSize13 = TextStyle(fontSize: 13);
static const textSize13Bold =
TextStyle(fontSize: 13, fontWeight: FontWeight.bold);
static const textSize13Grey = TextStyle(color: Colors.grey, fontSize: 13);
static const textSize15 = TextStyle(fontSize: 15);
static const textSize18 = TextStyle(fontSize: 18);
static const textSize27 = TextStyle(fontSize: 27);
static const textGrey = TextStyle(color: Colors.grey);
static const textRed = TextStyle(color: Colors.red);
/// Icon
final appIcon = Image.asset('assets/app_icon.png');
static final appIcon = Image.asset('assets/app_icon.png');
/// Padding
const roundRectCardPadding = EdgeInsets.symmetric(horizontal: 17, vertical: 13);
static const roundRectCardPadding =
EdgeInsets.symmetric(horizontal: 17, vertical: 13);
/// SizedBox
const placeholder = SizedBox();
const height13 = SizedBox(height: 13);
const height77 = SizedBox(height: 77);
const width13 = SizedBox(width: 13);
const width7 = SizedBox(width: 7);
static const placeholder = SizedBox();
static const height13 = SizedBox(height: 13);
static const height77 = SizedBox(height: 77);
static const width13 = SizedBox(width: 13);
static const width7 = SizedBox(width: 7);
/// Misc
const popMenuChild = Padding(
static const popMenuChild = Padding(
padding: EdgeInsets.only(left: 7),
child: Icon(
Icons.more_vert,
@@ -41,12 +43,13 @@ const popMenuChild = Padding(
),
);
const centerLoading = Center(child: CircularProgressIndicator());
static const centerLoading = Center(child: CircularProgressIndicator());
const centerSizedLoading = SizedBox(
static const centerSizedLoading = SizedBox(
width: 77,
height: 77,
child: Center(
child: CircularProgressIndicator(),
),
);
}

View File

@@ -1,4 +1,6 @@
const baseResUrl = 'https://res.lolli.tech/serverbox';
const myGithub = 'https://github.com/lollipopkit';
const appHelpUrl = '$myGithub/flutter_server_box#-help';
const appWikiUrl = '$myGithub/flutter_server_box/wiki';
class Urls {
static const resBase = 'https://res.lolli.tech/serverbox';
static const myGithub = 'https://github.com/lollipopkit';
static const appHelp = '$myGithub/flutter_server_box#-help';
static const appWiki = '$myGithub/flutter_server_box/wiki';
}

View File

@@ -5,7 +5,7 @@ import '../res/url.dart';
class AppService {
Future<AppUpdate> getUpdate() async {
final resp = await Dio().get('$baseResUrl/update.json');
final resp = await Dio().get('${Urls.resBase}/update.json');
return AppUpdate.fromJson(resp.data);
}
}

View File

@@ -52,12 +52,12 @@ class SettingStore extends PersistentStore {
late final launchPage = StoreProperty(
box,
'launchPage',
defaultLaunchPageIdx,
Defaults.launchPageIdx,
);
/// Server detail disk ignore path
late final diskIgnorePath =
StoreListProperty(box, 'diskIgnorePath', defaultDiskIgnorePath);
StoreListProperty(box, 'diskIgnorePath', Defaults.diskIgnorePath);
/// Use double column servers page on Desktop
late final doubleColumnServersPage = StoreProperty(
@@ -77,7 +77,7 @@ class SettingStore extends PersistentStore {
late final serverStatusUpdateInterval = StoreProperty(
box,
'serverStatusUpdateInterval',
defaultUpdateInterval,
Defaults.updateInterval,
);
// Max retry count when connect to server
@@ -99,7 +99,7 @@ class SettingStore extends PersistentStore {
// Server details page cards order
late final detailCardOrder =
StoreListProperty(box, 'detailCardPrder', defaultDetailCardOrder);
StoreListProperty(box, 'detailCardPrder', Defaults.detailCardOrder);
// SSH term font size
late final termFontSize = StoreProperty(box, 'termFontSize', 13.0);
@@ -117,13 +117,13 @@ class SettingStore extends PersistentStore {
late final editorTheme = StoreProperty(
box,
'editorTheme',
defaultEditorTheme,
Defaults.editorTheme,
);
late final editorDarkTheme = StoreProperty(
box,
'editorDarkTheme',
defaultEditorDarkTheme,
Defaults.editorDarkTheme,
);
late final fullScreen = StoreProperty(
@@ -153,7 +153,7 @@ class SettingStore extends PersistentStore {
late final sshVirtKeys = StoreListProperty(
box,
'sshVirtKeys',
defaultSSHVirtKeys,
Defaults.sshVirtKeys,
);
late final netViewType = StoreProperty(

View File

@@ -100,7 +100,7 @@ Future<void> initApp() async {
if (isAndroid) {
// Only start service when [bgRun] is true.
if (locator<SettingStore>().bgRun.fetch()) {
bgRunChannel.invokeMethod('startService');
Miscs.bgRunChannel.invokeMethod('startService');
}
// SharedPreferences is only used on Android for saving home widgets settings.
SharedPreferences.setPrefix('');

View File

@@ -4,7 +4,9 @@ import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/core/extension/context.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/core/utils/platform.dart';
import 'package:toolbox/data/model/app/backup.dart';
import 'package:toolbox/data/res/logger.dart';
@@ -28,7 +30,7 @@ class BackupPage extends StatelessWidget {
final s = S.of(context)!;
return Scaffold(
appBar: CustomAppBar(
title: Text(s.backupAndRestore, style: textSize18),
title: Text(s.backupAndRestore, style: UIs.textSize18),
),
body: _buildBody(context, s),
);
@@ -40,7 +42,7 @@ class BackupPage extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
if (isMacOS || isIOS) _buildIcloudSync(context, s),
height13,
UIs.height13,
Padding(
padding: const EdgeInsets.all(37),
child: Text(
@@ -48,24 +50,24 @@ class BackupPage extends StatelessWidget {
textAlign: TextAlign.center,
),
),
height77,
UIs.height77,
_buildCard(
s.restore,
Icons.download,
() => _onRestore(context, s),
),
height13,
UIs.height13,
const SizedBox(
width: 37,
child: Divider(),
),
height13,
UIs.height13,
_buildCard(
s.backup,
Icons.save,
() async {
await Backup.backup();
await shareFiles(context, [await backupPath]);
await shareFiles(context, [await Paths.bak]);
},
)
],
@@ -87,7 +89,7 @@ class BackupPage extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, size: 20),
width7,
UIs.width7,
Text(text),
],
),
@@ -104,7 +106,7 @@ class BackupPage extends StatelessWidget {
'iCloud',
textAlign: TextAlign.center,
),
width13,
UIs.width13,
// Hive db only save data into local file after app exit,
// so this button is useless
// IconButton(

View File

@@ -3,7 +3,7 @@ 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.dart';
import 'package:toolbox/core/extension/context/snackbar.dart';
import 'package:toolbox/data/res/ui.dart';
import 'package:toolbox/view/widget/value_notifier.dart';
@@ -61,7 +61,7 @@ class _ConvertPageState extends State<ConvertPage>
controller: ScrollController(),
child: Column(
children: [
height13,
UIs.height13,
_buildInputTop(),
_buildMiddleBtns(),
_buildResult(),

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/data/provider/debug.dart';
import '../widget/custom_appbar.dart';

View File

@@ -1,7 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:provider/provider.dart';
import 'package:toolbox/core/extension/context.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/core/route.dart';
import 'package:toolbox/data/model/docker/image.dart';
import 'package:toolbox/view/widget/input_field.dart';
@@ -214,7 +216,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
_docker.refresh();
}
});
return centerLoading;
return UIs.centerLoading;
}
final items = <Widget>[
@@ -236,7 +238,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
title: Text(_s.imagesList),
subtitle: Text(
_s.dockerImagesFmt(_docker.images!.length),
style: grey,
style: UIs.textGrey,
),
),
];
@@ -247,7 +249,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
Widget _buildImageItem(DockerImage e) {
return ListTile(
title: Text(e.repo),
subtitle: Text('${e.tag} - ${e.size}', style: grey),
subtitle: Text('${e.tag} - ${e.size}', style: UIs.textGrey),
trailing: IconButton(
padding: EdgeInsets.zero,
alignment: Alignment.centerRight,
@@ -276,14 +278,14 @@ class _DockerManagePageState extends State<DockerManagePage> {
context.showSnackBar(result.message ?? _s.unknownError);
}
},
child: Text(_s.ok, style: textRed),
child: Text(_s.ok, style: UIs.textRed),
),
],
);
}
Widget _buildLoading() {
if (_docker.runLog == null) return placeholder;
if (_docker.runLog == null) return UIs.placeholder;
return Padding(
padding: const EdgeInsets.all(17),
child: Column(
@@ -291,7 +293,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
const Center(
child: CircularProgressIndicator(),
),
height13,
UIs.height13,
Text(_docker.runLog ?? '...'),
],
),
@@ -309,7 +311,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
return Text(_s.waitConnection);
case DockerErrType.invalidVersion:
return UrlText(
text: _s.invalidVersionHelp(appHelpUrl),
text: _s.invalidVersionHelp(Urls.appHelp),
replace: 'Github',
);
case DockerErrType.parseImages:
@@ -344,7 +346,10 @@ class _DockerManagePageState extends State<DockerManagePage> {
final items = <Widget>[
ListTile(
title: Text(_s.containerStatus),
subtitle: Text(_buildPsCardSubtitle(_docker.items!), style: grey),
subtitle: Text(
_buildPsCardSubtitle(_docker.items!),
style: UIs.textGrey,
),
),
];
items.addAll(_docker.items!.map(_buildPsItem));
@@ -359,7 +364,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
title: Text(item.image),
subtitle: Text(
'${item.name} - ${item.status}',
style: textSize13Grey,
style: UIs.textSize13Grey,
),
trailing: _buildMoreBtn(item),
);

View File

@@ -7,7 +7,8 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter_highlight/theme_map.dart';
import 'package:flutter_highlight/themes/a11y-light.dart';
import 'package:flutter_highlight/themes/monokai.dart';
import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/utils/misc.dart';
import 'package:toolbox/data/res/highlight.dart';
import 'package:toolbox/data/store/setting.dart';
@@ -58,9 +59,9 @@ class _EditorPageState extends State<EditorPage> {
super.initState();
/// Higher priority than [path]
_langCode = widget.langCode ?? widget.path.highlightCode;
_langCode = widget.langCode ?? Highlights.getCode(widget.path);
_controller = CodeController(
language: suffix2HighlightMap[_langCode],
language: Highlights.all[_langCode],
);
/// TODO: This is a temporary solution to avoid the loading stuck
@@ -131,12 +132,12 @@ class _EditorPageState extends State<EditorPage> {
PopupMenuButton<String>(
icon: const Icon(Icons.language),
onSelected: (value) {
_controller.language = suffix2HighlightMap[value];
_controller.language = Highlights.all[value];
_langCode = value;
},
initialValue: _langCode,
itemBuilder: (BuildContext context) {
return suffix2HighlightMap.keys.map((e) {
return Highlights.all.keys.map((e) {
return PopupMenuItem(
value: e,
child: Text(e),

View File

@@ -213,7 +213,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
height13,
UIs.height13,
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
@@ -232,7 +232,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
)
],
),
height13,
UIs.height13,
_buildTopRightText(ss, cs),
],
),
@@ -248,7 +248,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
);
return Text(
topRightStr,
style: textSize11Grey,
style: UIs.textSize11Grey,
textScaleFactor: 1.0,
);
}

View File

@@ -4,7 +4,8 @@ import 'package:after_layout/after_layout.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:get_it/get_it.dart';
import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/data/res/github_id.dart';
import 'package:toolbox/data/res/logger.dart';
import '../../core/analysis.dart';
@@ -93,7 +94,7 @@ class _HomePageState extends State<HomePage>
// Keep running in background on Android device
if (isAndroid && _setting.bgRun.fetch()) {
if (_app.moveBg) {
bgRunChannel.invokeMethod('sendToBackground');
Miscs.bgRunChannel.invokeMethod('sendToBackground');
}
} else {
_serverProvider.setDisconnected();
@@ -214,7 +215,7 @@ class _HomePageState extends State<HomePage>
child: Text(
'${BuildData.name}\n$_versionStr',
textAlign: TextAlign.center,
style: textSize13,
style: UIs.textSize13,
),
),
const SizedBox(height: 37),
@@ -271,11 +272,11 @@ class _HomePageState extends State<HomePage>
child: _buildAboutContent(),
actions: [
TextButton(
onPressed: () => openUrl(appWikiUrl),
onPressed: () => openUrl(Urls.appWiki),
child: const Text('Wiki'),
),
TextButton(
onPressed: () => openUrl(appHelpUrl),
onPressed: () => openUrl(Urls.appHelp),
child: Text(_s.feedback),
),
TextButton(
@@ -293,23 +294,23 @@ class _HomePageState extends State<HomePage>
crossAxisAlignment: CrossAxisAlignment.start,
children: [
UrlText(
text: _s.madeWithLove(myGithub),
text: _s.madeWithLove(Urls.myGithub),
replace: 'lollipopkit',
),
height13,
UIs.height13,
// Use [UrlText] for same text style
Text(_s.aboutThanks),
height13,
UIs.height13,
const Text('Contributors:'),
...contributors.map(
...GithubIds.contributors.map(
(name) => UrlText(
text: name.url,
replace: name,
),
),
height13,
UIs.height13,
const Text('Participants:'),
...participants.map(
...GithubIds.participants.map(
(name) => UrlText(
text: name.url,
replace: name,
@@ -323,7 +324,7 @@ class _HomePageState extends State<HomePage>
Widget _buildIcon() {
return ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 57, maxWidth: 57),
child: appIcon,
child: UIs.appIcon,
);
}
@@ -354,7 +355,7 @@ class _HomePageState extends State<HomePage>
void updateHomeWidget() {
if (_setting.autoUpdateHomeWidget.fetch()) {
homeWidgetChannel.invokeMethod('update');
Miscs.homeWidgetChannel.invokeMethod('update');
}
}
@@ -362,7 +363,7 @@ class _HomePageState extends State<HomePage>
/// Encode [map] to String with indent `\t`
final map = _setting.toJson();
final keys = map.keys;
final text = jsonEncoder.convert(map);
final text = Miscs.jsonEncoder.convert(map);
final result = await AppRoute.editor(
text: text,
langCode: 'json',

View File

@@ -3,7 +3,9 @@ import 'dart:async';
import 'package:after_layout/after_layout.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/core/extension/context.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/core/utils/misc.dart';
import 'package:toolbox/view/widget/value_notifier.dart';
@@ -140,7 +142,7 @@ class _PingPageState extends State<PingPage>
),
subtitle: Text(
_buildPingSummary(result, unknown, ms),
style: textSize11,
style: UIs.textSize11,
),
trailing: Text(
'${_s.pingAvg}${result.statistic?.avg?.toStringAsFixed(2) ?? _s.unknown} $ms',

View File

@@ -4,7 +4,9 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/core/extension/context.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/core/extension/numx.dart';
import 'package:toolbox/core/utils/misc.dart';
import 'package:toolbox/data/res/misc.dart';
@@ -103,7 +105,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
},
child: Text(
_s.ok,
style: textRed,
style: UIs.textRed,
),
),
],
@@ -113,7 +115,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
)
];
return CustomAppBar(
title: Text(_s.edit, style: textSize18),
title: Text(_s.edit, style: UIs.textSize18),
actions: widget.pki == null ? null : actions,
);
}
@@ -131,7 +133,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
}
FocusScope.of(context).unfocus();
setState(() {
_loading = centerSizedLoading;
_loading = UIs.centerSizedLoading;
});
try {
final decrypted = await compute(decyptPem, [key, pwd]);
@@ -192,12 +194,12 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
return;
}
final size = (await file.stat()).size;
if (size > privateKeyMaxSize) {
if (size > Miscs.privateKeyMaxSize) {
context.showSnackBar(
_s.fileTooLarge(
path,
size.convertBytes,
privateKeyMaxSize.convertBytes,
Miscs.privateKeyMaxSize.convertBytes,
),
);
return;
@@ -216,7 +218,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
icon: Icons.password,
),
SizedBox(height: MediaQuery.of(context).size.height * 0.1),
_loading ?? placeholder,
_loading ?? UIs.placeholder,
],
);
}

View File

@@ -4,7 +4,8 @@ import 'package:after_layout/after_layout.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:provider/provider.dart';
import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/data/store/private_key.dart';
import 'package:toolbox/locator.dart';
@@ -37,7 +38,7 @@ class _PrivateKeyListState extends State<PrivateKeysListPage>
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: Text(_s.privateKey, style: textSize18),
title: Text(_s.privateKey, style: UIs.textSize18),
),
body: _buildBody(),
floatingActionButton: FloatingActionButton(
@@ -70,7 +71,7 @@ class _PrivateKeyListState extends State<PrivateKeysListPage>
),
),
title: Text(item.id),
subtitle: Text(item.type ?? _s.unknown, style: grey),
subtitle: Text(item.type ?? _s.unknown, style: UIs.textGrey),
onTap: () => AppRoute.keyEdit(pki: item).go(context),
trailing: const Icon(Icons.edit),
),

View File

@@ -3,7 +3,9 @@ import 'dart:async';
import 'package:dartssh2/dartssh2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/core/extension/context.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/core/extension/uint8list.dart';
import 'package:toolbox/core/utils/misc.dart';
@@ -126,7 +128,7 @@ class _ProcessPageState extends State<ProcessPage> {
}
Widget child;
if (_result.procs.isEmpty) {
child = centerLoading;
child = UIs.centerLoading;
} else {
child = ListView.builder(
itemCount: _result.procs.length,
@@ -157,7 +159,7 @@ class _ProcessPageState extends State<ProcessPage> {
title: Text(proc.binary),
subtitle: Text(
proc.command,
style: grey,
style: UIs.textGrey,
maxLines: 3,
overflow: TextOverflow.fade,
),
@@ -198,7 +200,7 @@ class _ProcessPageState extends State<ProcessPage> {
up: proc.cpu!.toStringAsFixed(1),
down: 'cpu',
),
width13,
UIs.width13,
if (proc.mem != null)
TwoLineText(
up: proc.mem!.toStringAsFixed(1),

View File

@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:provider/provider.dart';
import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/core/extension/order.dart';
import 'package:toolbox/data/model/server/cpu.dart';
import 'package:toolbox/data/model/server/server_private_info.dart';
@@ -41,7 +41,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
late final _textFactor = _setting.textFactor.fetch();
late final _cardBuildMap = Map.fromIterables(
defaultDetailCardOrder,
Defaults.detailCardOrder,
[
_buildUpTimeAndSys,
_buildCPUView,
@@ -85,7 +85,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
final buildFuncs = !_setting.moveOutServerTabFuncBtns.fetch();
return Scaffold(
appBar: CustomAppBar(
title: Text(si.spi.name, style: textSize18),
title: Text(si.spi.name, style: UIs.textSize18),
actions: [
IconButton(
icon: const Icon(Icons.edit),
@@ -120,21 +120,21 @@ class _ServerDetailPageState extends State<ServerDetailPage>
final percent = ss.cpu.usedPercent(coreIdx: 0).toInt();
final details = [
_buildDetailPercent(ss.cpu.user, 'user'),
width13,
UIs.width13,
_buildDetailPercent(ss.cpu.idle, 'idle')
];
if (ss.system == SystemType.linux) {
details.addAll([
width13,
UIs.width13,
_buildDetailPercent(ss.cpu.sys, 'sys'),
width13,
UIs.width13,
_buildDetailPercent(ss.cpu.iowait, 'io'),
]);
}
return RoundRectCard(
Padding(
padding: roundRectCardPadding,
padding: UIs.roundRectCardPadding,
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -142,14 +142,14 @@ class _ServerDetailPageState extends State<ServerDetailPage>
_buildAnimatedText(
ValueKey(percent),
'$percent%',
textSize27,
UIs.textSize27,
),
Row(
children: details,
)
],
),
height13,
UIs.height13,
_buildCPUProgress(ss.cpu)
]),
),
@@ -196,7 +196,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
return LinearProgressIndicator(
value: percentWithinOne,
minHeight: 7,
backgroundColor: progressColor.resolve(context),
backgroundColor: DynamicColors.progress.resolve(context),
color: primaryColor,
);
}
@@ -204,14 +204,18 @@ class _ServerDetailPageState extends State<ServerDetailPage>
Widget _buildUpTimeAndSys(ServerStatus ss) {
return RoundRectCard(
Padding(
padding: roundRectCardPadding,
padding: UIs.roundRectCardPadding,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(ss.sysVer, style: textSize11, textScaleFactor: _textFactor),
Text(
ss.sysVer,
style: UIs.textSize11,
textScaleFactor: _textFactor,
),
Text(
ss.uptime,
style: textSize11,
style: UIs.textSize11,
textScaleFactor: _textFactor,
),
],
@@ -228,7 +232,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
return RoundRectCard(
Padding(
padding: roundRectCardPadding,
padding: UIs.roundRectCardPadding,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
@@ -241,23 +245,25 @@ class _ServerDetailPageState extends State<ServerDetailPage>
_buildAnimatedText(
ValueKey(usedStr),
'$usedStr%',
textSize27,
UIs.textSize27,
),
width7,
Text('of ${(ss.mem.total * 1024).convertBytes}',
style: textSize13Grey)
UIs.width7,
Text(
'of ${(ss.mem.total * 1024).convertBytes}',
style: UIs.textSize13Grey,
)
],
),
Row(
children: [
_buildDetailPercent(free, 'free'),
width13,
UIs.width13,
_buildDetailPercent(avail, 'avail'),
],
),
],
),
height13,
UIs.height13,
_buildProgress(used)
],
),
@@ -266,12 +272,12 @@ class _ServerDetailPageState extends State<ServerDetailPage>
}
Widget _buildSwapView(ServerStatus ss) {
if (ss.swap.total == 0) return placeholder;
if (ss.swap.total == 0) return UIs.placeholder;
final used = ss.swap.usedPercent * 100;
final cached = ss.swap.cached / ss.swap.total * 100;
return RoundRectCard(
Padding(
padding: roundRectCardPadding,
padding: UIs.roundRectCardPadding,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
@@ -281,16 +287,18 @@ class _ServerDetailPageState extends State<ServerDetailPage>
children: [
Row(
children: [
Text('${used.toStringAsFixed(0)}%', style: textSize27),
width7,
Text('of ${(ss.swap.total * 1024).convertBytes} ',
style: textSize13Grey)
Text('${used.toStringAsFixed(0)}%', style: UIs.textSize27),
UIs.width7,
Text(
'of ${(ss.swap.total * 1024).convertBytes} ',
style: UIs.textSize13Grey,
)
],
),
_buildDetailPercent(cached, 'cached'),
],
),
height13,
UIs.height13,
_buildProgress(used)
],
),
@@ -317,12 +325,12 @@ class _ServerDetailPageState extends State<ServerDetailPage>
children: [
Text(
'${disk.usedPercent}% of ${disk.size}',
style: textSize11,
style: UIs.textSize11,
textScaleFactor: _textFactor,
),
Text(
disk.path,
style: textSize11,
style: UIs.textSize11,
textScaleFactor: _textFactor,
)
],
@@ -334,7 +342,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
.toList();
return RoundRectCard(
Padding(
padding: roundRectCardPadding,
padding: UIs.roundRectCardPadding,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: children,
@@ -364,7 +372,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
return RoundRectCard(
Padding(
padding: roundRectCardPadding,
padding: UIs.roundRectCardPadding,
child: Column(
children: children,
),
@@ -397,7 +405,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
width: width,
child: Text(
device,
style: textSize11,
style: UIs.textSize11,
textScaleFactor: _textFactor,
maxLines: 1,
overflow: TextOverflow.ellipsis,
@@ -407,7 +415,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
width: width,
child: Text(
'${ns.speedIn(device: device)} | ${ns.sizeIn(device: device)}',
style: textSize11,
style: UIs.textSize11,
textAlign: TextAlign.center,
textScaleFactor: 0.87 * _textFactor,
),
@@ -416,7 +424,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
width: width,
child: Text(
'${ns.speedOut(device: device)} | ${ns.sizeOut(device: device)}',
style: textSize11,
style: UIs.textSize11,
textAlign: TextAlign.right,
textScaleFactor: 0.87 * _textFactor,
),
@@ -429,7 +437,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
Widget _buildTemperature(ServerStatus ss) {
final temps = ss.temps;
if (temps.isEmpty) {
return placeholder;
return UIs.placeholder;
}
final List<Widget> children = [
const Row(
@@ -449,19 +457,19 @@ class _ServerDetailPageState extends State<ServerDetailPage>
children: [
Text(
key,
style: textSize11,
style: UIs.textSize11,
textScaleFactor: _textFactor,
),
Text(
'${temps.get(key)}°C',
style: textSize11,
style: UIs.textSize11,
textScaleFactor: _textFactor,
),
],
)));
return RoundRectCard(
Padding(
padding: roundRectCardPadding,
padding: UIs.roundRectCardPadding,
child: Column(children: children),
),
);

View File

@@ -1,7 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:provider/provider.dart';
import 'package:toolbox/core/extension/context.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 '../../../core/route.dart';
import '../../../data/model/server/private_key_info.dart';
@@ -123,7 +125,7 @@ class _ServerEditPageState extends State<ServerEditPage> {
context.pop();
context.pop(true);
},
child: Text(_s.ok, style: textRed),
child: Text(_s.ok, style: UIs.textRed),
),
],
);
@@ -132,7 +134,7 @@ class _ServerEditPageState extends State<ServerEditPage> {
);
final actions = widget.spi != null ? [delBtn] : null;
return CustomAppBar(
title: Text(_s.edit, style: textSize18),
title: Text(_s.edit, style: UIs.textSize18),
actions: actions,
);
}
@@ -271,7 +273,7 @@ class _ServerEditPageState extends State<ServerEditPage> {
subtitle: Text(
e.type ?? _s.unknown,
textAlign: TextAlign.start,
style: grey,
style: UIs.textGrey,
),
trailing: _buildRadio(index, e),
);

View File

@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:get_it/get_it.dart';
import 'package:provider/provider.dart';
import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/media_queryx.dart';
import 'package:toolbox/core/extension/ssh_client.dart';
import 'package:toolbox/data/model/app/shell_func.dart';
@@ -127,7 +127,7 @@ class _ServerPageState extends State<ServerPage>
if (index == 0 && buildTags) return _buildTagsSwitcher(provider);
// Issue #130
if (index == count - 1) return height77;
if (index == count - 1) return UIs.height77;
if (buildTags) index--;
return _buildEachServerCard(provider.servers[filtered[index]]);
@@ -173,7 +173,7 @@ class _ServerPageState extends State<ServerPage>
Widget _buildEachServerCard(Server? si) {
if (si == null) {
return placeholder;
return UIs.placeholder;
}
return RoundRectCard(
@@ -243,7 +243,7 @@ class _ServerPageState extends State<ServerPage>
List<Widget> _buildFlipedCard(Server srv) {
return [
height13,
UIs.height13,
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
@@ -273,7 +273,7 @@ class _ServerPageState extends State<ServerPage>
List<Widget> _buildNormalCard(ServerStatus ss, ServerPrivateInfo spi) {
final rootDisk = findRootDisk(ss.disk);
return [
height13,
UIs.height13,
Padding(
padding: const EdgeInsets.symmetric(horizontal: 13),
child: Row(
@@ -289,7 +289,7 @@ class _ServerPageState extends State<ServerPage>
],
),
),
height13,
UIs.height13,
if (_setting.moveOutServerTabFuncBtns.fetch() &&
// Discussion #146
!_setting.serverTabUseOldUI.fetch())
@@ -330,7 +330,7 @@ class _ServerPageState extends State<ServerPage>
children: [
Text(
spi.name,
style: textSize13Bold,
style: UIs.textSize13Bold,
textScaleFactor: 1.0,
),
const Icon(
@@ -363,14 +363,14 @@ class _ServerPageState extends State<ServerPage>
onTap: () => _showFailReason(ss),
child: Text(
_s.viewErr,
style: textSize11Grey,
style: UIs.textSize11Grey,
textScaleFactor: 1.0,
),
);
}
return Text(
topRightStr,
style: textSize11Grey,
style: UIs.textSize11Grey,
textScaleFactor: 1.0,
);
}
@@ -409,14 +409,14 @@ class _ServerPageState extends State<ServerPage>
const SizedBox(height: 5),
Text(
up,
style: textSize9Grey,
style: UIs.textSize9Grey,
textAlign: TextAlign.center,
textScaleFactor: 1.0,
),
const SizedBox(height: 3),
Text(
down,
style: textSize9Grey,
style: UIs.textSize9Grey,
textAlign: TextAlign.center,
textScaleFactor: 1.0,
)
@@ -444,7 +444,7 @@ class _ServerPageState extends State<ServerPage>
child: Text(
'${percent.toStringAsFixed(1)}%',
textAlign: TextAlign.center,
style: textSize11,
style: UIs.textSize11,
textScaleFactor: 1.0,
),
),

View File

@@ -7,8 +7,10 @@ import 'package:flutter_highlight/theme_map.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:toolbox/core/extension/colorx.dart';
import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/core/extension/context/snackbar.dart';
import 'package:toolbox/core/extension/locale.dart';
import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/stringx.dart';
import '../../../core/persistant_store.dart';
@@ -153,7 +155,7 @@ class _SettingPageState extends State<SettingPage> {
child: Center(
child: Text(
text,
style: grey,
style: UIs.textGrey,
),
),
);
@@ -245,7 +247,7 @@ class _SettingPageState extends State<SettingPage> {
}
return ListTile(
title: Text(_s.autoCheckUpdate),
subtitle: Text(display, style: grey),
subtitle: Text(display, style: UIs.textGrey),
onTap: () => doUpdate(ctx, force: true),
trailing: StoreSwitch(prop: _setting.autoCheckAppUpdate),
);
@@ -269,7 +271,7 @@ class _SettingPageState extends State<SettingPage> {
),
subtitle: Text(
_s.willTakEeffectImmediately,
style: grey,
style: UIs.textGrey,
),
onTap: () {
_updateIntervalKey.currentState?.showButtonMenu();
@@ -290,7 +292,7 @@ class _SettingPageState extends State<SettingPage> {
},
child: Text(
'${_updateInterval.value} ${_s.second}',
style: textSize15,
style: UIs.textSize15,
),
),
),
@@ -422,7 +424,7 @@ class _SettingPageState extends State<SettingPage> {
_s.maxRetryCount,
textAlign: TextAlign.start,
),
subtitle: Text(help, style: grey),
subtitle: Text(help, style: UIs.textGrey),
onTap: () {
_maxRetryKey.currentState?.showButtonMenu();
},
@@ -437,7 +439,7 @@ class _SettingPageState extends State<SettingPage> {
},
child: Text(
'${_maxRetryCount.value} ${_s.times}',
style: textSize15,
style: UIs.textSize15,
),
),
listenable: _maxRetryCount,
@@ -477,7 +479,7 @@ class _SettingPageState extends State<SettingPage> {
},
child: Text(
_buildThemeModeStr(_nightMode.value),
style: textSize15,
style: UIs.textSize15,
),
),
),
@@ -524,7 +526,7 @@ class _SettingPageState extends State<SettingPage> {
_pushToken.value = text;
return Text(
text ?? _s.nullToken,
style: grey,
style: UIs.textGrey,
overflow: TextOverflow.ellipsis,
maxLines: 1,
);
@@ -539,7 +541,7 @@ class _SettingPageState extends State<SettingPage> {
title: Text(_s.font),
trailing: Text(
fontName ?? _s.notSelected,
style: textSize15,
style: UIs.textSize15,
),
onTap: () {
context.showRoundDialog(
@@ -574,7 +576,7 @@ class _SettingPageState extends State<SettingPage> {
_setting.fontPath.put(path);
} else {
final fontFile = File(path);
final newPath = '${await fontDir}/${path.split('/').last}';
final newPath = '${await Paths.font}/${path.split('/').last}';
await fontFile.copy(newPath);
_setting.fontPath.put(newPath);
}
@@ -600,7 +602,7 @@ class _SettingPageState extends State<SettingPage> {
title: Text(_s.fontSize),
trailing: Text(
_termFontSize.value.toString(),
style: textSize15,
style: UIs.textSize15,
),
onTap: () => _showFontSizeDialog(_termFontSize, _setting.termFontSize),
),
@@ -671,7 +673,7 @@ class _SettingPageState extends State<SettingPage> {
},
child: Text(
_s.languageName,
style: textSize15,
style: UIs.textSize15,
),
),
),
@@ -681,7 +683,7 @@ class _SettingPageState extends State<SettingPage> {
Widget _buildSSHVirtualKeyAutoOff() {
return ListTile(
title: Text(_s.sshVirtualKeyAutoOff),
subtitle: const Text('Ctrl & Alt', style: grey),
subtitle: const Text('Ctrl & Alt', style: UIs.textGrey),
trailing: StoreSwitch(prop: _setting.sshVirtualKeyAutoOff),
);
}
@@ -709,7 +711,7 @@ class _SettingPageState extends State<SettingPage> {
},
child: Text(
_editorTheme.value,
style: textSize15,
style: UIs.textSize15,
),
),
),
@@ -742,7 +744,7 @@ class _SettingPageState extends State<SettingPage> {
},
child: Text(
_editorDarkTheme.value,
style: textSize15,
style: UIs.textSize15,
),
),
),
@@ -768,7 +770,7 @@ class _SettingPageState extends State<SettingPage> {
Widget _buildFullScreenJitter() {
return ListTile(
title: Text(_s.fullScreenJitter),
subtitle: Text(_s.fullScreenJitterHelp, style: grey),
subtitle: Text(_s.fullScreenJitterHelp, style: UIs.textGrey),
trailing: StoreSwitch(prop: _setting.fullScreenJitter),
);
}
@@ -799,7 +801,7 @@ class _SettingPageState extends State<SettingPage> {
},
child: Text(
degrees[_rotateQuarter.value],
style: textSize15,
style: UIs.textSize15,
),
),
),
@@ -834,7 +836,7 @@ class _SettingPageState extends State<SettingPage> {
).toList();
return ListTile(
title: Text(_s.keyboardType),
subtitle: Text(_s.keyboardCompatibility, style: grey),
subtitle: Text(_s.keyboardCompatibility, style: UIs.textGrey),
trailing: ValueBuilder(
listenable: _keyboardType,
build: () => PopupMenuButton<int>(
@@ -847,7 +849,7 @@ class _SettingPageState extends State<SettingPage> {
},
child: Text(
names[_keyboardType.value],
style: textSize15,
style: UIs.textSize15,
),
),
),
@@ -939,7 +941,7 @@ class _SettingPageState extends State<SettingPage> {
},
child: Text(
_netViewType.value.l10n(_s),
style: textSize15,
style: UIs.textSize15,
),
),
),
@@ -952,7 +954,7 @@ class _SettingPageState extends State<SettingPage> {
Widget _buildAutoUpdateHomeWidget() {
return ListTile(
title: Text(_s.autoUpdateHomeWidget),
subtitle: Text(_s.whenOpenApp, style: grey),
subtitle: Text(_s.whenOpenApp, style: UIs.textGrey),
trailing: StoreSwitch(prop: _setting.autoUpdateHomeWidget),
);
}
@@ -993,7 +995,7 @@ class _SettingPageState extends State<SettingPage> {
Widget _buildMoveOutServerFuncBtns() {
return ListTile(
title: Text(_s.moveOutServerFuncBtns),
subtitle: Text(_s.moveOutServerFuncBtnsHelp, style: textSize13Grey),
subtitle: Text(_s.moveOutServerFuncBtnsHelp, style: UIs.textSize13Grey),
trailing: StoreSwitch(prop: _setting.moveOutServerTabFuncBtns),
);
}
@@ -1021,7 +1023,7 @@ class _SettingPageState extends State<SettingPage> {
title: Text(_s.fontSize),
trailing: Text(
_editorFontSize.value.toString(),
style: textSize15,
style: UIs.textSize15,
),
onTap: () =>
_showFontSizeDialog(_editorFontSize, _setting.editorFontSize),
@@ -1069,7 +1071,7 @@ class _SettingPageState extends State<SettingPage> {
Widget _buildSftpRmrfDir() {
return ListTile(
title: const Text('rm -rf'),
subtitle: Text(_s.sftpRmrfDirSummary, style: grey),
subtitle: Text(_s.sftpRmrfDirSummary, style: UIs.textGrey),
trailing: StoreSwitch(prop: _setting.sftpRmrfDir),
);
}

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/core/extension/context/snackbar.dart';
import 'package:toolbox/core/extension/order.dart';
import 'package:toolbox/core/utils/platform.dart';
import 'package:toolbox/data/model/ssh/virtual_key.dart';
@@ -55,7 +55,7 @@ class _SSHVirtKeySettingPageState extends State<SSHVirtKeySettingPage> {
key: ValueKey(idx),
ListTile(
title: _buildTitle(key),
subtitle: help == null ? null : Text(help, style: grey),
subtitle: help == null ? null : Text(help, style: UIs.textGrey),
leading: _buildCheckBox(keys, key, idx, idx < keys.length),
trailing: isDesktop ? null : const Icon(Icons.drag_handle),
),

View File

@@ -1,7 +1,8 @@
import 'package:after_layout/after_layout.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/core/extension/context/snackbar.dart';
import 'package:toolbox/view/widget/input_field.dart';
import '../../../data/model/server/snippet.dart';
@@ -56,7 +57,7 @@ class _SnippetEditPageState extends State<SnippetEditPage>
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: Text(_s.edit, style: textSize18),
title: Text(_s.edit, style: UIs.textSize18),
actions: _buildAppBarActions(),
),
body: _buildBody(),

View File

@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:provider/provider.dart';
import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/order.dart';
import '../../../core/utils/misc.dart';
@@ -83,7 +83,7 @@ class _SnippetListPageState extends State<SnippetListPage> {
all: _s.all,
width: _media.size.width,
),
footer: height77,
footer: UIs.height77,
buildDefaultDragHandles: false,
itemBuilder: (context, idx) {
final snippet = filtered.elementAt(idx);
@@ -111,7 +111,7 @@ class _SnippetListPageState extends State<SnippetListPage> {
snippet.note ?? snippet.script,
overflow: TextOverflow.ellipsis,
maxLines: 3,
style: grey,
style: UIs.textGrey,
),
trailing: Row(
mainAxisSize: MainAxisSize.min,

View File

@@ -7,7 +7,9 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:provider/provider.dart';
import 'package:toolbox/core/extension/context.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:xterm/xterm.dart';
import '../../core/route.dart';

View File

@@ -2,7 +2,9 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/core/extension/context.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/model/sftp/req.dart';
import 'package:toolbox/data/provider/server.dart';
import 'package:toolbox/data/provider/sftp.dart';
@@ -47,7 +49,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
_path = LocalPath(widget.initDir!);
});
} else {
sftpDir.then((dir) {
Paths.sftp.then((dir) {
setState(() {
_path = LocalPath(dir);
});
@@ -165,12 +167,13 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
? const Icon(Icons.folder)
: const Icon(Icons.insert_drive_file),
title: Text(fileName),
subtitle: isDir ? null : Text(stat.size.convertBytes, style: grey),
subtitle:
isDir ? null : Text(stat.size.convertBytes, style: UIs.textGrey),
trailing: Text(
stat.modified
.toString()
.substring(0, stat.modified.toString().length - 4),
style: grey,
style: UIs.textGrey,
),
onLongPress: () {
if (!isDir) return;
@@ -242,7 +245,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
onTap: () async {
context.pop();
final stat = await file.stat();
if (stat.size > editorMaxSize) {
if (stat.size > Miscs.editorMaxSize) {
context.showRoundDialog(
title: Text(_s.attention),
child: Text(_s.fileTooLarge(fileName, stat.size, '1m')),

View File

@@ -4,7 +4,9 @@ import 'package:after_layout/after_layout.dart';
import 'package:dartssh2/dartssh2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/core/extension/context.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/core/extension/sftpfile.dart';
import 'package:toolbox/data/res/logger.dart';
import 'package:toolbox/data/res/misc.dart';
@@ -267,7 +269,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
Widget _buildFileView() {
if (_status.files == null) {
return centerLoading;
return UIs.centerLoading;
}
if (_status.files!.isEmpty) {
@@ -293,7 +295,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
final isDir = file.attr.isDirectory;
final trailing = Text(
'${getTime(file.attr.modifyTime)}\n${file.attr.mode?.str ?? ''}',
style: grey,
style: UIs.textGrey,
textAlign: TextAlign.right,
);
return RoundRectCard(ListTile(
@@ -304,7 +306,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
? null
: Text(
(file.attr.size ?? 0).convertBytes,
style: grey,
style: UIs.textGrey,
),
onTap: () {
if (isDir) {
@@ -362,11 +364,11 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
Future<void> _edit(BuildContext context, SftpName name) async {
final size = name.attr.size;
if (size == null || size > editorMaxSize) {
if (size == null || size > Miscs.editorMaxSize) {
context.showSnackBar(_s.fileTooLarge(
name.filename,
size ?? 0,
editorMaxSize,
Miscs.editorMaxSize,
));
return;
}
@@ -469,7 +471,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
}
_listDir();
},
child: Text(_s.delete, style: textRed),
child: Text(_s.delete, style: UIs.textRed),
),
],
);
@@ -510,7 +512,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
context.pop();
_listDir();
},
child: Text(_s.ok, style: textRed),
child: Text(_s.ok, style: UIs.textRed),
),
],
);
@@ -550,7 +552,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
context.pop();
_listDir();
},
child: Text(_s.ok, style: textRed),
child: Text(_s.ok, style: UIs.textRed),
),
],
);
@@ -588,7 +590,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
context.pop();
_listDir();
},
child: Text(_s.rename, style: textRed),
child: Text(_s.rename, style: UIs.textRed),
),
],
);
@@ -623,7 +625,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
}
Future<String> _getLocalPath(String remotePath) async {
return '${await sftpDir}$remotePath';
return '${await Paths.sftp}$remotePath';
}
/// Only return true if the path is changed

View File

@@ -1,8 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:provider/provider.dart';
import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/core/extension/datetime.dart';
import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/route.dart';
import 'package:toolbox/locator.dart';
@@ -34,7 +35,7 @@ class _SftpMissionPageState extends State<SftpMissionPage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: Text(_s.mission, style: textSize18),
title: Text(_s.mission, style: UIs.textSize18),
),
body: _buildBody(),
);
@@ -134,12 +135,7 @@ class _SftpMissionPageState extends State<SftpMissionPage> {
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
subtitle: subtitle == null
? null
: Text(
subtitle,
style: grey,
),
subtitle: subtitle == null ? null : Text(subtitle, style: UIs.textGrey),
trailing: trailing,
),
);

View File

@@ -12,7 +12,7 @@ class PopupMenu<T> extends StatelessWidget {
super.key,
required this.items,
required this.onSelected,
this.child = popMenuChild,
this.child = UIs.popMenuChild,
this.padding = const EdgeInsets.all(7),
this.initialValue,
});

View File

@@ -2,7 +2,9 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/core/extension/context.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/core/extension/ssh_client.dart';
import 'package:toolbox/core/extension/uint8list.dart';
import 'package:toolbox/data/model/pkg/manager.dart';

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/data/res/ui.dart';
import 'package:toolbox/view/widget/input_field.dart';
import 'package:toolbox/view/widget/round_rect_card.dart';
@@ -29,7 +30,7 @@ class TagBtn extends StatelessWidget {
content,
textAlign: TextAlign.center,
textScaleFactor: 1.0,
style: isEnable ? textSize13 : textSize13Grey,
style: isEnable ? UIs.textSize13 : UIs.textSize13Grey,
),
onTap: onTap,
);
@@ -107,7 +108,7 @@ class _TagEditorState extends State<TagEditor> {
Text(
'#$tag',
textAlign: TextAlign.center,
style: isAdd ? textSize13Grey : textSize13,
style: isAdd ? UIs.textSize13Grey : UIs.textSize13,
textScaleFactor: 1.0,
),
const SizedBox(width: 4.0),
@@ -211,7 +212,7 @@ class _TagPickerState<T extends TagPickable> extends State<TagPicker<T>> {
final children = <Widget>[];
if (widget.tags.isNotEmpty) {
children.add(Text(_s.tag));
children.add(height13);
children.add(UIs.height13);
children.add(SizedBox(
height: _kTagBtnHeight,
width: _media.size.width * 0.7,
@@ -220,7 +221,7 @@ class _TagPickerState<T extends TagPickable> extends State<TagPicker<T>> {
}
if (widget.items.isNotEmpty) {
children.add(Text(_s.all));
children.add(height13);
children.add(UIs.height13);
children.add(SizedBox(
height: _kTagBtnHeight,
width: _media.size.width * 0.7,
@@ -313,7 +314,7 @@ class TagSwitcher extends StatelessWidget {
@override
Widget build(BuildContext context) {
if (tags.isEmpty) return placeholder;
if (tags.isEmpty) return UIs.placeholder;
final items = <String?>[null, ...tags];
return Container(
height: _kTagBtnHeight,

View File

@@ -15,12 +15,12 @@ class TwoLineText extends StatelessWidget {
children: [
Text(
up,
style: textSize15,
style: UIs.textSize15,
overflow: TextOverflow.ellipsis,
),
Text(
down,
style: textSize11,
style: UIs.textSize11,
overflow: TextOverflow.ellipsis,
)
],

View File

@@ -82,7 +82,9 @@ class UrlText extends StatelessWidget {
Widget build(BuildContext context) {
return RichText(
textAlign: textAlign ?? TextAlign.start,
text: TextSpan(children: getTextSpans(contentColor.resolve(context))),
text: TextSpan(
children: getTextSpans(DynamicColors.content.resolve(context)),
),
);
}
}