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})
 | 
					  const ExifBottomSheet({Key? key, required this.assetDetail})
 | 
				
			||||||
      : super(key: key);
 | 
					      : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool get showMap => assetDetail.latitude != null && assetDetail.longitude != null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context, WidgetRef ref) {
 | 
					  Widget build(BuildContext context, WidgetRef ref) {
 | 
				
			||||||
    buildMap() {
 | 
					    buildMap() {
 | 
				
			||||||
      return Padding(
 | 
					      return Padding(
 | 
				
			||||||
        padding: const EdgeInsets.symmetric(vertical: 16.0),
 | 
					        padding: const EdgeInsets.symmetric(vertical: 16.0),
 | 
				
			||||||
        child: Container(
 | 
					        child: LayoutBuilder(
 | 
				
			||||||
 | 
					          builder: (context, constraints) {
 | 
				
			||||||
 | 
					            return Container(
 | 
				
			||||||
              height: 150,
 | 
					              height: 150,
 | 
				
			||||||
          width: MediaQuery.of(context).size.width,
 | 
					              width: constraints.maxWidth,
 | 
				
			||||||
              decoration: const BoxDecoration(
 | 
					              decoration: const BoxDecoration(
 | 
				
			||||||
                borderRadius: BorderRadius.all(Radius.circular(15)),
 | 
					                borderRadius: BorderRadius.all(Radius.circular(15)),
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
              child: FlutterMap(
 | 
					              child: FlutterMap(
 | 
				
			||||||
                options: MapOptions(
 | 
					                options: MapOptions(
 | 
				
			||||||
 | 
					                  interactiveFlags: InteractiveFlag.none,
 | 
				
			||||||
                  center: LatLng(
 | 
					                  center: LatLng(
 | 
				
			||||||
                    assetDetail.latitude ?? 0,
 | 
					                    assetDetail.latitude ?? 0,
 | 
				
			||||||
                    assetDetail.longitude ?? 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 text.isEmpty ? null : Text(text);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return SingleChildScrollView(
 | 
					    buildDragHeader() {
 | 
				
			||||||
      child: Card(
 | 
					      return Column(
 | 
				
			||||||
        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(
 | 
					 | 
				
			||||||
        crossAxisAlignment: CrossAxisAlignment.start,
 | 
					        crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
            children: [
 | 
					        children: const [
 | 
				
			||||||
              const SizedBox(height: 12),
 | 
					          SizedBox(height: 12),
 | 
				
			||||||
              const Align(
 | 
					          Align(
 | 
				
			||||||
            alignment: Alignment.center,
 | 
					            alignment: Alignment.center,
 | 
				
			||||||
            child: CustomDraggingHandle(),
 | 
					            child: CustomDraggingHandle(),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
              const SizedBox(height: 12),
 | 
					          SizedBox(height: 12),
 | 
				
			||||||
              Text(
 | 
					        ],
 | 
				
			||||||
                DateFormat('date_format'.tr()).format(
 | 
					      );
 | 
				
			||||||
                  assetDetail.createdAt.toLocal(),
 | 
					    }
 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
                style: const TextStyle(
 | 
					 | 
				
			||||||
                  fontWeight: FontWeight.bold,
 | 
					 | 
				
			||||||
                  fontSize: 14,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
              ),
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buildLocation() {
 | 
				
			||||||
 | 
					      // Guard no lat/lng
 | 
				
			||||||
 | 
					      if (!showMap) {
 | 
				
			||||||
 | 
					        return Container();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return Column(
 | 
				
			||||||
 | 
					        children: [
 | 
				
			||||||
          // Location
 | 
					          // Location
 | 
				
			||||||
              if (assetDetail.latitude != null && assetDetail.longitude != null)
 | 
					          Column(
 | 
				
			||||||
                Padding(
 | 
					 | 
				
			||||||
                  padding: const EdgeInsets.only(top: 32.0),
 | 
					 | 
				
			||||||
                  child: Column(
 | 
					 | 
				
			||||||
            crossAxisAlignment: CrossAxisAlignment.start,
 | 
					            crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
            children: [
 | 
					            children: [
 | 
				
			||||||
                      const Divider(
 | 
					 | 
				
			||||||
                        thickness: 1,
 | 
					 | 
				
			||||||
                      ),
 | 
					 | 
				
			||||||
              Text(
 | 
					              Text(
 | 
				
			||||||
                "exif_bottom_sheet_location",
 | 
					                "exif_bottom_sheet_location",
 | 
				
			||||||
                style: TextStyle(fontSize: 11, color: textColor),
 | 
					                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
 | 
					        style: const TextStyle(
 | 
				
			||||||
              Padding(
 | 
					          fontWeight: FontWeight.bold,
 | 
				
			||||||
                padding: const EdgeInsets.only(top: 32.0),
 | 
					          fontSize: 14,
 | 
				
			||||||
                child: Column(
 | 
					        ),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buildDetail() {
 | 
				
			||||||
 | 
					      return Column(
 | 
				
			||||||
        crossAxisAlignment: CrossAxisAlignment.start,
 | 
					        crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
        children: [
 | 
					        children: [
 | 
				
			||||||
                    Divider(
 | 
					 | 
				
			||||||
                      thickness: 1,
 | 
					 | 
				
			||||||
                      color: Colors.grey[600],
 | 
					 | 
				
			||||||
                    ),
 | 
					 | 
				
			||||||
          Padding(
 | 
					          Padding(
 | 
				
			||||||
            padding: const EdgeInsets.only(bottom: 8.0),
 | 
					            padding: const EdgeInsets.only(bottom: 8.0),
 | 
				
			||||||
            child: Text(
 | 
					            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(
 | 
					        margin: const EdgeInsets.all(0),
 | 
				
			||||||
                height: 50,
 | 
					        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