feat: home grid

This commit is contained in:
shenlong-tanwen
2024-09-10 01:14:05 +05:30
parent 80009a77ec
commit 419d3669a2
33 changed files with 808 additions and 429 deletions
@@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
import 'package:immich_mobile/domain/interfaces/asset.interface.dart';
import 'package:immich_mobile/domain/models/render_list_element.model.dart';
import 'package:immich_mobile/presentation/components/image/immich_image.widget.dart';
import 'package:immich_mobile/service_locator.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
class ImAssetGrid extends StatelessWidget {
const ImAssetGrid({super.key});
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: di<IAssetRepository>().getRenderList(),
builder: (_, renderSnap) {
final renderList = renderSnap.data;
if (renderList == null) {
return const SizedBox.shrink();
}
final elements = renderList.elements;
return ScrollablePositionedList.builder(
itemCount: elements.length,
itemBuilder: (_, sectionIndex) {
final section = elements[sectionIndex];
return switch (section) {
RenderListMonthHeaderElement() => Text(section.header),
RenderListDayHeaderElement() => Text(section.header),
RenderListAssetElement() => FutureBuilder(
future: renderList.loadAssets(
section.assetOffset,
section.assetCount,
),
builder: (_, assetsSnap) {
final assets = assetsSnap.data;
if (assets == null) {
return const SizedBox.shrink();
}
return GridView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
),
itemBuilder: (_, i) {
return SizedBox.square(
dimension: 200,
// ignore: avoid-unsafe-collection-methods
child: ImImage(assets.elementAt(i)),
);
},
itemCount: section.assetCount,
);
},
),
};
},
);
},
);
}
}
@@ -0,0 +1,50 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:immich_mobile/domain/models/asset.model.dart';
import 'package:immich_mobile/service_locator.dart';
import 'package:immich_mobile/utils/immich_api_client.dart';
import 'package:immich_mobile/utils/immich_image_url_helper.dart';
import 'package:material_symbols_icons/symbols.dart';
class ImImage extends StatelessWidget {
final Asset asset;
final double? width;
final double? height;
const ImImage(this.asset, {this.width, this.height, super.key});
@override
Widget build(BuildContext context) {
return CachedNetworkImage(
imageUrl: ImImageUrlHelper.getThumbnailUrl(asset),
httpHeaders: di<ImmichApiClient>().headers,
cacheKey: ImImageUrlHelper.getThumbnailUrl(asset),
width: width,
height: height,
// keeping memCacheWidth, memCacheHeight, maxWidthDiskCache and
// maxHeightDiskCache = null allows to simply store the webp thumbnail
// from the server and use it for all rendered thumbnail sizes
fit: BoxFit.cover,
fadeInDuration: const Duration(milliseconds: 250),
progressIndicatorBuilder: (_, url, downloadProgress) {
// Show loading if desired
return const SizedBox.square(
dimension: 250,
child: DecoratedBox(decoration: BoxDecoration(color: Colors.grey)),
);
},
errorWidget: (_, url, error) {
if (error is HttpExceptionWithStatus &&
error.statusCode >= 400 &&
error.statusCode < 500) {
CachedNetworkImage.evictFromCache(url);
}
return Icon(
Symbols.image_not_supported_rounded,
color: Theme.of(context).primaryColor,
);
},
);
}
}
@@ -1,8 +1,6 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/domain/services/sync.service.dart';
import 'package:immich_mobile/presentation/modules/common/states/current_user.state.dart';
import 'package:immich_mobile/service_locator.dart';
import 'package:immich_mobile/presentation/components/grid/immich_asset_grid.widget.dart';
@RoutePage()
class HomePage extends StatelessWidget {
@@ -10,12 +8,6 @@ class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: ElevatedButton(
onPressed: () => di<SyncService>()
.doFullSyncForUserDrift(di<CurrentUserCubit>().state),
child: const Text('Sync'),
),
);
return const ImAssetGrid();
}
}
@@ -1,6 +1,7 @@
import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.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';
import 'package:immich_mobile/domain/models/store.model.dart';
@@ -135,7 +136,8 @@ class LoginPageCubit extends Cubit<LoginPageState> with LogContext {
// Register user
ServiceLocator.registerCurrentUser(user);
await di<IUserRepository>().add(user);
// Sync assets in background
// Remove and Sync assets in background
await di<IAssetRepository>().clearAll();
unawaited(di<SyncService>().doFullSyncForUserDrift(user));
emit(state.copyWith(