diff --git a/mobile/lib/utils/version_compatibility.dart b/mobile/lib/utils/version_compatibility.dart index b997b8524c..55dbdc6269 100644 --- a/mobile/lib/utils/version_compatibility.dart +++ b/mobile/lib/utils/version_compatibility.dart @@ -1,7 +1,16 @@ -String? getVersionCompatibilityMessage(int _, int appMinor, int _, int serverMinor) { +import 'package:immich_mobile/utils/semver.dart'; + +String? getVersionCompatibilityMessage(SemVer serverVersion, SemVer appVersion) { // Add latest compat info up top - if (serverMinor < 106 && appMinor >= 106) { - return 'Your app minor version is not compatible with the server! Please update your server to version v1.106.0 or newer to login'; + + // ensure mobile app major version is not behind server major version + if (appVersion.major < serverVersion.major) { + return 'Your mobile app version is not compatible with the server! Please update your mobile app to the latest version.'; + } + + // ensure mobile app major version is not ahead of server major version by more than 1 major version + if (appVersion.major > serverVersion.major + 1) { + return 'Your server version is not compatible with the mobile app! Please update your server to the latest version.'; } return null; diff --git a/mobile/lib/widgets/forms/login/login_form.dart b/mobile/lib/widgets/forms/login/login_form.dart index 7615218159..9adf15b448 100644 --- a/mobile/lib/widgets/forms/login/login_form.dart +++ b/mobile/lib/widgets/forms/login/login_form.dart @@ -26,6 +26,7 @@ import 'package:immich_mobile/providers/websocket.provider.dart'; import 'package:immich_mobile/repositories/permission.repository.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/utils/provider_utils.dart'; +import 'package:immich_mobile/utils/semver.dart'; import 'package:immich_mobile/utils/url_helper.dart'; import 'package:immich_mobile/utils/version_compatibility.dart'; import 'package:immich_mobile/widgets/common/immich_logo.dart'; @@ -88,18 +89,9 @@ class LoginForm extends HookConsumerWidget { checkVersionMismatch() async { try { final packageInfo = await PackageInfo.fromPlatform(); - final appVersion = packageInfo.version; - final appMajorVersion = int.parse(appVersion.split('.')[0]); - final appMinorVersion = int.parse(appVersion.split('.')[1]); - final serverMajorVersion = serverInfo.serverVersion.major; - final serverMinorVersion = serverInfo.serverVersion.minor; - - warningMessage.value = getVersionCompatibilityMessage( - appMajorVersion, - appMinorVersion, - serverMajorVersion, - serverMinorVersion, - ); + final appSemVer = SemVer.fromString(packageInfo.version); + final serverSemVer = serverInfo.serverVersion; + warningMessage.value = getVersionCompatibilityMessage(appSemVer, serverSemVer); } catch (error) { warningMessage.value = 'Error checking version compatibility'; } diff --git a/mobile/test/modules/utils/version_compatibility_test.dart b/mobile/test/modules/utils/version_compatibility_test.dart index 6f1abc218f..70f3d9ef8c 100644 --- a/mobile/test/modules/utils/version_compatibility_test.dart +++ b/mobile/test/modules/utils/version_compatibility_test.dart @@ -1,29 +1,47 @@ import 'package:flutter_test/flutter_test.dart'; +import 'package:immich_mobile/utils/semver.dart'; import 'package:immich_mobile/utils/version_compatibility.dart'; void main() { - test('getVersionCompatibilityMessage', () { - String? result; + group('app major version behind server', () { + const message = + 'Your mobile app version is not compatible with the server! Please update your mobile app to the latest version.'; - result = getVersionCompatibilityMessage(1, 106, 1, 105); - expect( - result, - 'Your app minor version is not compatible with the server! Please update your server to version v1.106.0 or newer to login', - ); + test('returns message when app major is behind server major', () { + final result = getVersionCompatibilityMessage( + const SemVer(major: 2, minor: 0, patch: 0), + const SemVer(major: 1, minor: 200, patch: 0), + ); + expect(result, message); + }); - result = getVersionCompatibilityMessage(1, 107, 1, 105); - expect( - result, - 'Your app minor version is not compatible with the server! Please update your server to version v1.106.0 or newer to login', - ); + test('returns null when app major matches server major', () { + final result = getVersionCompatibilityMessage( + const SemVer(major: 2, minor: 0, patch: 0), + const SemVer(major: 2, minor: 0, patch: 0), + ); + expect(result, null); + }); + }); - result = getVersionCompatibilityMessage(1, 106, 1, 106); - expect(result, null); + group('app major version too far ahead of server', () { + const message = + 'Your server version is not compatible with the mobile app! Please update your server to the latest version.'; - result = getVersionCompatibilityMessage(1, 107, 1, 106); - expect(result, null); + test('returns message when app major is more than one ahead of server', () { + final result = getVersionCompatibilityMessage( + const SemVer(major: 1, minor: 200, patch: 0), + const SemVer(major: 3, minor: 0, patch: 0), + ); + expect(result, message); + }); - result = getVersionCompatibilityMessage(1, 107, 1, 108); - expect(result, null); + test('returns null when app major is exactly one ahead of server', () { + final result = getVersionCompatibilityMessage( + const SemVer(major: 1, minor: 200, patch: 0), + const SemVer(major: 2, minor: 0, patch: 0), + ); + expect(result, null); + }); }); }