mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-03 19:29:32 -05:00 
			
		
		
		
	feat(mobile): Responsive display of exif data in bottom sheet (#1725)
* two column view of exif * fixes padding * fixed divider when no map * fixed map visibility in two column
This commit is contained in:
		
							parent
							
								
									bd71e087d4
								
							
						
					
					
						commit
						ad9373312b
					
				@ -14,19 +14,24 @@ class ExifBottomSheet extends HookConsumerWidget {
 | 
			
		||||
  const ExifBottomSheet({Key? key, required this.assetDetail})
 | 
			
		||||
      : super(key: key);
 | 
			
		||||
 | 
			
		||||
  bool get showMap => assetDetail.latitude != null && assetDetail.longitude != null;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context, WidgetRef ref) {
 | 
			
		||||
    buildMap() {
 | 
			
		||||
      return Padding(
 | 
			
		||||
        padding: const EdgeInsets.symmetric(vertical: 16.0),
 | 
			
		||||
        child: Container(
 | 
			
		||||
        child: LayoutBuilder(
 | 
			
		||||
          builder: (context, constraints) {
 | 
			
		||||
            return Container(
 | 
			
		||||
              height: 150,
 | 
			
		||||
          width: MediaQuery.of(context).size.width,
 | 
			
		||||
              width: constraints.maxWidth,
 | 
			
		||||
              decoration: const BoxDecoration(
 | 
			
		||||
                borderRadius: BorderRadius.all(Radius.circular(15)),
 | 
			
		||||
              ),
 | 
			
		||||
              child: FlutterMap(
 | 
			
		||||
                options: MapOptions(
 | 
			
		||||
                  interactiveFlags: InteractiveFlag.none,
 | 
			
		||||
                  center: LatLng(
 | 
			
		||||
                    assetDetail.latitude ?? 0,
 | 
			
		||||
                    assetDetail.longitude ?? 0,
 | 
			
		||||
@ -61,6 +66,8 @@ class ExifBottomSheet extends HookConsumerWidget {
 | 
			
		||||
                  ),
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
            );
 | 
			
		||||
          },
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
@ -91,46 +98,32 @@ class ExifBottomSheet extends HookConsumerWidget {
 | 
			
		||||
      return text.isEmpty ? null : Text(text);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return SingleChildScrollView(
 | 
			
		||||
      child: Card(
 | 
			
		||||
        shape: const RoundedRectangleBorder(
 | 
			
		||||
          borderRadius: BorderRadius.only(
 | 
			
		||||
            topLeft: Radius.circular(15),
 | 
			
		||||
            topRight: Radius.circular(15),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
        margin: const EdgeInsets.all(0),
 | 
			
		||||
        child: Container(
 | 
			
		||||
          margin: const EdgeInsets.symmetric(horizontal: 8.0),
 | 
			
		||||
          child: Column(
 | 
			
		||||
    buildDragHeader() {
 | 
			
		||||
      return Column(
 | 
			
		||||
        crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
            children: [
 | 
			
		||||
              const SizedBox(height: 12),
 | 
			
		||||
              const Align(
 | 
			
		||||
        children: const [
 | 
			
		||||
          SizedBox(height: 12),
 | 
			
		||||
          Align(
 | 
			
		||||
            alignment: Alignment.center,
 | 
			
		||||
            child: CustomDraggingHandle(),
 | 
			
		||||
          ),
 | 
			
		||||
              const SizedBox(height: 12),
 | 
			
		||||
              Text(
 | 
			
		||||
                DateFormat('date_format'.tr()).format(
 | 
			
		||||
                  assetDetail.createdAt.toLocal(),
 | 
			
		||||
                ),
 | 
			
		||||
                style: const TextStyle(
 | 
			
		||||
                  fontWeight: FontWeight.bold,
 | 
			
		||||
                  fontSize: 14,
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
          SizedBox(height: 12),
 | 
			
		||||
        ],
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildLocation() {
 | 
			
		||||
      // Guard no lat/lng
 | 
			
		||||
      if (!showMap) {
 | 
			
		||||
        return Container();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return Column(
 | 
			
		||||
        children: [
 | 
			
		||||
          // Location
 | 
			
		||||
              if (assetDetail.latitude != null && assetDetail.longitude != null)
 | 
			
		||||
                Padding(
 | 
			
		||||
                  padding: const EdgeInsets.only(top: 32.0),
 | 
			
		||||
                  child: Column(
 | 
			
		||||
          Column(
 | 
			
		||||
            crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
            children: [
 | 
			
		||||
                      const Divider(
 | 
			
		||||
                        thickness: 1,
 | 
			
		||||
                      ),
 | 
			
		||||
              Text(
 | 
			
		||||
                "exif_bottom_sheet_location",
 | 
			
		||||
                style: TextStyle(fontSize: 11, color: textColor),
 | 
			
		||||
@ -146,17 +139,26 @@ class ExifBottomSheet extends HookConsumerWidget {
 | 
			
		||||
              )
 | 
			
		||||
            ],
 | 
			
		||||
          ),
 | 
			
		||||
        ],
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildDate() {
 | 
			
		||||
      return Text(
 | 
			
		||||
        DateFormat('date_format'.tr()).format(
 | 
			
		||||
          assetDetail.createdAt.toLocal(),
 | 
			
		||||
        ),
 | 
			
		||||
              // Detail
 | 
			
		||||
              Padding(
 | 
			
		||||
                padding: const EdgeInsets.only(top: 32.0),
 | 
			
		||||
                child: Column(
 | 
			
		||||
        style: const TextStyle(
 | 
			
		||||
          fontWeight: FontWeight.bold,
 | 
			
		||||
          fontSize: 14,
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildDetail() {
 | 
			
		||||
      return Column(
 | 
			
		||||
        crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
        children: [
 | 
			
		||||
                    Divider(
 | 
			
		||||
                      thickness: 1,
 | 
			
		||||
                      color: Colors.grey[600],
 | 
			
		||||
                    ),
 | 
			
		||||
          Padding(
 | 
			
		||||
            padding: const EdgeInsets.only(bottom: 8.0),
 | 
			
		||||
            child: Text(
 | 
			
		||||
@ -194,13 +196,84 @@ class ExifBottomSheet extends HookConsumerWidget {
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
        ],
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return SingleChildScrollView(
 | 
			
		||||
      child: Card(
 | 
			
		||||
        shape: const RoundedRectangleBorder(
 | 
			
		||||
          borderRadius: BorderRadius.only(
 | 
			
		||||
            topLeft: Radius.circular(15),
 | 
			
		||||
            topRight: Radius.circular(15),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
              const SizedBox(
 | 
			
		||||
                height: 50,
 | 
			
		||||
        margin: const EdgeInsets.all(0),
 | 
			
		||||
        child: Container(
 | 
			
		||||
          margin: const EdgeInsets.symmetric(horizontal: 8.0),
 | 
			
		||||
          child: LayoutBuilder(
 | 
			
		||||
            builder: (context, constraints) {
 | 
			
		||||
              if (constraints.maxWidth > 600) {
 | 
			
		||||
                // Two column
 | 
			
		||||
                return Padding(
 | 
			
		||||
                  padding: const EdgeInsets.symmetric(horizontal: 12.0),
 | 
			
		||||
                  child: Column(
 | 
			
		||||
                    crossAxisAlignment: CrossAxisAlignment.stretch,
 | 
			
		||||
                    children: [
 | 
			
		||||
                      buildDragHeader(),
 | 
			
		||||
                      buildDate(),
 | 
			
		||||
                      const SizedBox(height: 32.0),
 | 
			
		||||
                      Row(
 | 
			
		||||
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
 | 
			
		||||
                        crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
                        children: [
 | 
			
		||||
                          Flexible(
 | 
			
		||||
                            flex: showMap ? 5 : 0,
 | 
			
		||||
                            child: Padding(
 | 
			
		||||
                              padding: const EdgeInsets.only(right: 8.0),
 | 
			
		||||
                              child: buildLocation(),
 | 
			
		||||
                            ),
 | 
			
		||||
                          ),
 | 
			
		||||
                          Flexible(
 | 
			
		||||
                            flex: 5,
 | 
			
		||||
                            child: Padding(
 | 
			
		||||
                              padding: const EdgeInsets.only(left: 8.0),
 | 
			
		||||
                              child: buildDetail(),
 | 
			
		||||
                            ),
 | 
			
		||||
                          ),
 | 
			
		||||
                        ],
 | 
			
		||||
                      ),
 | 
			
		||||
                      const SizedBox(height: 50),
 | 
			
		||||
                    ],
 | 
			
		||||
                  ),
 | 
			
		||||
                );
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
              // One column
 | 
			
		||||
              return Column(
 | 
			
		||||
                crossAxisAlignment: CrossAxisAlignment.stretch,
 | 
			
		||||
                children: [
 | 
			
		||||
                  buildDragHeader(),
 | 
			
		||||
                  buildDate(),
 | 
			
		||||
                  const SizedBox(height: 16.0),
 | 
			
		||||
                  if (showMap)
 | 
			
		||||
                    Divider(
 | 
			
		||||
                      thickness: 1,
 | 
			
		||||
                      color: Colors.grey[600],
 | 
			
		||||
                    ),
 | 
			
		||||
                  const SizedBox(height: 16.0),
 | 
			
		||||
                  buildLocation(),
 | 
			
		||||
                  const SizedBox(height: 16.0),
 | 
			
		||||
                  Divider(
 | 
			
		||||
                    thickness: 1,
 | 
			
		||||
                    color: Colors.grey[600],
 | 
			
		||||
                  ),
 | 
			
		||||
                  const SizedBox(height: 16.0),
 | 
			
		||||
                  buildDetail(),
 | 
			
		||||
                  const SizedBox(height: 50),
 | 
			
		||||
                ],
 | 
			
		||||
              );
 | 
			
		||||
            },
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user