new: support msg push

This commit is contained in:
lollipopkit
2023-03-12 16:06:51 +08:00
parent 35b5d1ccb5
commit 4c4153ef98
12 changed files with 113 additions and 25 deletions

View File

@@ -447,6 +447,12 @@ abstract class S {
/// **'Found {count} update'** /// **'Found {count} update'**
String foundNUpdate(Object count); String foundNUpdate(Object count);
/// No description provided for @getPushTokenFailed.
///
/// In en, this message translates to:
/// **'Can\'t fetch push token'**
String get getPushTokenFailed;
/// No description provided for @go. /// No description provided for @go.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -765,6 +771,12 @@ abstract class S {
/// **'Private Key'** /// **'Private Key'**
String get privateKey; String get privateKey;
/// No description provided for @pushToken.
///
/// In en, this message translates to:
/// **'Push token'**
String get pushToken;
/// No description provided for @pwd. /// No description provided for @pwd.
/// ///
/// In en, this message translates to: /// In en, this message translates to:

View File

@@ -197,6 +197,9 @@ class SEn extends S {
return 'Found $count update'; return 'Found $count update';
} }
@override
String get getPushTokenFailed => 'Can\'t fetch push token';
@override @override
String get go => 'Go'; String get go => 'Go';
@@ -362,6 +365,9 @@ class SEn extends S {
@override @override
String get privateKey => 'Private Key'; String get privateKey => 'Private Key';
@override
String get pushToken => 'Push token';
@override @override
String get pwd => 'Password'; String get pwd => 'Password';

View File

@@ -197,6 +197,9 @@ class SZh extends S {
return '找到 $count 个更新'; return '找到 $count 个更新';
} }
@override
String get getPushTokenFailed => '未能获取到推送token';
@override @override
String get go => '开始'; String get go => '开始';
@@ -362,6 +365,9 @@ class SZh extends S {
@override @override
String get privateKey => '私钥'; String get privateKey => '私钥';
@override
String get pushToken => '消息推送 Token';
@override @override
String get pwd => '密码'; String get pwd => '密码';

View File

@@ -9,6 +9,8 @@ PODS:
- path_provider_foundation (0.0.1): - path_provider_foundation (0.0.1):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
- plain_notification_token (0.0.1):
- Flutter
- r_upgrade (0.0.1): - r_upgrade (0.0.1):
- Flutter - Flutter
- share_plus (0.0.1): - share_plus (0.0.1):
@@ -22,6 +24,7 @@ DEPENDENCIES:
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
- plain_notification_token (from `.symlinks/plugins/plain_notification_token/ios`)
- r_upgrade (from `.symlinks/plugins/r_upgrade/ios`) - r_upgrade (from `.symlinks/plugins/r_upgrade/ios`)
- share_plus (from `.symlinks/plugins/share_plus/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
@@ -37,6 +40,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_native_splash/ios" :path: ".symlinks/plugins/flutter_native_splash/ios"
path_provider_foundation: path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/ios" :path: ".symlinks/plugins/path_provider_foundation/ios"
plain_notification_token:
:path: ".symlinks/plugins/plain_notification_token/ios"
r_upgrade: r_upgrade:
:path: ".symlinks/plugins/r_upgrade/ios" :path: ".symlinks/plugins/r_upgrade/ios"
share_plus: share_plus:
@@ -50,6 +55,7 @@ SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9 path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
plain_notification_token: b36467dc91939a7b6754267c701bbaca14996ee1
r_upgrade: 44d715c61914cce3d01ea225abffe894fd51c114 r_upgrade: 44d715c61914cce3d01ea225abffe894fd51c114
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68 share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4 url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4

View File

@@ -47,6 +47,7 @@
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9C5314B89F1F73A1900CCAFD /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; }; 9C5314B89F1F73A1900CCAFD /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
A775F241DEE026555178AC01 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; }; A775F241DEE026555178AC01 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
E398BF6A29BDB34500FE4FD5 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@@ -104,6 +105,7 @@
97C146F01CF9000F007C117D /* Runner */ = { 97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
E398BF6A29BDB34500FE4FD5 /* Runner.entitlements */,
97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
@@ -356,6 +358,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 228; CURRENT_PROJECT_VERSION = 228;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@@ -486,6 +489,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 228; CURRENT_PROJECT_VERSION = 228;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@@ -510,6 +514,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 228; CURRENT_PROJECT_VERSION = 228;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
</dict>
</plist>

View File

@@ -4,6 +4,7 @@ import 'package:file_picker/file_picker.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:plain_notification_token/plain_notification_token.dart';
import 'package:share_plus/share_plus.dart'; import 'package:share_plus/share_plus.dart';
Future<bool> shareFiles(BuildContext context, List<String> filePaths) async { Future<bool> shareFiles(BuildContext context, List<String> filePaths) async {
@@ -31,3 +32,16 @@ Future<String?> pickOneFile() async {
final result = await FilePicker.platform.pickFiles(type: FileType.any); final result = await FilePicker.platform.pickFiles(type: FileType.any);
return result?.files.single.path; return result?.files.single.path;
} }
Future<String?> getToken() async {
final plainNotificationToken = PlainNotificationToken();
if (Platform.isIOS) {
plainNotificationToken.requestPermission();
// If you want to wait until Permission dialog close,
// you need wait changing setting registered.
await plainNotificationToken.onIosSettingsRegistered.first;
}
return await plainNotificationToken.getToken();
}

View File

@@ -58,6 +58,7 @@
"fileTooLarge": "File '{file}' too large {size}, max {sizeMax}", "fileTooLarge": "File '{file}' too large {size}, max {sizeMax}",
"files": "Files", "files": "Files",
"foundNUpdate": "Found {count} update", "foundNUpdate": "Found {count} update",
"getPushTokenFailed": "Can't fetch push token",
"go": "Go", "go": "Go",
"goto": "Go to", "goto": "Go to",
"host": "Host", "host": "Host",
@@ -111,6 +112,7 @@
"port": "Port", "port": "Port",
"preview": "Preview", "preview": "Preview",
"privateKey": "Private Key", "privateKey": "Private Key",
"pushToken": "Push token",
"pwd": "Password", "pwd": "Password",
"rename": "Rename", "rename": "Rename",
"reportBugsOnGithubIssue": "Please report bugs on {url}", "reportBugsOnGithubIssue": "Please report bugs on {url}",

View File

@@ -58,6 +58,7 @@
"fileTooLarge": "文件 '{file}' 过大 '{size}',超过了 {sizeMax}", "fileTooLarge": "文件 '{file}' 过大 '{size}',超过了 {sizeMax}",
"files": "文件", "files": "文件",
"foundNUpdate": "找到 {count} 个更新", "foundNUpdate": "找到 {count} 个更新",
"getPushTokenFailed": "未能获取到推送token",
"go": "开始", "go": "开始",
"goto": "前往", "goto": "前往",
"host": "主机", "host": "主机",
@@ -111,6 +112,7 @@
"port": "端口", "port": "端口",
"preview": "预览", "preview": "预览",
"privateKey": "私钥", "privateKey": "私钥",
"pushToken": "消息推送 Token",
"pwd": "密码", "pwd": "密码",
"rename": "重命名", "rename": "重命名",
"reportBugsOnGithubIssue": "请到 {url} 提交问题", "reportBugsOnGithubIssue": "请到 {url} 提交问题",

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter_material_color_picker/flutter_material_color_picker.dart'; import 'package:flutter_material_color_picker/flutter_material_color_picker.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:toolbox/core/utils/misc.dart';
import '../../data/model/ssh/terminal_color.dart'; import '../../data/model/ssh/terminal_color.dart';
import '../../core/update.dart'; import '../../core/update.dart';
@@ -36,6 +37,8 @@ class _SettingPageState extends State<SettingPage> {
late double _maxRetryCount; late double _maxRetryCount;
late double _updateInterval; late double _updateInterval;
String? _pushToken;
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
@@ -70,6 +73,7 @@ class _SettingPageState extends State<SettingPage> {
// Server // Server
_buildTitle(_s.server), _buildTitle(_s.server),
_buildServer(), _buildServer(),
const SizedBox(height: 37),
], ],
), ),
); );
@@ -81,7 +85,6 @@ class _SettingPageState extends State<SettingPage> {
child: Center( child: Center(
child: Text( child: Text(
text, text,
style: textSize13,
), ),
), ),
); );
@@ -90,10 +93,11 @@ class _SettingPageState extends State<SettingPage> {
Widget _buildApp() { Widget _buildApp() {
return Column( return Column(
children: [ children: [
_buildNightMode(), _buildThemeMode(),
_buildAppColorPreview(), _buildAppColorPreview(),
_buildLaunchPage(), _buildLaunchPage(),
_buildCheckUpdate(), _buildCheckUpdate(),
_buildPushToken(),
].map((e) => RoundRectCard(e)).toList(), ].map((e) => RoundRectCard(e)).toList(),
); );
} }
@@ -113,11 +117,10 @@ class _SettingPageState extends State<SettingPage> {
return ListTile( return ListTile(
title: Text( title: Text(
_s.showDistLogo, _s.showDistLogo,
style: textSize13,
), ),
subtitle: Text( subtitle: Text(
_s.onServerDetailPage, _s.onServerDetailPage,
style: textSize13Grey, style: grey,
), ),
trailing: buildSwitch(context, _setting.showDistLogo), trailing: buildSwitch(context, _setting.showDistLogo),
); );
@@ -140,8 +143,6 @@ class _SettingPageState extends State<SettingPage> {
trailing: const Icon(Icons.keyboard_arrow_right), trailing: const Icon(Icons.keyboard_arrow_right),
title: Text( title: Text(
display, display,
style: textSize13,
textAlign: TextAlign.start,
), ),
onTap: () => doUpdate(context, force: true), onTap: () => doUpdate(context, force: true),
); );
@@ -154,16 +155,13 @@ class _SettingPageState extends State<SettingPage> {
textColor: primaryColor, textColor: primaryColor,
title: Text( title: Text(
_s.updateServerStatusInterval, _s.updateServerStatusInterval,
style: textSize13,
textAlign: TextAlign.start,
), ),
subtitle: Text( subtitle: Text(
_s.willTakEeffectImmediately, _s.willTakEeffectImmediately,
style: textSize13Grey, style: grey,
), ),
trailing: Text( trailing: Text(
'${_updateInterval.toInt()} ${_s.second}', '${_updateInterval.toInt()} ${_s.second}',
style: textSize13,
), ),
children: [ children: [
Slider( Slider(
@@ -190,7 +188,7 @@ class _SettingPageState extends State<SettingPage> {
_updateInterval == 0.0 _updateInterval == 0.0
? Text( ? Text(
_s.updateIntervalEqual0, _s.updateIntervalEqual0,
style: const TextStyle(color: Colors.grey, fontSize: 12), style: grey,
textAlign: TextAlign.center, textAlign: TextAlign.center,
) )
: const SizedBox(), : const SizedBox(),
@@ -213,7 +211,6 @@ class _SettingPageState extends State<SettingPage> {
), ),
title: Text( title: Text(
_s.appPrimaryColor, _s.appPrimaryColor,
style: textSize13,
), ),
children: [_buildAppColorPicker(), _buildColorPickerConfirmBtn()], children: [_buildAppColorPicker(), _buildColorPickerConfirmBtn()],
); );
@@ -245,13 +242,11 @@ class _SettingPageState extends State<SettingPage> {
textColor: primaryColor, textColor: primaryColor,
title: Text( title: Text(
_s.launchPage, _s.launchPage,
style: textSize13,
), ),
trailing: ConstrainedBox( trailing: ConstrainedBox(
constraints: BoxConstraints(maxWidth: _media.size.width * 0.35), constraints: BoxConstraints(maxWidth: _media.size.width * 0.35),
child: Text( child: Text(
tabTitleName(context, _launchPageIdx), tabTitleName(context, _launchPageIdx),
style: textSize13,
textAlign: TextAlign.right, textAlign: TextAlign.right,
), ),
), ),
@@ -261,7 +256,6 @@ class _SettingPageState extends State<SettingPage> {
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
title: Text( title: Text(
tabTitleName(context, tabs.indexOf(e)), tabTitleName(context, tabs.indexOf(e)),
style: textSize13,
), ),
trailing: _buildRadio(tabs.indexOf(e)), trailing: _buildRadio(tabs.indexOf(e)),
), ),
@@ -289,11 +283,9 @@ class _SettingPageState extends State<SettingPage> {
childrenPadding: const EdgeInsets.only(left: 17), childrenPadding: const EdgeInsets.only(left: 17),
title: Text( title: Text(
_s.termTheme, _s.termTheme,
style: textSize13,
), ),
trailing: Text( trailing: Text(
TerminalColorsPlatform.values[_termThemeIdx].name, TerminalColorsPlatform.values[_termThemeIdx].name,
style: textSize13,
), ),
children: _buildTermThemeRadioList(), children: _buildTermThemeRadioList(),
); );
@@ -306,7 +298,6 @@ class _SettingPageState extends State<SettingPage> {
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
title: Text( title: Text(
e.name, e.name,
style: textSize13,
), ),
trailing: _buildTermThemeRadio(e), trailing: _buildTermThemeRadio(e),
), ),
@@ -333,12 +324,10 @@ class _SettingPageState extends State<SettingPage> {
textColor: primaryColor, textColor: primaryColor,
title: Text( title: Text(
_s.maxRetryCount, _s.maxRetryCount,
style: textSize13,
textAlign: TextAlign.start, textAlign: TextAlign.start,
), ),
trailing: Text( trailing: Text(
'${_maxRetryCount.toInt()} ${_s.times}', '${_maxRetryCount.toInt()} ${_s.times}',
style: textSize13,
), ),
children: [ children: [
Slider( Slider(
@@ -364,7 +353,7 @@ class _SettingPageState extends State<SettingPage> {
_maxRetryCount == 0.0 _maxRetryCount == 0.0
? Text( ? Text(
_s.maxRetryCountEqual0, _s.maxRetryCountEqual0,
style: const TextStyle(color: Colors.grey, fontSize: 12), style: grey,
textAlign: TextAlign.center, textAlign: TextAlign.center,
) )
: const SizedBox(), : const SizedBox(),
@@ -375,17 +364,14 @@ class _SettingPageState extends State<SettingPage> {
); );
} }
Widget _buildNightMode() { Widget _buildThemeMode() {
return ExpansionTile( return ExpansionTile(
textColor: primaryColor, textColor: primaryColor,
title: Text( title: Text(
_s.themeMode, _s.themeMode,
style: textSize13,
textAlign: TextAlign.start,
), ),
trailing: Text( trailing: Text(
_buildNightModeStr(_nightMode), _buildNightModeStr(_nightMode),
style: textSize13,
), ),
children: [ children: [
Slider( Slider(
@@ -419,4 +405,36 @@ class _SettingPageState extends State<SettingPage> {
return _s.auto; return _s.auto;
} }
} }
Widget _buildPushToken() {
return ListTile(
title: Text(
_s.pushToken,
),
trailing: TextButton(
child: Text(_s.copy),
onPressed: () {
if (_pushToken != null) {
copy(_pushToken!);
} else {
showSnackBar(context, Text(_s.getPushTokenFailed));
}
},
),
subtitle: FutureBuilder<String?>(
future: getToken(),
builder: (context, snapshot) {
if (snapshot.hasData) {
_pushToken = snapshot.data;
}
return Text(
_pushToken ?? 'Getting Token...',
style: grey,
overflow: TextOverflow.ellipsis,
maxLines: 1,
);
},
),
);
}
} }

View File

@@ -646,6 +646,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.5.1" version: "0.5.1"
plain_notification_token:
dependency: "direct main"
description:
name: plain_notification_token
sha256: "32481c1c6ad76613ed38822ffe819ea5d5534f9e07e8ff1d44aafe069f45ea24"
url: "https://pub.dev"
source: hosted
version: "0.0.4"
platform: platform:
dependency: transitive dependency: transitive
description: description:

View File

@@ -57,6 +57,7 @@ dependencies:
xterm: xterm:
path: ../xterm.dart path: ../xterm.dart
file_picker: ^5.2.5 file_picker: ^5.2.5
plain_notification_token: ^0.0.4
dev_dependencies: dev_dependencies:
flutter_native_splash: ^2.1.6 flutter_native_splash: ^2.1.6