浏览代码

Optimize mobile - Avoid creating unnecessary widgets (#268)

* Avoid creating unnecessary widgets

* more flexible null handling and runtime errors prevention
xpwmaosldk 3 年之前
父节点
当前提交
c4ef523564
共有 29 个文件被更改,包括 367 次插入448 次删除
  1. 1 5
      mobile/lib/modules/asset_viewer/services/image_viewer.service.dart
  2. 128 138
      mobile/lib/modules/asset_viewer/ui/exif_bottom_sheet.dart
  3. 1 2
      mobile/lib/modules/asset_viewer/views/video_viewer_page.dart
  4. 7 4
      mobile/lib/modules/backup/ui/album_info_card.dart
  5. 2 6
      mobile/lib/modules/backup/views/backup_album_selection_page.dart
  6. 6 7
      mobile/lib/modules/backup/views/backup_controller_page.dart
  7. 1 1
      mobile/lib/modules/home/ui/disable_multi_select_button.dart
  8. 1 1
      mobile/lib/modules/home/ui/draggable_scrollbar.dart
  9. 19 23
      mobile/lib/modules/home/ui/image_grid.dart
  10. 44 49
      mobile/lib/modules/home/ui/immich_sliver_appbar.dart
  11. 1 1
      mobile/lib/modules/home/ui/profile_drawer.dart
  12. 8 11
      mobile/lib/modules/home/ui/thumbnail_image.dart
  13. 8 13
      mobile/lib/modules/home/views/home_page.dart
  14. 3 10
      mobile/lib/modules/login/ui/login_form.dart
  15. 3 10
      mobile/lib/modules/search/providers/search_page_state.provider.dart
  16. 2 3
      mobile/lib/modules/search/views/search_page.dart
  17. 3 4
      mobile/lib/modules/search/views/search_result_page.dart
  18. 1 4
      mobile/lib/modules/sharing/models/shared_album.model.dart
  19. 3 15
      mobile/lib/modules/sharing/services/shared_album.service.dart
  20. 3 3
      mobile/lib/modules/sharing/ui/album_viewer_appbar.dart
  21. 33 40
      mobile/lib/modules/sharing/ui/album_viewer_thumbnail.dart
  22. 19 20
      mobile/lib/modules/sharing/ui/selection_thumbnail_image.dart
  23. 2 1
      mobile/lib/modules/sharing/ui/sharing_sliver_appbar.dart
  24. 29 33
      mobile/lib/modules/sharing/views/album_viewer_page.dart
  25. 16 17
      mobile/lib/modules/sharing/views/asset_selection_page.dart
  26. 18 21
      mobile/lib/modules/sharing/views/create_shared_album_page.dart
  27. 3 4
      mobile/lib/shared/providers/websocket.provider.dart
  28. 1 1
      mobile/lib/shared/views/splash_screen.dart
  29. 1 1
      mobile/lib/shared/views/version_announcement_overlay.dart

+ 1 - 5
mobile/lib/modules/asset_viewer/services/image_viewer.service.dart

@@ -39,14 +39,10 @@ class ImageViewerService {
         entity = await PhotoManager.editor.saveVideo(tempFile, title: fileName);
         entity = await PhotoManager.editor.saveVideo(tempFile, title: fileName);
       }
       }
 
 
-      if (entity != null) {
-        return true;
-      }
+      return entity != null;
     } catch (e) {
     } catch (e) {
       debugPrint("Error saving file $e");
       debugPrint("Error saving file $e");
       return false;
       return false;
     }
     }
-
-    return false;
   }
   }
 }
 }

+ 128 - 138
mobile/lib/modules/asset_viewer/ui/exif_bottom_sheet.dart

