feat(mobile): ios widgets (#19148)

* feat: working widgets

* chore/feat: cleaned up API, added album picker to random widget

* album filtering for requests

* check album and throw if not found

* fix app IDs and project configuration

* switch to repository/service model for updating widgets

* fix: remove home widget import

* revert info.plist formatting changes

* ran swift-format on widget code

* more formatting changes (this time run from xcode)

* show memory on widget picker snapshot

* fix: dart changes from code review

* fix: swift code review changes (not including task groups)

* fix: use task groups to run image retrievals concurrently, get rid of do catch in favor of if let

* chore: cleanup widget service in dart app

* chore: format swift

* fix: remove comma

why does xcode not freak out over this >:(

* switch to preview size for thumbnail

* chore: cropped large image

* fix: properly resize widgets so we dont OOM

* fix: set app group on logout

happens on first install

* fix: stupid app ids

* fix: revert back to thumbnail

we are hitting OOM exceptions due to resizing, once we have on-the-fly resizing on server this can be upgraded

* fix: more memory efficient resizing method, remove extraneous resize commands from API call

* fix: random widget use 12 entries instead of 24 to save memory

* fix: modify duration of entries to 20 minutes and only generate 10 at a time to avoid OOM

* feat: toggle to show album name on random widget

* Podfile lock

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
Brandon Wees 2025-06-17 09:43:09 -05:00 committed by GitHub
parent 15c488ccd9
commit a0f44f147b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 1092 additions and 1 deletions

View file

@ -13,6 +13,7 @@ import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
import 'package:immich_mobile/services/api.service.dart';
import 'package:immich_mobile/services/auth.service.dart';
import 'package:immich_mobile/services/secure_storage.service.dart';
import 'package:immich_mobile/services/widget.service.dart';
import 'package:immich_mobile/utils/hash.dart';
import 'package:logging/logging.dart';
import 'package:openapi/api.dart';
@ -23,6 +24,7 @@ final authProvider = StateNotifierProvider<AuthNotifier, AuthState>((ref) {
ref.watch(apiServiceProvider),
ref.watch(userServiceProvider),
ref.watch(secureStorageServiceProvider),
ref.watch(widgetServiceProvider),
);
});
@ -31,6 +33,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
final ApiService _apiService;
final UserService _userService;
final SecureStorageService _secureStorageService;
final WidgetService _widgetService;
final _log = Logger("AuthenticationNotifier");
static const Duration _timeoutDuration = Duration(seconds: 7);
@ -40,6 +43,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
this._apiService,
this._userService,
this._secureStorageService,
this._widgetService,
) : super(
AuthState(
deviceId: "",
@ -76,6 +80,8 @@ class AuthNotifier extends StateNotifier<AuthState> {
Future<void> logout() async {
try {
await _secureStorageService.delete(kSecuredPinCode);
await _widgetService.clearCredentials();
await _authService.logout();
} finally {
await _cleanUp();
@ -112,6 +118,11 @@ class AuthNotifier extends StateNotifier<AuthState> {
}) async {
await _apiService.setAccessToken(accessToken);
await _widgetService.writeCredentials(
Store.get(StoreKey.serverEndpoint),
accessToken,
);
// Get the deviceid from the store if it exists, otherwise generate a new one
String deviceId =
Store.tryGet(StoreKey.deviceId) ?? await FlutterUdid.consistentUdid;