Add service provider (#250)

* optimize android side gradle settings

* android minsdk back to 21

* remove unused package, update linter and fix lint error

* clean code of 'shared module' with offical dart style guide

* restore uploadProfileImage method in UserService

* add service provider

* fix searchFocusNode init error
This commit is contained in:
xpwmaosldk 2022-06-26 03:46:51 +09:00 committed by GitHub
parent 485b152beb
commit d02b97e1c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 288 additions and 157 deletions

View File

@ -20,20 +20,26 @@ class ImageViewerPage extends HookConsumerWidget {
final String heroTag; final String heroTag;
final String thumbnailUrl; final String thumbnailUrl;
final ImmichAsset asset; final ImmichAsset asset;
final AssetService _assetService = AssetService();
ImmichAssetWithExif? assetDetail; ImmichAssetWithExif? assetDetail;
ImageViewerPage( ImageViewerPage({
{Key? key, required this.imageUrl, required this.heroTag, required this.thumbnailUrl, required this.asset}) Key? key,
: super(key: key); required this.imageUrl,
required this.heroTag,
required this.thumbnailUrl,
required this.asset,
}) : super(key: key);
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final downloadAssetStatus = ref.watch(imageViewerStateProvider).downloadAssetStatus; final downloadAssetStatus =
ref.watch(imageViewerStateProvider).downloadAssetStatus;
var box = Hive.box(userInfoBox); var box = Hive.box(userInfoBox);
getAssetExif() async { getAssetExif() async {
assetDetail = await _assetService.getAssetById(asset.id); assetDetail =
await ref.watch(assetServiceProvider).getAssetById(asset.id);
} }
showInfo() { showInfo() {
@ -59,31 +65,32 @@ class ImageViewerPage extends HookConsumerWidget {
asset: asset, asset: asset,
onMoreInfoPressed: showInfo, onMoreInfoPressed: showInfo,
onDownloadPressed: () { onDownloadPressed: () {
ref.watch(imageViewerStateProvider.notifier).downloadAsset(asset, context); ref
.watch(imageViewerStateProvider.notifier)
.downloadAsset(asset, context);
}, },
), ),
body: SafeArea( body: SafeArea(
child: Stack( child: Stack(
children: [ children: [
Center( Center(
child: Hero( child: Hero(
tag: heroTag, tag: heroTag,
child: RemotePhotoView( child: RemotePhotoView(
thumbnailUrl: thumbnailUrl, thumbnailUrl: thumbnailUrl,
imageUrl: imageUrl, imageUrl: imageUrl,
authToken: "Bearer ${box.get(accessTokenKey)}", authToken: "Bearer ${box.get(accessTokenKey)}",
onSwipeDown: () => AutoRouter.of(context).pop(), onSwipeDown: () => AutoRouter.of(context).pop(),
onSwipeUp: () => showInfo(), onSwipeUp: () => showInfo(),
) )),
), ),
if (downloadAssetStatus == DownloadAssetStatus.loading)
const Center(
child: DownloadLoadingIndicator(),
), ),
if (downloadAssetStatus == DownloadAssetStatus.loading) ],
const Center(
child: DownloadLoadingIndicator(),
),
],
),
), ),
),
); );
} }
} }

View File

