fix & opt

fix: android in-app upgrade
fmt: proj struct
opt: fetch primaryColor
This commit is contained in:
lollipopkit
2023-02-01 12:52:40 +08:00
parent 068089d207
commit 4d741ac82a
30 changed files with 523 additions and 448 deletions

View File

@@ -11,7 +11,7 @@ import '../data/res/build_data.dart';
import '../data/service/app.dart';
import '../generated/l10n.dart';
import '../locator.dart';
import 'utils.dart';
import 'utils/ui.dart';
final _logger = Logger('UPDATE');
@@ -74,7 +74,7 @@ Future<void> doUpdate(BuildContext context, {bool force = false}) async {
Future<void> _doUpdate(AppUpdate update, BuildContext context, S s) async {
if (Platform.isAndroid) {
await RUpgrade.upgrade(update.android,
fileName: update.android.split('/').last);
fileName: update.android.split('/').last, isAutoRequestInstall: true);
} else if (Platform.isIOS) {
await RUpgrade.upgradeFromAppStore('1586449703');
} else {

23
lib/core/utils/misc.dart Normal file
View File

@@ -0,0 +1,23 @@
import 'dart:io';
import 'package:flutter/widgets.dart';
import 'package:share_plus/share_plus.dart';
import '../../generated/l10n.dart';
Future<bool> shareFiles(BuildContext context, List<String> filePaths) async {
for (final filePath in filePaths) {
if (!await File(filePath).exists()) {
return false;
}
}
var text = '';
if (filePaths.length == 1) {
text = filePaths.first.split('/').last;
} else {
text = '${filePaths.length} ${S.of(context).files}';
}
final xfiles = filePaths.map((e) => XFile(e)).toList();
await Share.shareXFiles(xfiles, text: 'ServerBox -> $text');
return filePaths.isNotEmpty;
}

View File

@@ -0,0 +1,32 @@
import 'dart:async';
import 'package:dartssh2/dartssh2.dart';
import 'package:flutter/foundation.dart';
import '../../data/model/server/server_private_info.dart';
import '../../data/store/private_key.dart';
import '../../locator.dart';
/// Must put this func out of any Class.
/// Because of this function is called by [compute] in [ServerProvider.genClient].
/// https://stackoverflow.com/questions/51998995/invalid-arguments-illegal-argument-in-isolate-message-object-is-a-closure
List<SSHKeyPair> loadIndentity(String key) {
return SSHKeyPair.fromPem(key);
}
Future<SSHClient> genClient(ServerPrivateInfo spi) async {
final socket = await SSHSocket.connect(spi.ip, spi.port);
if (spi.pubKeyId == null) {
return SSHClient(
socket,
username: spi.user,
onPasswordRequest: () => spi.pwd,
);
}
final key = locator<PrivateKeyStore>().get(spi.pubKeyId!);
return SSHClient(
socket,
username: spi.user,
identities: await compute(loadIndentity, key.privateKey),
);
}

View File

@@ -1,22 +1,13 @@
import 'dart:async';
import 'dart:io';
import 'package:dartssh2/dartssh2.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:share_plus/share_plus.dart';
import 'package:toolbox/core/persistant_store.dart';
import 'package:toolbox/generated/l10n.dart';
import 'package:toolbox/view/widget/card_dialog.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:toolbox/core/extension/stringx.dart';
import 'package:url_launcher/url_launcher.dart';
/// Must put this func out of any Class.
/// Because of this function is called by [compute] in [ServerProvider.genClient].
/// https://stackoverflow.com/questions/51998995/invalid-arguments-illegal-argument-in-isolate-message-object-is-a-closure
List<SSHKeyPair> loadIndentity(String key) {
return SSHKeyPair.fromPem(key);
}
import '../../generated/l10n.dart';
import '../../view/widget/card_dialog.dart';
import '../persistant_store.dart';
bool isDarkMode(BuildContext context) =>
Theme.of(context).brightness == Brightness.dark;
@@ -79,37 +70,6 @@ void setTransparentNavigationBar(BuildContext context) {
}
}
String tabTitleName(BuildContext context, int i) {
final s = S.of(context);
switch (i) {
case 0:
return s.server;
case 1:
return s.convert;
case 2:
return s.ping;
default:
return '';
}
}
Future<bool> shareFiles(BuildContext context, List<String> filePaths) async {
for (final filePath in filePaths) {
if (!await File(filePath).exists()) {
return false;
}
}
var text = '';
if (filePaths.length == 1) {
text = filePaths.first.split('/').last;
} else {
text = '${filePaths.length} ${S.of(context).files}';
}
final xfiles = filePaths.map((e) => XFile(e)).toList();
await Share.shareXFiles(xfiles, text: 'ServerBox -> $text');
return filePaths.isNotEmpty;
}
Widget buildPopuopMenu(
{required List<PopupMenuEntry> items,
required Function(dynamic) onSelected}) {
@@ -127,3 +87,17 @@ Widget buildPopuopMenu(
),
);
}
String tabTitleName(BuildContext context, int i) {
final s = S.of(context);
switch (i) {
case 0:
return s.server;
case 1:
return s.convert;
case 2:
return s.ping;
default:
return '';
}
}