Compare commits

..

21 Commits

Author SHA1 Message Date
lollipopkit🏳️‍⚧️
6b9b8f0dbb chore: bump version 2024-06-25 13:15:29 +08:00
lollipopkit🏳️‍⚧️
5eb48b2717 fix: linux build (#422)
Fixes #421
2024-06-25 11:48:56 +08:00
lollipopkit🏳️‍⚧️
5339cfca70 chore: lib vers bump (#420)
Fixes #419
2024-06-25 11:16:34 +08:00
lollipopkit🏳️‍⚧️
1462b2d0b8 fix: always enter intro page (#418)
Fixes #417
2024-06-24 16:32:37 +08:00
lollipopkit🏳️‍⚧️
3798a23183 chore: bump version 2024-06-24 00:56:45 +08:00
lollipopkit🏳️‍⚧️
ddaf916170 feat: intro page (#416)
Fixes #415
2024-06-24 00:43:52 +08:00
lollipopkit🏳️‍⚧️
d6e37b058f fix: docker parse (#414)
Fixes #395
2024-06-23 18:37:05 +08:00
lollipopkit🏳️‍⚧️
2e9ad7d7cb chore: missing l10n noLineChart (#413)
Fixes #412
2024-06-23 15:39:30 +08:00
lollipopkit🏳️‍⚧️
190da74f66 chore: add participants (#410)
Fixes #409
2024-06-23 00:27:26 +08:00
lollipopkit🏳️‍⚧️
f1315dda7f fix: batch delete servers (#408)
Fixes #393
2024-06-23 00:24:30 +08:00
lollipopkit🏳️‍⚧️
43e6105eb3 fix: hideTitleBar doesn't work (#407)
Fixes #406
2024-06-22 22:58:22 +08:00
lollipopkit🏳️‍⚧️
d785209eb6 opt.: share on desktop (#405) 2024-06-22 22:50:17 +08:00
lollipopkit🏳️‍⚧️
da8b6a9010 feat: remember window size (#404)
Fixes #398
2024-06-22 21:52:48 +08:00
lollipopkit🏳️‍⚧️
1fd68722da fix: watchos settings (#403)
Fixes #401
2024-06-22 21:09:05 +08:00
lollipopkit🏳️‍⚧️
c9a2c1d0e4 Android - default to English (#402) 2024-06-18 14:39:18 +08:00
lollipopkit
161f536a62 fix: conform fdroid version fmt
Signed-off-by: lollipopkit <10864310+lollipopkit@users.noreply.github.com>
2024-06-13 23:51:10 +08:00
lollipopkit
1a32e9944e opt.: put version logic somewhere else (#381)
Signed-off-by: lollipopkit <10864310+lollipopkit@users.noreply.github.com>
2024-06-13 22:40:18 +08:00
lollipopkit
6deb753198 fix: version change logic (#381) 2024-06-13 21:29:03 +08:00
lollipopkit
4e33a98631 chore: fl_build 2024-06-13 21:22:44 +08:00
lollipopkit
dcb9464d8f fix
Signed-off-by: lollipopkit <10864310+lollipopkit@users.noreply.github.com>
2024-06-13 20:39:06 +08:00
lollipopkit
b94936b29f fix: reproducible (#381)
Signed-off-by: lollipopkit <10864310+lollipopkit@users.noreply.github.com>
2024-06-13 20:28:22 +08:00
39 changed files with 468 additions and 237 deletions

View File

@@ -32,13 +32,18 @@ jobs:
curl -u ${{ secrets.BASIC_AUTH }} -o android/key.properties ${{ secrets.URL_PREFIX }}key.properties
- name: Build
run: dart run fl_build -p android,linux
- name: Rename for fdroid
run: |
mv build/app/outputs/flutter-apk/${{ env.APP_NAME }}_${{ env.BUILD_NUMBER }}_arm64.apk build/app/outputs/flutter-apk/${{ env.APP_NAME }}_v1.0.${{ env.BUILD_NUMBER }}_arm64.apk
mv build/app/outputs/flutter-apk/${{ env.APP_NAME }}_${{ env.BUILD_NUMBER }}_arm.apk build/app/outputs/flutter-apk/${{ env.APP_NAME }}_v1.0.${{ env.BUILD_NUMBER }}_arm.apk
mv build/app/outputs/flutter-apk/${{ env.APP_NAME }}_${{ env.BUILD_NUMBER }}_amd64.apk build/app/outputs/flutter-apk/${{ env.APP_NAME }}_v1.0.${{ env.BUILD_NUMBER }}_amd64.apk
- name: Create Release
uses: softprops/action-gh-release@v2
with:
files: |
build/app/outputs/flutter-apk/${{ env.APP_NAME }}_${{ env.BUILD_NUMBER }}_arm64.apk
build/app/outputs/flutter-apk/${{ env.APP_NAME }}_${{ env.BUILD_NUMBER }}_arm.apk
build/app/outputs/flutter-apk/${{ env.APP_NAME }}_${{ env.BUILD_NUMBER }}_amd64.apk
build/app/outputs/flutter-apk/${{ env.APP_NAME }}_v1.0.${{ env.BUILD_NUMBER }}_arm64.apk
build/app/outputs/flutter-apk/${{ env.APP_NAME }}_v1.0.${{ env.BUILD_NUMBER }}_arm.apk
build/app/outputs/flutter-apk/${{ env.APP_NAME }}_v1.0.${{ env.BUILD_NUMBER }}_amd64.apk
${{ env.APP_NAME }}_${{ env.BUILD_NUMBER }}_amd64.AppImage
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,6 +1,4 @@
PODS:
- countly_flutter (24.4.1):
- Flutter
- device_info_plus (0.0.1):
- Flutter
- file_picker (0.0.1):
@@ -36,7 +34,6 @@ PODS:
- Flutter
DEPENDENCIES:
- countly_flutter (from `.symlinks/plugins/countly_flutter/ios`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`)
- Flutter (from `Flutter`)
@@ -55,8 +52,6 @@ DEPENDENCIES:
- watch_connectivity (from `.symlinks/plugins/watch_connectivity/ios`)
EXTERNAL SOURCES:
countly_flutter:
:path: ".symlinks/plugins/countly_flutter/ios"
device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios"
file_picker:
@@ -91,7 +86,6 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/watch_connectivity/ios"
SPEC CHECKSUMS:
countly_flutter: 56233d921c6b4e0a720774a39b8ee8110d6f8d91
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
file_picker: c79185e70b9b45728cde2a8d8da454e0cb43f287
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7

View File

@@ -690,7 +690,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 970;
CURRENT_PROJECT_VERSION = 992;
DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -700,7 +700,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.970;
MARKETING_VERSION = 1.0.992;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -826,7 +826,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 970;
CURRENT_PROJECT_VERSION = 992;
DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -836,7 +836,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.970;
MARKETING_VERSION = 1.0.992;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -854,7 +854,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 970;
CURRENT_PROJECT_VERSION = 992;
DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -864,7 +864,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.970;
MARKETING_VERSION = 1.0.992;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -885,7 +885,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 970;
CURRENT_PROJECT_VERSION = 992;
DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
@@ -898,7 +898,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0.970;
MARKETING_VERSION = 1.0.992;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
@@ -924,7 +924,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 970;
CURRENT_PROJECT_VERSION = 992;
DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
@@ -937,7 +937,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0.970;
MARKETING_VERSION = 1.0.992;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -960,7 +960,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 970;
CURRENT_PROJECT_VERSION = 992;
DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
@@ -973,7 +973,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0.970;
MARKETING_VERSION = 1.0.992;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -996,7 +996,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 970;
CURRENT_PROJECT_VERSION = 992;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES;
@@ -1008,7 +1008,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.970;
MARKETING_VERSION = 1.0.992;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
@@ -1037,7 +1037,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 970;
CURRENT_PROJECT_VERSION = 992;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES;
@@ -1049,7 +1049,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.970;
MARKETING_VERSION = 1.0.992;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
PRODUCT_NAME = ServerBox;
@@ -1075,7 +1075,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 970;
CURRENT_PROJECT_VERSION = 992;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES;
@@ -1087,7 +1087,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.970;
MARKETING_VERSION = 1.0.992;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
PRODUCT_NAME = ServerBox;

View File

@@ -3,10 +3,14 @@ import 'package:fl_lib/fl_lib.dart';
import 'package:fl_lib/l10n/gen_l10n/lib_l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:server_box/core/extension/context/locale.dart';
import 'package:server_box/data/res/build_data.dart';
import 'package:server_box/data/res/rebuild.dart';
import 'package:server_box/data/res/store.dart';
import 'package:server_box/view/page/home/home.dart';
import 'package:icons_plus/icons_plus.dart';
part 'intro.dart';
class MyApp extends StatelessWidget {
const MyApp({super.key});
@@ -71,6 +75,7 @@ class MyApp extends StatelessWidget {
...AppLocalizations.localizationsDelegates,
],
supportedLocales: AppLocalizations.supportedLocales,
localeListResolutionCallback: LocaleUtil.resolve,
title: BuildData.name,
themeMode: themeMode,
theme: light,
@@ -81,7 +86,30 @@ class MyApp extends StatelessWidget {
Widget _buildAppContent(BuildContext ctx) {
//if (Pros.app.isWearOS) return const WearHome();
return const HomePage();
return const _AppContent(
intro: _IntroPage(),
child: HomePage(),
);
}
}
/// It's used for init settings related to [BuildContext]
final class _AppContent extends StatelessWidget {
final Widget child;
final Widget intro;
const _AppContent({required this.child, required this.intro});
@override
Widget build(BuildContext context) {
context.setLibL10n();
final appL10n = AppLocalizations.of(context);
if (appL10n != null) l10n = appL10n;
final showIntro = Stores.setting.showIntro.fetch();
if (showIntro) return intro;
return child;
}
}

View File

@@ -72,7 +72,7 @@ final class DockerImg implements ContainerImg {
final String repository;
final String size;
@override
final String tag;
final String? tag;
DockerImg({
required this.containers,
@@ -95,14 +95,30 @@ final class DockerImg implements ContainerImg {
String toRawJson() => json.encode(toJson());
factory DockerImg.fromJson(Map<String, dynamic> json) => DockerImg(
containers: json["Containers"],
createdAt: json["CreatedAt"],
id: json["ID"],
repository: json["Repository"],
size: json["Size"],
tag: json["Tag"],
);
factory DockerImg.fromJson(Map<String, dynamic> json) {
final containers = switch (json["Containers"]) {
final String a => a,
final Object? a => a.toString(),
};
final repo = switch (json["Repository"] ?? json["Names"]) {
final String a => a,
final List a => a.firstOrNull.toString(),
final Object? a => a.toString(),
};
final size = switch (json["Size"]) {
final String a => a,
final int a => a.bytes2Str,
final Object? a => a.toString(),
};
return DockerImg(
containers: containers,
createdAt: json["CreatedAt"],
id: json["ID"] ?? json["Id"] ?? '',
repository: repo,
size: size,
tag: json["Tag"],
);
}
Map<String, dynamic> toJson() => {
"Containers": containers,

View File

@@ -160,11 +160,18 @@ class ContainerProvider extends ChangeNotifier {
}
// Parse images
final imageRaw = ContainerCmdType.images.find(segments);
final imageRaw = ContainerCmdType.images.find(segments).trim();
final isEntireJson = imageRaw.startsWith('[') && imageRaw.endsWith(']');
try {
final imgLines = imageRaw.split('\n');
imgLines.removeWhere((element) => element.isEmpty);
images = imgLines.map((e) => ContainerImg.fromRawJson(e, type)).toList();
if (isEntireJson) {
images = (json.decode(imageRaw) as List)
.map((e) => ContainerImg.fromRawJson(json.encode(e), type))
.toList();
} else {
final lines = imageRaw.split('\n');
lines.removeWhere((element) => element.isEmpty);
images = lines.map((e) => ContainerImg.fromRawJson(e, type)).toList();
}
} catch (e, trace) {
error = ContainerErr(
type: ContainerErrType.parseImages,
@@ -298,6 +305,6 @@ enum ContainerCmdType {
}) {
return ContainerCmdType.values
.map((e) => e.exec(type, sudo: sudo, includeStats: includeStats))
.join(' && echo ${ShellFunc.seperator} && ');
.join('\necho ${ShellFunc.seperator}\n');
}
}

View File

@@ -2,9 +2,6 @@
class BuildData {
static const String name = "ServerBox";
static const int build = 970;
static const String engine = "3.22.2";
static const String buildAt = "2024-06-13 00:44:23";
static const int modifications = 0;
static const int build = 992;
static const int script = 49;
}

View File

@@ -3,15 +3,17 @@ abstract final class GithubIds {
// If you want to change your Github ID, please open an issue.
static const contributors = <GhId>{
'PaperCube',
'Integral-Tech',
'its-tom',
'leganck',
'azkadev',
'kalashnikov',
'FrancXPT',
'RainSunMe',
'calvinweb',
'QazCetelic',
'RainSunMe',
'FrancXPT',
'Liloupar',
'dccif',
'QazCetelic',
};
static const participants = <GhId>{
@@ -71,6 +73,17 @@ abstract final class GithubIds {
'FHU-yezi',
'ZRY233',
'Jasonzhu1207',
'sakuraanzu',
'licaon-kter',
'77160860',
'mijjjj',
'muyunil',
'Hua159',
'jaydong2016',
'geol',
'Mooling0602',
'IllTamer',
'marlkiller',
};
}

View File

@@ -276,6 +276,12 @@ class SettingStore extends PersistentStore {
late final betaTest = property('betaTest', false);
/// If it's empty, skip change window size.
/// Format: {width}x{height}
late final windowSize = property('windowSize', '');
late final showIntro = property('showIntro', true);
// Never show these settings for users
//
// ------BEGIN------

107
lib/intro.dart Normal file
View File

@@ -0,0 +1,107 @@
part of 'app.dart';
final class _IntroPage extends StatelessWidget {
const _IntroPage();
static final _setting = Stores.setting;
static const _kIconSize = 23.0;
static const _introListPad = EdgeInsets.symmetric(horizontal: 17);
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, cons) {
final padTop = cons.maxHeight * .2;
return IntroPage(
pages: [
_buildAppSettings(context, padTop),
_buildRecommended(context, padTop),
],
onDone: (ctx) {
Stores.setting.showIntro.put(false);
Navigator.of(ctx).pushReplacement(
MaterialPageRoute(builder: (_) => const HomePage()),
);
},
);
},
);
}
Widget _buildRecommended(BuildContext context, double padTop) {
return ListView(
padding: _introListPad,
children: [
SizedBox(height: padTop),
const Icon(Bootstrap.stars, size: 35),
SizedBox(height: padTop),
ListTile(
leading: const Icon(MingCute.delete_2_fill),
title: const Text('rm -r'),
subtitle: Text(l10n.sftpRmrDirSummary, style: UIs.textGrey),
trailing: StoreSwitch(prop: _setting.sftpRmrDir),
).cardx,
ListTile(
leading: const Icon(IonIcons.stats_chart, size: _kIconSize),
title: Text(l10n.parseContainerStats),
subtitle: Text(l10n.parseContainerStatsTip, style: UIs.textGrey),
trailing: StoreSwitch(prop: _setting.containerParseStat),
).cardx,
ListTile(
leading: const Icon(OctIcons.cpu),
title: Text('CPU ${l10n.noLineChart}'),
subtitle: Text(l10n.cpuViewAsProgressTip, style: UIs.textGrey),
trailing: StoreSwitch(prop: _setting.cpuViewAsProgress),
).cardx,
],
);
}
Widget _buildAppSettings(BuildContext ctx, double padTop) {
return ListView(
padding: _introListPad,
children: [
SizedBox(height: padTop),
_buildTitle(l10n.init, big: true),
SizedBox(height: padTop),
ListTile(
leading: const Icon(IonIcons.language),
title: Text(l10n.language),
onTap: () async {
final selected = await ctx.showPickSingleDialog(
title: l10n.language,
items: AppLocalizations.supportedLocales,
name: (p0) => p0.code,
initial: _setting.locale.fetch().toLocale,
);
if (selected != null) {
_setting.locale.put(selected.code);
RNodes.app.build();
}
},
trailing: Text(
l10n.languageName,
style: const TextStyle(fontSize: 15, color: Colors.grey),
),
).cardx,
ListTile(
leading: const Icon(Icons.update),
title: Text(l10n.autoCheckUpdate),
subtitle: Text(l10n.fdroidReleaseTip, style: UIs.textGrey),
trailing: StoreSwitch(prop: _setting.autoCheckAppUpdate),
).cardx,
],
);
}
Widget _buildTitle(String text, {bool big = false}) {
return Center(
child: Text(
text,
style: big
? const TextStyle(fontSize: 41, fontWeight: FontWeight.w500)
: UIs.textGrey,
),
);
}
}

View File

@@ -101,6 +101,7 @@
"export": "Export",
"extraArgs": "Extra args",
"failed": "Failed",
"fdroidReleaseTip": "Wenn Sie diese App von Fdroid heruntergeladen haben, wird empfohlen, diese Option zu deaktivieren.",
"feedback": "Feedback",
"feedbackOnGithub": "Wenn du Fragen hast, stelle diese bitte auf Github.",
"fieldMustNotEmpty": "Die Eingabefelder dürfen nicht leer sein.",
@@ -135,6 +136,7 @@
"imagesList": "Images",
"import": "Importieren",
"inAppUpdate": "Im App aktualisieren? Andernfalls mit einem Browser herunterladen.",
"init": "Initialisieren",
"inner": "Eingebaut",
"inputDomainHere": "Domain eingeben",
"install": "install",
@@ -231,6 +233,7 @@
"rememberChoice": "Auswahl merken",
"rememberPwdInMem": "Passwort im Speicher behalten",
"rememberPwdInMemTip": "Für Container, Aufhängen usw.",
"rememberWindowSize": "Fenstergröße merken",
"remotePath": "Entfernte Pfade",
"rename": "Umbenennen",
"reportBugsOnGithubIssue": "Bitte Bugs auf {url} melden",

View File

@@ -101,6 +101,7 @@
"export": "Export",
"extraArgs": "Extra args",
"failed": "Failed",
"fdroidReleaseTip": "If you downloaded this app from Fdroid, it is recommended to turn off this option.",
"feedback": "Feedback",
"feedbackOnGithub": "If you have any questions, please feedback on Github.",
"fieldMustNotEmpty": "These fields must not be empty.",
@@ -135,6 +136,7 @@
"imagesList": "Images list",
"import": "Import",
"inAppUpdate": "Update within the app? Otherwise, download using a browser.",
"init": "Initialize",
"inner": "Inner",
"inputDomainHere": "Input Domain here",
"install": "install",
@@ -231,6 +233,7 @@
"rememberChoice": "Remember the selection",
"rememberPwdInMem": "Remember password in memory",
"rememberPwdInMemTip": "Used for containers, suspending, etc.",
"rememberWindowSize": "Remember window size",
"remotePath": "Remote path",
"rename": "Rename",
"reportBugsOnGithubIssue": "Please report bugs on {url}",

View File

@@ -101,6 +101,7 @@
"export": "Exportar",
"extraArgs": "Argumentos extra",
"failed": "Fallido",
"fdroidReleaseTip": "Si descargaste esta aplicación desde Fdroid, se recomienda desactivar esta opción.",
"feedback": "Retroalimentación",
"feedbackOnGithub": "Si tienes algún problema, por favor informa en GitHub",
"fieldMustNotEmpty": "Estos campos no pueden estar vacíos.",
@@ -135,6 +136,7 @@
"imagesList": "Lista de imágenes",
"import": "Importar",
"inAppUpdate": "¿Actualizar dentro de la app? De lo contrario, descargar usando un navegador.",
"init": "Inicializar",
"inner": "Interno",
"inputDomainHere": "Introduce el dominio aquí",
"install": "Instalar",
@@ -231,6 +233,7 @@
"rememberChoice": "Recordar la selección",
"rememberPwdInMem": "Recordar contraseña en la memoria",
"rememberPwdInMemTip": "Utilizado para contenedores, suspensión, etc.",
"rememberWindowSize": "Recordar el tamaño de la ventana",
"remotePath": "Ruta remota",
"rename": "Renombrar",
"reportBugsOnGithubIssue": "Por favor, informa los problemas en {url}",

View File

@@ -101,6 +101,7 @@
"export": "Exporter",
"extraArgs": "Arguments supplémentaires",
"failed": "Échoué",
"fdroidReleaseTip": "Si vous avez téléchargé cette application depuis Fdroid, il est recommandé de désactiver cette option.",
"feedback": "Retour",
"feedbackOnGithub": "Si vous avez des questions, veuillez donner votre avis sur Github.",
"fieldMustNotEmpty": "Ces champs ne doivent pas être vides.",
@@ -135,6 +136,7 @@
"imagesList": "Liste des images",
"import": "Importer",
"inAppUpdate": "Mettre à jour dans l'application ? Sinon, téléchargez en utilisant un navigateur.",
"init": "Initialiser",
"inner": "Interne",
"inputDomainHere": "Saisissez le domaine ici",
"install": "Installer",
@@ -231,6 +233,7 @@
"rememberChoice": "Se souvenir du choix",
"rememberPwdInMem": "Mémoriser le mot de passe en mémoire",
"rememberPwdInMemTip": "Utilisé pour les conteneurs, la suspension, etc.",
"rememberWindowSize": "Se souvenir de la taille de la fenêtre",
"remotePath": "Chemin distant",
"rename": "Renommer",
"reportBugsOnGithubIssue": "Veuillez signaler les bugs sur {url}",

View File

@@ -101,6 +101,7 @@
"export": "Ekspor",
"extraArgs": "Args ekstra",
"failed": "Gagal",
"fdroidReleaseTip": "Jika Anda mengunduh aplikasi ini dari Fdroid, disarankan untuk mematikan opsi ini.",
"feedback": "Masukan",
"feedbackOnGithub": "Jika Anda memiliki pertanyaan, silakan umpan balik tentang GitHub.",
"fieldMustNotEmpty": "Bidang -bidang ini tidak boleh kosong.",
@@ -135,6 +136,7 @@
"imagesList": "Daftar gambar",
"import": "Impor",
"inAppUpdate": "Perbarui di dalam aplikasi? Jika tidak, unduh menggunakan browser.",
"init": "Menginisialisasi",
"inner": "Batin",
"inputDomainHere": "Input domain di sini",
"install": "Install",
@@ -231,6 +233,7 @@
"rememberChoice": "Ingat pilihan",
"rememberPwdInMem": "Ingat kata sandi di dalam memori",
"rememberPwdInMemTip": "Digunakan untuk kontainer, menangguhkan, dll.",
"rememberWindowSize": "Ingat ukuran jendela",
"remotePath": "Jalur jarak jauh",
"rename": "Ganti nama",
"reportBugsOnGithubIssue": "Harap laporkan bug di {url}",

View File

@@ -101,6 +101,7 @@
"export": "エクスポート",
"extraArgs": "追加引数",
"failed": "失敗しました",
"fdroidReleaseTip": "このアプリをFdroidからダウンロードした場合、このオプションをオフにすることをお勧めします。",
"feedback": "フィードバック",
"feedbackOnGithub": "問題がある場合は、GitHubでフィードバックしてください",
"fieldMustNotEmpty": "これらの入力フィールドは空にできません。",
@@ -135,6 +136,7 @@
"imagesList": "イメージリスト",
"import": "インポート",
"inAppUpdate": "アプリ内で更新しますか?それ以外の場合は、ブラウザを使用してダウンロードしてください。",
"init": "初期化する",
"inner": "内蔵",
"inputDomainHere": "ここにドメインを入力",
"install": "インストール",
@@ -231,6 +233,7 @@
"rememberChoice": "選択を記憶する",
"rememberPwdInMem": "メモリにパスワードを記憶する",
"rememberPwdInMemTip": "コンテナ、一時停止などに使用されます。",
"rememberWindowSize": "ウィンドウサイズを記憶する",
"remotePath": "リモートパス",
"rename": "名前を変更",
"reportBugsOnGithubIssue": "{url}で問題を報告してください",

View File

@@ -101,6 +101,7 @@
"export": "Exporteren",
"extraArgs": "Extra argumenten",
"failed": "Mislukt",
"fdroidReleaseTip": "Als u deze app van Fdroid heeft gedownload, wordt aanbevolen deze optie uit te schakelen.",
"feedback": "Feedback",
"feedbackOnGithub": "Als je vragen hebt, geef dan feedback op Github.",
"fieldMustNotEmpty": "Deze velden mogen niet leeg zijn.",
@@ -135,6 +136,7 @@
"imagesList": "Lijst met afbeeldingen",
"import": "Importeren",
"inAppUpdate": "Bijwerken binnen de app? Anders downloaden via een browser.",
"init": "Initialiseren",
"inner": "Intern",
"inputDomainHere": "Voer hier domein in",
"install": "Installeren",
@@ -178,6 +180,7 @@
"newContainer": "Nieuwe container",
"noClient": "Geen client",
"noInterface": "Geen interface",
"noLineChart": "lijndiagrammen gebruiken",
"noNotiPerm": "Geen meldingsmachtigingen, mogelijk geen voortgangsindicatie bij het downloaden van app-updates.",
"noOptions": "Geen opties",
"noPrivateKeyTip": "De privésleutel bestaat niet, deze is mogelijk verwijderd of er is een configuratiefout.",
@@ -230,6 +233,7 @@
"rememberChoice": "Selectie onthouden",
"rememberPwdInMem": "Wachtwoord onthouden in geheugen",
"rememberPwdInMemTip": "Gebruikt voor containers, opschorting, enz.",
"rememberWindowSize": "Venstergrootte onthouden",
"remotePath": "Extern pad",
"rename": "Hernoemen",
"reportBugsOnGithubIssue": "Meld alstublieft bugs op {url}",

View File

@@ -101,6 +101,7 @@
"export": "Exportar",
"extraArgs": "Argumentos extras",
"failed": "Falhou",
"fdroidReleaseTip": "Se você baixou este aplicativo do Fdroid, é recomendado desativar esta opção.",
"feedback": "Feedback",
"feedbackOnGithub": "Se você tem qualquer problema, por favor, dê feedback no GitHub",
"fieldMustNotEmpty": "Estes campos não podem estar vazios.",
@@ -135,6 +136,7 @@
"imagesList": "Lista de imagens",
"import": "Importar",
"inAppUpdate": "Atualizar dentro do app? Caso contrário, baixe usando um navegador.",
"init": "Inicializar",
"inner": "Interno",
"inputDomainHere": "Insira o domínio aqui",
"install": "Instalar",
@@ -178,7 +180,7 @@
"newContainer": "Novo contêiner",
"noClient": "Sem conexão SSH",
"noInterface": "Sem interface disponível",
"noLineChart": "Gebruik geen lijndiagrammen",
"noLineChart": "Não usar gráficos de linha",
"noNotiPerm": "Sem permissão de notificação, possivelmente sem indicação de progresso ao baixar atualizações de aplicativos.",
"noOptions": "Sem opções",
"noPrivateKeyTip": "A chave privada não existe, pode ter sido deletada ou há um erro de configuração.",
@@ -231,6 +233,7 @@
"rememberChoice": "Lembrar da seleção",
"rememberPwdInMem": "Lembrar senha na memória",
"rememberPwdInMemTip": "Usado para contêineres, suspensão, etc.",
"rememberWindowSize": "Lembrar o tamanho da janela",
"remotePath": "Caminho remoto",
"rename": "Renomear",
"reportBugsOnGithubIssue": "Por favor, reporte problemas em {url}",

View File

@@ -101,6 +101,7 @@
"export": "экспорт",
"extraArgs": "дополнительные аргументы",
"failed": "неудача",
"fdroidReleaseTip": "Если вы скачали это приложение с Fdroid, рекомендуется отключить эту опцию.",
"feedback": "обратная связь",
"feedbackOnGithub": "Если у вас есть какие-либо вопросы, пожалуйста, отправьте отзыв на GitHub",
"fieldMustNotEmpty": "Эти поля не могут быть пустыми.",
@@ -135,6 +136,7 @@
"imagesList": "список образов",
"import": "импорт",
"inAppUpdate": "Обновить в приложении? В противном случае загрузите с помощью браузера.",
"init": "Инициализировать",
"inner": "встроенный",
"inputDomainHere": "введите домен здесь",
"install": "установить",
@@ -178,7 +180,7 @@
"newContainer": "создать контейнер",
"noClient": "нет SSH соединения",
"noInterface": "нет доступных интерфейсов",
"noLineChart": "Não use gráficos de linha",
"noLineChart": "Не использовать линейные графики",
"noNotiPerm": "Нет разрешения на уведомления, возможно отсутствие индикации прогресса при загрузке обновлений приложений.",
"noOptions": "нет доступных опций",
"noPrivateKeyTip": "Приватный ключ не существует, возможно, он был удален или есть ошибка в настройках.",
@@ -231,6 +233,7 @@
"rememberChoice": "Запомнить выбор",
"rememberPwdInMem": "Запомнить пароль в памяти",
"rememberPwdInMemTip": "Используется для контейнеров, приостановки и т. д.",
"rememberWindowSize": "Запомнить размер окна",
"remotePath": "удаленный путь",
"rename": "переименовать",
"reportBugsOnGithubIssue": "Пожалуйста, сообщайте о проблемах на {url}",

View File

@@ -101,6 +101,7 @@
"export": "导出",
"extraArgs": "额外参数",
"failed": "失败",
"fdroidReleaseTip": "如果你是从 Fdroid 下载的本应用,推荐关闭此选项",
"feedback": "反馈",
"feedbackOnGithub": "如果你有任何问题请在GitHub反馈",
"fieldMustNotEmpty": "这些输入框不能为空。",
@@ -135,6 +136,7 @@
"imagesList": "镜像列表",
"import": "导入",
"inAppUpdate": "在App内更新否则使用浏览器下载",
"init": "初始化",
"inner": "内置",
"inputDomainHere": "在这里输入域名",
"install": "安装",
@@ -231,6 +233,7 @@
"rememberChoice": "记住选择",
"rememberPwdInMem": "在内存中记住密码",
"rememberPwdInMemTip": "用于容器、挂起等",
"rememberWindowSize": "记住窗口大小",
"remotePath": "远端路径",
"rename": "重命名",
"reportBugsOnGithubIssue": "请到 {url} 提交问题",

View File

@@ -101,6 +101,7 @@
"export": "導出",
"extraArgs": "額外參數",
"failed": "失敗",
"fdroidReleaseTip": "如果你是從 Fdroid 下載的本應用,推薦關閉此選項",
"feedback": "反饋",
"feedbackOnGithub": "如果你有任何問題請在GitHub反饋",
"fieldMustNotEmpty": "這些輸入框不能為空。",
@@ -135,6 +136,7 @@
"imagesList": "鏡像列表",
"import": "導入",
"inAppUpdate": "在App內更新否則使用瀏覽器下載。",
"init": "初始化",
"inner": "內置",
"inputDomainHere": "在這裡輸入域名",
"install": "安裝",
@@ -231,6 +233,7 @@
"rememberChoice": "記住選擇",
"rememberPwdInMem": "在記憶體中記住密碼",
"rememberPwdInMemTip": "用於容器、暫停等",
"rememberWindowSize": "記住窗口大小",
"remotePath": "遠端路徑",
"rename": "重命名",
"reportBugsOnGithubIssue": "請到 {url} 提交問題",

View File

@@ -68,7 +68,13 @@ Future<void> _initApp() async {
await _initData();
_setupDebug();
SystemUIs.initDesktopWindow(Stores.setting.hideTitleBar.fetch());
final windowSize = Stores.setting.windowSize;
final hideTitleBar = Stores.setting.hideTitleBar.fetch();
SystemUIs.initDesktopWindow(
hideTitleBar: hideTitleBar,
size: windowSize.fetch().toSize(),
listener: WindowSizeListener(windowSize),
);
FontUtils.loadFrom(Stores.setting.fontPath.fetch());
_doPlatformRelated();

View File

@@ -66,18 +66,7 @@ class BackupPage extends StatelessWidget {
trailing: const Icon(Icons.save),
onTap: () async {
final path = await Backup.backup();
debugPrint("Backup path: $path");
/// Issue #188
switch (Pfs.type) {
case Pfs.windows:
final backslashPath = path.replaceAll('/', '\\');
await Process.run('explorer', ['/select,$backslashPath']);
case Pfs.linux:
await Process.run('xdg-open', [path]);
default:
await Pfs.sharePath(path);
}
await Pfs.share(path: path);
},
),
ListTile(

View File

@@ -1,9 +1,7 @@
import 'dart:convert';
import 'package:after_layout/after_layout.dart';
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:icons_plus/icons_plus.dart';
import 'package:server_box/core/channel/home_widget.dart';
import 'package:server_box/core/extension/build.dart';
@@ -60,9 +58,6 @@ class _HomePageState extends State<HomePage>
@override
void didChangeDependencies() {
super.didChangeDependencies();
context.setLibL10n();
final appL10n = AppLocalizations.of(context);
if (appL10n != null) l10n = appL10n;
_isLandscape.value =
MediaQuery.of(context).orientation == Orientation.landscape;
}
@@ -224,17 +219,10 @@ class _HomePageState extends State<HomePage>
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildIcon(),
TextButton(
onPressed: () => context.showRoundDialog(
title: BuildDataX.versionStr,
child: const Text(
'${BuildData.buildAt}\nFlutter ${BuildData.engine}'),
),
child: const Text(
'${BuildData.name}\n${BuildDataX.versionStr}',
textAlign: TextAlign.center,
style: UIs.text15,
),
const Text(
'${BuildData.name}\n${BuildDataX.versionStr}',
textAlign: TextAlign.center,
style: UIs.text15,
),
const SizedBox(height: 37),
_buildTiles(),

View File

@@ -1,6 +1,5 @@
import 'dart:async';
import 'package:after_layout/after_layout.dart';
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

View File

@@ -1,6 +1,6 @@
import 'dart:io';
import 'dart:async';
import 'package:after_layout/after_layout.dart';
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

View File

@@ -1,7 +1,6 @@
import 'dart:async';
import 'dart:math' as math;
import 'package:after_layout/after_layout.dart';
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:icons_plus/icons_plus.dart';

View File

@@ -7,10 +7,10 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:icons_plus/icons_plus.dart';
import 'package:provider/provider.dart';
import 'package:server_box/core/extension/context/locale.dart';
import 'package:server_box/data/res/provider.dart';
import 'package:server_box/data/res/rebuild.dart';
import 'package:server_box/data/res/store.dart';
import 'package:server_box/data/res/url.dart';
import 'package:server_box/view/page/setting/platform/platform_pub.dart';
import '../../../core/route.dart';
import '../../../data/model/app/net_view.dart';
@@ -736,47 +736,29 @@ class _SettingPageState extends State<SettingPage> {
leading: const Icon(Icons.delete_forever),
trailing: const Icon(Icons.keyboard_arrow_right),
onTap: () async {
context.showRoundDialog<List<String>>(
title: l10n.choose,
child: SingleChildScrollView(
child: StatefulBuilder(builder: (ctx, setState) {
final keys = Stores.server.box.keys.toList();
keys.removeWhere((element) => element == BoxX.lastModifiedKey);
final all = keys.map(
(e) {
final name = Pros.server.pick(id: e)?.spi.name;
return ListTile(
title: Text(name ?? e),
subtitle: name != null ? Text(e) : null,
onTap: () => context.showRoundDialog(
title: l10n.attention,
child: Text(l10n.askContinue(
'${l10n.delete} ${l10n.server}($e)',
)),
actions: [
TextButton(
onPressed: () {
Pros.server.delServer(e);
ctx.pop();
setState(() {});
},
child: Text(l10n.ok),
)
],
),
);
},
);
return ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 377),
child: Column(
mainAxisSize: MainAxisSize.min,
children: all.toList(),
),
);
}),
),
final keys = Stores.server.box.keys.toList();
keys.removeWhere((element) => element == BoxX.lastModifiedKey);
final strKeys = List<String>.empty(growable: true);
for (final key in keys) {
if (key is String) strKeys.add(key);
}
final deleteKeys = await context.showPickDialog<String>(
clearable: true,
items: strKeys,
);
if (deleteKeys == null) return;
final md = deleteKeys.map((e) => '- $e').join('\n');
final sure = await context.showRoundDialog(
title: l10n.attention,
child: SimpleMarkdown(data: md),
);
if (sure != true) return;
for (final key in deleteKeys) {
Stores.server.box.delete(key);
}
context.showSnackBar(l10n.success);
},
);
}
@@ -1071,6 +1053,7 @@ class _SettingPageState extends State<SettingPage> {
_buildCollapseUI(),
_buildCupertinoRoute(),
if (isDesktop) _buildHideTitleBar(),
if (isDesktop) PlatformPublicSettings.buildSaveWindowSize(),
],
);
}

View File

@@ -82,9 +82,7 @@ class _IOSSettingsPageState extends State<IOSSettingsPage> {
Widget _buildWatchApp() {
return FutureWidget(
future: () async {
if (!await wc.isPaired) {
return null;
}
if (!await wc.isPaired) return null;
return await wc.applicationContext;
}(),
loading: UIs.centerLoading,
@@ -114,16 +112,15 @@ class _IOSSettingsPageState extends State<IOSSettingsPage> {
void _onTapWatchApp(Map<String, dynamic> map) async {
final urls = Map<String, String>.from(map['urls'] as Map? ?? {});
final result = await AppRoutes.kvEditor(data: urls).go(context);
if (result == null || result! is Map<String, String>) return;
if (result == null || result is! Map<String, String>) return;
try {
await wc.updateApplicationContext({'urls': result});
} catch (e, trace) {
context.showRoundDialog(
title: l10n.error,
child: Text('${l10n.save}:\n$e'),
);
Loggers.app.warning('Update watch config failed', e, trace);
await context.showLoadingDialog(fn: () async {
await wc.updateApplicationContext({'urls': result});
});
} catch (e, s) {
context.showErrDialog(e: e, s: s, operation: 'Watch Context');
Loggers.app.warning('Update watch config failed', e, s);
}
}
}

View File

@@ -2,6 +2,7 @@ import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:server_box/core/extension/context/locale.dart';
import 'package:server_box/data/res/store.dart';
import 'package:window_manager/window_manager.dart';
abstract final class PlatformPublicSettings {
static Widget buildBioAuth() {
@@ -45,4 +46,49 @@ abstract final class PlatformPublicSettings {
},
);
}
static Widget buildSaveWindowSize() {
final isBusy = false.vn;
// Only show [FadeIn] when previous state is busy.
var lastIsBusy = false;
final prop = Stores.setting.windowSize;
return ListTile(
title: Text(l10n.rememberWindowSize),
/// Copied from `fl_build/view/store_switch`
trailing: ValBuilder(
listenable: isBusy,
builder: (busy) {
return ValBuilder(
listenable: prop.listenable(),
builder: (value) {
if (busy) {
lastIsBusy = true;
return UIs.centerSizedLoadingSmall.paddingOnly(right: 17);
}
final switcher = Switch(
value: value.isNotEmpty,
onChanged: (value) async {
isBusy.value = true;
final size = await windowManager.getSize();
isBusy.value = false;
prop.put(size.toIntStr());
},
);
if (lastIsBusy) {
final ret = FadeIn(child: switcher);
lastIsBusy = false;
return ret;
}
return switcher;
},
);
},
),
);
}
}

View File

@@ -1,4 +1,3 @@
import 'package:after_layout/after_layout.dart';
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';

View File

@@ -1,7 +1,6 @@
import 'dart:async';
import 'dart:convert';
import 'package:after_layout/after_layout.dart';
import 'package:dartssh2/dartssh2.dart';
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';

View File

@@ -314,7 +314,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
leading: const Icon(Icons.open_in_new),
title: Text(l10n.open),
onTap: () {
Pfs.sharePath(file.absolute.path);
Pfs.share(path: file.absolute.path);
},
),
],

View File

@@ -1,6 +1,5 @@
import 'dart:async';
import 'package:after_layout/after_layout.dart';
import 'package:dartssh2/dartssh2.dart';
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';

View File

@@ -59,65 +59,84 @@ class _SftpMissionPageState extends State<SftpMissionPage> {
),
);
}
switch (status.status) {
case SftpWorkerStatus.finished:
final time = status.spentTime.toString();
final str = '${l10n.finished} ${l10n.spentTime(
time == 'null' ? l10n.unknown : (time.substring(0, time.length - 7)),
)}';
return _wrapInCard(
status: status,
subtitle: str,
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
onPressed: () {
final idx = status.req.localPath.lastIndexOf('/');
final dir = status.req.localPath.substring(0, idx);
AppRoutes.localStorage(initDir: dir).go(context);
},
icon: const Icon(Icons.file_open)),
IconButton(
onPressed: () => Pfs.sharePath(status.req.localPath),
icon: const Icon(Icons.open_in_new),
)
],
),
);
case SftpWorkerStatus.loading:
final percentStr = (status.progress ?? 0.0).toStringAsFixed(2);
final size = (status.size ?? 0).bytes2Str;
return _wrapInCard(
status: status,
subtitle: l10n.percentOfSize(percentStr, size),
trailing: _buildDelete(status.fileName, status.id),
);
case SftpWorkerStatus.preparing:
return _wrapInCard(
status: status,
subtitle: l10n.sftpDlPrepare,
trailing: _buildDelete(status.fileName, status.id),
);
case SftpWorkerStatus.sshConnectted:
return _wrapInCard(
status: status,
subtitle: l10n.sftpSSHConnected,
trailing: _buildDelete(status.fileName, status.id),
);
default:
return _wrapInCard(
status: status,
subtitle: l10n.unknown,
trailing: IconButton(
onPressed: () => context.showRoundDialog(
title: l10n.error,
child: Text((status.error ?? l10n.unknown).toString()),
),
icon: const Icon(Icons.error),
),
);
}
return switch (status.status) {
const (SftpWorkerStatus.finished) => _buildFinished(status),
const (SftpWorkerStatus.loading) => _buildLoading(status),
const (SftpWorkerStatus.sshConnectted) => _buildConnected(status),
const (SftpWorkerStatus.preparing) => _buildPreparing(status),
_ => _buildDefault(status),
};
}
Widget _buildPreparing(SftpReqStatus status) {
return _wrapInCard(
status: status,
subtitle: l10n.sftpDlPrepare,
trailing: _buildDelete(status.fileName, status.id),
);
}
Widget _buildDefault(SftpReqStatus status) {
return _wrapInCard(
status: status,
subtitle: l10n.unknown,
trailing: IconButton(
onPressed: () => context.showRoundDialog(
title: l10n.error,
child: Text((status.error ?? l10n.unknown).toString()),
),
icon: const Icon(Icons.error),
),
);
}
Widget _buildConnected(SftpReqStatus status) {
return _wrapInCard(
status: status,
subtitle: l10n.sftpSSHConnected,
trailing: _buildDelete(status.fileName, status.id),
);
}
Widget _buildLoading(SftpReqStatus status) {
final percentStr = (status.progress ?? 0.0).toStringAsFixed(2);
final size = (status.size ?? 0).bytes2Str;
return _wrapInCard(
status: status,
subtitle: l10n.percentOfSize(percentStr, size),
trailing: _buildDelete(status.fileName, status.id),
);
}
Widget _buildFinished(SftpReqStatus status) {
final time = status.spentTime.toString();
final str = '${l10n.finished} ${l10n.spentTime(
time == 'null' ? l10n.unknown : (time.substring(0, time.length - 7)),
)}';
final btns = Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
onPressed: () {
final idx = status.req.localPath.lastIndexOf('/');
final dir = status.req.localPath.substring(0, idx);
AppRoutes.localStorage(initDir: dir).go(context);
},
icon: const Icon(Icons.file_open),
),
IconButton(
onPressed: () => Pfs.share(path: status.req.localPath),
icon: const Icon(Icons.open_in_new),
)
],
);
return _wrapInCard(
status: status,
subtitle: str,
trailing: btns,
);
}
Widget _wrapInCard({

View File

@@ -1,9 +1,13 @@
PODS:
- device_info_plus (0.0.1):
- FlutterMacOS
- dynamic_color (0.0.2):
- FlutterMacOS
- FlutterMacOS (1.0.0)
- icloud_storage (0.0.1):
- FlutterMacOS
- package_info_plus (0.0.1):
- FlutterMacOS
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
@@ -16,27 +20,36 @@ PODS:
- FlutterMacOS
- url_launcher_macos (0.0.1):
- FlutterMacOS
- wakelock_plus (0.0.1):
- FlutterMacOS
- window_manager (0.2.0):
- FlutterMacOS
DEPENDENCIES:
- device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
- dynamic_color (from `Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos`)
- FlutterMacOS (from `Flutter/ephemeral`)
- icloud_storage (from `Flutter/ephemeral/.symlinks/plugins/icloud_storage/macos`)
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
- screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`)
- share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`)
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
- wakelock_plus (from `Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos`)
- window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`)
EXTERNAL SOURCES:
device_info_plus:
:path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos
dynamic_color:
:path: Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos
FlutterMacOS:
:path: Flutter/ephemeral
icloud_storage:
:path: Flutter/ephemeral/.symlinks/plugins/icloud_storage/macos
package_info_plus:
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
path_provider_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
screen_retriever:
@@ -47,18 +60,23 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
url_launcher_macos:
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
wakelock_plus:
:path: Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos
window_manager:
:path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos
SPEC CHECKSUMS:
device_info_plus: ce1b7762849d3ec103d0e0517299f2db7ad60720
dynamic_color: 2eaa27267de1ca20d879fbd6e01259773fb1670f
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
icloud_storage: 33b05299e26d1391d724da8d62860e702380a1cd
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38
share_plus: 36537c04ce0c3e3f5bd297ce4318b6d5ee5fd6cf
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399
wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8
PODFILE CHECKSUM: 8cdf29216ea1ab6b9743188287968d22b4579c1d

View File

@@ -471,7 +471,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 970;
CURRENT_PROJECT_VERSION = 992;
DEVELOPMENT_TEAM = BA88US33G6;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Server Box";
@@ -481,7 +481,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 1.0.970;
MARKETING_VERSION = 1.0.992;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "Server Box";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -608,7 +608,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 970;
CURRENT_PROJECT_VERSION = 992;
DEVELOPMENT_TEAM = BA88US33G6;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Server Box";
@@ -618,7 +618,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 1.0.970;
MARKETING_VERSION = 1.0.992;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "Server Box";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -638,7 +638,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 970;
CURRENT_PROJECT_VERSION = 992;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=macosx*]" = BA88US33G6;
INFOPLIST_FILE = Runner/Info.plist;
@@ -649,7 +649,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 1.0.970;
MARKETING_VERSION = 1.0.992;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "Server Box";
PROVISIONING_PROFILE_SPECIFIER = "";

View File

@@ -9,14 +9,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "67.0.0"
after_layout:
dependency: "direct main"
description:
name: after_layout
sha256: "95a1cb2ca1464f44f14769329fbf15987d20ab6c88f8fc5d359bd362be625f29"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
analyzer:
dependency: transitive
description:
@@ -376,8 +368,8 @@ packages:
dependency: "direct dev"
description:
path: "."
ref: "v1.0.17"
resolved-ref: bcb7019cc8bb3ab8c9c36653cd13936909c6e075
ref: "v1.0.30"
resolved-ref: "30d527ddc7f25c9e1fd7aa5f90df1a9c928ed306"
url: "https://github.com/lppcg/fl_build.git"
source: git
version: "1.0.0"
@@ -393,8 +385,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: "v1.0.40"
resolved-ref: "1f547b45bc9083558ee88eafa61df92eb0abf552"
ref: "v1.0.50"
resolved-ref: fc4e847cc0513157b6ac77e9e82ab57edbdc9482
url: "https://github.com/lppcg/fl_lib"
source: git
version: "0.0.1"
@@ -1404,19 +1396,11 @@ packages:
dependency: "direct main"
description:
path: "."
ref: "v1.0.84"
resolved-ref: "50405d87bea86aece143c235b8b17263d37de3ef"
ref: "v1.0.85"
resolved-ref: "13e42750a8f8dbf9a6c7890198b0dd18283a0692"
url: "https://github.com/lollipopkit/watch_connectivity"
source: git
version: "0.1.5"
watch_connectivity_platform_interface:
dependency: transitive
description:
name: watch_connectivity_platform_interface
sha256: "9074115391bd764c08a17346fcbc4d5c0b555672defbe6928ac648503b54aa9c"
url: "https://pub.dev"
source: hosted
version: "0.1.2"
watcher:
dependency: transitive
description:
@@ -1502,8 +1486,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: master
resolved-ref: "13a280e77dd077b439af24ad3d054d318ae5df4a"
ref: "v1.0.586"
resolved-ref: b8c73bec722055f24c5724cd2f2297859e95b6af
url: "https://github.com/lollipopkit/xterm.dart"
source: git
version: "4.0.0"

View File

@@ -1,7 +1,7 @@
name: server_box
description: server status & toolbox app.
publish_to: 'none'
version: 1.0.971+971
version: 1.0.992+992
environment:
sdk: ">=3.0.0"
@@ -14,7 +14,6 @@ dependencies:
provider: ^6.0.0
hive_flutter: ^1.1.0
dio: ^5.2.1
after_layout: ^1.1.0
easy_isolate: ^1.3.0
intl: ^0.19.0
highlight: ^0.7.0
@@ -43,7 +42,7 @@ dependencies:
xterm:
git:
url: https://github.com/lollipopkit/xterm.dart
ref: master
ref: v1.0.586
computer:
git:
url: https://github.com/lollipopkit/dart_computer
@@ -51,7 +50,7 @@ dependencies:
watch_connectivity:
git:
url: https://github.com/lollipopkit/watch_connectivity
ref: v1.0.84
ref: v1.0.85
plain_notification_token:
git:
url: https://github.com/lollipopkit/plain_notification_token
@@ -59,7 +58,7 @@ dependencies:
fl_lib:
git:
url: https://github.com/lppcg/fl_lib
ref: v1.0.40
ref: v1.0.50
dependency_overrides:
# dartssh2:
@@ -80,7 +79,7 @@ dev_dependencies:
# path: ../fl_build
git:
url: https://github.com/lppcg/fl_build.git
ref: v1.0.17
ref: v1.0.30
flutter:
generate: true