@@ -15,81 +15,72 @@ class ExifBottomSheet extends ConsumerWidget {
   @override
   @override
   Widget build(BuildContext context, WidgetRef ref) {
   Widget build(BuildContext context, WidgetRef ref) {
     _buildMap() {
     _buildMap() {
-      return (assetDetail.exifInfo!.latitude != null &&
-              assetDetail.exifInfo!.longitude != null)
-          ? Padding(
-              padding: const EdgeInsets.symmetric(vertical: 16.0),
-              child: Container(
-                height: 150,
-                width: MediaQuery.of(context).size.width,
-                decoration: const BoxDecoration(
-                  borderRadius: BorderRadius.all(Radius.circular(15)),
-                ),
-                child: FlutterMap(
-                  options: MapOptions(
-                    center: LatLng(assetDetail.exifInfo!.latitude!,
+      return Padding(
+        padding: const EdgeInsets.symmetric(vertical: 16.0),
+        child: Container(
+          height: 150,
+          width: MediaQuery.of(context).size.width,
+          decoration: const BoxDecoration(
+            borderRadius: BorderRadius.all(Radius.circular(15)),
+          ),
+          child: FlutterMap(
+            options: MapOptions(
+              center: LatLng(assetDetail.exifInfo!.latitude!,
+                  assetDetail.exifInfo!.longitude!),
+              zoom: 16.0,
+            ),
+            layers: [
+              TileLayerOptions(
+                urlTemplate:
+                    "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
+                subdomains: ['a', 'b', 'c'],
+                attributionBuilder: (_) {
+                  return const Text(
+                    "© OpenStreetMap",
+                    style: TextStyle(fontSize: 10),
+                  );
+                },
+              ),
+              MarkerLayerOptions(
+                markers: [
+                  Marker(
+                    anchorPos: AnchorPos.align(AnchorAlign.top),
+                    point: LatLng(assetDetail.exifInfo!.latitude!,
                         assetDetail.exifInfo!.longitude!),
                         assetDetail.exifInfo!.longitude!),
-                    zoom: 16.0,
+                    builder: (ctx) => const Image(
+                        image: AssetImage('assets/location-pin.png')),
                   ),
                   ),
-                  layers: [
-                    TileLayerOptions(
-                      urlTemplate:
-                          "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
-                      subdomains: ['a', 'b', 'c'],
-                      attributionBuilder: (_) {
-                        return const Text(
-                          "© OpenStreetMap",
-                          style: TextStyle(fontSize: 10),
-                        );
-                      },
-                    ),
-                    MarkerLayerOptions(
-                      markers: [
-                        Marker(
-                          anchorPos: AnchorPos.align(AnchorAlign.top),
-                          point: LatLng(assetDetail.exifInfo!.latitude!,
-                              assetDetail.exifInfo!.longitude!),
-                          builder: (ctx) => const Image(
-                              image: AssetImage('assets/location-pin.png')),
-                        ),
-                      ],
-                    ),
-                  ],
-                ),
+                ],
               ),
               ),
-            )
-          : Container();
+            ],
+          ),
+        ),
+      );
     }
     }
 
 
     _buildLocationText() {
     _buildLocationText() {
-      return (assetDetail.exifInfo!.city != null &&
-              assetDetail.exifInfo!.state != null)
-          ? Text(
-              "${assetDetail.exifInfo!.city}, ${assetDetail.exifInfo!.state}",
-              style: TextStyle(
-                  fontSize: 12,
-                  color: Colors.grey[200],
-                  fontWeight: FontWeight.bold),
-            )
-          : Container();
+      return Text(
+        "${assetDetail.exifInfo!.city}, ${assetDetail.exifInfo!.state}",
+        style: TextStyle(
+            fontSize: 12, color: Colors.grey[200], fontWeight: FontWeight.bold),
+      );
     }
     }
 
 
     return Padding(
     return Padding(
       padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 8),
       padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 8),
       child: ListView(
       child: ListView(
         children: [
         children: [
-          assetDetail.exifInfo?.dateTimeOriginal != null
-              ? Text(
-                  DateFormat('E, LLL d, y • h:mm a').format(
-                    DateTime.parse(assetDetail.exifInfo!.dateTimeOriginal!),
-                  ),
-                  style: TextStyle(
-                    color: Colors.grey[400],
-                    fontWeight: FontWeight.bold,
-                    fontSize: 14,
-                  ),
-                )
-              : Container(),
+          if (assetDetail.exifInfo?.dateTimeOriginal != null)
+            Text(
+              DateFormat('E, LLL d, y • h:mm a').format(
+                DateTime.parse(assetDetail.exifInfo!.dateTimeOriginal!),
+              ),
+              style: TextStyle(
+                color: Colors.grey[400],
+                fontWeight: FontWeight.bold,
+                fontSize: 14,
+              ),
+            ),
           Padding(
           Padding(
             padding: const EdgeInsets.only(top: 16.0),
             padding: const EdgeInsets.only(top: 16.0),
             child: Text(
             child: Text(
@@ -102,84 +93,83 @@ class ExifBottomSheet extends ConsumerWidget {
           ),
           ),
 
 
           // Location
           // Location
-          assetDetail.exifInfo?.latitude != null
-              ? Padding(
-                  padding: const EdgeInsets.only(top: 32.0),
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.start,
-                    children: [
-                      Divider(
-                        thickness: 1,
-                        color: Colors.grey[600],
-                      ),
-                      Text(
-                        "LOCATION",
-                        style: TextStyle(fontSize: 11, color: Colors.grey[400]),
-                      ),
-                      _buildMap(),
-                      _buildLocationText(),
-                      Text(
-                        "${assetDetail.exifInfo!.latitude!.toStringAsFixed(4)}, ${assetDetail.exifInfo!.longitude!.toStringAsFixed(4)}",
-                        style: TextStyle(fontSize: 12, color: Colors.grey[400]),
-                      )
-                    ],
+          if (assetDetail.exifInfo?.latitude != null)
+            Padding(
+              padding: const EdgeInsets.only(top: 32.0),
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Divider(
+                    thickness: 1,
+                    color: Colors.grey[600],
                   ),
                   ),
-                )
-              : Container(),
+                  Text(
+                    "LOCATION",
+                    style: TextStyle(fontSize: 11, color: Colors.grey[400]),
+                  ),
+                  if (assetDetail.exifInfo?.latitude != null &&
+                      assetDetail.exifInfo?.longitude != null)
+                    _buildMap(),
+                  if (assetDetail.exifInfo?.city != null &&
+                      assetDetail.exifInfo?.state != null)
+                    _buildLocationText(),
+                  Text(
+                    "${assetDetail.exifInfo?.latitude?.toStringAsFixed(4)}, ${assetDetail.exifInfo?.longitude?.toStringAsFixed(4)}",
+                    style: TextStyle(fontSize: 12, color: Colors.grey[400]),
+                  )
+                ],
+              ),
+            ),
           // Detail
           // Detail
-          assetDetail.exifInfo != null
-              ? Padding(
-                  padding: const EdgeInsets.only(top: 32.0),
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.start,
-                    children: [
-                      Divider(
-                        thickness: 1,
-                        color: Colors.grey[600],
-                      ),
-                      Padding(
-                        padding: const EdgeInsets.only(bottom: 8.0),
-                        child: Text(
-                          "DETAILS",
-                          style:
-                              TextStyle(fontSize: 11, color: Colors.grey[400]),
-                        ),
-                      ),
-                      ListTile(
-                        contentPadding: const EdgeInsets.all(0),
-                        dense: true,
-                        textColor: Colors.grey[300],
-                        iconColor: Colors.grey[300],
-                        leading: const Icon(Icons.image),
-                        title: Text(
-                          "${assetDetail.exifInfo?.imageName!}${p.extension(assetDetail.originalPath)}",
-                          style: const TextStyle(fontWeight: FontWeight.bold),
-                        ),
-                        subtitle: assetDetail.exifInfo?.exifImageHeight != null
-                            ? Text(
-                                "${assetDetail.exifInfo?.exifImageHeight} x ${assetDetail.exifInfo?.exifImageWidth}  ${assetDetail.exifInfo?.fileSizeInByte!}B ")
-                            : Container(),
-                      ),
-                      assetDetail.exifInfo?.make != null
-                          ? ListTile(
-                              contentPadding: const EdgeInsets.all(0),
-                              dense: true,
-                              textColor: Colors.grey[300],
-                              iconColor: Colors.grey[300],
-                              leading: const Icon(Icons.camera),
-                              title: Text(
-                                "${assetDetail.exifInfo?.make} ${assetDetail.exifInfo?.model}",
-                                style: const TextStyle(
-                                    fontWeight: FontWeight.bold),
-                              ),
-                              subtitle: Text(
-                                  "ƒ/${assetDetail.exifInfo?.fNumber}   1/${(1 / assetDetail.exifInfo!.exposureTime!).toStringAsFixed(0)}   ${assetDetail.exifInfo?.focalLength}mm   ISO${assetDetail.exifInfo?.iso} "),
-                            )
-                          : Container()
-                    ],
+          if (assetDetail.exifInfo != null)
+            Padding(
+              padding: const EdgeInsets.only(top: 32.0),
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Divider(
+                    thickness: 1,
+                    color: Colors.grey[600],
+                  ),
+                  Padding(
+                    padding: const EdgeInsets.only(bottom: 8.0),
+                    child: Text(
+                      "DETAILS",
+                      style: TextStyle(fontSize: 11, color: Colors.grey[400]),
+                    ),
+                  ),
+                  ListTile(
+                    contentPadding: const EdgeInsets.all(0),
+                    dense: true,
+                    textColor: Colors.grey[300],
+                    iconColor: Colors.grey[300],
+                    leading: const Icon(Icons.image),
+                    title: Text(
+                      "${assetDetail.exifInfo?.imageName!}${p.extension(assetDetail.originalPath)}",
+                      style: const TextStyle(fontWeight: FontWeight.bold),
+                    ),
+                    subtitle: assetDetail.exifInfo?.exifImageHeight != null
+                        ? Text(
+                            "${assetDetail.exifInfo?.exifImageHeight} x ${assetDetail.exifInfo?.exifImageWidth}  ${assetDetail.exifInfo?.fileSizeInByte!}B ")
+                        : null,
                   ),
                   ),
-                )
-              : Container()
+                  if (assetDetail.exifInfo?.make != null)
+                    ListTile(
+                      contentPadding: const EdgeInsets.all(0),
+                      dense: true,
+                      textColor: Colors.grey[300],
+                      iconColor: Colors.grey[300],
+                      leading: const Icon(Icons.camera),
+                      title: Text(
+                        "${assetDetail.exifInfo?.make} ${assetDetail.exifInfo?.model}",
+                        style: const TextStyle(fontWeight: FontWeight.bold),
+                      ),
+                      subtitle: Text(
+                          "ƒ/${assetDetail.exifInfo?.fNumber}   1/${(1 / (assetDetail.exifInfo?.exposureTime ?? 1)).toStringAsFixed(0)}   ${assetDetail.exifInfo?.focalLength}mm   ISO${assetDetail.exifInfo?.iso} "),
+                    ),
+                ],
+              ),
+            ),
         ],
         ],
       ),
       ),
     );
     );

