mirror of
https://github.com/immich-app/immich
synced 2025-10-17 18:19:27 +00:00
Merge d83cb6a5f8 into e7d6a066f8
This commit is contained in:
commit
73c167c155
7 changed files with 112 additions and 56 deletions
|
|
@ -474,6 +474,7 @@
|
|||
"app_bar_signout_dialog_title": "Sign out",
|
||||
"app_download_links": "App Download Links",
|
||||
"app_settings": "App Settings",
|
||||
"app_update_available": "An app update is available",
|
||||
"appears_in": "Appears in",
|
||||
"apply_count": "Apply ({count, number})",
|
||||
"archive": "Archive",
|
||||
|
|
@ -705,7 +706,6 @@
|
|||
"comments_and_likes": "Comments & likes",
|
||||
"comments_are_disabled": "Comments are disabled",
|
||||
"common_create_new_album": "Create new album",
|
||||
"common_server_error": "Please check your network connection, make sure the server is reachable and app/server versions are compatible.",
|
||||
"completed": "Completed",
|
||||
"confirm": "Confirm",
|
||||
"confirm_admin_password": "Confirm Admin Password",
|
||||
|
|
@ -1555,13 +1555,9 @@
|
|||
"privacy": "Privacy",
|
||||
"profile": "Profile",
|
||||
"profile_drawer_app_logs": "Logs",
|
||||
"profile_drawer_client_out_of_date_major": "Mobile App is out of date. Please update to the latest major version.",
|
||||
"profile_drawer_client_out_of_date_minor": "Mobile App is out of date. Please update to the latest minor version.",
|
||||
"profile_drawer_client_server_up_to_date": "Client and Server are up-to-date",
|
||||
"profile_drawer_github": "GitHub",
|
||||
"profile_drawer_readonly_mode": "Read-only mode enabled. Long-press the user avatar icon to exit.",
|
||||
"profile_drawer_server_out_of_date_major": "Server is out of date. Please update to the latest major version.",
|
||||
"profile_drawer_server_out_of_date_minor": "Server is out of date. Please update to the latest minor version.",
|
||||
"profile_image_of_user": "Profile image of {user}",
|
||||
"profile_picture_set": "Profile picture set.",
|
||||
"public_album": "Public album",
|
||||
|
|
@ -1790,6 +1786,7 @@
|
|||
"server_online": "Server Online",
|
||||
"server_privacy": "Server Privacy",
|
||||
"server_stats": "Server Stats",
|
||||
"server_update_available": "A server update is available",
|
||||
"server_version": "Server Version",
|
||||
"set": "Set",
|
||||
"set_as_album_cover": "Set as album cover",
|
||||
|
|
@ -2031,6 +2028,7 @@
|
|||
"troubleshoot": "Troubleshoot",
|
||||
"type": "Type",
|
||||
"unable_to_change_pin_code": "Unable to change PIN code",
|
||||
"unable_to_check_version": "Unable to check app or server version",
|
||||
"unable_to_setup_pin_code": "Unable to setup PIN code",
|
||||
"unarchive": "Unarchive",
|
||||
"unarchive_action_prompt": "{count} removed from Archive",
|
||||
|
|
|
|||
|
|
@ -49,3 +49,7 @@ const double kUploadStatusFailed = -1.0;
|
|||
const double kUploadStatusCanceled = -2.0;
|
||||
|
||||
const int kMinMonthsToEnableScrubberSnap = 12;
|
||||
|
||||
const String kImmichAppStoreLink = "https://apps.apple.com/app/immich/id6449244941";
|
||||
const String kImmichPlayStoreLink = "https://play.google.com/store/apps/details?id=app.alextran.immich";
|
||||
const String kImmichLatestRelease = "https://github.com/immich-app/immich/releases/latest";
|
||||
|
|
|
|||
|
|
@ -9,9 +9,11 @@ class ServerInfo {
|
|||
final ServerFeatures serverFeatures;
|
||||
final ServerConfig serverConfig;
|
||||
final ServerDiskInfo serverDiskInfo;
|
||||
final bool isVersionMismatch;
|
||||
final bool isClientOutOfDate;
|
||||
final bool isServerOutOfDate;
|
||||
final bool isNewReleaseAvailable;
|
||||
final String versionMismatchErrorMessage;
|
||||
final bool errorGettingVersions;
|
||||
|
||||
const ServerInfo({
|
||||
required this.serverVersion,
|
||||
|
|
@ -19,9 +21,11 @@ class ServerInfo {
|
|||
required this.serverFeatures,
|
||||
required this.serverConfig,
|
||||
required this.serverDiskInfo,
|
||||
required this.isVersionMismatch,
|
||||
required this.isClientOutOfDate,
|
||||
required this.isServerOutOfDate,
|
||||
required this.isNewReleaseAvailable,
|
||||
required this.versionMismatchErrorMessage,
|
||||
required this.errorGettingVersions,
|
||||
});
|
||||
|
||||
ServerInfo copyWith({
|
||||
|
|
@ -30,9 +34,11 @@ class ServerInfo {
|
|||
ServerFeatures? serverFeatures,
|
||||
ServerConfig? serverConfig,
|
||||
ServerDiskInfo? serverDiskInfo,
|
||||
bool? isVersionMismatch,
|
||||
bool? isClientOutOfDate,
|
||||
bool? isServerOutOfDate,
|
||||
bool? isNewReleaseAvailable,
|
||||
String? versionMismatchErrorMessage,
|
||||
bool? errorGettingVersions,
|
||||
}) {
|
||||
return ServerInfo(
|
||||
serverVersion: serverVersion ?? this.serverVersion,
|
||||
|
|
@ -40,15 +46,17 @@ class ServerInfo {
|
|||
serverFeatures: serverFeatures ?? this.serverFeatures,
|
||||
serverConfig: serverConfig ?? this.serverConfig,
|
||||
serverDiskInfo: serverDiskInfo ?? this.serverDiskInfo,
|
||||
isVersionMismatch: isVersionMismatch ?? this.isVersionMismatch,
|
||||
isClientOutOfDate: isClientOutOfDate ?? this.isClientOutOfDate,
|
||||
isServerOutOfDate: isServerOutOfDate ?? this.isServerOutOfDate,
|
||||
isNewReleaseAvailable: isNewReleaseAvailable ?? this.isNewReleaseAvailable,
|
||||
versionMismatchErrorMessage: versionMismatchErrorMessage ?? this.versionMismatchErrorMessage,
|
||||
errorGettingVersions: errorGettingVersions ?? this.errorGettingVersions,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ServerInfo(serverVersion: $serverVersion, latestVersion: $latestVersion, serverFeatures: $serverFeatures, serverConfig: $serverConfig, serverDiskInfo: $serverDiskInfo, isVersionMismatch: $isVersionMismatch, isNewReleaseAvailable: $isNewReleaseAvailable, versionMismatchErrorMessage: $versionMismatchErrorMessage)';
|
||||
return 'ServerInfo(serverVersion: $serverVersion, latestVersion: $latestVersion, serverFeatures: $serverFeatures, serverConfig: $serverConfig, serverDiskInfo: $serverDiskInfo, isClientOutOfDate: $isClientOutOfDate, isServerOutOfDate: $isServerOutOfDate, isNewReleaseAvailable: $isNewReleaseAvailable, versionMismatchErrorMessage: $versionMismatchErrorMessage, errorGettingVersions: $errorGettingVersions)';
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -61,9 +69,11 @@ class ServerInfo {
|
|||
other.serverFeatures == serverFeatures &&
|
||||
other.serverConfig == serverConfig &&
|
||||
other.serverDiskInfo == serverDiskInfo &&
|
||||
other.isVersionMismatch == isVersionMismatch &&
|
||||
other.isClientOutOfDate == isClientOutOfDate &&
|
||||
other.isServerOutOfDate == isServerOutOfDate &&
|
||||
other.isNewReleaseAvailable == isNewReleaseAvailable &&
|
||||
other.versionMismatchErrorMessage == versionMismatchErrorMessage;
|
||||
other.versionMismatchErrorMessage == versionMismatchErrorMessage &&
|
||||
other.errorGettingVersions == errorGettingVersions;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -73,8 +83,10 @@ class ServerInfo {
|
|||
serverFeatures.hashCode ^
|
||||
serverConfig.hashCode ^
|
||||
serverDiskInfo.hashCode ^
|
||||
isVersionMismatch.hashCode ^
|
||||
isClientOutOfDate.hashCode ^
|
||||
isServerOutOfDate.hashCode ^
|
||||
isNewReleaseAvailable.hashCode ^
|
||||
versionMismatchErrorMessage.hashCode;
|
||||
versionMismatchErrorMessage.hashCode ^
|
||||
errorGettingVersions.hashCode;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,11 @@ class ServerInfoNotifier extends StateNotifier<ServerInfo> {
|
|||
mapDarkStyleUrl: 'https://tiles.immich.cloud/v1/style/dark.json',
|
||||
),
|
||||
serverDiskInfo: ServerDiskInfo(diskAvailable: "0", diskSize: "0", diskUse: "0", diskUsagePercentage: 0),
|
||||
isVersionMismatch: false,
|
||||
isClientOutOfDate: false,
|
||||
isServerOutOfDate: false,
|
||||
isNewReleaseAvailable: false,
|
||||
versionMismatchErrorMessage: "",
|
||||
errorGettingVersions: false,
|
||||
),
|
||||
);
|
||||
|
||||
|
|
@ -43,15 +45,16 @@ class ServerInfoNotifier extends StateNotifier<ServerInfo> {
|
|||
try {
|
||||
final serverVersion = await _serverInfoService.getServerVersion();
|
||||
|
||||
// using isClientOutOfDate since that will show to users reguardless of if they are an admin
|
||||
if (serverVersion == null) {
|
||||
state = state.copyWith(isVersionMismatch: true, versionMismatchErrorMessage: "common_server_error".tr());
|
||||
state = state.copyWith(errorGettingVersions: true, versionMismatchErrorMessage: "unable_to_check_version".tr());
|
||||
return;
|
||||
}
|
||||
|
||||
await _checkServerVersionMismatch(serverVersion);
|
||||
} catch (e, stackTrace) {
|
||||
_log.severe("Failed to get server version", e, stackTrace);
|
||||
state = state.copyWith(isVersionMismatch: true);
|
||||
state = state.copyWith(errorGettingVersions: true, versionMismatchErrorMessage: "unable_to_check_version".tr());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -63,39 +66,17 @@ class ServerInfoNotifier extends StateNotifier<ServerInfo> {
|
|||
|
||||
Map<String, int> appVersion = _getDetailVersion(packageInfo.version);
|
||||
|
||||
if (appVersion["major"]! > serverVersion.major) {
|
||||
state = state.copyWith(
|
||||
isVersionMismatch: true,
|
||||
versionMismatchErrorMessage: "profile_drawer_server_out_of_date_major".tr(),
|
||||
);
|
||||
if (appVersion["major"]! > serverVersion.major || appVersion["minor"]! > serverVersion.minor) {
|
||||
state = state.copyWith(isServerOutOfDate: true, versionMismatchErrorMessage: "server_update_available".tr());
|
||||
return;
|
||||
}
|
||||
|
||||
if (appVersion["major"]! < serverVersion.major) {
|
||||
state = state.copyWith(
|
||||
isVersionMismatch: true,
|
||||
versionMismatchErrorMessage: "profile_drawer_client_out_of_date_major".tr(),
|
||||
);
|
||||
if (appVersion["major"]! < serverVersion.major || appVersion["minor"]! < serverVersion.minor) {
|
||||
state = state.copyWith(isClientOutOfDate: true, versionMismatchErrorMessage: "app_update_available".tr());
|
||||
return;
|
||||
}
|
||||
|
||||
if (appVersion["minor"]! > serverVersion.minor) {
|
||||
state = state.copyWith(
|
||||
isVersionMismatch: true,
|
||||
versionMismatchErrorMessage: "profile_drawer_server_out_of_date_minor".tr(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (appVersion["minor"]! < serverVersion.minor) {
|
||||
state = state.copyWith(
|
||||
isVersionMismatch: true,
|
||||
versionMismatchErrorMessage: "profile_drawer_client_out_of_date_minor".tr(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
state = state.copyWith(isVersionMismatch: false, versionMismatchErrorMessage: "");
|
||||
state = state.copyWith(isClientOutOfDate: false, isServerOutOfDate: false, versionMismatchErrorMessage: "");
|
||||
}
|
||||
|
||||
handleNewRelease(ServerVersion serverVersion, ServerVersion latestVersion) {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,19 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart' hide Store;
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/constants/constants.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||
import 'package:immich_mobile/models/server_info/server_info.model.dart';
|
||||
import 'package:immich_mobile/providers/locale_provider.dart';
|
||||
import 'package:immich_mobile/providers/server_info.provider.dart';
|
||||
import 'package:immich_mobile/providers/user.provider.dart';
|
||||
import 'package:immich_mobile/utils/url_helper.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class AppBarServerInfo extends HookConsumerWidget {
|
||||
const AppBarServerInfo({super.key});
|
||||
|
|
@ -18,16 +23,44 @@ class AppBarServerInfo extends HookConsumerWidget {
|
|||
ref.watch(localeProvider);
|
||||
ServerInfo serverInfoState = ref.watch(serverInfoProvider);
|
||||
|
||||
final user = ref.watch(currentUserProvider);
|
||||
|
||||
final appInfo = useState({});
|
||||
const titleFontSize = 12.0;
|
||||
const contentFontSize = 11.0;
|
||||
|
||||
final showWarning =
|
||||
serverInfoState.isClientOutOfDate ||
|
||||
serverInfoState.errorGettingVersions ||
|
||||
((user?.isAdmin ?? false) && serverInfoState.isServerOutOfDate);
|
||||
|
||||
getPackageInfo() async {
|
||||
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||||
|
||||
appInfo.value = {"version": packageInfo.version, "buildNumber": packageInfo.buildNumber};
|
||||
}
|
||||
|
||||
void openUpdateLink() {
|
||||
if (serverInfoState.isServerOutOfDate) {
|
||||
launchUrl(
|
||||
Uri.parse("https://github.com/immich-app/immich/releases/latest"),
|
||||
mode: LaunchMode.externalApplication,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
String url;
|
||||
if (Platform.isIOS) {
|
||||
url = kImmichAppStoreLink;
|
||||
} else if (Platform.isAndroid) {
|
||||
url = kImmichPlayStoreLink;
|
||||
} else {
|
||||
url = kImmichLatestRelease;
|
||||
}
|
||||
|
||||
launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication);
|
||||
}
|
||||
|
||||
useEffect(() {
|
||||
getPackageInfo();
|
||||
return null;
|
||||
|
|
@ -45,17 +78,45 @@ class AppBarServerInfo extends HookConsumerWidget {
|
|||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
if (showWarning) ...[
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Color.fromARGB(80, 243, 188, 106),
|
||||
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
serverInfoState.isVersionMismatch
|
||||
? serverInfoState.versionMismatchErrorMessage
|
||||
: "profile_drawer_client_server_up_to_date".tr(),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(fontSize: 11, color: context.primaryColor, fontWeight: FontWeight.w500),
|
||||
serverInfoState.versionMismatchErrorMessage,
|
||||
textAlign: (serverInfoState.isClientOutOfDate || serverInfoState.isServerOutOfDate)
|
||||
? TextAlign.start
|
||||
: TextAlign.center,
|
||||
style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w500),
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
if (serverInfoState.isClientOutOfDate || serverInfoState.isServerOutOfDate)
|
||||
TextButton(
|
||||
onPressed: openUpdateLink,
|
||||
style: TextButton.styleFrom(
|
||||
padding: const EdgeInsets.all(4),
|
||||
minimumSize: const Size(0, 0),
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
),
|
||||
child: Text("action_common_update".tr(context: context)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const Padding(padding: EdgeInsets.symmetric(horizontal: 10), child: Divider(thickness: 1)),
|
||||
],
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
|
|||
backgroundColor: Colors.transparent,
|
||||
alignment: Alignment.bottomRight,
|
||||
isLabelVisible:
|
||||
serverInfoState.isVersionMismatch || ((user?.isAdmin ?? false) && serverInfoState.isNewReleaseAvailable),
|
||||
serverInfoState.isClientOutOfDate || ((user?.isAdmin ?? false) && serverInfoState.isNewReleaseAvailable),
|
||||
offset: const Offset(-2, -12),
|
||||
child: user == null
|
||||
? const Icon(Icons.face_outlined, size: widgetSize)
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ class _ProfileIndicator extends ConsumerWidget {
|
|||
backgroundColor: Colors.transparent,
|
||||
alignment: Alignment.bottomRight,
|
||||
isLabelVisible:
|
||||
serverInfoState.isVersionMismatch || ((user?.isAdmin ?? false) && serverInfoState.isNewReleaseAvailable),
|
||||
serverInfoState.isClientOutOfDate || ((user?.isAdmin ?? false) && serverInfoState.isNewReleaseAvailable),
|
||||
offset: const Offset(-2, -12),
|
||||
child: user == null
|
||||
? const Icon(Icons.face_outlined, size: widgetSize)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue