Optimize mobile - Avoid creating unnecessary widgets (#268)

* Avoid creating unnecessary widgets

* more flexible null handling and runtime errors prevention
This commit is contained in:
xpwmaosldk 2022-07-01 10:08:49 +09:00 committed by GitHub
parent 992f792c0a
commit c4ef523564
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 369 additions and 450 deletions

View File

@ -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 entity != null;
return true;
}
} catch (e) { } catch (e) {
debugPrint("Error saving file $e"); debugPrint("Error saving file $e");
return false; return false;
} }
return false;
} }
} }

View File

@ -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 && return Padding(
assetDetail.exifInfo!.longitude != null) padding: const EdgeInsets.symmetric(vertical: 16.0),
? Padding( child: Container(
padding: const EdgeInsets.symmetric(vertical: 16.0), height: 150,
child: Container( width: MediaQuery.of(context).size.width,
height: 150, decoration: const BoxDecoration(
width: MediaQuery.of(context).size.width, borderRadius: BorderRadius.all(Radius.circular(15)),
decoration: const BoxDecoration( ),
borderRadius: BorderRadius.all(Radius.circular(15)), child: FlutterMap(
), options: MapOptions(
child: FlutterMap( center: LatLng(assetDetail.exifInfo!.latitude!,
options: MapOptions( assetDetail.exifInfo!.longitude!),
center: LatLng(assetDetail.exifInfo!.latitude!, zoom: 16.0,
assetDetail.exifInfo!.longitude!), ),
zoom: 16.0, layers: [
), TileLayerOptions(
layers: [ urlTemplate:
TileLayerOptions( "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
urlTemplate: subdomains: ['a', 'b', 'c'],
"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", attributionBuilder: (_) {
subdomains: ['a', 'b', 'c'], return const Text(
attributionBuilder: (_) { "© OpenStreetMap",
return const Text( style: TextStyle(fontSize: 10),
"© 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')),
),
],
),
],
),
), ),
) MarkerLayerOptions(
: Container(); 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')),
),
],
),
],
),
),
);
} }
_buildLocationText() { _buildLocationText() {
return (assetDetail.exifInfo!.city != null && return Text(
assetDetail.exifInfo!.state != null) "${assetDetail.exifInfo!.city}, ${assetDetail.exifInfo!.state}",
? Text( style: TextStyle(
"${assetDetail.exifInfo!.city}, ${assetDetail.exifInfo!.state}", fontSize: 12, color: Colors.grey[200], fontWeight: FontWeight.bold),
style: TextStyle( );
fontSize: 12,
color: Colors.grey[200],
fontWeight: FontWeight.bold),
)
: Container();
} }
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 if (assetDetail.exifInfo?.dateTimeOriginal != null)
? Text( Text(
DateFormat('E, LLL d, y • h:mm a').format( DateFormat('E, LLL d, y • h:mm a').format(
DateTime.parse(assetDetail.exifInfo!.dateTimeOriginal!), DateTime.parse(assetDetail.exifInfo!.dateTimeOriginal!),
), ),
style: TextStyle( style: TextStyle(
color: Colors.grey[400], color: Colors.grey[400],
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 14, fontSize: 14,
), ),
) ),
: Container(),
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 if (assetDetail.exifInfo?.latitude != null)
? Padding( Padding(
padding: const EdgeInsets.only(top: 32.0), padding: const EdgeInsets.only(top: 32.0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Divider( Divider(
thickness: 1, thickness: 1,
color: Colors.grey[600], 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]),
)
],
), ),
) Text(
: Container(), "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 if (assetDetail.exifInfo != null)
? Padding( Padding(
padding: const EdgeInsets.only(top: 32.0), padding: const EdgeInsets.only(top: 32.0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Divider( Divider(
thickness: 1, thickness: 1,
color: Colors.grey[600], 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()
],
), ),
) Padding(
: Container() 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,
),
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} "),
),
],
),
),
], ],
), ),
); );

View File

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

View File

@ -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.assetCount} ${(albumInfo.isAll ? " (ALL)" : "")}',
(albumInfo.isAll ? " (ALL)" : ""),
style: TextStyle( style: TextStyle(
fontSize: 12, color: Colors.grey[600]), fontSize: 12, color: Colors.grey[600]),
), ),

View File