+ 1 - 2
mobile/lib/modules/asset_viewer/views/video_viewer_page.dart

@@ -147,8 +147,7 @@ class _VideoThumbnailPlayerState extends State<VideoThumbnailPlayer> {
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
-    return chewieController != null &&
-            chewieController!.videoPlayerController.value.isInitialized
+    return chewieController?.videoPlayerController.value.isInitialized == true
         ? SizedBox(
         ? SizedBox(
             child: Chewie(
             child: Chewie(
               controller: chewieController!,
               controller: chewieController!,

+ 7 - 4
mobile/lib/modules/backup/ui/album_info_card.dart

@@ -56,7 +56,7 @@ class AlbumInfoCard extends HookConsumerWidget {
         );
         );
       }
       }
 
 
-      return Container();
+      return const SizedBox();
     }
     }
 
 
     _buildImageFilter() {
     _buildImageFilter() {
@@ -151,7 +151,11 @@ class AlbumInfoCard extends HookConsumerWidget {
                   ),
                   ),
                   child: null,
                   child: null,
                 ),
                 ),
-                Positioned(bottom: 10, left: 25, child: _buildSelectedTextBox())
+                Positioned(
+                  bottom: 10,
+                  left: 25,
+                  child: _buildSelectedTextBox(),
+                )
               ],
               ],
             ),
             ),
             Padding(
             Padding(
@@ -176,8 +180,7 @@ class AlbumInfoCard extends HookConsumerWidget {
                           Padding(
                           Padding(
                             padding: const EdgeInsets.only(top: 2.0),
                             padding: const EdgeInsets.only(top: 2.0),
                             child: Text(
                             child: Text(
-                              albumInfo.assetCount.toString() +
-                                  (albumInfo.isAll ? " (ALL)" : ""),
+                              '${albumInfo.assetCount} ${(albumInfo.isAll ? " (ALL)" : "")}',
                               style: TextStyle(
                               style: TextStyle(
                                   fontSize: 12, color: Colors.grey[600]),
                                   fontSize: 12, color: Colors.grey[600]),
                             ),
                             ),

+ 2 - 6
mobile/lib/modules/backup/views/backup_album_selection_page.dart

@@ -188,11 +188,7 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
                           color: Colors.grey[700]),
                           color: Colors.grey[700]),
                     ),
                     ),
                     trailing: Text(
                     trailing: Text(
-                      ref
-                          .watch(backupProvider)
-                          .allUniqueAssets
-                          .length
-                          .toString(),
+                      '${ref.watch(backupProvider).allUniqueAssets.length}',
                       style: const TextStyle(fontWeight: FontWeight.bold),
                       style: const TextStyle(fontWeight: FontWeight.bold),
                     ),
                     ),
                   ),
                   ),
