✨ Android self-update
This commit is contained in:
parent
d2f37ae45d
commit
358677ade0
@ -1,4 +1,4 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="dev.solsynth.solian">
|
||||||
<uses-feature android:name="android.hardware.camera" />
|
<uses-feature android:name="android.hardware.camera" />
|
||||||
<uses-feature android:name="android.hardware.camera.autofocus" />
|
<uses-feature android:name="android.hardware.camera.autofocus" />
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
|
@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
|
||||||
|
@ -18,7 +18,7 @@ pluginManagement {
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||||
id "com.android.application" version '8.4.0' apply false
|
id "com.android.application" version '8.6.0' apply false
|
||||||
id "com.google.gms.google-services" version "4.3.15" apply false
|
id "com.google.gms.google-services" version "4.3.15" apply false
|
||||||
id "com.google.firebase.crashlytics" version "2.8.1" apply false
|
id "com.google.firebase.crashlytics" version "2.8.1" apply false
|
||||||
id "org.jetbrains.kotlin.android" version '2.0.0' apply false
|
id "org.jetbrains.kotlin.android" version '2.0.0' apply false
|
||||||
|
@ -68,6 +68,11 @@
|
|||||||
"notificationUnreadCount": "@count unread notifications",
|
"notificationUnreadCount": "@count unread notifications",
|
||||||
"errorHappened": "An error occurred",
|
"errorHappened": "An error occurred",
|
||||||
"errorHappenedUnauthorized": "Unauthorized request, please sign in or try resign in.",
|
"errorHappenedUnauthorized": "Unauthorized request, please sign in or try resign in.",
|
||||||
|
"errorHappenedRequestBad": "Request error, the server refused to process the request. Please check your request data.",
|
||||||
|
"errorHappenedRequestForbidden": "Request error, insufficient permissions.",
|
||||||
|
"errorHappenedRequestNotFound": "Request error, the requested data does not exist.",
|
||||||
|
"errorHappenedRequestConnection": "Network request failed. Please check the connection status and service status, then try again.",
|
||||||
|
"errorHappenedRequestUnknown": "Request error, unknown type. Please take a full screenshot of this message and submit feedback.",
|
||||||
"forgotPassword": "Forgot password",
|
"forgotPassword": "Forgot password",
|
||||||
"email": "Email",
|
"email": "Email",
|
||||||
"username": "Username",
|
"username": "Username",
|
||||||
@ -350,8 +355,7 @@
|
|||||||
"bsCheckForUpdate": "Checking For Updates",
|
"bsCheckForUpdate": "Checking For Updates",
|
||||||
"bsCheckForUpdateFailed": "Unable to Check Updates",
|
"bsCheckForUpdateFailed": "Unable to Check Updates",
|
||||||
"bsCheckForUpdateNew": "Found New Version",
|
"bsCheckForUpdateNew": "Found New Version",
|
||||||
"bsCheckForUpdateDescApple": "Please head to TestFlight and update your app to latest version to prevent error happens and get latest functions.",
|
"bsCheckForUpdateDesc": "Please head to app store and update your app to latest version to prevent error happens and get latest functions.",
|
||||||
"bsCheckForUpdateDescCommon": "Please head to our website download and install latest version of application to prevent error happens and get latest functions.",
|
|
||||||
"bsCheckingServer": "Checking Server Status",
|
"bsCheckingServer": "Checking Server Status",
|
||||||
"bsCheckingServerFail": "Unable connect to server, check your network connection",
|
"bsCheckingServerFail": "Unable connect to server, check your network connection",
|
||||||
"bsCheckingServerDown": "Server currently unavailable, please retry later",
|
"bsCheckingServerDown": "Server currently unavailable, please retry later",
|
||||||
@ -422,5 +426,7 @@
|
|||||||
"notificationTopicPostFeedback": "Post feedbacks",
|
"notificationTopicPostFeedback": "Post feedbacks",
|
||||||
"notificationTopicPostSubscription": "Post subscriptions",
|
"notificationTopicPostSubscription": "Post subscriptions",
|
||||||
"preferencesApplied": "Preferences has been applied.",
|
"preferencesApplied": "Preferences has been applied.",
|
||||||
"save": "Save"
|
"save": "Save",
|
||||||
|
"updateAvailable": "Update available",
|
||||||
|
"updateAvailableDesc": "There is an update available (@version). Do you want to download and install it now? You can still use the app normally while waiting for the download to complete."
|
||||||
}
|
}
|
||||||
|
@ -351,8 +351,7 @@
|
|||||||
"bsCheckForUpdate": "正在检查更新",
|
"bsCheckForUpdate": "正在检查更新",
|
||||||
"bsCheckForUpdateFailed": "无法检查更新",
|
"bsCheckForUpdateFailed": "无法检查更新",
|
||||||
"bsCheckForUpdateNew": "发现新版本",
|
"bsCheckForUpdateNew": "发现新版本",
|
||||||
"bsCheckForUpdateDescApple": "请前往 TestFlight 并将您的应用程序更新到最新版本,以防止出现错误并获取最新功能。",
|
"bsCheckForUpdateDesc": "请前往应用商店并将您的应用程序更新到最新版本,以防止出现错误并获取最新功能。",
|
||||||
"bsCheckForUpdateDescCommon": "请前往我们的网站下载并安装最新版本的应用程序,以防止出现错误并获取最新功能。",
|
|
||||||
"bsCheckingServer": "检查服务器状态中",
|
"bsCheckingServer": "检查服务器状态中",
|
||||||
"bsCheckingServerFail": "无法连接至服务器,请检查你的网络连接状态",
|
"bsCheckingServerFail": "无法连接至服务器,请检查你的网络连接状态",
|
||||||
"bsCheckingServerDown": "当前服务器不可用,请稍后重试",
|
"bsCheckingServerDown": "当前服务器不可用,请稍后重试",
|
||||||
@ -423,5 +422,7 @@
|
|||||||
"notificationTopicPostFeedback": "帖子反馈",
|
"notificationTopicPostFeedback": "帖子反馈",
|
||||||
"notificationTopicPostSubscription": "订阅源",
|
"notificationTopicPostSubscription": "订阅源",
|
||||||
"preferencesApplied": "偏好设置已应用",
|
"preferencesApplied": "偏好设置已应用",
|
||||||
"save": "保存"
|
"save": "保存",
|
||||||
|
"updateAvailable": "有可用更新",
|
||||||
|
"updateAvailableDesc": "有可用更新 (@version) 你想现在下载安装吗?在等待下载期间你仍可以正常使用。"
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import 'package:solian/providers/theme_switcher.dart';
|
|||||||
import 'package:solian/providers/websocket.dart';
|
import 'package:solian/providers/websocket.dart';
|
||||||
import 'package:solian/services.dart';
|
import 'package:solian/services.dart';
|
||||||
import 'package:solian/widgets/sized_container.dart';
|
import 'package:solian/widgets/sized_container.dart';
|
||||||
|
import 'package:flutter_app_update/flutter_app_update.dart';
|
||||||
|
|
||||||
class BootstrapperShell extends StatefulWidget {
|
class BootstrapperShell extends StatefulWidget {
|
||||||
final Widget child;
|
final Widget child;
|
||||||
@ -49,15 +50,40 @@ class _BootstrapperShellState extends State<BootstrapperShell> {
|
|||||||
final info = await PackageInfo.fromPlatform();
|
final info = await PackageInfo.fromPlatform();
|
||||||
final localVersionString = '${info.version}+${info.buildNumber}';
|
final localVersionString = '${info.version}+${info.buildNumber}';
|
||||||
final resp = await GetConnect().get(
|
final resp = await GetConnect().get(
|
||||||
'https://git.solsynth.dev/api/v1/repos/hydrogen/solian/tags?limit=1',
|
'https://git.solsynth.dev/api/v1/repos/hydrogen/solian/tags?page=1&limit=1',
|
||||||
);
|
);
|
||||||
if (resp.body[0]['name'] != localVersionString) {
|
if (resp.body[0]['name'] != localVersionString) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isErrored = true;
|
_isErrored = true;
|
||||||
_subtitle = PlatformInfo.isIOS || PlatformInfo.isMacOS
|
_subtitle = 'bsCheckForUpdateDesc'.tr;
|
||||||
? 'bsCheckForUpdateDescApple'.tr
|
|
||||||
: 'bsCheckForUpdateDescCommon'.tr;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (PlatformInfo.isAndroid) {
|
||||||
|
context
|
||||||
|
.showConfirmDialog(
|
||||||
|
'updateAvailable'.tr,
|
||||||
|
'updateAvailableDesc'.trParams({
|
||||||
|
'version': resp.body[0]['name'],
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.then((result) {
|
||||||
|
if (result) {
|
||||||
|
final model = UpdateModel(
|
||||||
|
'https://files.solsynth.dev/d/production01/solian/app-arm64-v8a-release.apk',
|
||||||
|
'solian-app-arm64-v8a-release.apk',
|
||||||
|
'ic_launcher',
|
||||||
|
'https://testflight.apple.com/join/YJ0lmN6O',
|
||||||
|
);
|
||||||
|
AzhonAppUpdate.update(model);
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_isErrored = false;
|
||||||
|
_subtitle = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
@ -51,6 +51,28 @@ extension AppExtensions on BuildContext {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> showConfirmDialog(String title, body) async {
|
||||||
|
return await showDialog<bool>(
|
||||||
|
useRootNavigator: true,
|
||||||
|
context: this,
|
||||||
|
builder: (ctx) => AlertDialog(
|
||||||
|
title: Text(title),
|
||||||
|
content: Text(body),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(ctx, false),
|
||||||
|
child: Text('cancel'.tr),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(ctx, true),
|
||||||
|
child: Text('okay'.tr),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
) ??
|
||||||
|
false;
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> showErrorDialog(dynamic exception) {
|
Future<void> showErrorDialog(dynamic exception) {
|
||||||
Widget content = Text(exception.toString().capitalize!);
|
Widget content = Text(exception.toString().capitalize!);
|
||||||
if (exception is UnauthorizedException) {
|
if (exception is UnauthorizedException) {
|
||||||
|
@ -9,7 +9,6 @@ import 'package:go_router/go_router.dart';
|
|||||||
import 'package:protocol_handler/protocol_handler.dart';
|
import 'package:protocol_handler/protocol_handler.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:solian/background.dart';
|
import 'package:solian/background.dart';
|
||||||
import 'package:solian/bootstrapper.dart';
|
|
||||||
import 'package:solian/firebase_options.dart';
|
import 'package:solian/firebase_options.dart';
|
||||||
import 'package:solian/platform.dart';
|
import 'package:solian/platform.dart';
|
||||||
import 'package:solian/providers/attachment_uploader.dart';
|
import 'package:solian/providers/attachment_uploader.dart';
|
||||||
@ -123,10 +122,8 @@ class SolianApp extends StatelessWidget {
|
|||||||
builder: (context, child) {
|
builder: (context, child) {
|
||||||
return SystemShell(
|
return SystemShell(
|
||||||
child: ScaffoldMessenger(
|
child: ScaffoldMessenger(
|
||||||
child: BootstrapperShell(
|
|
||||||
child: child ?? const SizedBox.shrink(),
|
child: child ?? const SizedBox.shrink(),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:animations/animations.dart';
|
import 'package:animations/animations.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:solian/bootstrapper.dart';
|
||||||
import 'package:solian/models/realm.dart';
|
import 'package:solian/models/realm.dart';
|
||||||
import 'package:solian/screens/about.dart';
|
import 'package:solian/screens/about.dart';
|
||||||
import 'package:solian/screens/account.dart';
|
import 'package:solian/screens/account.dart';
|
||||||
@ -32,10 +33,13 @@ abstract class AppRouter {
|
|||||||
static GoRouter instance = GoRouter(
|
static GoRouter instance = GoRouter(
|
||||||
routes: [
|
routes: [
|
||||||
ShellRoute(
|
ShellRoute(
|
||||||
builder: (context, state, child) => RootShell(
|
builder: (context, state, child) => BootstrapperShell(
|
||||||
|
key: const Key('global-bootstrapper'),
|
||||||
|
child: RootShell(
|
||||||
state: state,
|
state: state,
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
|
),
|
||||||
routes: [
|
routes: [
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/',
|
path: '/',
|
||||||
|
@ -635,6 +635,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.5.0"
|
version: "4.5.0"
|
||||||
|
flutter_app_update:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_app_update
|
||||||
|
sha256: "2b83278d5cc807f543e623d5b466216316104335a4918d9cc4556f39985fe84a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.0"
|
||||||
flutter_background_service:
|
flutter_background_service:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -2,7 +2,7 @@ name: solian
|
|||||||
description: "The Solar Network App"
|
description: "The Solar Network App"
|
||||||
publish_to: "none"
|
publish_to: "none"
|
||||||
|
|
||||||
version: 1.2.1+40
|
version: 1.2.1+41
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.3.4 <4.0.0"
|
sdk: ">=3.3.4 <4.0.0"
|
||||||
@ -80,6 +80,7 @@ dependencies:
|
|||||||
path_provider: ^2.1.4
|
path_provider: ^2.1.4
|
||||||
flutter_background_service: ^5.0.10
|
flutter_background_service: ^5.0.10
|
||||||
flutter_local_notifications: ^17.2.2
|
flutter_local_notifications: ^17.2.2
|
||||||
|
flutter_app_update: ^3.1.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
Reference in New Issue
Block a user