feat: full local assets / album sync

This commit is contained in:
shenlong-tanwen
2024-10-17 23:33:00 +05:30
parent a09710ec7b
commit c91a2878dc
87 changed files with 2417 additions and 366 deletions
@@ -1,8 +0,0 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:immich_mobile/domain/models/user.model.dart';
class CurrentUserCubit extends Cubit<User> {
CurrentUserCubit(super.initialState);
void updateUser(User user) => emit(user);
}
@@ -1,27 +0,0 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:immich_mobile/domain/models/server-info/server_feature_config.model.dart';
import 'package:immich_mobile/domain/services/server_info.service.dart';
class ServerFeatureConfigCubit extends Cubit<ServerFeatureConfig> {
final ServerInfoService _serverInfoService;
ServerFeatureConfigCubit(this._serverInfoService)
: super(const ServerFeatureConfig.reset());
Future<void> getFeatures() async =>
await Future.wait([_getFeatures(), _getConfig()]);
Future<void> _getFeatures() async {
final features = await _serverInfoService.getServerFeatures();
if (features != null) {
emit(state.copyWith(features: features));
}
}
Future<void> _getConfig() async {
final config = await _serverInfoService.getServerConfig();
if (config != null) {
emit(state.copyWith(config: config));
}
}
}
@@ -15,7 +15,7 @@ class HomePage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
body: BlocProvider(
create: (_) => ImmichAssetGridCubit(
create: (_) => AssetGridCubit(
renderStream: di<IRenderListRepository>().watchAll(),
assetProvider: di<IAssetRepository>().getAll,
),
@@ -5,12 +5,14 @@ import 'package:immich_mobile/domain/interfaces/asset.interface.dart';
import 'package:immich_mobile/domain/interfaces/store.interface.dart';
import 'package:immich_mobile/domain/interfaces/user.interface.dart';
import 'package:immich_mobile/domain/models/store.model.dart';
import 'package:immich_mobile/domain/services/album_sync.service.dart';
import 'package:immich_mobile/domain/services/asset_sync.service.dart';
import 'package:immich_mobile/domain/services/login.service.dart';
import 'package:immich_mobile/domain/services/user.service.dart';
import 'package:immich_mobile/i18n/strings.g.dart';
import 'package:immich_mobile/presentation/modules/common/states/server_info/server_feature_config.state.dart';
import 'package:immich_mobile/presentation/modules/login/models/login_page.model.dart';
import 'package:immich_mobile/presentation/states/gallery_permission.state.dart';
import 'package:immich_mobile/presentation/states/server_info/server_feature_config.state.dart';
import 'package:immich_mobile/service_locator.dart';
import 'package:immich_mobile/utils/immich_api_client.dart';
import 'package:immich_mobile/utils/mixins/log.mixin.dart';
@@ -126,7 +128,7 @@ class LoginPageCubit extends Cubit<LoginPageState> with LogMixin {
await di<IStoreRepository>().upsert(StoreKey.accessToken, accessToken);
/// Set token to interceptor
await di<ImmichApiClient>().init(accessToken: accessToken);
await di<ImApiClient>().init(accessToken: accessToken);
final user = await di<UserService>().getMyUser();
if (user == null) {
@@ -139,7 +141,9 @@ class LoginPageCubit extends Cubit<LoginPageState> with LogMixin {
await di<IUserRepository>().upsert(user);
// Remove and Sync assets in background
await di<IAssetRepository>().deleteAll();
unawaited(di<AssetSyncService>().performFullRemoteSyncForUser(user));
await di<GalleryPermissionNotifier>().requestPermission();
unawaited(di<AssetSyncService>().performFullRemoteSyncIsolate(user));
unawaited(di<AlbumSyncService>().performFullDeviceSyncIsolate());
emit(state.copyWith(
isValidationInProgress: false,
@@ -10,9 +10,9 @@ import 'package:immich_mobile/presentation/components/input/filled_button.widget
import 'package:immich_mobile/presentation/components/input/password_form_field.widget.dart';
import 'package:immich_mobile/presentation/components/input/text_button.widget.dart';
import 'package:immich_mobile/presentation/components/input/text_form_field.widget.dart';
import 'package:immich_mobile/presentation/modules/common/states/server_info/server_feature_config.state.dart';
import 'package:immich_mobile/presentation/modules/login/models/login_page.model.dart';
import 'package:immich_mobile/presentation/modules/login/states/login_page.state.dart';
import 'package:immich_mobile/presentation/states/server_info/server_feature_config.state.dart';
import 'package:immich_mobile/service_locator.dart';
import 'package:material_symbols_icons/symbols.dart';
@@ -4,17 +4,17 @@ import 'package:immich_mobile/presentation/router/router.dart';
import 'package:material_symbols_icons/symbols.dart';
enum SettingSection {
general(
general._(
icon: Symbols.interests_rounded,
labelKey: 'settings.sections.general',
destination: GeneralSettingsRoute(),
),
advance(
advance._(
icon: Symbols.build_rounded,
labelKey: 'settings.sections.advance',
destination: AdvanceSettingsRoute(),
),
about(
about._(
icon: Symbols.help_rounded,
labelKey: 'settings.sections.about',
destination: AboutSettingsRoute(),
@@ -24,7 +24,7 @@ enum SettingSection {
final String labelKey;
final IconData icon;
const SettingSection({
const SettingSection._({
required this.labelKey,
required this.icon,
required this.destination,
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:immich_mobile/i18n/strings.g.dart';
import 'package:immich_mobile/presentation/components/image/immich_logo.widget.dart';
import 'package:immich_mobile/presentation/components/scaffold/adaptive_route_appbar.widget.dart';
import 'package:immich_mobile/utils/constants/globals.dart';
import 'package:immich_mobile/utils/constants/size_constants.dart';
@RoutePage()
@@ -17,9 +18,10 @@ class AboutSettingsPage extends StatelessWidget {
title: Text(context.t.settings.about.third_party_title),
subtitle: Text(context.t.settings.about.third_party_sub_title),
onTap: () => showLicensePage(
context: context,
applicationName: "Immich",
applicationIcon: const ImLogo(width: SizeConstants.xl)),
context: context,
applicationName: kImmichAppName,
applicationIcon: const ImLogo(width: SizeConstants.xl),
),
),
);
}
@@ -22,6 +22,7 @@ class SettingsWrapperPage extends StatelessWidget {
}
@RoutePage()
// ignore: prefer-single-widget-per-file
class SettingsPage extends StatelessWidget {
const SettingsPage({super.key});
@@ -3,14 +3,14 @@ import 'package:immich_mobile/presentation/modules/theme/models/app_colors.model
import 'package:immich_mobile/utils/extensions/material_state.extension.dart';
enum AppTheme {
blue(AppColors.blueLight, AppColors.blueDark),
blue._(AppColors.blueLight, AppColors.blueDark),
// Fallback color for dynamic theme for non-supported platforms
dynamic(AppColors.blueLight, AppColors.blueDark);
dynamic._(AppColors.blueLight, AppColors.blueDark);
final ColorScheme lightSchema;
final ColorScheme darkSchema;
const AppTheme(this.lightSchema, this.darkSchema);
const AppTheme._(this.lightSchema, this.darkSchema);
static ThemeData generateThemeData(ColorScheme color) {
return ThemeData(
@@ -51,6 +51,14 @@ enum AppTheme {
borderSide: BorderSide(color: color.outlineVariant),
borderRadius: const BorderRadius.all(Radius.circular(15)),
),
errorBorder: OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(15)),
borderSide: BorderSide(color: color.error),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(15)),
borderSide: BorderSide(color: color.error),
),
hintStyle: const TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.normal,