@@ -203,7 +199,7 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
 
 
           ListTile(
           ListTile(
             title: Text(
             title: Text(
-              "Albums on device (${availableAlbums.length.toString()})",
+              "Albums on device (${availableAlbums.length})",
               style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 14),
               style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 14),
             ),
             ),
             subtitle: Padding(
             subtitle: Padding(

+ 6 - 7
mobile/lib/modules/backup/views/backup_controller_page.dart

@@ -96,12 +96,11 @@ class BackupControllerPage extends HookConsumerWidget {
           child: Column(
           child: Column(
             crossAxisAlignment: CrossAxisAlignment.start,
             crossAxisAlignment: CrossAxisAlignment.start,
             children: [
             children: [
-              !isAutoBackup
-                  ? const Text(
-                      "Turn on backup to automatically upload new assets to the server.",
-                      style: TextStyle(fontSize: 14),
-                    )
-                  : Container(),
+              if (!isAutoBackup)
+                const Text(
+                  "Turn on backup to automatically upload new assets to the server.",
+                  style: TextStyle(fontSize: 14),
+                ),
               Padding(
               Padding(
                 padding: const EdgeInsets.only(top: 8.0),
                 padding: const EdgeInsets.only(top: 8.0),
                 child: OutlinedButton(
                 child: OutlinedButton(
@@ -189,7 +188,7 @@ class BackupControllerPage extends HookConsumerWidget {
           ),
           ),
         );
         );
       } else {
       } else {
-        return Container();
+        return const SizedBox();
       }
       }
     }
     }
 
 

+ 1 - 1
mobile/lib/modules/home/ui/disable_multi_select_button.dart

@@ -34,7 +34,7 @@ class DisableMultiSelectButton extends ConsumerWidget {
                   },
                   },
                   icon: const Icon(Icons.close_rounded),
                   icon: const Icon(Icons.close_rounded),
                   label: Text(
                   label: Text(
-                    selectedItemCount.toString(),
+                    '$selectedItemCount',
                     style: const TextStyle(
                     style: const TextStyle(
                         fontWeight: FontWeight.w600, fontSize: 18),
                         fontWeight: FontWeight.w600, fontSize: 18),
                   )),
                   )),

+ 1 - 1
mobile/lib/modules/home/ui/draggable_scrollbar.dart

@@ -615,7 +615,7 @@ class SlideFadeTransition extends StatelessWidget {
     return AnimatedBuilder(
     return AnimatedBuilder(
       animation: animation,
       animation: animation,
       builder: (context, child) =>
       builder: (context, child) =>
-          animation.value == 0.0 ? Container() : child!,
+          animation.value == 0.0 ? const SizedBox() : child!,
       child: SlideTransition(
       child: SlideTransition(
         position: Tween(
         position: Tween(
           begin: const Offset(0.3, 0.0),
           begin: const Offset(0.3, 0.0),

+ 19 - 23
mobile/lib/modules/home/ui/image_grid.dart

@@ -25,30 +25,26 @@ class ImageGrid extends ConsumerWidget {
             child: Stack(
             child: Stack(
               children: [
               children: [
                 ThumbnailImage(asset: assetGroup[index]),
                 ThumbnailImage(asset: assetGroup[index]),
-                assetType == 'IMAGE'
-                    ? Container()
-                    : Positioned(
-                        top: 5,
-                        right: 5,
-                        child: Row(
-                          children: [
-                            Text(
-                              assetGroup[index]
-                                  .duration
-                                  .toString()
-                                  .substring(0, 7),
-                              style: const TextStyle(
-                                color: Colors.white,
-                                fontSize: 10,
-                              ),
-                            ),
-                            const Icon(
-                              Icons.play_circle_outline_rounded,
-                              color: Colors.white,
-                            ),
-                          ],
+                if (assetType != 'IMAGE')
+                  Positioned(
+                    top: 5,
+                    right: 5,
+                    child: Row(
+                      children: [
+                        Text(
+                          assetGroup[index].duration.toString().substring(0, 7),
+                          style: const TextStyle(
+                            color: Colors.white,
+                            fontSize: 10,
+                          ),
                         ),
                         ),
-                      )
+                        const Icon(
+                          Icons.play_circle_outline_rounded,
+                          color: Colors.white,
+                        ),
+                      ],
+                    ),
+                  ),
               ],
               ],
             ),
             ),
           );
           );

+ 44 - 49
mobile/lib/modules/home/ui/immich_sliver_appbar.dart

@@ -49,30 +49,29 @@ class ImmichSliverAppBar extends ConsumerWidget {
                   },
                   },
                 ),
                 ),
               ),
               ),
-              serverInfoState.isVersionMismatch
-                  ? Positioned(
-                      bottom: 12,
-                      right: 12,
-                      child: GestureDetector(
-                        onTap: () => Scaffold.of(context).openDrawer(),
-                        child: Material(
-                          color: Colors.grey[200],
-                          elevation: 1,
-                          shape: RoundedRectangleBorder(
-                            borderRadius: BorderRadius.circular(50.0),
-                          ),
-                          child: const Padding(
-                            padding: EdgeInsets.all(2.0),
-                            child: Icon(
-                              Icons.info,
-                              color: Color.fromARGB(255, 243, 188, 106),
-                              size: 15,
-                            ),
-                          ),
+              if (serverInfoState.isVersionMismatch)
+                Positioned(
+                  bottom: 12,
+                  right: 12,
+                  child: GestureDetector(
+                    onTap: () => Scaffold.of(context).openDrawer(),
+                    child: Material(
+                      color: Colors.grey[200],
+                      elevation: 1,
+                      shape: RoundedRectangleBorder(
+                        borderRadius: BorderRadius.circular(50.0),
+                      ),
+                      child: const Padding(
+                        padding: EdgeInsets.all(2.0),
+                        child: Icon(
+                          Icons.info,
+                          color: Color.fromARGB(255, 243, 188, 106),
+                          size: 15,
                         ),
                         ),
                       ),
                       ),
-                    )
-                  : Container(),
+                    ),
+                  ),
+                ),
             ],
             ],
           );
           );
         },
         },
@@ -90,21 +89,20 @@ class ImmichSliverAppBar extends ConsumerWidget {
         Stack(
         Stack(
           alignment: AlignmentDirectional.center,
           alignment: AlignmentDirectional.center,
           children: [
           children: [
-            backupState.backupProgress == BackUpProgressEnum.inProgress
-                ? Positioned(
-                    top: 10,
-                    right: 12,
-                    child: SizedBox(
-                      height: 8,
-                      width: 8,
-                      child: CircularProgressIndicator(
-                        strokeWidth: 1,
-                        valueColor: AlwaysStoppedAnimation<Color>(
-                            Theme.of(context).primaryColor),
-                      ),
-                    ),
-                  )
-                : Container(),
+            if (backupState.backupProgress == BackUpProgressEnum.inProgress)
+              Positioned(
+                top: 10,
+                right: 12,
+                child: SizedBox(
+                  height: 8,
+                  width: 8,
+                  child: CircularProgressIndicator(
+                    strokeWidth: 1,
+                    valueColor: AlwaysStoppedAnimation<Color>(
+                        Theme.of(context).primaryColor),
+                  ),
+                ),
+              ),
             IconButton(
             IconButton(
               splashRadius: 25,
               splashRadius: 25,
               iconSize: 30,
               iconSize: 30,
@@ -129,18 +127,15 @@ class ImmichSliverAppBar extends ConsumerWidget {
                 }
                 }
               },
               },
             ),
             ),
-            backupState.backupProgress == BackUpProgressEnum.inProgress
-                ? Positioned(
-                    bottom: 5,
-                    child: Text(
-                      (backupState.allUniqueAssets.length -
-                              backupState.selectedAlbumsBackupAssetsIds.length)
-                          .toString(),
-                      style: const TextStyle(
-                          fontSize: 9, fontWeight: FontWeight.bold),
-                    ),
-                  )
-                : Container()
+            if (backupState.backupProgress == BackUpProgressEnum.inProgress)
+              Positioned(
+                bottom: 5,
+                child: Text(
+                  '${backupState.allUniqueAssets.length - backupState.selectedAlbumsBackupAssetsIds.length}',
+                  style:
+                      const TextStyle(fontSize: 9, fontWeight: FontWeight.bold),
+                ),
+              ),
           ],
           ],
         ),
         ),
       ],
       ],