@ -188,11 +188,7 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
color: Colors.grey[700]), color: Colors.grey[700]),
), ),
trailing: Text( trailing: Text(
ref '${ref.watch(backupProvider).allUniqueAssets.length}',
.watch(backupProvider)
.allUniqueAssets
.length
.toString(),
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(

View File

@ -96,12 +96,11 @@ class BackupControllerPage extends HookConsumerWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
!isAutoBackup if (!isAutoBackup)
? const Text( const Text(
"Turn on backup to automatically upload new assets to the server.", "Turn on backup to automatically upload new assets to the server.",
style: TextStyle(fontSize: 14), style: TextStyle(fontSize: 14),
) ),
: Container(),
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();
} }
} }

View File

@ -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),
)), )),

View File

@ -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),

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
} } else {
if (url.isEmpty) {
return 'Server endpoint is required';
}
if (!url.startsWith(RegExp(r'https?://'))) {
return 'Please specify http:// or https://'; return 'Please specify http:// or https://';
} }
return null;
} }
@override @override

View File

@ -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 ?? [];
return curatedLocation;
} else {
return [];
}
}); });
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; return curatedObject ?? [];
} else {
return [];
}
}); });

View File

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

View File

@ -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 if (isNewSearch.value)
? SearchSuggestionList(onSubmitted: _onSearchSubmitted) SearchSuggestionList(onSubmitted: _onSearchSubmitted),
: Container(),
], ],
), ),
), ),

View File

@ -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 assets: map['assets']?.map((x) => ImmichAsset.fromMap(x)).toList(),
? List<ImmichAsset>.from(
map['assets']?.map((x) => ImmichAsset.fromMap(x)))
: null,
); );
} }

View File

@ -39,11 +39,7 @@ class SharedAlbumService {
"assetIds": assets.map((asset) => asset.id).toList(), "assetIds": assets.map((asset) => asset.id).toList(),
}); });
if (res == null) { return res != null;
return false;
}
return true;
} 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 res != null;
return false;
}
return true;
} 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 res != null;
return false;
}
return true;
} catch (e) { } catch (e) {
debugPrint("Error addAdditionalUserToAlbum ${e.toString()}"); debugPrint("Error addAdditionalUserToAlbum ${e.toString()}");
return false; return false;

View File

@ -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()) ? Text('${selectedAssetsInAlbum.length}')
: Container(), : null,
centerTitle: false, centerTitle: false,
actions: [ actions: [
IconButton( IconButton(

View File

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

View File

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

View File

@ -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',

View File

@ -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 = "";
String startDate = ""; DateTime parsedStartDate =
DateTime parsedStartDate = DateTime.parse(albumInfo.assets!.first.createdAt);
DateTime.parse(albumInfo.assets!.first.createdAt); DateTime parsedEndDate = DateTime.parse(
DateTime parsedEndDate = albumInfo.assets?.last.createdAt ?? '11111111'); //Need default.
DateTime.parse(albumInfo.assets!.last.createdAt);
if (parsedStartDate.year == parsedEndDate.year) { if (parsedStartDate.year == parsedEndDate.year) {
startDate = DateFormat('LLL d').format(parsedStartDate); 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),
),
);
} 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 if (userId == albumInfo.ownerId)
? AlbumActionOutlinedButton( AlbumActionOutlinedButton(
iconData: Icons.person_add_alt_rounded, iconData: Icons.person_add_alt_rounded,
onPressed: () => _onAddUsersPressed(albumInfo), onPressed: () => _onAddUsersPressed(albumInfo),
labelText: "Add users", labelText: "Add users",
) ),
: Container(),
], ],
), ),
), ),

View File

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

View File

@ -113,26 +113,22 @@ class CreateSharedAlbumPage extends HookConsumerWidget {
} }
_buildControlButton() { _buildControlButton() {
if (selectedAssets.isNotEmpty) { return Padding(
return Padding( padding: const EdgeInsets.only(left: 12.0, top: 16, bottom: 16),
padding: const EdgeInsets.only(left: 12.0, top: 16, bottom: 16), child: SizedBox(
child: SizedBox( height: 30,
height: 30, child: ListView(
child: ListView( scrollDirection: Axis.horizontal,
scrollDirection: Axis.horizontal, children: [
children: [ AlbumActionOutlinedButton(
AlbumActionOutlinedButton( iconData: Icons.add_photo_alternate_outlined,
iconData: Icons.add_photo_alternate_outlined, onPressed: _onSelectPhotosButtonPressed,
onPressed: _onSelectPhotosButtonPressed, labelText: "Add photos",
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(),
], ],
), ),
), ),

View File

@ -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) { if (socket?.disconnected == true) {
state = WebscoketState(isConnected: false, socket: null); state = WebscoketState(isConnected: false, socket: null);
}
} }
} }

View File

@ -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());

View File

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