more refactors

This commit is contained in:
shenlong-tanwen
2024-10-19 14:34:42 +05:30
parent e8bb9a3934
commit 3b8951fde6
46 changed files with 598 additions and 435 deletions
@@ -5,17 +5,11 @@ import 'package:collection/collection.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:immich_mobile/domain/models/asset.model.dart';
import 'package:immich_mobile/domain/models/render_list.model.dart';
import 'package:immich_mobile/domain/utils/renderlist_providers.dart';
import 'package:immich_mobile/utils/constants/globals.dart';
typedef RenderListProvider = Stream<RenderList> Function();
typedef RenderListAssetProvider = FutureOr<List<Asset>> Function({
int? offset,
int? limit,
});
class AssetGridCubit extends Cubit<RenderList> {
final Stream<RenderList> _renderStream;
final RenderListAssetProvider _assetProvider;
final RenderListProvider _renderListProvider;
late final StreamSubscription _renderListSubscription;
/// offset of the assets from last section in [_buf]
@@ -24,13 +18,11 @@ class AssetGridCubit extends Cubit<RenderList> {
/// assets cache loaded from DB with offset [_bufOffset]
List<Asset> _buf = [];
AssetGridCubit({
required Stream<RenderList> renderStream,
required RenderListAssetProvider assetProvider,
}) : _renderStream = renderStream,
_assetProvider = assetProvider,
AssetGridCubit({required RenderListProvider renderListProvider})
: _renderListProvider = renderListProvider,
super(RenderList.empty()) {
_renderListSubscription = _renderStream.listen((renderList) {
_renderListSubscription =
_renderListProvider.renderStreamProvider().listen((renderList) {
_bufOffset = 0;
_buf = [];
emit(renderList);
@@ -68,7 +60,10 @@ class AssetGridCubit extends Cubit<RenderList> {
);
// load the calculated batch (start:start+len) from the DB and put it into the buffer
_buf = await _assetProvider(offset: start, limit: len);
_buf = await _renderListProvider.renderAssetProvider(
offset: start,
limit: len,
);
_bufOffset = start;
assert(_bufOffset <= offset);
@@ -1,11 +1,9 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:immich_mobile/domain/interfaces/asset.interface.dart';
import 'package:immich_mobile/domain/interfaces/renderlist.interface.dart';
import 'package:immich_mobile/domain/utils/renderlist_providers.dart';
import 'package:immich_mobile/presentation/components/grid/immich_asset_grid.state.dart';
import 'package:immich_mobile/presentation/components/grid/immich_asset_grid.widget.dart';
import 'package:immich_mobile/service_locator.dart';
@RoutePage()
class HomePage extends StatelessWidget {
@@ -16,8 +14,7 @@ class HomePage extends StatelessWidget {
return Scaffold(
body: BlocProvider(
create: (_) => AssetGridCubit(
renderStream: di<IRenderListRepository>().watchAll(),
assetProvider: di<IAssetRepository>().getAll,
renderListProvider: RenderListProvider.mainTimeline(),
),
child: const ImAssetGrid(),
),
@@ -12,7 +12,7 @@ class LoginPageState {
required this.isLoginSuccessful,
});
factory LoginPageState.reset() {
factory LoginPageState.initial() {
return const LoginPageState(
isServerValidated: false,
isValidationInProgress: false,
@@ -1,6 +1,7 @@
import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:immich_mobile/domain/interfaces/api/user_api.interface.dart';
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';
@@ -8,7 +9,6 @@ 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/login/models/login_page.model.dart';
import 'package:immich_mobile/presentation/states/gallery_permission.state.dart';
@@ -19,7 +19,7 @@ import 'package:immich_mobile/utils/mixins/log.mixin.dart';
import 'package:immich_mobile/utils/snackbar_manager.dart';
class LoginPageCubit extends Cubit<LoginPageState> with LogMixin {
LoginPageCubit() : super(LoginPageState.reset());
LoginPageCubit() : super(LoginPageState.initial());
String _appendSchema(String url) {
// Add schema if none is set
@@ -68,8 +68,7 @@ class LoginPageCubit extends Cubit<LoginPageState> with LogMixin {
url = await loginService.resolveEndpoint(uri);
di<IStoreRepository>().upsert(StoreKey.serverEndpoint, url);
ServiceLocator.registerApiClient(url);
ServiceLocator.registerPostValidationServices();
await ServiceLocator.registerApiClient(url);
ServiceLocator.registerPostGlobalStates();
// Fetch server features
@@ -130,7 +129,7 @@ class LoginPageCubit extends Cubit<LoginPageState> with LogMixin {
/// Set token to interceptor
await di<ImApiClient>().init(accessToken: accessToken);
final user = await di<UserService>().getMyUser();
final user = await di<IUserApiRepository>().getMyUser();
if (user == null) {
SnackbarManager.showError(t.login.error.error_login);
return;
@@ -152,6 +151,6 @@ class LoginPageCubit extends Cubit<LoginPageState> with LogMixin {
}
void resetServerValidation() {
emit(LoginPageState.reset());
emit(LoginPageState.initial());
}
}
@@ -1,22 +0,0 @@
import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:immich_mobile/domain/models/app_setting.model.dart';
import 'package:immich_mobile/domain/services/app_setting.service.dart';
import 'package:immich_mobile/presentation/modules/theme/models/app_theme.model.dart';
class AppThemeCubit extends Cubit<AppTheme> {
final AppSettingService _appSettings;
late final StreamSubscription _appSettingSubscription;
AppThemeCubit(this._appSettings) : super(AppTheme.blue) {
_appSettingSubscription =
_appSettings.watch(AppSetting.appTheme).listen((theme) => emit(theme));
}
@override
Future<void> close() {
_appSettingSubscription.cancel();
return super.close();
}
}
@@ -1,43 +0,0 @@
import 'package:dynamic_color/dynamic_color.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/presentation/modules/theme/models/app_theme.model.dart';
class AppThemeBuilder extends StatelessWidget {
const AppThemeBuilder({
super.key,
required this.theme,
required this.builder,
});
/// Current app theme to switch the theme data used
final AppTheme theme;
/// Builds the child widget of this widget, providing a light and dark [ThemeData] based on the
/// [theme] passed.
final Widget Function(
BuildContext context,
ThemeData lightTheme,
ThemeData darkTheme,
) builder;
@override
Widget build(BuildContext context) {
// Static colors
if (theme != AppTheme.dynamic) {
final lightTheme = AppTheme.generateThemeData(theme.lightSchema);
final darkTheme = AppTheme.generateThemeData(theme.darkSchema);
return builder(context, lightTheme, darkTheme);
}
// Dynamic color builder
return DynamicColorBuilder(builder: (lightDynamic, darkDynamic) {
final lightTheme =
AppTheme.generateThemeData(lightDynamic ?? theme.lightSchema);
final darkTheme =
AppTheme.generateThemeData(darkDynamic ?? theme.darkSchema);
return builder(context, lightTheme, darkTheme);
});
}
}
@@ -10,6 +10,7 @@ import 'package:immich_mobile/presentation/components/image/immich_logo.widget.d
import 'package:immich_mobile/presentation/modules/login/states/login_page.state.dart';
import 'package:immich_mobile/presentation/router/router.dart';
import 'package:immich_mobile/presentation/states/current_user.state.dart';
import 'package:immich_mobile/presentation/states/gallery_permission.state.dart';
import 'package:immich_mobile/service_locator.dart';
import 'package:immich_mobile/utils/mixins/log.mixin.dart';
@@ -52,12 +53,13 @@ class _SplashScreenState extends State<SplashScreenPage>
}
Future<void> _tryLogin() async {
await di<GalleryPermissionProvider>().requestPermission();
if (await di<LoginService>().tryAutoLogin() && mounted) {
unawaited(di<AssetSyncService>()
.performFullRemoteSyncIsolate(di<CurrentUserProvider>().value));
unawaited(di<AlbumSyncService>().performFullDeviceSyncIsolate());
unawaited(context.replaceRoute(const TabControllerRoute()));
} else {
} else if (mounted) {
unawaited(context.replaceRoute(const LoginRoute()));
}
}
@@ -0,0 +1,25 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:immich_mobile/domain/models/app_setting.model.dart';
import 'package:immich_mobile/domain/services/app_setting.service.dart';
import 'package:immich_mobile/presentation/theme/app_theme.dart';
class AppThemeProvider extends ValueNotifier<AppTheme> {
final AppSettingService _appSettings;
late final StreamSubscription _appSettingSubscription;
AppThemeProvider({required AppSettingService settingsService})
: _appSettings = settingsService,
super(AppTheme.blue) {
_appSettingSubscription = _appSettings
.watch(AppSetting.appTheme)
.listen((theme) => value = theme);
}
@override
void dispose() {
_appSettingSubscription.cancel();
super.dispose();
}
}
@@ -1,25 +1,26 @@
import 'package:flutter/foundation.dart';
import 'package:immich_mobile/domain/interfaces/api/server_api.interface.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 ServerFeatureConfigProvider extends ValueNotifier<ServerFeatureConfig> {
final ServerInfoService _serverInfoService;
final IServerApiRepository _serverApiRepository;
ServerFeatureConfigProvider(this._serverInfoService)
: super(const ServerFeatureConfig.reset());
ServerFeatureConfigProvider({required IServerApiRepository serverApiRepo})
: _serverApiRepository = serverApiRepo,
super(const ServerFeatureConfig.initial());
Future<void> getFeatures() async =>
await Future.wait([_getFeatures(), _getConfig()]);
Future<void> _getFeatures() async {
final features = await _serverInfoService.getServerFeatures();
final features = await _serverApiRepository.getServerFeatures();
if (features != null) {
value = value.copyWith(features: features);
}
}
Future<void> _getConfig() async {
final config = await _serverInfoService.getServerConfig();
final config = await _serverApiRepository.getServerConfig();
if (config != null) {
value = value.copyWith(config: config);
}
@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:immich_mobile/presentation/modules/theme/models/app_colors.model.dart';
import 'package:immich_mobile/presentation/theme/app_colors.dart';
import 'package:immich_mobile/utils/extensions/material_state.extension.dart';
enum AppTheme {