forked from Cutlery/immich
		
	feat(mobile) Enhance bottom app bar on home page (#934)
* Added bottom sheet * Finished styling bottom app bar * Fixed border radius
This commit is contained in:
		
							parent
							
								
									c8538cc62f
								
							
						
					
					
						commit
						f0874ff3fd
					
				@ -28,13 +28,17 @@ class ControlBottomAppBar extends ConsumerWidget {
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context, WidgetRef ref) {
 | 
			
		||||
    Widget renderActionButtons() {
 | 
			
		||||
      return Padding(
 | 
			
		||||
        padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
 | 
			
		||||
        child: Row(
 | 
			
		||||
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
 | 
			
		||||
      return Row(
 | 
			
		||||
        children: [
 | 
			
		||||
          ControlBoxButton(
 | 
			
		||||
              iconData: Icons.delete_forever_rounded,
 | 
			
		||||
            iconData: Icons.ios_share_rounded,
 | 
			
		||||
            label: "control_bottom_app_bar_share".tr(),
 | 
			
		||||
            onPressed: () {
 | 
			
		||||
              onShare();
 | 
			
		||||
            },
 | 
			
		||||
          ),
 | 
			
		||||
          ControlBoxButton(
 | 
			
		||||
            iconData: Icons.delete_outline_rounded,
 | 
			
		||||
            label: "control_bottom_app_bar_delete".tr(),
 | 
			
		||||
            onPressed: () {
 | 
			
		||||
              showDialog(
 | 
			
		||||
@ -47,15 +51,7 @@ class ControlBottomAppBar extends ConsumerWidget {
 | 
			
		||||
              );
 | 
			
		||||
            },
 | 
			
		||||
          ),
 | 
			
		||||
            ControlBoxButton(
 | 
			
		||||
              iconData: Icons.share,
 | 
			
		||||
              label: "control_bottom_app_bar_share".tr(),
 | 
			
		||||
              onPressed: () {
 | 
			
		||||
                onShare();
 | 
			
		||||
              },
 | 
			
		||||
            ),
 | 
			
		||||
        ],
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -63,7 +59,9 @@ class ControlBottomAppBar extends ConsumerWidget {
 | 
			
		||||
      Widget renderAlbum(AlbumResponseDto album) {
 | 
			
		||||
        final box = Hive.box(userInfoBox);
 | 
			
		||||
 | 
			
		||||
        return GestureDetector(
 | 
			
		||||
        return Padding(
 | 
			
		||||
          padding: const EdgeInsets.only(left: 8.0),
 | 
			
		||||
          child: GestureDetector(
 | 
			
		||||
            onTap: () => onAddToAlbum(album),
 | 
			
		||||
            child: Container(
 | 
			
		||||
              width: 112,
 | 
			
		||||
@ -77,8 +75,10 @@ class ControlBottomAppBar extends ConsumerWidget {
 | 
			
		||||
                      width: 100,
 | 
			
		||||
                      height: 100,
 | 
			
		||||
                      fit: BoxFit.cover,
 | 
			
		||||
                    imageUrl:
 | 
			
		||||
                        getAlbumThumbnailUrl(album, type: ThumbnailFormat.JPEG),
 | 
			
		||||
                      imageUrl: getAlbumThumbnailUrl(
 | 
			
		||||
                        album,
 | 
			
		||||
                        type: ThumbnailFormat.JPEG,
 | 
			
		||||
                      ),
 | 
			
		||||
                      httpHeaders: {
 | 
			
		||||
                        "Authorization": "Bearer ${box.get(accessTokenKey)}"
 | 
			
		||||
                      },
 | 
			
		||||
@ -89,16 +89,16 @@ class ControlBottomAppBar extends ConsumerWidget {
 | 
			
		||||
                    padding: const EdgeInsets.only(top: 12),
 | 
			
		||||
                    child: Text(
 | 
			
		||||
                      album.albumName,
 | 
			
		||||
                    style: TextStyle(fontWeight: FontWeight.bold),
 | 
			
		||||
                      style: const TextStyle(
 | 
			
		||||
                        fontWeight: FontWeight.bold,
 | 
			
		||||
                        fontSize: 12.0,
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                  ),
 | 
			
		||||
                Text(album.shared
 | 
			
		||||
                        ? "control_bottom_app_bar_album_info_shared"
 | 
			
		||||
                        : "control_bottom_app_bar_album_info")
 | 
			
		||||
                    .tr(args: [album.assetCount.toString()]),
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -112,34 +112,78 @@ class ControlBottomAppBar extends ConsumerWidget {
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return Positioned(
 | 
			
		||||
      bottom: 0,
 | 
			
		||||
      left: 0,
 | 
			
		||||
      child: Container(
 | 
			
		||||
        width: MediaQuery.of(context).size.width,
 | 
			
		||||
        decoration: BoxDecoration(
 | 
			
		||||
          borderRadius: const BorderRadius.only(
 | 
			
		||||
            topLeft: Radius.circular(10),
 | 
			
		||||
            topRight: Radius.circular(10),
 | 
			
		||||
    return DraggableScrollableSheet(
 | 
			
		||||
      initialChildSize: 0.30,
 | 
			
		||||
      minChildSize: 0.15,
 | 
			
		||||
      maxChildSize: 0.57,
 | 
			
		||||
      snap: true,
 | 
			
		||||
      builder: (
 | 
			
		||||
        BuildContext context,
 | 
			
		||||
        ScrollController scrollController,
 | 
			
		||||
      ) {
 | 
			
		||||
        return SingleChildScrollView(
 | 
			
		||||
          controller: scrollController,
 | 
			
		||||
          child: Card(
 | 
			
		||||
            elevation: 12.0,
 | 
			
		||||
            shape: const RoundedRectangleBorder(
 | 
			
		||||
              borderRadius: BorderRadius.only(
 | 
			
		||||
                topLeft: Radius.circular(12),
 | 
			
		||||
                topRight: Radius.circular(12),
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
            margin: const EdgeInsets.all(0),
 | 
			
		||||
            child: Container(
 | 
			
		||||
              decoration: const BoxDecoration(
 | 
			
		||||
                borderRadius: BorderRadius.only(
 | 
			
		||||
                  topLeft: Radius.circular(12),
 | 
			
		||||
                  topRight: Radius.circular(12),
 | 
			
		||||
                ),
 | 
			
		||||
          color: Theme.of(context).scaffoldBackgroundColor,
 | 
			
		||||
              ),
 | 
			
		||||
              child: Column(
 | 
			
		||||
          crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
          children: [
 | 
			
		||||
                children: <Widget>[
 | 
			
		||||
                  const SizedBox(height: 12),
 | 
			
		||||
                  const CustomDraggingHandle(),
 | 
			
		||||
                  const SizedBox(height: 12),
 | 
			
		||||
                  renderActionButtons(),
 | 
			
		||||
                  const Divider(
 | 
			
		||||
              thickness: 2,
 | 
			
		||||
                    indent: 16,
 | 
			
		||||
                    endIndent: 16,
 | 
			
		||||
                    thickness: 1,
 | 
			
		||||
                  ),
 | 
			
		||||
            Padding(
 | 
			
		||||
                padding: const EdgeInsets.all(12),
 | 
			
		||||
                  AddToAlbumTitleRow(
 | 
			
		||||
                    onCreateNewAlbum: () => onCreateNewAlbum(),
 | 
			
		||||
                  ),
 | 
			
		||||
                  renderAlbums(),
 | 
			
		||||
                  const SizedBox(height: 12),
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        );
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class AddToAlbumTitleRow extends StatelessWidget {
 | 
			
		||||
  const AddToAlbumTitleRow({
 | 
			
		||||
    super.key,
 | 
			
		||||
    required this.onCreateNewAlbum,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  final VoidCallback onCreateNewAlbum;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Padding(
 | 
			
		||||
      padding: const EdgeInsets.symmetric(horizontal: 16),
 | 
			
		||||
      child: Row(
 | 
			
		||||
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | 
			
		||||
        children: [
 | 
			
		||||
          const Text(
 | 
			
		||||
            "control_bottom_app_bar_add_to_album",
 | 
			
		||||
            style: TextStyle(
 | 
			
		||||
                        fontSize: 16,
 | 
			
		||||
              fontSize: 14,
 | 
			
		||||
              fontWeight: FontWeight.bold,
 | 
			
		||||
            ),
 | 
			
		||||
          ).tr(),
 | 
			
		||||
@ -150,14 +194,27 @@ class ControlBottomAppBar extends ConsumerWidget {
 | 
			
		||||
              style: TextStyle(
 | 
			
		||||
                color: Theme.of(context).primaryColor,
 | 
			
		||||
                fontWeight: FontWeight.bold,
 | 
			
		||||
                fontSize: 14,
 | 
			
		||||
              ),
 | 
			
		||||
            ).tr(),
 | 
			
		||||
          ),
 | 
			
		||||
        ],
 | 
			
		||||
                )),
 | 
			
		||||
            renderAlbums(),
 | 
			
		||||
          ],
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class CustomDraggingHandle extends StatelessWidget {
 | 
			
		||||
  const CustomDraggingHandle({super.key});
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Container(
 | 
			
		||||
      height: 5,
 | 
			
		||||
      width: 30,
 | 
			
		||||
      decoration: BoxDecoration(
 | 
			
		||||
        color: Colors.grey[500],
 | 
			
		||||
        borderRadius: BorderRadius.circular(16),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
@ -177,19 +234,20 @@ class ControlBoxButton extends StatelessWidget {
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return SizedBox(
 | 
			
		||||
      width: 60,
 | 
			
		||||
    return MaterialButton(
 | 
			
		||||
      padding: const EdgeInsets.all(10),
 | 
			
		||||
      shape: const CircleBorder(),
 | 
			
		||||
      onPressed: () => onPressed(),
 | 
			
		||||
      child: Column(
 | 
			
		||||
        mainAxisAlignment: MainAxisAlignment.start,
 | 
			
		||||
        crossAxisAlignment: CrossAxisAlignment.center,
 | 
			
		||||
        children: [
 | 
			
		||||
          IconButton(
 | 
			
		||||
            onPressed: () {
 | 
			
		||||
              onPressed();
 | 
			
		||||
            },
 | 
			
		||||
            icon: Icon(iconData, size: 30),
 | 
			
		||||
          Icon(iconData, size: 24),
 | 
			
		||||
          const SizedBox(height: 6),
 | 
			
		||||
          Text(
 | 
			
		||||
            label,
 | 
			
		||||
            style: const TextStyle(fontSize: 12.0),
 | 
			
		||||
          ),
 | 
			
		||||
          Text(label)
 | 
			
		||||
        ],
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_hooks/flutter_hooks.dart';
 | 
			
		||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
			
		||||
import 'package:immich_mobile/modules/album/providers/album.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart';
 | 
			
		||||
import 'package:immich_mobile/modules/album/services/album.service.dart';
 | 
			
		||||
import 'package:immich_mobile/modules/home/providers/home_page_render_list_provider.dart';
 | 
			
		||||
import 'package:immich_mobile/modules/home/providers/multiselect.provider.dart';
 | 
			
		||||
@ -79,10 +78,11 @@ class HomePage extends HookConsumerWidget {
 | 
			
		||||
 | 
			
		||||
      void onAddToAlbum(AlbumResponseDto album) async {
 | 
			
		||||
        final result = await albumService.addAdditionalAssetToAlbum(
 | 
			
		||||
            selection.value, album.id);
 | 
			
		||||
          selection.value,
 | 
			
		||||
          album.id,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        if (result != null) {
 | 
			
		||||
 | 
			
		||||
          if (result.alreadyInAlbum.isNotEmpty) {
 | 
			
		||||
            ImmichToast.show(
 | 
			
		||||
              context: context,
 | 
			
		||||
@ -137,7 +137,9 @@ class HomePage extends HookConsumerWidget {
 | 
			
		||||
            ),
 | 
			
		||||
            Padding(
 | 
			
		||||
              padding: EdgeInsets.only(
 | 
			
		||||
                  top: selectionEnabledHook.value ? 0 : 60, bottom: 0.0),
 | 
			
		||||
                top: selectionEnabledHook.value ? 0 : 60,
 | 
			
		||||
                bottom: 0.0,
 | 
			
		||||
              ),
 | 
			
		||||
              child: ImmichAssetGrid(
 | 
			
		||||
                renderList: renderList,
 | 
			
		||||
                assetsPerRow:
 | 
			
		||||
@ -148,7 +150,7 @@ class HomePage extends HookConsumerWidget {
 | 
			
		||||
                selectionActive: selectionEnabledHook.value,
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
            if (selectionEnabledHook.value) ...[
 | 
			
		||||
            if (selectionEnabledHook.value)
 | 
			
		||||
              ControlBottomAppBar(
 | 
			
		||||
                onShare: onShareAssets,
 | 
			
		||||
                onDelete: onDelete,
 | 
			
		||||
@ -157,7 +159,6 @@ class HomePage extends HookConsumerWidget {
 | 
			
		||||
                onCreateNewAlbum: onCreateNewAlbum,
 | 
			
		||||
              ),
 | 
			
		||||
          ],
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user