+ 1 - 1
mobile/lib/modules/home/ui/profile_drawer.dart

@@ -87,7 +87,7 @@ class ProfileDrawer extends HookConsumerWidget {
         return const ImmichLoadingIndicator();
         return const ImmichLoadingIndicator();
       }
       }
 
 
-      return Container();
+      return const SizedBox();
     }
     }
 
 
     _pickUserProfileImage() async {
     _pickUserProfileImage() async {

+ 8 - 11
mobile/lib/modules/home/ui/thumbnail_image.dart

@@ -122,17 +122,14 @@ class ThumbnailImage extends HookConsumerWidget {
                 },
                 },
               ),
               ),
             ),
             ),
-            Container(
-              child: isMultiSelectEnable
-                  ? Padding(
-                      padding: const EdgeInsets.all(3.0),
-                      child: Align(
-                        alignment: Alignment.topLeft,
-                        child: _buildSelectionIcon(asset),
-                      ),
-                    )
-                  : Container(),
-            ),
+            if (isMultiSelectEnable)
+              Padding(
+                padding: const EdgeInsets.all(3.0),
+                child: Align(
+                  alignment: Alignment.topLeft,
+                  child: _buildSelectionIcon(asset),
+                ),
+              ),
             Positioned(
             Positioned(
               right: 10,
               right: 10,
               bottom: 5,
               bottom: 5,

+ 8 - 13
mobile/lib/modules/home/views/home_page.dart

@@ -38,17 +38,10 @@ class HomePage extends HookConsumerWidget {
     }
     }
 
 
     _buildSelectedItemCountIndicator() {
     _buildSelectedItemCountIndicator() {
-      return isMultiSelectEnable
-          ? DisableMultiSelectButton(
-              onPressed:
-                  ref.watch(homePageStateProvider.notifier).disableMultiSelect,
-              selectedItemCount: homePageState.selectedItems.length,
-            )
-          : Container();
-    }
-
-    _buildBottomAppBar() {
-      return isMultiSelectEnable ? const ControlBottomAppBar() : Container();
+      return DisableMultiSelectButton(
+        onPressed: ref.watch(homePageStateProvider.notifier).disableMultiSelect,
+        selectedItemCount: homePageState.selectedItems.length,
+      );
     }
     }
 
 
     Widget _buildBody() {
     Widget _buildBody() {
@@ -121,8 +114,10 @@ class HomePage extends HookConsumerWidget {
                 ),
                 ),
               ),
               ),
             ),
             ),
-            _buildSelectedItemCountIndicator(),
-            _buildBottomAppBar(),
+            if (isMultiSelectEnable) ...[
+              _buildSelectedItemCountIndicator(),
+              const ControlBottomAppBar(),
+            ],
           ],
           ],
         ),
         ),
       );
       );

+ 3 - 10
mobile/lib/modules/login/ui/login_form.dart

@@ -107,19 +107,12 @@ class ServerEndpointInput extends StatelessWidget {
       : super(key: key);
       : super(key: key);
 
 
   String? _validateInput(String? url) {
   String? _validateInput(String? url) {
-    if (url == null) {
+  
+    if (url?.startsWith(RegExp(r'https?://')) == true) {
       return null;
       return null;
-    }
-
-    if (url.isEmpty) {
-      return 'Server endpoint is required';
-    }
-
-    if (!url.startsWith(RegExp(r'https?://'))) {
+    } else {
       return 'Please specify http:// or https://';
       return 'Please specify http:// or https://';
     }
     }
-
-    return null;
   }
   }
 
 
   @override
   @override

+ 3 - 10
mobile/lib/modules/search/providers/search_page_state.provider.dart

@@ -62,11 +62,7 @@ final getCuratedLocationProvider =
   final SearchService searchService = ref.watch(searchServiceProvider);
   final SearchService searchService = ref.watch(searchServiceProvider);
 
 
   var curatedLocation = await searchService.getCuratedLocation();
   var curatedLocation = await searchService.getCuratedLocation();
-  if (curatedLocation != null) {
-    return curatedLocation;
-  } else {
-    return [];
-  }
+  return curatedLocation ?? [];
 });
 });
 
 
 final getCuratedObjectProvider =
 final getCuratedObjectProvider =
@@ -74,9 +70,6 @@ final getCuratedObjectProvider =
   final SearchService searchService = ref.watch(searchServiceProvider);
   final SearchService searchService = ref.watch(searchServiceProvider);
 
 
   var curatedObject = await searchService.getCuratedObjects();
   var curatedObject = await searchService.getCuratedObjects();
-  if (curatedObject != null) {
-    return curatedObject;
-  } else {
-    return [];
-  }
+
+  return curatedObject ?? [];
 });
 });

+ 2 - 3
mobile/lib/modules/search/views/search_page.dart

@@ -176,9 +176,8 @@ class SearchPage extends HookConsumerWidget {
                 _buildThings()
                 _buildThings()
               ],
               ],
             ),
             ),
-            isSearchEnabled
-                ? SearchSuggestionList(onSubmitted: _onSearchSubmitted)
-                : Container(),
+            if (isSearchEnabled)
+              SearchSuggestionList(onSubmitted: _onSearchSubmitted),
           ],
           ],
         ),
         ),
       ),
       ),

+ 3 - 4
mobile/lib/modules/search/views/search_result_page.dart

@@ -166,7 +166,7 @@ class SearchResultPage extends HookConsumerWidget {
         }
         }
       }
       }
 
 
-      return Container();
+      return const SizedBox();
     }
     }
 
 
     return Scaffold(
     return Scaffold(
@@ -198,9 +198,8 @@ class SearchResultPage extends HookConsumerWidget {
         child: Stack(
         child: Stack(
           children: [
           children: [
             _buildSearchResult(),
             _buildSearchResult(),
-            isNewSearch.value
-                ? SearchSuggestionList(onSubmitted: _onSearchSubmitted)
-                : Container(),
+            if (isNewSearch.value)
+              SearchSuggestionList(onSubmitted: _onSearchSubmitted),
           ],
           ],
         ),
         ),
       ),
       ),

+ 1 - 4
mobile/lib/modules/sharing/models/shared_album.model.dart

@@ -72,10 +72,7 @@ class SharedAlbum {
       albumThumbnailAssetId: map['albumThumbnailAssetId'],
       albumThumbnailAssetId: map['albumThumbnailAssetId'],
       sharedUsers:
       sharedUsers:
           List<User>.from(map['sharedUsers']?.map((x) => User.fromMap(x))),
           List<User>.from(map['sharedUsers']?.map((x) => User.fromMap(x))),
-      assets: map['assets'] != null
-          ? List<ImmichAsset>.from(
-              map['assets']?.map((x) => ImmichAsset.fromMap(x)))
-          : null,
+      assets: map['assets']?.map((x) => ImmichAsset.fromMap(x)).toList(),
     );
     );
   }
   }
 
 

