From fbabd8c3516f25393c904bb609b210e7d7b610a7 Mon Sep 17 00:00:00 2001 From: lollipopkit Date: Mon, 27 May 2024 20:52:46 +0800 Subject: [PATCH] new: wear settings (#358) & opt.: android widget edit --- .github/workflows/release.yml | 20 +++-- lib/app.dart | 2 +- lib/core/route.dart | 4 + lib/view/page/home/wear.dart | 27 ++++++- lib/view/page/setting/entry.dart | 24 ++++-- lib/view/page/setting/platform/android.dart | 83 ++++++++++++++------- pubspec.lock | 2 +- 7 files changed, 119 insertions(+), 43 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index adbe5336..1645ba3f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,22 +11,32 @@ permissions: jobs: releaseAL: name: Release android and linux - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@v4 + with: + fetch-depth: '0' - name: Install Flutter uses: subosito/flutter-action@v2 + - uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: '17' + - name: Fetch secrets + run: | + curl -u ${{ secrets.BASIC_AUTH }} -o android/app/app.key ${{ secrets.URL_PREFIX }}app.key + 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: Create Release uses: softprops/action-gh-release@v1 with: files: | - build/app/outputs/flutter-apk/${{ env.APP_NAME }}_arm64.apk - build/app/outputs/flutter-apk/${{ env.APP_NAME }}_arm.apk - build/app/outputs/flutter-apk/${{ env.APP_NAME }}_amd64.apk - ${{ env.APP_NAME }}_amd64.AppImage + 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 + ${{ env.APP_NAME }}_${{ env.BUILD_NUMBER }}_amd64.AppImage env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/lib/app.dart b/lib/app.dart index 195ae307..a501f7b9 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -1,6 +1,6 @@ import 'package:dynamic_color/dynamic_color.dart'; import 'package:fl_lib/fl_lib.dart'; -import 'package:fl_lib/l10n/gen/lib_l10n.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:toolbox/data/res/build_data.dart'; diff --git a/lib/core/route.dart b/lib/core/route.dart index de29e6c0..a45d1bd8 100644 --- a/lib/core/route.dart +++ b/lib/core/route.dart @@ -246,4 +246,8 @@ class AppRoutes { static AppRoutes pve({Key? key, required ServerPrivateInfo spi}) { return AppRoutes(PvePage(key: key, spi: spi), 'pve'); } + + static AppRoutes kvEditor({Key? key, required Map data}) { + return AppRoutes(KvEditor(key: key, data: data), 'kv_editor'); + } } diff --git a/lib/view/page/home/wear.dart b/lib/view/page/home/wear.dart index 3227f891..d4070ee4 100644 --- a/lib/view/page/home/wear.dart +++ b/lib/view/page/home/wear.dart @@ -16,7 +16,7 @@ final class WearHome extends StatefulWidget { const WearHome({super.key}); @override - _WearHomeState createState() => _WearHomeState(); + State createState() => _WearHomeState(); } final class _WearHomeState extends State with AfterLayoutMixin { @@ -61,11 +61,30 @@ final class _WearHomeState extends State with AfterLayoutMixin { } Widget _buildEachSever(Server srv) { - return const Padding( - padding: EdgeInsets.all(7), + final mem = () { + final total = srv.status.mem.total; + final used = srv.status.mem.total - srv.status.mem.avail; + return '${used.bytes2Str} / ${total.bytes2Str}'; + }(); + final disk = () { + final total = srv.status.diskUsage?.size.kb2Str; + final used = srv.status.diskUsage?.used.kb2Str; + return '$used / $total'; + }(); + final net = '↓ ${srv.status.netSpeed.cachedRealVals.speedIn}' + '↑ ${srv.status.netSpeed.cachedRealVals.speedOut}'; + return Padding( + padding: const EdgeInsets.all(7), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [], + children: [ + Text(srv.spi.name, style: UIs.text15Bold), + UIs.height7, + KvRow(k: 'CPU', v: '${srv.status.cpu.usedPercent()}%'), + KvRow(k: 'Mem', v: mem), + KvRow(k: 'Disk', v: disk), + KvRow(k: 'Net', v: net) + ], ), ); } diff --git a/lib/view/page/setting/entry.dart b/lib/view/page/setting/entry.dart index e8e70e6e..302970de 100644 --- a/lib/view/page/setting/entry.dart +++ b/lib/view/page/setting/entry.dart @@ -1163,19 +1163,29 @@ class _SettingPageState extends State { return ListTile( leading: const Icon(Icons.image), title: Text('Logo ${l10n.addr}'), - subtitle: SimpleMarkdown(data: '[${l10n.doc}](${Urls.appWiki})'), trailing: const Icon(Icons.keyboard_arrow_right), onTap: () { final ctrl = TextEditingController(text: _setting.serverLogoUrl.fetch()); context.showRoundDialog( title: 'Logo ${l10n.addr}', - child: Input( - controller: ctrl, - autoFocus: true, - hint: 'https://example.com/logo.png', - icon: Icons.link, - onSubmitted: onSave, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Input( + controller: ctrl, + autoFocus: true, + hint: 'https://example.com/logo.png', + icon: Icons.link, + maxLines: 3, + onSubmitted: onSave, + ), + ListTile( + title: Text(l10n.doc), + trailing: const Icon(Icons.open_in_new), + onTap: () => Urls.appWiki.launch(), + ), + ], ), actions: [ TextButton( diff --git a/lib/view/page/setting/platform/android.dart b/lib/view/page/setting/platform/android.dart index fd803b8c..1a4c99be 100644 --- a/lib/view/page/setting/platform/android.dart +++ b/lib/view/page/setting/platform/android.dart @@ -1,21 +1,22 @@ -import 'dart:convert'; - import 'package:fl_lib/fl_lib.dart'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:toolbox/core/extension/context/locale.dart'; +import 'package:toolbox/core/route.dart'; import 'package:toolbox/data/res/store.dart'; import 'package:toolbox/view/page/setting/platform/platform_pub.dart'; +import 'package:watch_connectivity/watch_connectivity.dart'; class AndroidSettingsPage extends StatefulWidget { const AndroidSettingsPage({super.key}); @override - _AndroidSettingsPageState createState() => _AndroidSettingsPageState(); + State createState() => _AndroidSettingsPageState(); } class _AndroidSettingsPageState extends State { late SharedPreferences _sp; + final wc = WatchConnectivity(); @override void initState() { @@ -34,6 +35,7 @@ class _AndroidSettingsPageState extends State { children: [ _buildBgRun(), _buildAndroidWidgetSharedPreference(), + _buildWatch(), if (BioAuth.isPlatformSupported) PlatformPublicSettings.buildBioAuth(), ].map((e) => CardX(child: e)).toList(), @@ -49,10 +51,9 @@ class _AndroidSettingsPageState extends State { ); } - void _saveWidgetSP(String data, Map old) { + void _saveWidgetSP(Map map, Map old) { context.pop(); try { - final map = Map.from(json.decode(data)); final keysDel = old.keys.toSet().difference(map.keys.toSet()); for (final key in keysDel) { _sp.remove(key); @@ -70,7 +71,7 @@ class _AndroidSettingsPageState extends State { return ListTile( title: Text(l10n.homeWidgetUrlConfig), trailing: const Icon(Icons.keyboard_arrow_right), - onTap: () { + onTap: () async { final data = {}; _sp.getKeys().forEach((key) { final val = _sp.getString(key); @@ -78,25 +79,57 @@ class _AndroidSettingsPageState extends State { data[key] = val; } }); - final ctrl = TextEditingController(text: json.encode(data)); - context.showRoundDialog( - title: l10n.homeWidgetUrlConfig, - child: Input( - autoFocus: true, - controller: ctrl, - label: 'JSON', - type: TextInputType.visiblePassword, - maxLines: 7, - onSubmitted: (p0) => _saveWidgetSP(p0, data), - ), - actions: [ - TextButton( - onPressed: () { - _saveWidgetSP(ctrl.text, data); - }, - child: Text(l10n.ok), - ), - ], + final result = await AppRoutes.kvEditor(data: data).go(context); + if (result != null) { + if (result is Map) { + _saveWidgetSP(result, data); + } else { + final err = 'Save Android widget SharedPreference failed: ' + 'unexpected type: ${result.runtimeType}'; + Loggers.app.warning(err); + context.showRoundDialog( + title: l10n.error, + child: SingleChildScrollView( + child: SimpleMarkdown(data: '$err\n\n```$result```'), + ), + ); + } + } + }, + ); + } + + Widget _buildWatch() { + return FutureWidget( + future: wc.isReachable, + error: (e, s) { + Loggers.app.warning('WatchOS error', e, s); + return ListTile( + title: const Text('Watch app'), + subtitle: Text(l10n.viewErr, style: UIs.textGrey), + trailing: const Icon(Icons.keyboard_arrow_right), + onTap: () { + context.showRoundDialog( + title: l10n.error, + child: SingleChildScrollView( + child: SimpleMarkdown(data: '${e.toString()}\n```$s```'), + ), + ); + }, + ); + }, + success: (val) { + if (val == null) { + return ListTile( + title: const Text('Watch app'), + subtitle: Text(l10n.watchNotPaired, style: UIs.textGrey), + ); + } + return ListTile( + title: const Text('Watch app'), + subtitle: Text(l10n.sync, style: UIs.textGrey), + trailing: const Icon(Icons.keyboard_arrow_right), + onTap: () async {}, ); }, ); diff --git a/pubspec.lock b/pubspec.lock index a1d88759..e321e7c8 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -410,7 +410,7 @@ packages: description: path: "." ref: main - resolved-ref: a2aa5359253ad83000ff2612ed2c5729cb0dcfc5 + resolved-ref: "4a3ac8cec9b39a08790101e45ff80a42c6dfd36a" url: "https://github.com/lollipopkit/fl_lib" source: git version: "0.0.1"