diff --git a/mobile/lib/modules/backup/background_service/background.service.dart b/mobile/lib/modules/backup/background_service/background.service.dart index c05341627a..1e3e120851 100644 --- a/mobile/lib/modules/backup/background_service/background.service.dart +++ b/mobile/lib/modules/backup/background_service/background.service.dart @@ -357,7 +357,6 @@ class BackgroundService { Hive.openBox(hiveBackupInfoBox), ]); ApiService apiService = ApiService(); - apiService.setEndpoint(Hive.box(userInfoBox).get(serverEndpointKey)); apiService.setAccessToken(Hive.box(userInfoBox).get(accessTokenKey)); BackupService backupService = BackupService(apiService); AppSettingsService settingsService = AppSettingsService(); diff --git a/mobile/lib/modules/login/providers/authentication.provider.dart b/mobile/lib/modules/login/providers/authentication.provider.dart index 6c02fd98a1..ed83595295 100644 --- a/mobile/lib/modules/login/providers/authentication.provider.dart +++ b/mobile/lib/modules/login/providers/authentication.provider.dart @@ -59,10 +59,8 @@ class AuthenticationNotifier extends StateNotifier { ) async { try { // Resolve API server endpoint from user provided serverUrl - final serverEndpoint = await _apiService.resolveEndpoint(serverUrl); - _apiService.setEndpoint(serverEndpoint); + await _apiService.resolveAndSetEndpoint(serverUrl); await _apiService.serverInfoApi.pingServer(); - Hive.box(userInfoBox).put(serverEndpointKey, serverEndpoint); } catch (e) { debugPrint('Invalid Server Endpoint Url $e'); return false; diff --git a/mobile/lib/modules/login/services/oauth.service.dart b/mobile/lib/modules/login/services/oauth.service.dart index 688164162a..f056898f36 100644 --- a/mobile/lib/modules/login/services/oauth.service.dart +++ b/mobile/lib/modules/login/services/oauth.service.dart @@ -14,8 +14,7 @@ class OAuthService { String serverUrl, ) async { // Resolve API server endpoint from user provided serverUrl - final serverEndpoint = await _apiService.resolveEndpoint(serverUrl); - _apiService.setEndpoint(serverEndpoint); + await _apiService.resolveAndSetEndpoint(serverUrl); return await _apiService.oAuthApi.generateConfig( OAuthConfigDto(redirectUri: '$callbackUrlScheme:/'), diff --git a/mobile/lib/modules/login/ui/login_form.dart b/mobile/lib/modules/login/ui/login_form.dart index 230252a3df..a355527523 100644 --- a/mobile/lib/modules/login/ui/login_form.dart +++ b/mobile/lib/modules/login/ui/login_form.dart @@ -42,9 +42,7 @@ class LoginForm extends HookConsumerWidget { if (serverUrl.isNotEmpty) { isLoading.value = true; final serverEndpoint = - await apiService.resolveEndpoint(serverUrl.toString()); - apiService.setEndpoint(serverEndpoint); - Hive.box(userInfoBox).put(serverEndpointKey, serverEndpoint); + await apiService.resolveAndSetEndpoint(serverUrl.toString()); var loginConfig = await apiService.oAuthApi.generateConfig( OAuthConfigDto(redirectUri: serverEndpoint), @@ -218,11 +216,11 @@ class ServerEndpointInput extends StatelessWidget { String? _validateInput(String? url) { if (url == null || url.isEmpty) return null; - final validate = Uri.tryParse(sanitizeUrl(url)); - if (validate == null || - !validate.isAbsolute || - !validate.scheme.startsWith("http") || - validate.host.isEmpty) { + final parsedUrl = Uri.tryParse(sanitizeUrl(url)); + if (parsedUrl == null || + !parsedUrl.isAbsolute || + !parsedUrl.scheme.startsWith("http") || + parsedUrl.host.isEmpty) { return 'login_form_err_invalid_url'.tr(); } return null; diff --git a/mobile/lib/shared/services/api.service.dart b/mobile/lib/shared/services/api.service.dart index 28e03a23d5..3251883e72 100644 --- a/mobile/lib/shared/services/api.service.dart +++ b/mobile/lib/shared/services/api.service.dart @@ -1,6 +1,8 @@ import 'dart:convert'; import 'package:flutter/material.dart'; +import 'package:hive/hive.dart'; +import 'package:immich_mobile/constants/hive_box.dart'; import 'package:immich_mobile/utils/url_helper.dart'; import 'package:openapi/api.dart'; import 'package:http/http.dart'; @@ -16,6 +18,17 @@ class ApiService { late ServerInfoApi serverInfoApi; late DeviceInfoApi deviceInfoApi; + ApiService() { + if (Hive.isBoxOpen(userInfoBox)) { + final endpoint = Hive.box(userInfoBox).get(serverEndpointKey) as String; + if (endpoint.isNotEmpty) { + setEndpoint(endpoint); + } + } else { + debugPrint("Cannot init ApiServer endpoint, userInfoBox not open yet."); + } + } + setEndpoint(String endpoint) { _apiClient = ApiClient(basePath: endpoint); userApi = UserApi(_apiClient); @@ -27,6 +40,15 @@ class ApiService { deviceInfoApi = DeviceInfoApi(_apiClient); } + Future resolveAndSetEndpoint(String serverUrl) async { + final endpoint = await _resolveEndpoint(serverUrl); + setEndpoint(endpoint); + + // Save in hivebox for next startup + Hive.box(userInfoBox).put(serverEndpointKey, endpoint); + return endpoint; + } + /// Takes a server URL and attempts to resolve the API endpoint. /// /// Input: [schema://]host[:port][/path] @@ -34,18 +56,18 @@ class ApiService { /// host - required /// port - optional (default: based on schema) /// path - optional - Future resolveEndpoint(String serverUrl) async { + Future _resolveEndpoint(String serverUrl) async { final url = sanitizeUrl(serverUrl); // Check for /.well-known/immich - final wellKnownEndpoint = await getWellKnownEndpoint(url); + final wellKnownEndpoint = await _getWellKnownEndpoint(url); if (wellKnownEndpoint.isNotEmpty) return wellKnownEndpoint; // Otherwise, assume the URL provided is the api endpoint return url; } - Future getWellKnownEndpoint(String baseUrl) async { + Future _getWellKnownEndpoint(String baseUrl) async { final Client client = Client(); try { diff --git a/mobile/lib/shared/views/splash_screen.dart b/mobile/lib/shared/views/splash_screen.dart index 37c009d50d..7aa973fcf6 100644 --- a/mobile/lib/shared/views/splash_screen.dart +++ b/mobile/lib/shared/views/splash_screen.dart @@ -23,10 +23,7 @@ class SplashScreenPage extends HookConsumerWidget { try { if (loginInfo != null) { // Resolve API server endpoint from user provided serverUrl - final serverEndpoint = - await apiService.resolveEndpoint(loginInfo.serverUrl); - apiService.setEndpoint(serverEndpoint); - Hive.box(userInfoBox).put(serverEndpointKey, serverEndpoint); + await apiService.resolveAndSetEndpoint(loginInfo.serverUrl); var isSuccess = await ref .read(authenticationProvider.notifier)