+ 3 - 15
mobile/lib/modules/sharing/services/shared_album.service.dart

@@ -39,11 +39,7 @@ class SharedAlbumService {
         "assetIds": assets.map((asset) => asset.id).toList(),
         "assetIds": assets.map((asset) => asset.id).toList(),
       });
       });
 
 
-      if (res == null) {
-        return false;
-      }
-
-      return true;
+      return res != null;
     } catch (e) {
     } catch (e) {
       debugPrint("Error createSharedAlbum  ${e.toString()}");
       debugPrint("Error createSharedAlbum  ${e.toString()}");
       return false;
       return false;
@@ -71,11 +67,7 @@ class SharedAlbumService {
         "assetIds": assets.map((asset) => asset.id).toList(),
         "assetIds": assets.map((asset) => asset.id).toList(),
       });
       });
 
 
-      if (res == null) {
-        return false;
-      }
-
-      return true;
+      return res != null;
     } catch (e) {
     } catch (e) {
       debugPrint("Error addAdditionalAssetToAlbum  ${e.toString()}");
       debugPrint("Error addAdditionalAssetToAlbum  ${e.toString()}");
       return false;
       return false;
@@ -90,11 +82,7 @@ class SharedAlbumService {
         "sharedUserIds": sharedUserIds,
         "sharedUserIds": sharedUserIds,
       });
       });
 
 
-      if (res == null) {
-        return false;
-      }
-
-      return true;
+      return res != null;
     } catch (e) {
     } catch (e) {
       debugPrint("Error addAdditionalUserToAlbum  ${e.toString()}");
       debugPrint("Error addAdditionalUserToAlbum  ${e.toString()}");
       return false;
       return false;

+ 3 - 3
mobile/lib/modules/sharing/ui/album_viewer_appbar.dart

@@ -114,7 +114,7 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget {
             onTap: () => _onRemoveFromAlbumPressed(albumId),
             onTap: () => _onRemoveFromAlbumPressed(albumId),
           );
           );
         } else {
         } else {
-          return Container();
+          return const SizedBox();
         }
         }
       } else {
       } else {
         if (_albumInfo.asData?.value.ownerId == userId) {
         if (_albumInfo.asData?.value.ownerId == userId) {
@@ -198,8 +198,8 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget {
       elevation: 0,
       elevation: 0,
       leading: _buildLeadingButton(),
       leading: _buildLeadingButton(),
       title: isMultiSelectionEnable
       title: isMultiSelectionEnable
-          ? Text(selectedAssetsInAlbum.length.toString())
-          : Container(),
+          ? Text('${selectedAssetsInAlbum.length}')
+          : null,
       centerTitle: false,
       centerTitle: false,
       actions: [
       actions: [
         IconButton(
         IconButton(

+ 33 - 40
mobile/lib/modules/sharing/ui/album_viewer_thumbnail.dart

@@ -71,29 +71,25 @@ class AlbumViewerThumbnail extends HookConsumerWidget {
     }
     }
 
 
     _buildVideoLabel() {
     _buildVideoLabel() {
-      if (asset.type == 'IMAGE') {
-        return Container();
-      } else {
-        return Positioned(
-          top: 5,
-          right: 5,
-          child: Row(
-            children: [
-              Text(
-                asset.duration.toString().substring(0, 7),
-                style: const TextStyle(
-                  color: Colors.white,
-                  fontSize: 10,
-                ),
-              ),
-              const Icon(
-                Icons.play_circle_outline_rounded,
+      return Positioned(
+        top: 5,
+        right: 5,
+        child: Row(
+          children: [
+            Text(
+              asset.duration.toString().substring(0, 7),
+              style: const TextStyle(
                 color: Colors.white,
                 color: Colors.white,
+                fontSize: 10,
               ),
               ),
-            ],
-          ),
-        );
-      }
+            ),
+            const Icon(
+              Icons.play_circle_outline_rounded,
+              color: Colors.white,
+            ),
+          ],
+        ),
+      );
     }
     }
 
 
     _buildAssetStoreLocationIcon() {
     _buildAssetStoreLocationIcon() {
@@ -112,23 +108,20 @@ class AlbumViewerThumbnail extends HookConsumerWidget {
 
 
     _buildAssetSelectionIcon() {
     _buildAssetSelectionIcon() {
       bool isSelected = selectedAssetsInAlbumViewer.contains(asset);
       bool isSelected = selectedAssetsInAlbumViewer.contains(asset);
-      if (isMultiSelectionEnable) {
-        return Positioned(
-          left: 10,
-          top: 5,
-          child: isSelected
-              ? Icon(
-                  Icons.check_circle_rounded,
-                  color: Theme.of(context).primaryColor,
-                )
-              : const Icon(
-                  Icons.check_circle_outline_rounded,
-                  color: Colors.white,
-                ),
-        );
-      } else {
-        return Container();
-      }
+
+      return Positioned(
+        left: 10,
+        top: 5,
+        child: isSelected
+            ? Icon(
+                Icons.check_circle_rounded,
+                color: Theme.of(context).primaryColor,
+              )
+            : const Icon(
+                Icons.check_circle_outline_rounded,
+                color: Colors.white,
+              ),
+      );
     }
     }
 
 
     _buildThumbnailImage() {
     _buildThumbnailImage() {
@@ -183,8 +176,8 @@ class AlbumViewerThumbnail extends HookConsumerWidget {
           children: [
           children: [
             _buildThumbnailImage(),
             _buildThumbnailImage(),
             _buildAssetStoreLocationIcon(),
             _buildAssetStoreLocationIcon(),
-            _buildVideoLabel(),
-            _buildAssetSelectionIcon(),
+            if (asset.type != 'IMAGE') _buildVideoLabel(),
+            if (isMultiSelectionEnable) _buildAssetSelectionIcon(),
           ],
           ],
         ),
         ),
       ),
       ),

+ 19 - 20
mobile/lib/modules/sharing/ui/selection_thumbnail_image.dart

@@ -131,27 +131,26 @@ class SelectionThumbnailImage extends HookConsumerWidget {
               child: _buildSelectionIcon(asset),
               child: _buildSelectionIcon(asset),
             ),
             ),
           ),
           ),
-          asset.type == 'IMAGE'
-              ? Container()
-              : Positioned(
-                  bottom: 5,
-                  right: 5,
-                  child: Row(
-                    children: [
-                      Text(
-                        asset.duration.toString().substring(0, 7),
-                        style: const TextStyle(
-                          color: Colors.white,
-                          fontSize: 10,
-                        ),
-                      ),
-                      const Icon(
-                        Icons.play_circle_outline_rounded,
-                        color: Colors.white,
-                      ),
-                    ],
+          if (asset.type != 'IMAGE')
+            Positioned(
+              bottom: 5,
+              right: 5,
+              child: Row(
+                children: [
+                  Text(
+                    '${asset.duration?.substring(0, 7)}',
+                    style: const TextStyle(
+                      color: Colors.white,
+                      fontSize: 10,
+                    ),
                   ),
                   ),
-                )
+                  const Icon(
+                    Icons.play_circle_outline_rounded,
+                    color: Colors.white,
+                  ),
+                ],
+              ),
+            ),
         ],
         ],
       ),
       ),
     );
     );