@ -21,13 +21,14 @@ class VideoViewerPage extends HookConsumerWidget {
final String videoUrl; final String videoUrl;
final ImmichAsset asset; final ImmichAsset asset;
ImmichAssetWithExif? assetDetail; ImmichAssetWithExif? assetDetail;
final AssetService _assetService = AssetService();
VideoViewerPage({Key? key, required this.videoUrl, required this.asset}) : super(key: key); VideoViewerPage({Key? key, required this.videoUrl, required this.asset})
: super(key: key);
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final downloadAssetStatus = ref.watch(imageViewerStateProvider).downloadAssetStatus; final downloadAssetStatus =
ref.watch(imageViewerStateProvider).downloadAssetStatus;
String jwtToken = Hive.box(userInfoBox).get(accessTokenKey); String jwtToken = Hive.box(userInfoBox).get(accessTokenKey);
@ -44,7 +45,8 @@ class VideoViewerPage extends HookConsumerWidget {
} }
getAssetExif() async { getAssetExif() async {
assetDetail = await _assetService.getAssetById(asset.id); assetDetail =
await ref.watch(assetServiceProvider).getAssetById(asset.id);
} }
useEffect(() { useEffect(() {
@ -60,7 +62,9 @@ class VideoViewerPage extends HookConsumerWidget {
showInfo(); showInfo();
}, },
onDownloadPressed: () { onDownloadPressed: () {
ref.watch(imageViewerStateProvider.notifier).downloadAsset(asset, context); ref
.watch(imageViewerStateProvider.notifier)
.downloadAsset(asset, context);
}, },
), ),
body: SwipeDetector( body: SwipeDetector(
@ -93,7 +97,8 @@ class VideoThumbnailPlayer extends StatefulWidget {
final String url; final String url;
final String? jwtToken; final String? jwtToken;
const VideoThumbnailPlayer({Key? key, required this.url, this.jwtToken}) : super(key: key); const VideoThumbnailPlayer({Key? key, required this.url, this.jwtToken})
: super(key: key);
@override @override
State<VideoThumbnailPlayer> createState() => _VideoThumbnailPlayerState(); State<VideoThumbnailPlayer> createState() => _VideoThumbnailPlayerState();
@ -111,8 +116,8 @@ class _VideoThumbnailPlayerState extends State<VideoThumbnailPlayer> {
Future<void> initializePlayer() async { Future<void> initializePlayer() async {
try { try {
videoPlayerController = videoPlayerController = VideoPlayerController.network(widget.url,
VideoPlayerController.network(widget.url, httpHeaders: {"Authorization": "Bearer ${widget.jwtToken}"}); httpHeaders: {"Authorization": "Bearer ${widget.jwtToken}"});
await videoPlayerController.initialize(); await videoPlayerController.initialize();
_createChewieController(); _createChewieController();
@ -142,7 +147,8 @@ class _VideoThumbnailPlayerState extends State<VideoThumbnailPlayer> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return chewieController != null && chewieController!.videoPlayerController.value.isInitialized return chewieController != null &&
chewieController!.videoPlayerController.value.isInitialized
? SizedBox( ? SizedBox(
child: Chewie( child: Chewie(
controller: chewieController!, controller: chewieController!,

View File

@ -7,13 +7,14 @@ import 'package:immich_mobile/modules/backup/models/available_album.model.dart';
import 'package:immich_mobile/modules/backup/models/backup_state.model.dart'; import 'package:immich_mobile/modules/backup/models/backup_state.model.dart';
import 'package:immich_mobile/modules/backup/models/hive_backup_albums.model.dart'; import 'package:immich_mobile/modules/backup/models/hive_backup_albums.model.dart';
import 'package:immich_mobile/modules/backup/services/backup.service.dart'; import 'package:immich_mobile/modules/backup/services/backup.service.dart';
import 'package:immich_mobile/modules/login/models/authentication_state.model.dart';
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart'; import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
import 'package:immich_mobile/shared/models/server_info.model.dart'; import 'package:immich_mobile/shared/models/server_info.model.dart';
import 'package:immich_mobile/shared/services/server_info.service.dart'; import 'package:immich_mobile/shared/services/server_info.service.dart';
import 'package:photo_manager/photo_manager.dart'; import 'package:photo_manager/photo_manager.dart';
class BackupNotifier extends StateNotifier<BackUpState> { class BackupNotifier extends StateNotifier<BackUpState> {
BackupNotifier({this.ref}) BackupNotifier(this._backupService, this._serverInfoService, this._authState)
: super( : super(
BackUpState( BackUpState(
backupProgress: BackUpProgressEnum.idle, backupProgress: BackUpProgressEnum.idle,
@ -37,9 +38,9 @@ class BackupNotifier extends StateNotifier<BackUpState> {
), ),
); );
Ref? ref; final BackupService _backupService;
final BackupService _backupService = BackupService(); final ServerInfoService _serverInfoService;
final ServerInfoService _serverInfoService = ServerInfoService(); final AuthenticationState _authState;
/// ///
/// UI INTERACTION /// UI INTERACTION
@ -338,38 +339,38 @@ class BackupNotifier extends StateNotifier<BackUpState> {
} }
void resumeBackup() { void resumeBackup() {
var authState = ref?.read(authenticationProvider);
// Check if user is login // Check if user is login
var accessKey = Hive.box(userInfoBox).get(accessTokenKey); var accessKey = Hive.box(userInfoBox).get(accessTokenKey);
// User has been logged out return // User has been logged out return
if (authState != null) { if (accessKey == null || !_authState.isAuthenticated) {
if (accessKey == null || !authState.isAuthenticated) { debugPrint("[resumeBackup] not authenticated - abort");
debugPrint("[resumeBackup] not authenticated - abort"); return;
}
// Check if this device is enable backup by the user
if ((_authState.deviceInfo.deviceId == _authState.deviceId) &&
_authState.deviceInfo.isAutoBackup) {
// check if backup is alreayd in process - then return
if (state.backupProgress == BackUpProgressEnum.inProgress) {
debugPrint("[resumeBackup] Backup is already in progress - abort");
return; return;
} }
// Check if this device is enable backup by the user // Run backup
if ((authState.deviceInfo.deviceId == authState.deviceId) && debugPrint("[resumeBackup] Start back up");
authState.deviceInfo.isAutoBackup) { startBackupProcess();
// check if backup is alreayd in process - then return
if (state.backupProgress == BackUpProgressEnum.inProgress) {
debugPrint("[resumeBackup] Backup is already in progress - abort");
return;
}
// Run backup
debugPrint("[resumeBackup] Start back up");
startBackupProcess();
}
return;
} }
return;
} }
} }
final backupProvider = final backupProvider =
StateNotifierProvider<BackupNotifier, BackUpState>((ref) { StateNotifierProvider<BackupNotifier, BackUpState>((ref) {
return BackupNotifier(ref: ref); return BackupNotifier(
ref.watch(backupServiceProvider),
ref.watch(serverInfoServiceProvider),
ref.watch(authenticationProvider),
);
}); });

View File

@ -5,6 +5,7 @@ import 'dart:io';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/hive_box.dart'; import 'package:immich_mobile/constants/hive_box.dart';
import 'package:immich_mobile/shared/services/network.service.dart'; import 'package:immich_mobile/shared/services/network.service.dart';
import 'package:immich_mobile/shared/models/device_info.model.dart'; import 'package:immich_mobile/shared/models/device_info.model.dart';
@ -14,20 +15,28 @@ import 'package:http_parser/http_parser.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:cancellation_token_http/http.dart' as http; import 'package:cancellation_token_http/http.dart' as http;
final backupServiceProvider =
Provider((ref) => BackupService(ref.watch(networkServiceProvider)));
class BackupService { class BackupService {
final NetworkService _networkService = NetworkService(); final NetworkService _networkService;
BackupService(this._networkService);
Future<List<String>> getDeviceBackupAsset() async { Future<List<String>> getDeviceBackupAsset() async {
String deviceId = Hive.box(userInfoBox).get(deviceIdKey); String deviceId = Hive.box(userInfoBox).get(deviceIdKey);
Response response = await _networkService.getRequest(url: "asset/$deviceId"); Response response =
await _networkService.getRequest(url: "asset/$deviceId");
List<dynamic> result = jsonDecode(response.toString()); List<dynamic> result = jsonDecode(response.toString());
return result.cast<String>(); return result.cast<String>();
} }
backupAsset(Set<AssetEntity> assetList, http.CancellationToken cancelToken, backupAsset(
Function(String, String) singleAssetDoneCb, Function(int, int) uploadProgress) async { Set<AssetEntity> assetList,
http.CancellationToken cancelToken,
Function(String, String) singleAssetDoneCb,
Function(int, int) uploadProgress) async {
String deviceId = Hive.box(userInfoBox).get(deviceIdKey); String deviceId = Hive.box(userInfoBox).get(deviceIdKey);
String savedEndpoint = Hive.box(userInfoBox).get(serverEndpointKey); String savedEndpoint = Hive.box(userInfoBox).get(serverEndpointKey);
File? file; File? file;
@ -44,7 +53,8 @@ class BackupService {
if (file != null) { if (file != null) {
String originalFileName = await entity.titleAsync; String originalFileName = await entity.titleAsync;
String fileNameWithoutPath = originalFileName.toString().split(".")[0]; String fileNameWithoutPath =
originalFileName.toString().split(".")[0];
var fileExtension = p.extension(file.path); var fileExtension = p.extension(file.path);
var mimeType = FileHelper.getMimeType(file.path); var mimeType = FileHelper.getMimeType(file.path);
var fileStream = file.openRead(); var fileStream = file.openRead();
@ -60,7 +70,8 @@ class BackupService {
); );
// Build thumbnail multipart data // Build thumbnail multipart data
var thumbnailData = await entity.thumbnailDataWithSize(const ThumbnailSize(1440, 2560)); var thumbnailData = await entity
.thumbnailDataWithSize(const ThumbnailSize(1440, 2560));
if (thumbnailData != null) { if (thumbnailData != null) {
thumbnailUploadData = http.MultipartFile.fromBytes( thumbnailUploadData = http.MultipartFile.fromBytes(
"thumbnailData", "thumbnailData",
@ -75,8 +86,10 @@ class BackupService {
var box = Hive.box(userInfoBox); var box = Hive.box(userInfoBox);
var req = MultipartRequest('POST', Uri.parse('$savedEndpoint/asset/upload'), var req = MultipartRequest(
onProgress: ((bytes, totalBytes) => uploadProgress(bytes, totalBytes))); 'POST', Uri.parse('$savedEndpoint/asset/upload'),
onProgress: ((bytes, totalBytes) =>
uploadProgress(bytes, totalBytes)));
req.headers["Authorization"] = "Bearer ${box.get(accessTokenKey)}"; req.headers["Authorization"] = "Bearer ${box.get(accessTokenKey)}";
req.fields['deviceAssetId'] = entity.id; req.fields['deviceAssetId'] = entity.id;
@ -126,7 +139,8 @@ class BackupService {
} }
} }
Future<DeviceInfoRemote> setAutoBackup(bool status, String deviceId, String deviceType) async { Future<DeviceInfoRemote> setAutoBackup(
bool status, String deviceId, String deviceType) async {
var res = await _networkService.patchRequest(url: 'device-info', data: { var res = await _networkService.patchRequest(url: 'device-info', data: {
"isAutoBackup": status, "isAutoBackup": status,
"deviceId": deviceId, "deviceId": deviceId,

View File

@ -50,37 +50,46 @@ class UploadProfileImageState {
String toJson() => json.encode(toMap()); String toJson() => json.encode(toMap());
factory UploadProfileImageState.fromJson(String source) => UploadProfileImageState.fromMap(json.decode(source)); factory UploadProfileImageState.fromJson(String source) =>
UploadProfileImageState.fromMap(json.decode(source));
@override @override
String toString() => 'UploadProfileImageState(status: $status, profileImagePath: $profileImagePath)'; String toString() =>
'UploadProfileImageState(status: $status, profileImagePath: $profileImagePath)';
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
if (identical(this, other)) return true; if (identical(this, other)) return true;
return other is UploadProfileImageState && other.status == status && other.profileImagePath == profileImagePath; return other is UploadProfileImageState &&
other.status == status &&
other.profileImagePath == profileImagePath;
} }
@override @override
int get hashCode => status.hashCode ^ profileImagePath.hashCode; int get hashCode => status.hashCode ^ profileImagePath.hashCode;
} }
class UploadProfileImageNotifier extends StateNotifier<UploadProfileImageState> { class UploadProfileImageNotifier
UploadProfileImageNotifier() extends StateNotifier<UploadProfileImageState> {
UploadProfileImageNotifier(this._userSErvice)
: super(UploadProfileImageState( : super(UploadProfileImageState(
profileImagePath: '', profileImagePath: '',
status: UploadProfileStatus.idle, status: UploadProfileStatus.idle,
)); ));
final UserService _userSErvice;
Future<bool> upload(XFile file) async { Future<bool> upload(XFile file) async {
state = state.copyWith(status: UploadProfileStatus.loading); state = state.copyWith(status: UploadProfileStatus.loading);
var res = await UserService().uploadProfileImage(file); var res = await _userSErvice.uploadProfileImage(file);
if (res != null) { if (res != null) {
debugPrint("Succesfully upload profile image"); debugPrint("Succesfully upload profile image");
state = state.copyWith(status: UploadProfileStatus.success, profileImagePath: res.profileImagePath); state = state.copyWith(
status: UploadProfileStatus.success,
profileImagePath: res.profileImagePath);
return true; return true;
} }
@ -90,4 +99,5 @@ class UploadProfileImageNotifier extends StateNotifier<UploadProfileImageState>
} }
final uploadProfileImageProvider = final uploadProfileImageProvider =
StateNotifierProvider<UploadProfileImageNotifier, UploadProfileImageState>(((ref) => UploadProfileImageNotifier())); StateNotifierProvider<UploadProfileImageNotifier, UploadProfileImageState>(
((ref) => UploadProfileImageNotifier(ref.watch(userServiceProvider))));

View File

@ -1,21 +1,27 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/modules/home/models/delete_asset_response.model.dart'; import 'package:immich_mobile/modules/home/models/delete_asset_response.model.dart';
import 'package:immich_mobile/modules/home/models/get_all_asset_response.model.dart'; import 'package:immich_mobile/modules/home/models/get_all_asset_response.model.dart';
import 'package:immich_mobile/shared/models/immich_asset.model.dart'; import 'package:immich_mobile/shared/models/immich_asset.model.dart';
import 'package:immich_mobile/shared/models/immich_asset_with_exif.model.dart'; import 'package:immich_mobile/shared/models/immich_asset_with_exif.model.dart';
import 'package:immich_mobile/shared/services/network.service.dart'; import 'package:immich_mobile/shared/services/network.service.dart';
final assetServiceProvider =
Provider((ref) => AssetService(ref.watch(networkServiceProvider)));
class AssetService { class AssetService {
final NetworkService _networkService = NetworkService(); final NetworkService _networkService;
AssetService(this._networkService);
Future<List<ImmichAsset>?> getAllAsset() async { Future<List<ImmichAsset>?> getAllAsset() async {
var res = await _networkService.getRequest(url: "asset/"); var res = await _networkService.getRequest(url: "asset/");
try { try {
List<dynamic> decodedData = jsonDecode(res.toString()); List<dynamic> decodedData = jsonDecode(res.toString());
List<ImmichAsset> result = List.from(decodedData.map((a) => ImmichAsset.fromMap(a))); List<ImmichAsset> result =
List.from(decodedData.map((a) => ImmichAsset.fromMap(a)));
return result; return result;
} catch (e) { } catch (e) {
debugPrint("Error getAllAsset ${e.toString()}"); debugPrint("Error getAllAsset ${e.toString()}");
@ -62,7 +68,8 @@ class AssetService {
List<dynamic> decodedData = jsonDecode(res.toString()); List<dynamic> decodedData = jsonDecode(res.toString());
List<ImmichAsset> result = List.from(decodedData.map((a) => ImmichAsset.fromMap(a))); List<ImmichAsset> result =
List.from(decodedData.map((a) => ImmichAsset.fromMap(a)));
if (result.isNotEmpty) { if (result.isNotEmpty) {
return result; return result;
} }
@ -90,7 +97,8 @@ class AssetService {
} }
} }
Future<List<DeleteAssetResponse>?> deleteAssets(Set<ImmichAsset> deleteAssets) async { Future<List<DeleteAssetResponse>?> deleteAssets(
Set<ImmichAsset> deleteAssets) async {
try { try {
var payload = []; var payload = [];
@ -98,11 +106,13 @@ class AssetService {
payload.add(asset.id); payload.add(asset.id);
} }
var res = await _networkService.deleteRequest(url: "asset/", data: {"ids": payload}); var res = await _networkService
.deleteRequest(url: "asset/", data: {"ids": payload});
List<dynamic> decodedData = jsonDecode(res.toString()); List<dynamic> decodedData = jsonDecode(res.toString());
List<DeleteAssetResponse> result = List.from(decodedData.map((a) => DeleteAssetResponse.fromMap(a))); List<DeleteAssetResponse> result =
List.from(decodedData.map((a) => DeleteAssetResponse.fromMap(a)));
return result; return result;
} catch (e) { } catch (e) {

View File

@ -12,7 +12,8 @@ import 'package:immich_mobile/shared/services/network.service.dart';
import 'package:immich_mobile/shared/models/device_info.model.dart'; import 'package:immich_mobile/shared/models/device_info.model.dart';
class AuthenticationNotifier extends StateNotifier<AuthenticationState> { class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
AuthenticationNotifier(this.ref) AuthenticationNotifier(
this._deviceInfoService, this._backupService, this._networkService)
: super( : super(
AuthenticationState( AuthenticationState(
deviceId: "", deviceId: "",
@ -37,12 +38,12 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
), ),
); );
final Ref ref; final DeviceInfoService _deviceInfoService;
final DeviceInfoService _deviceInfoService = DeviceInfoService(); final BackupService _backupService;
final BackupService _backupService = BackupService(); final NetworkService _networkService;
final NetworkService _networkService = NetworkService();
Future<bool> login(String email, String password, String serverEndpoint, bool isSavedLoginInfo) async { Future<bool> login(String email, String password, String serverEndpoint,
bool isSavedLoginInfo) async {
// Store server endpoint to Hive and test endpoint // Store server endpoint to Hive and test endpoint
if (serverEndpoint[serverEndpoint.length - 1] == "/") { if (serverEndpoint[serverEndpoint.length - 1] == "/") {
var validUrl = serverEndpoint.substring(0, serverEndpoint.length - 1); var validUrl = serverEndpoint.substring(0, serverEndpoint.length - 1);
@ -71,7 +72,8 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
// Make sign-in request // Make sign-in request
try { try {
Response res = await _networkService.postRequest(url: 'auth/login', data: {'email': email, 'password': password}); Response res = await _networkService.postRequest(
url: 'auth/login', data: {'email': email, 'password': password});
var payload = LogInReponse.fromJson(res.toString()); var payload = LogInReponse.fromJson(res.toString());
@ -99,7 +101,8 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
serverUrl: Hive.box(userInfoBox).get(serverEndpointKey)), serverUrl: Hive.box(userInfoBox).get(serverEndpointKey)),
); );
} else { } else {
Hive.box<HiveSavedLoginInfo>(hiveLoginInfoBox).delete(savedLoginInfoKey); Hive.box<HiveSavedLoginInfo>(hiveLoginInfoBox)
.delete(savedLoginInfoKey);
} }
} catch (e) { } catch (e) {
return false; return false;
@ -107,8 +110,9 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
// Register device info // Register device info
try { try {
Response res = await _networkService Response res = await _networkService.postRequest(
.postRequest(url: 'device-info', data: {'deviceId': state.deviceId, 'deviceType': state.deviceType}); url: 'device-info',
data: {'deviceId': state.deviceId, 'deviceType': state.deviceType});
DeviceInfoRemote deviceInfo = DeviceInfoRemote.fromJson(res.toString()); DeviceInfoRemote deviceInfo = DeviceInfoRemote.fromJson(res.toString());
state = state.copyWith(deviceInfo: deviceInfo); state = state.copyWith(deviceInfo: deviceInfo);
@ -151,7 +155,8 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
var deviceId = deviceInfo["deviceId"]; var deviceId = deviceInfo["deviceId"];
var deviceType = deviceInfo["deviceType"]; var deviceType = deviceInfo["deviceType"];
DeviceInfoRemote deviceInfoRemote = await _backupService.setAutoBackup(backupState, deviceId, deviceType); DeviceInfoRemote deviceInfoRemote =
await _backupService.setAutoBackup(backupState, deviceId, deviceType);
state = state.copyWith(deviceInfo: deviceInfoRemote); state = state.copyWith(deviceInfo: deviceInfoRemote);
} }
@ -160,6 +165,11 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
} }
} }
final authenticationProvider = StateNotifierProvider<AuthenticationNotifier, AuthenticationState>((ref) { final authenticationProvider =
return AuthenticationNotifier(ref); StateNotifierProvider<AuthenticationNotifier, AuthenticationState>((ref) {
return AuthenticationNotifier(
ref.watch(deviceInfoServiceProvider),
ref.watch(backupServiceProvider),
ref.watch(networkServiceProvider),
);
}); });

View File

@ -6,7 +6,7 @@ import 'package:immich_mobile/modules/search/models/search_page_state.model.dart
import 'package:immich_mobile/modules/search/services/search.service.dart'; import 'package:immich_mobile/modules/search/services/search.service.dart';
class SearchPageStateNotifier extends StateNotifier<SearchPageState> { class SearchPageStateNotifier extends StateNotifier<SearchPageState> {
SearchPageStateNotifier() SearchPageStateNotifier(this._searchService)
: super( : super(
SearchPageState( SearchPageState(
searchTerm: "", searchTerm: "",
@ -16,7 +16,7 @@ class SearchPageStateNotifier extends StateNotifier<SearchPageState> {
), ),
); );
final SearchService _searchService = SearchService(); final SearchService _searchService;
void enableSearch() { void enableSearch() {
state = state.copyWith(isSearchEnabled: true); state = state.copyWith(isSearchEnabled: true);
@ -54,12 +54,12 @@ class SearchPageStateNotifier extends StateNotifier<SearchPageState> {
final searchPageStateProvider = final searchPageStateProvider =
StateNotifierProvider<SearchPageStateNotifier, SearchPageState>((ref) { StateNotifierProvider<SearchPageStateNotifier, SearchPageState>((ref) {
return SearchPageStateNotifier(); return SearchPageStateNotifier(ref.watch(searchServiceProvider));
}); });
final getCuratedLocationProvider = final getCuratedLocationProvider =
FutureProvider.autoDispose<List<CuratedLocation>>((ref) async { FutureProvider.autoDispose<List<CuratedLocation>>((ref) async {
final SearchService searchService = SearchService(); final SearchService searchService = ref.watch(searchServiceProvider);
var curatedLocation = await searchService.getCuratedLocation(); var curatedLocation = await searchService.getCuratedLocation();
if (curatedLocation != null) { if (curatedLocation != null) {
@ -71,7 +71,7 @@ final getCuratedLocationProvider =
final getCuratedObjectProvider = final getCuratedObjectProvider =
FutureProvider.autoDispose<List<CuratedObject>>((ref) async { FutureProvider.autoDispose<List<CuratedObject>>((ref) async {
final SearchService searchService = SearchService(); final SearchService searchService = ref.watch(searchServiceProvider);
var curatedObject = await searchService.getCuratedObjects(); var curatedObject = await searchService.getCuratedObjects();
if (curatedObject != null) { if (curatedObject != null) {

View File

@ -7,31 +7,48 @@ import 'package:immich_mobile/shared/models/immich_asset.model.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
class SearchResultPageNotifier extends StateNotifier<SearchResultPageState> { class SearchResultPageNotifier extends StateNotifier<SearchResultPageState> {
SearchResultPageNotifier() SearchResultPageNotifier(this._searchService)
: super(SearchResultPageState(searchResult: [], isError: false, isLoading: true, isSuccess: false)); : super(
SearchResultPageState(
searchResult: [],
isError: false,
isLoading: true,
isSuccess: false,
),
);
final SearchService _searchService = SearchService(); final SearchService _searchService;
void search(String searchTerm) async { void search(String searchTerm) async {
state = state.copyWith(searchResult: [], isError: false, isLoading: true, isSuccess: false); state = state.copyWith(
searchResult: [], isError: false, isLoading: true, isSuccess: false);
List<ImmichAsset>? assets = await _searchService.searchAsset(searchTerm); List<ImmichAsset>? assets = await _searchService.searchAsset(searchTerm);
if (assets != null) { if (assets != null) {
state = state.copyWith(searchResult: assets, isError: false, isLoading: false, isSuccess: true); state = state.copyWith(
searchResult: assets,
isError: false,
isLoading: false,
isSuccess: true);
} else { } else {
state = state.copyWith(searchResult: [], isError: true, isLoading: false, isSuccess: false); state = state.copyWith(
searchResult: [], isError: true, isLoading: false, isSuccess: false);
} }
} }
} }
final searchResultPageProvider = StateNotifierProvider<SearchResultPageNotifier, SearchResultPageState>((ref) { final searchResultPageProvider =
return SearchResultPageNotifier(); StateNotifierProvider<SearchResultPageNotifier, SearchResultPageState>(
(ref) {
return SearchResultPageNotifier(ref.watch(searchServiceProvider));
}); });
final searchResultGroupByDateTimeProvider = StateProvider((ref) { final searchResultGroupByDateTimeProvider = StateProvider((ref) {
var assets = ref.watch(searchResultPageProvider).searchResult; var assets = ref.watch(searchResultPageProvider).searchResult;
assets.sortByCompare<DateTime>((e) => DateTime.parse(e.createdAt), (a, b) => b.compareTo(a)); assets.sortByCompare<DateTime>(
return assets.groupListsBy((element) => DateFormat('y-MM-dd').format(DateTime.parse(element.createdAt))); (e) => DateTime.parse(e.createdAt), (a, b) => b.compareTo(a));
return assets.groupListsBy((element) =>
DateFormat('y-MM-dd').format(DateTime.parse(element.createdAt)));
}); });

View File

@ -1,13 +1,18 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/modules/search/models/curated_location.model.dart'; import 'package:immich_mobile/modules/search/models/curated_location.model.dart';
import 'package:immich_mobile/modules/search/models/curated_object.model.dart'; import 'package:immich_mobile/modules/search/models/curated_object.model.dart';
import 'package:immich_mobile/shared/models/immich_asset.model.dart'; import 'package:immich_mobile/shared/models/immich_asset.model.dart';
import 'package:immich_mobile/shared/services/network.service.dart'; import 'package:immich_mobile/shared/services/network.service.dart';
final searchServiceProvider =
Provider((ref) => SearchService(ref.watch(networkServiceProvider)));
class SearchService { class SearchService {
final NetworkService _networkService = NetworkService(); final NetworkService _networkService;
SearchService(this._networkService);
Future<List<String>?> getUserSuggestedSearchTerms() async { Future<List<String>?> getUserSuggestedSearchTerms() async {
try { try {
@ -30,7 +35,8 @@ class SearchService {
List<dynamic> decodedData = jsonDecode(res.toString()); List<dynamic> decodedData = jsonDecode(res.toString());
List<ImmichAsset> result = List.from(decodedData.map((a) => ImmichAsset.fromMap(a))); List<ImmichAsset> result =
List.from(decodedData.map((a) => ImmichAsset.fromMap(a)));
return result; return result;
} catch (e) { } catch (e) {
@ -45,7 +51,8 @@ class SearchService {
List<dynamic> decodedData = jsonDecode(res.toString()); List<dynamic> decodedData = jsonDecode(res.toString());
List<CuratedLocation> result = List.from(decodedData.map((a) => CuratedLocation.fromMap(a))); List<CuratedLocation> result =
List.from(decodedData.map((a) => CuratedLocation.fromMap(a)));
return result; return result;
} catch (e) { } catch (e) {
@ -60,7 +67,8 @@ class SearchService {
List<dynamic> decodedData = jsonDecode(res.toString()); List<dynamic> decodedData = jsonDecode(res.toString());
List<CuratedObject> result = List.from(decodedData.map((a) => CuratedObject.fromMap(a))); List<CuratedObject> result =
List.from(decodedData.map((a) => CuratedObject.fromMap(a)));
return result; return result;
} catch (e) { } catch (e) {

View File

@ -18,7 +18,7 @@ import 'package:immich_mobile/utils/capitalize_first_letter.dart';
class SearchPage extends HookConsumerWidget { class SearchPage extends HookConsumerWidget {
SearchPage({Key? key}) : super(key: key); SearchPage({Key? key}) : super(key: key);
late FocusNode searchFocusNode; FocusNode searchFocusNode = FocusNode();
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {

View File

@ -4,7 +4,8 @@ import 'package:immich_mobile/modules/sharing/providers/shared_album.provider.da
import 'package:immich_mobile/modules/sharing/services/shared_album.service.dart'; import 'package:immich_mobile/modules/sharing/services/shared_album.service.dart';
class AlbumViewerNotifier extends StateNotifier<AlbumViewerPageState> { class AlbumViewerNotifier extends StateNotifier<AlbumViewerPageState> {
AlbumViewerNotifier(this.ref) : super(AlbumViewerPageState(editTitleText: "", isEditAlbum: false)); AlbumViewerNotifier(this.ref)
: super(AlbumViewerPageState(editTitleText: "", isEditAlbum: false));
final Ref ref; final Ref ref;
@ -28,10 +29,12 @@ class AlbumViewerNotifier extends StateNotifier<AlbumViewerPageState> {
state = state.copyWith(editTitleText: "", isEditAlbum: false); state = state.copyWith(editTitleText: "", isEditAlbum: false);
} }
Future<bool> changeAlbumTitle(String albumId, String ownerId, String newAlbumTitle) async { Future<bool> changeAlbumTitle(
SharedAlbumService service = SharedAlbumService(); String albumId, String ownerId, String newAlbumTitle) async {
SharedAlbumService service = ref.watch(sharedAlbumServiceProvider);
bool isSuccess = await service.changeTitleAlbum(albumId, ownerId, newAlbumTitle); bool isSuccess =
await service.changeTitleAlbum(albumId, ownerId, newAlbumTitle);
if (isSuccess) { if (isSuccess) {
state = state.copyWith(editTitleText: "", isEditAlbum: false); state = state.copyWith(editTitleText: "", isEditAlbum: false);
@ -45,6 +48,7 @@ class AlbumViewerNotifier extends StateNotifier<AlbumViewerPageState> {
} }
} }
final albumViewerProvider = StateNotifierProvider<AlbumViewerNotifier, AlbumViewerPageState>((ref) { final albumViewerProvider =
StateNotifierProvider<AlbumViewerNotifier, AlbumViewerPageState>((ref) {
return AlbumViewerNotifier(ref); return AlbumViewerNotifier(ref);
}); });

View File

@ -3,9 +3,9 @@ import 'package:immich_mobile/modules/sharing/models/shared_album.model.dart';
import 'package:immich_mobile/modules/sharing/services/shared_album.service.dart'; import 'package:immich_mobile/modules/sharing/services/shared_album.service.dart';
class SharedAlbumNotifier extends StateNotifier<List<SharedAlbum>> { class SharedAlbumNotifier extends StateNotifier<List<SharedAlbum>> {
SharedAlbumNotifier() : super([]); SharedAlbumNotifier(this._sharedAlbumService) : super([]);
final SharedAlbumService _sharedAlbumService = SharedAlbumService(); final SharedAlbumService _sharedAlbumService;
getAllSharedAlbums() async { getAllSharedAlbums() async {
List<SharedAlbum> sharedAlbums = List<SharedAlbum> sharedAlbums =
@ -50,12 +50,13 @@ class SharedAlbumNotifier extends StateNotifier<List<SharedAlbum>> {
final sharedAlbumProvider = final sharedAlbumProvider =
StateNotifierProvider<SharedAlbumNotifier, List<SharedAlbum>>((ref) { StateNotifierProvider<SharedAlbumNotifier, List<SharedAlbum>>((ref) {
return SharedAlbumNotifier(); return SharedAlbumNotifier(ref.watch(sharedAlbumServiceProvider));
}); });
final sharedAlbumDetailProvider = FutureProvider.autoDispose final sharedAlbumDetailProvider = FutureProvider.autoDispose
.family<SharedAlbum, String>((ref, albumId) async { .family<SharedAlbum, String>((ref, albumId) async {
final SharedAlbumService sharedAlbumService = SharedAlbumService(); final SharedAlbumService sharedAlbumService =
ref.watch(sharedAlbumServiceProvider);
return await sharedAlbumService.getAlbumDetail(albumId); return await sharedAlbumService.getAlbumDetail(albumId);
}); });

View File

@ -2,8 +2,9 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/shared/models/user.model.dart'; import 'package:immich_mobile/shared/models/user.model.dart';
import 'package:immich_mobile/shared/services/user.service.dart'; import 'package:immich_mobile/shared/services/user.service.dart';
final suggestedSharedUsersProvider = FutureProvider.autoDispose<List<User>>((ref) async { final suggestedSharedUsersProvider =
UserService userService = UserService(); FutureProvider.autoDispose<List<User>>((ref) async {
UserService userService = ref.watch(userServiceProvider);
return await userService.getAllUsersInfo(); return await userService.getAllUsersInfo();
}); });

View File

@ -3,12 +3,17 @@ import 'dart:convert';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/modules/sharing/models/shared_album.model.dart'; import 'package:immich_mobile/modules/sharing/models/shared_album.model.dart';
import 'package:immich_mobile/shared/models/immich_asset.model.dart'; import 'package:immich_mobile/shared/models/immich_asset.model.dart';
import 'package:immich_mobile/shared/services/network.service.dart'; import 'package:immich_mobile/shared/services/network.service.dart';
final sharedAlbumServiceProvider =
Provider((ref) => SharedAlbumService(ref.watch(networkServiceProvider)));
class SharedAlbumService { class SharedAlbumService {
final NetworkService _networkService = NetworkService(); final NetworkService _networkService;
SharedAlbumService(this._networkService);
Future<List<SharedAlbum>> getAllSharedAlbum() async { Future<List<SharedAlbum>> getAllSharedAlbum() async {
try { try {

View File

@ -53,8 +53,10 @@ class AlbumViewerPage extends HookConsumerWidget {
if (returnPayload.selectedAdditionalAsset.isNotEmpty) { if (returnPayload.selectedAdditionalAsset.isNotEmpty) {
ImmichLoadingOverlayController.appLoader.show(); ImmichLoadingOverlayController.appLoader.show();
var isSuccess = await SharedAlbumService().addAdditionalAssetToAlbum( var isSuccess = await ref
returnPayload.selectedAdditionalAsset, albumId); .watch(sharedAlbumServiceProvider)
.addAdditionalAssetToAlbum(
returnPayload.selectedAdditionalAsset, albumId);
if (isSuccess) { if (isSuccess) {
ref.refresh(sharedAlbumDetailProvider(albumId)); ref.refresh(sharedAlbumDetailProvider(albumId));
@ -77,7 +79,8 @@ class AlbumViewerPage extends HookConsumerWidget {
if (sharedUserIds != null) { if (sharedUserIds != null) {
ImmichLoadingOverlayController.appLoader.show(); ImmichLoadingOverlayController.appLoader.show();
var isSuccess = await SharedAlbumService() var isSuccess = await ref
.watch(sharedAlbumServiceProvider)
.addAdditionalUserToAlbum(sharedUserIds, albumId); .addAdditionalUserToAlbum(sharedUserIds, albumId);
if (isSuccess) { if (isSuccess) {

View File

@ -16,24 +16,28 @@ class SelectUserForSharingPage extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final sharedUsersList = useState<Set<User>>({}); final sharedUsersList = useState<Set<User>>({});
AsyncValue<List<User>> suggestedShareUsers = ref.watch(suggestedSharedUsersProvider); AsyncValue<List<User>> suggestedShareUsers =
ref.watch(suggestedSharedUsersProvider);
_createSharedAlbum() async { _createSharedAlbum() async {
var isSuccess = await SharedAlbumService().createSharedAlbum( var isSuccess =
ref.watch(albumTitleProvider), await ref.watch(sharedAlbumServiceProvider).createSharedAlbum(
ref.watch(assetSelectionProvider).selectedNewAssetsForAlbum, ref.watch(albumTitleProvider),
sharedUsersList.value.map((userInfo) => userInfo.id).toList(), ref.watch(assetSelectionProvider).selectedNewAssetsForAlbum,
); sharedUsersList.value.map((userInfo) => userInfo.id).toList(),
);
if (isSuccess) { if (isSuccess) {
await ref.watch(sharedAlbumProvider.notifier).getAllSharedAlbums(); await ref.watch(sharedAlbumProvider.notifier).getAllSharedAlbums();
ref.watch(assetSelectionProvider.notifier).removeAll(); ref.watch(assetSelectionProvider.notifier).removeAll();
ref.watch(albumTitleProvider.notifier).clearAlbumTitle(); ref.watch(albumTitleProvider.notifier).clearAlbumTitle();
AutoRouter.of(context).navigate(const TabControllerRoute(children: [SharingRoute()])); AutoRouter.of(context)
.navigate(const TabControllerRoute(children: [SharingRoute()]));
} }
const ScaffoldMessenger(child: SnackBar(content: Text('Failed to create album'))); const ScaffoldMessenger(
child: SnackBar(content: Text('Failed to create album')));
} }
_buildTileIcon(User user) { _buildTileIcon(User user) {
@ -47,7 +51,8 @@ class SelectUserForSharingPage extends HookConsumerWidget {
); );
} else { } else {
return CircleAvatar( return CircleAvatar(
backgroundImage: const AssetImage('assets/immich-logo-no-outline.png'), backgroundImage:
const AssetImage('assets/immich-logo-no-outline.png'),
backgroundColor: Theme.of(context).primaryColor.withAlpha(50), backgroundColor: Theme.of(context).primaryColor.withAlpha(50),
); );
} }
@ -64,7 +69,10 @@ class SelectUserForSharingPage extends HookConsumerWidget {
backgroundColor: Theme.of(context).primaryColor.withOpacity(0.15), backgroundColor: Theme.of(context).primaryColor.withOpacity(0.15),
label: Text( label: Text(
user.email, user.email,
style: const TextStyle(fontSize: 12, color: Colors.black87, fontWeight: FontWeight.bold), style: const TextStyle(
fontSize: 12,
color: Colors.black87,
fontWeight: FontWeight.bold),
), ),
), ),
), ),
@ -80,7 +88,10 @@ class SelectUserForSharingPage extends HookConsumerWidget {
padding: EdgeInsets.all(16.0), padding: EdgeInsets.all(16.0),
child: Text( child: Text(
'Suggestions', 'Suggestions',
style: TextStyle(fontSize: 14, color: Colors.grey, fontWeight: FontWeight.bold), style: TextStyle(
fontSize: 14,
color: Colors.grey,
fontWeight: FontWeight.bold),
), ),
), ),
ListView.builder( ListView.builder(
@ -90,14 +101,20 @@ class SelectUserForSharingPage extends HookConsumerWidget {
leading: _buildTileIcon(users[index]), leading: _buildTileIcon(users[index]),
title: Text( title: Text(
users[index].email, users[index].email,
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold), style: const TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
), ),
onTap: () { onTap: () {
if (sharedUsersList.value.contains(users[index])) { if (sharedUsersList.value.contains(users[index])) {
sharedUsersList.value = sharedUsersList.value = sharedUsersList.value
sharedUsersList.value.where((selectedUser) => selectedUser.id != users[index].id).toSet(); .where((selectedUser) =>
selectedUser.id != users[index].id)
.toSet();
} else { } else {
sharedUsersList.value = {...sharedUsersList.value, users[index]}; sharedUsersList.value = {
...sharedUsersList.value,
users[index]
};
} }
}, },
); );
@ -124,7 +141,8 @@ class SelectUserForSharingPage extends HookConsumerWidget {
), ),
actions: [ actions: [
TextButton( TextButton(
onPressed: sharedUsersList.value.isEmpty ? null : _createSharedAlbum, onPressed:
sharedUsersList.value.isEmpty ? null : _createSharedAlbum,
child: const Text( child: const Text(
"Create Album", "Create Album",
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),

View File

@ -9,11 +9,10 @@ import 'package:intl/intl.dart';
import 'package:photo_manager/photo_manager.dart'; import 'package:photo_manager/photo_manager.dart';
class AssetNotifier extends StateNotifier<List<ImmichAsset>> { class AssetNotifier extends StateNotifier<List<ImmichAsset>> {
final AssetService _assetService = AssetService(); final AssetService _assetService;
final DeviceInfoService _deviceInfoService = DeviceInfoService(); final DeviceInfoService _deviceInfoService = DeviceInfoService();
final Ref ref;
AssetNotifier(this.ref) : super([]); AssetNotifier(this._assetService) : super([]);
getAllAsset() async { getAllAsset() async {
List<ImmichAsset>? allAssets = await _assetService.getAllAsset(); List<ImmichAsset>? allAssets = await _assetService.getAllAsset();
@ -71,7 +70,7 @@ class AssetNotifier extends StateNotifier<List<ImmichAsset>> {
final assetProvider = final assetProvider =
StateNotifierProvider<AssetNotifier, List<ImmichAsset>>((ref) { StateNotifierProvider<AssetNotifier, List<ImmichAsset>>((ref) {
return AssetNotifier(ref); return AssetNotifier(ref.watch(assetServiceProvider));
}); });
final assetGroupByDateTimeProvider = StateProvider((ref) { final assetGroupByDateTimeProvider = StateProvider((ref) {

View File

@ -7,7 +7,7 @@ import 'package:immich_mobile/shared/services/server_info.service.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
class ServerInfoNotifier extends StateNotifier<ServerInfoState> { class ServerInfoNotifier extends StateNotifier<ServerInfoState> {
ServerInfoNotifier() ServerInfoNotifier(this._serverInfoService)
: super( : super(
ServerInfoState( ServerInfoState(
mapboxInfo: MapboxInfo(isEnable: false, mapboxSecret: ""), mapboxInfo: MapboxInfo(isEnable: false, mapboxSecret: ""),
@ -18,7 +18,7 @@ class ServerInfoNotifier extends StateNotifier<ServerInfoState> {
), ),
); );
final ServerInfoService _serverInfoService = ServerInfoService(); final ServerInfoService _serverInfoService;
getServerVersion() async { getServerVersion() async {
ServerVersion? serverVersion = await _serverInfoService.getServerVersion(); ServerVersion? serverVersion = await _serverInfoService.getServerVersion();
@ -79,5 +79,5 @@ class ServerInfoNotifier extends StateNotifier<ServerInfoState> {
final serverInfoProvider = final serverInfoProvider =
StateNotifierProvider<ServerInfoNotifier, ServerInfoState>((ref) { StateNotifierProvider<ServerInfoNotifier, ServerInfoState>((ref) {
return ServerInfoNotifier(); return ServerInfoNotifier(ref.watch(serverInfoServiceProvider));
}); });

View File

@ -1,6 +1,10 @@
import 'package:flutter_udid/flutter_udid.dart'; import 'package:flutter_udid/flutter_udid.dart';
import 'dart:io' show Platform; import 'dart:io' show Platform;
import 'package:hooks_riverpod/hooks_riverpod.dart';
final deviceInfoServiceProvider = Provider((_) => DeviceInfoService());
class DeviceInfoService { class DeviceInfoService {
Future<Map<String, dynamic>> getDeviceInfo() async { Future<Map<String, dynamic>> getDeviceInfo() async {
// Get device info // Get device info

View File

@ -1,6 +1,9 @@
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/hive_box.dart'; import 'package:immich_mobile/constants/hive_box.dart';
final localStorageServiceProvider = Provider((_) => LocalStorageService());
class LocalStorageService { class LocalStorageService {
late Box _box; late Box _box;

View File

@ -4,11 +4,11 @@ import 'dart:convert';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:http_parser/http_parser.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:image_picker/image_picker.dart';
import 'package:immich_mobile/constants/hive_box.dart'; import 'package:immich_mobile/constants/hive_box.dart';
import 'package:immich_mobile/utils/dio_http_interceptor.dart'; import 'package:immich_mobile/utils/dio_http_interceptor.dart';
import 'package:immich_mobile/utils/files_helper.dart';
final networkServiceProvider = Provider((_) => NetworkService());
class NetworkService { class NetworkService {
late final Dio dio; late final Dio dio;

View File

@ -1,11 +1,16 @@
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/shared/models/server_info.model.dart'; import 'package:immich_mobile/shared/models/server_info.model.dart';
import 'package:immich_mobile/shared/models/server_version.model.dart'; import 'package:immich_mobile/shared/models/server_version.model.dart';
import 'package:immich_mobile/shared/services/network.service.dart'; import 'package:immich_mobile/shared/services/network.service.dart';
final serverInfoServiceProvider =
Provider((ref) => ServerInfoService(ref.watch(networkServiceProvider)));
class ServerInfoService { class ServerInfoService {
final NetworkService _networkService = NetworkService(); final NetworkService _networkService;
ServerInfoService(this._networkService);
Future<ServerInfo> getServerInfo() async { Future<ServerInfo> getServerInfo() async {
Response response = await _networkService.getRequest(url: 'server-info'); Response response = await _networkService.getRequest(url: 'server-info');

View File

@ -3,6 +3,7 @@ import 'dart:convert';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:http_parser/http_parser.dart'; import 'package:http_parser/http_parser.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:immich_mobile/constants/hive_box.dart'; import 'package:immich_mobile/constants/hive_box.dart';
@ -12,8 +13,12 @@ import 'package:immich_mobile/shared/services/network.service.dart';
import 'package:immich_mobile/utils/dio_http_interceptor.dart'; import 'package:immich_mobile/utils/dio_http_interceptor.dart';
import 'package:immich_mobile/utils/files_helper.dart'; import 'package:immich_mobile/utils/files_helper.dart';
final userServiceProvider =
Provider((ref) => UserService(ref.watch(networkServiceProvider)));
class UserService { class UserService {
final NetworkService _networkService = NetworkService(); final NetworkService _networkService;
UserService(this._networkService);
Future<List<User>> getAllUsersInfo() async { Future<List<User>> getAllUsersInfo() async {
try { try {