+ 2 - 1
mobile/lib/modules/sharing/ui/sharing_sliver_appbar.dart

@@ -14,7 +14,8 @@ class SharingSliverAppBar extends StatelessWidget {
       floating: false,
       floating: false,
       pinned: true,
       pinned: true,
       snap: false,
       snap: false,
-      leading: Container(),
+      automaticallyImplyLeading: false,
+      // leading: Container(),
       // elevation: 0,
       // elevation: 0,
       title: Text(
       title: Text(
         'IMMICH',
         'IMMICH',

+ 29 - 33
mobile/lib/modules/sharing/views/album_viewer_page.dart

@@ -37,7 +37,7 @@ class AlbumViewerPage extends HookConsumerWidget {
     /// Find out if the assets in album exist on the device
     /// Find out if the assets in album exist on the device
     /// If they exist, add to selected asset state to show they are already selected.
     /// If they exist, add to selected asset state to show they are already selected.
     void _onAddPhotosPressed(SharedAlbum albumInfo) async {
     void _onAddPhotosPressed(SharedAlbum albumInfo) async {
-      if (albumInfo.assets != null && albumInfo.assets!.isNotEmpty) {
+      if (albumInfo.assets?.isNotEmpty == true) {
         ref
         ref
             .watch(assetSelectionProvider.notifier)
             .watch(assetSelectionProvider.notifier)
             .addNewAssets(albumInfo.assets!.toList());
             .addNewAssets(albumInfo.assets!.toList());
@@ -109,32 +109,28 @@ class AlbumViewerPage extends HookConsumerWidget {
     }
     }
 
 
     Widget _buildAlbumDateRange(SharedAlbum albumInfo) {
     Widget _buildAlbumDateRange(SharedAlbum albumInfo) {
-      if (albumInfo.assets != null && albumInfo.assets!.isNotEmpty) {
-        String startDate = "";
-        DateTime parsedStartDate =
-            DateTime.parse(albumInfo.assets!.first.createdAt);
-        DateTime parsedEndDate =
-            DateTime.parse(albumInfo.assets!.last.createdAt);
+      String startDate = "";
+      DateTime parsedStartDate =
+          DateTime.parse(albumInfo.assets!.first.createdAt);
+      DateTime parsedEndDate = DateTime.parse(
+          albumInfo.assets?.last.createdAt ?? '11111111'); //Need default.
 
 
-        if (parsedStartDate.year == parsedEndDate.year) {
-          startDate = DateFormat('LLL d').format(parsedStartDate);
-        } else {
-          startDate = DateFormat('LLL d, y').format(parsedStartDate);
-        }
-
-        String endDate = DateFormat('LLL d, y').format(parsedEndDate);
-
-        return Padding(
-          padding: const EdgeInsets.only(left: 16.0, top: 8),
-          child: Text(
-            "$startDate-$endDate",
-            style: const TextStyle(
-                fontSize: 14, fontWeight: FontWeight.bold, color: Colors.grey),
-          ),
-        );
+      if (parsedStartDate.year == parsedEndDate.year) {
+        startDate = DateFormat('LLL d').format(parsedStartDate);
       } else {
       } else {
-        return Container();
+        startDate = DateFormat('LLL d, y').format(parsedStartDate);
       }
       }
+
+      String endDate = DateFormat('LLL d, y').format(parsedEndDate);
+
+      return Padding(
+        padding: const EdgeInsets.only(left: 16.0, top: 8),
+        child: Text(
+          "$startDate-$endDate",
+          style: const TextStyle(
+              fontSize: 14, fontWeight: FontWeight.bold, color: Colors.grey),
+        ),
+      );
     }
     }
 
 
     Widget _buildHeader(SharedAlbum albumInfo) {
     Widget _buildHeader(SharedAlbum albumInfo) {
@@ -143,7 +139,8 @@ class AlbumViewerPage extends HookConsumerWidget {
           crossAxisAlignment: CrossAxisAlignment.start,
           crossAxisAlignment: CrossAxisAlignment.start,
           children: [
           children: [
             _buildTitle(albumInfo),
             _buildTitle(albumInfo),
-            _buildAlbumDateRange(albumInfo),
+            if (albumInfo.assets?.isNotEmpty == true)
+              _buildAlbumDateRange(albumInfo),
             SizedBox(
             SizedBox(
               height: 60,
               height: 60,
               child: ListView.builder(
               child: ListView.builder(
@@ -175,7 +172,7 @@ class AlbumViewerPage extends HookConsumerWidget {
     }
     }
 
 
     Widget _buildImageGrid(SharedAlbum albumInfo) {
     Widget _buildImageGrid(SharedAlbum albumInfo) {
-      if (albumInfo.assets != null && albumInfo.assets!.isNotEmpty) {
+      if (albumInfo.assets?.isNotEmpty == true) {
         return SliverPadding(
         return SliverPadding(
           padding: const EdgeInsets.only(top: 10.0),
           padding: const EdgeInsets.only(top: 10.0),
           sliver: SliverGrid(
           sliver: SliverGrid(
@@ -209,13 +206,12 @@ class AlbumViewerPage extends HookConsumerWidget {
                 onPressed: () => _onAddPhotosPressed(albumInfo),
                 onPressed: () => _onAddPhotosPressed(albumInfo),
                 labelText: "Add photos",
                 labelText: "Add photos",
               ),
               ),
-              userId == albumInfo.ownerId
-                  ? AlbumActionOutlinedButton(
-                      iconData: Icons.person_add_alt_rounded,
-                      onPressed: () => _onAddUsersPressed(albumInfo),
-                      labelText: "Add users",
-                    )
-                  : Container(),
+              if (userId == albumInfo.ownerId)
+                AlbumActionOutlinedButton(
+                  iconData: Icons.person_add_alt_rounded,
+                  onPressed: () => _onAddUsersPressed(albumInfo),
+                  labelText: "Add users",
+                ),
             ],
             ],
           ),
           ),
         ),
         ),

+ 16 - 17
mobile/lib/modules/sharing/views/asset_selection_page.dart

@@ -74,23 +74,22 @@ class AssetSelectionPage extends HookConsumerWidget {
               ),
               ),
         centerTitle: false,
         centerTitle: false,
         actions: [
         actions: [
-          (!isAlbumExist && selectedAssets.isNotEmpty) ||
-                  (isAlbumExist && newAssetsForAlbum.isNotEmpty)
-              ? TextButton(
-                  onPressed: () {
-                    var payload = AssetSelectionPageResult(
-                      isAlbumExist: isAlbumExist,
-                      selectedAdditionalAsset: newAssetsForAlbum,
-                      selectedNewAsset: selectedAssets,
-                    );
-                    AutoRouter.of(context).pop(payload);
-                  },
-                  child: const Text(
-                    "Add",
-                    style: TextStyle(fontWeight: FontWeight.bold),
-                  ),
-                )
-              : Container()
+          if ((!isAlbumExist && selectedAssets.isNotEmpty) ||
+              (isAlbumExist && newAssetsForAlbum.isNotEmpty))
+            TextButton(
+              onPressed: () {
+                var payload = AssetSelectionPageResult(
+                  isAlbumExist: isAlbumExist,
+                  selectedAdditionalAsset: newAssetsForAlbum,
+                  selectedNewAsset: selectedAssets,
+                );
+                AutoRouter.of(context).pop(payload);
+              },
+              child: const Text(
+                "Add",
+                style: TextStyle(fontWeight: FontWeight.bold),
+              ),
+            ),
         ],
         ],
       ),
       ),
       body: _buildBody(),
       body: _buildBody(),

+ 18 - 21
mobile/lib/modules/sharing/views/create_shared_album_page.dart

@@ -113,26 +113,22 @@ class CreateSharedAlbumPage extends HookConsumerWidget {
     }
     }
 
 
     _buildControlButton() {
     _buildControlButton() {
-      if (selectedAssets.isNotEmpty) {
-        return Padding(
-          padding: const EdgeInsets.only(left: 12.0, top: 16, bottom: 16),
-          child: SizedBox(
-            height: 30,
-            child: ListView(
-              scrollDirection: Axis.horizontal,
-              children: [
-                AlbumActionOutlinedButton(
-                  iconData: Icons.add_photo_alternate_outlined,
-                  onPressed: _onSelectPhotosButtonPressed,
-                  labelText: "Add photos",
-                ),
-              ],
-            ),
+      return Padding(
+        padding: const EdgeInsets.only(left: 12.0, top: 16, bottom: 16),
+        child: SizedBox(
+          height: 30,
+          child: ListView(
+            scrollDirection: Axis.horizontal,
+            children: [
+              AlbumActionOutlinedButton(
+                iconData: Icons.add_photo_alternate_outlined,
+                onPressed: _onSelectPhotosButtonPressed,
+                labelText: "Add photos",
+              ),
+            ],
           ),
           ),
-        );
-      }
-
-      return Container();
+        ),
+      );
     }
     }
 
 
     _buildSelectedImageGrid() {
     _buildSelectedImageGrid() {
@@ -196,7 +192,8 @@ class CreateSharedAlbumPage extends HookConsumerWidget {
             slivers: [
             slivers: [
               SliverAppBar(
               SliverAppBar(
                 elevation: 5,
                 elevation: 5,
-                leading: Container(),
+                automaticallyImplyLeading: false,
+                // leading: Container(),
                 pinned: true,
                 pinned: true,
                 floating: false,
                 floating: false,
                 bottom: PreferredSize(
                 bottom: PreferredSize(
@@ -204,7 +201,7 @@ class CreateSharedAlbumPage extends HookConsumerWidget {
                   child: Column(
                   child: Column(
                     children: [
                     children: [
                       _buildTitleInputField(),
                       _buildTitleInputField(),
-                      _buildControlButton(),
+                      if (selectedAssets.isNotEmpty) _buildControlButton(),
                     ],
                     ],
                   ),
                   ),
                 ),
                 ),

+ 3 - 4
mobile/lib/shared/providers/websocket.provider.dart

@@ -104,10 +104,9 @@ class WebsocketNotifier extends StateNotifier<WebscoketState> {
   disconnect() {
   disconnect() {
     debugPrint("[WEBSOCKET] Attempting to disconnect");
     debugPrint("[WEBSOCKET] Attempting to disconnect");
     var socket = state.socket?.disconnect();
     var socket = state.socket?.disconnect();
-    if (socket != null) {
-      if (socket.disconnected) {
-        state = WebscoketState(isConnected: false, socket: null);
-      }
+
+    if (socket?.disconnected == true) {
+      state = WebscoketState(isConnected: false, socket: null);
     }
     }
   }
   }
 
 

+ 1 - 1
mobile/lib/shared/views/splash_screen.dart

@@ -34,7 +34,7 @@ class SplashScreenPage extends HookConsumerWidget {
     }
     }
 
 
     useEffect(() {
     useEffect(() {
-      if (loginInfo != null && loginInfo.isSaveLogin) {
+      if (loginInfo?.isSaveLogin == true) {
         performLoggingIn();
         performLoggingIn();
       } else {
       } else {
         AutoRouter.of(context).push(const LoginRoute());
         AutoRouter.of(context).push(const LoginRoute());

+ 1 - 1
mobile/lib/shared/views/version_announcement_overlay.dart

@@ -121,7 +121,7 @@ class VersionAnnouncementOverlay extends HookConsumerWidget {
             ),
             ),
           );
           );
         } else {
         } else {
-          return Container();
+          return const SizedBox();
         }
         }
       },
       },
     );
     );