mirror of
https://github.com/immich-app/immich.git
synced 2025-05-31 12:15:47 -04:00
Optimize mobile - Avoid creating unnecessary widgets (#268)
* Avoid creating unnecessary widgets * more flexible null handling and runtime errors prevention
This commit is contained in:
parent
992f792c0a
commit
c4ef523564
@ -39,14 +39,10 @@ class ImageViewerService {
|
||||
entity = await PhotoManager.editor.saveVideo(tempFile, title: fileName);
|
||||
}
|
||||
|
||||
if (entity != null) {
|
||||
return true;
|
||||
}
|
||||
return entity != null;
|
||||
} catch (e) {
|
||||
debugPrint("Error saving file $e");
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -15,9 +15,7 @@ class ExifBottomSheet extends ConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
_buildMap() {
|
||||
return (assetDetail.exifInfo!.latitude != null &&
|
||||
assetDetail.exifInfo!.longitude != null)
|
||||
? Padding(
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
||||
child: Container(
|
||||
height: 150,
|
||||
@ -57,29 +55,23 @@ class ExifBottomSheet extends ConsumerWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container();
|
||||
);
|
||||
}
|
||||
|
||||
_buildLocationText() {
|
||||
return (assetDetail.exifInfo!.city != null &&
|
||||
assetDetail.exifInfo!.state != null)
|
||||
? Text(
|
||||
return Text(
|
||||
"${assetDetail.exifInfo!.city}, ${assetDetail.exifInfo!.state}",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey[200],
|
||||
fontWeight: FontWeight.bold),
|
||||
)
|
||||
: Container();
|
||||
fontSize: 12, color: Colors.grey[200], fontWeight: FontWeight.bold),
|
||||
);
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 8),
|
||||
child: ListView(
|
||||
children: [
|
||||
assetDetail.exifInfo?.dateTimeOriginal != null
|
||||
? Text(
|
||||
if (assetDetail.exifInfo?.dateTimeOriginal != null)
|
||||
Text(
|
||||
DateFormat('E, LLL d, y • h:mm a').format(
|
||||
DateTime.parse(assetDetail.exifInfo!.dateTimeOriginal!),
|
||||
),
|
||||
@ -88,8 +80,7 @@ class ExifBottomSheet extends ConsumerWidget {
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14,
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 16.0),
|
||||
child: Text(
|
||||
@ -102,8 +93,8 @@ class ExifBottomSheet extends ConsumerWidget {
|
||||
),
|
||||
|
||||
// Location
|
||||
assetDetail.exifInfo?.latitude != null
|
||||
? Padding(
|
||||
if (assetDetail.exifInfo?.latitude != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 32.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@ -116,19 +107,22 @@ class ExifBottomSheet extends ConsumerWidget {
|
||||
"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)}",
|
||||
"${assetDetail.exifInfo?.latitude?.toStringAsFixed(4)}, ${assetDetail.exifInfo?.longitude?.toStringAsFixed(4)}",
|
||||
style: TextStyle(fontSize: 12, color: Colors.grey[400]),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
),
|
||||
// Detail
|
||||
assetDetail.exifInfo != null
|
||||
? Padding(
|
||||
if (assetDetail.exifInfo != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 32.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@ -141,8 +135,7 @@ class ExifBottomSheet extends ConsumerWidget {
|
||||
padding: const EdgeInsets.only(bottom: 8.0),
|
||||
child: Text(
|
||||
"DETAILS",
|
||||
style:
|
||||
TextStyle(fontSize: 11, color: Colors.grey[400]),
|
||||
style: TextStyle(fontSize: 11, color: Colors.grey[400]),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
@ -158,10 +151,10 @@ class ExifBottomSheet extends ConsumerWidget {
|
||||
subtitle: assetDetail.exifInfo?.exifImageHeight != null
|
||||
? Text(
|
||||
"${assetDetail.exifInfo?.exifImageHeight} x ${assetDetail.exifInfo?.exifImageWidth} ${assetDetail.exifInfo?.fileSizeInByte!}B ")
|
||||
: Container(),
|
||||
: null,
|
||||
),
|
||||
assetDetail.exifInfo?.make != null
|
||||
? ListTile(
|
||||
if (assetDetail.exifInfo?.make != null)
|
||||
ListTile(
|
||||
contentPadding: const EdgeInsets.all(0),
|
||||
dense: true,
|
||||
textColor: Colors.grey[300],
|
||||
@ -169,17 +162,14 @@ class ExifBottomSheet extends ConsumerWidget {
|
||||
leading: const Icon(Icons.camera),
|
||||
title: Text(
|
||||
"${assetDetail.exifInfo?.make} ${assetDetail.exifInfo?.model}",
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold),
|
||||
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()
|
||||
"ƒ/${assetDetail.exifInfo?.fNumber} 1/${(1 / (assetDetail.exifInfo?.exposureTime ?? 1)).toStringAsFixed(0)} ${assetDetail.exifInfo?.focalLength}mm ISO${assetDetail.exifInfo?.iso} "),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Container()
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -147,8 +147,7 @@ class _VideoThumbnailPlayerState extends State<VideoThumbnailPlayer> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return chewieController != null &&
|
||||
chewieController!.videoPlayerController.value.isInitialized
|
||||
return chewieController?.videoPlayerController.value.isInitialized == true
|
||||
? SizedBox(
|
||||
child: Chewie(
|
||||
controller: chewieController!,
|
||||
|
@ -56,7 +56,7 @@ class AlbumInfoCard extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
return Container();
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
_buildImageFilter() {
|
||||
@ -151,7 +151,11 @@ class AlbumInfoCard extends HookConsumerWidget {
|
||||
),
|
||||
child: null,
|
||||
),
|
||||
Positioned(bottom: 10, left: 25, child: _buildSelectedTextBox())
|
||||
Positioned(
|
||||
bottom: 10,
|
||||
left: 25,
|
||||
child: _buildSelectedTextBox(),
|
||||
)
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
@ -176,8 +180,7 @@ class AlbumInfoCard extends HookConsumerWidget {
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 2.0),
|
||||
child: Text(
|
||||
albumInfo.assetCount.toString() +
|
||||
(albumInfo.isAll ? " (ALL)" : ""),
|
||||
'${albumInfo.assetCount} ${(albumInfo.isAll ? " (ALL)" : "")}',
|
||||
style: TextStyle(
|
||||
fontSize: 12, color: Colors.grey[600]),
|
||||
),
|
||||
|
@ -188,11 +188,7 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
|
||||
color: Colors.grey[700]),
|
||||
),
|
||||
trailing: Text(
|
||||
ref
|
||||
.watch(backupProvider)
|
||||
.allUniqueAssets
|
||||
.length
|
||||
.toString(),
|
||||
'${ref.watch(backupProvider).allUniqueAssets.length}',
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
@ -203,7 +199,7 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
|
||||
|
||||
ListTile(
|
||||
title: Text(
|
||||
"Albums on device (${availableAlbums.length.toString()})",
|
||||
"Albums on device (${availableAlbums.length})",
|
||||
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 14),
|
||||
),
|
||||
subtitle: Padding(
|
||||
|
@ -96,12 +96,11 @@ class BackupControllerPage extends HookConsumerWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
!isAutoBackup
|
||||
? const Text(
|
||||
if (!isAutoBackup)
|
||||
const Text(
|
||||
"Turn on backup to automatically upload new assets to the server.",
|
||||
style: TextStyle(fontSize: 14),
|
||||
)
|
||||
: Container(),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: OutlinedButton(
|
||||
@ -189,7 +188,7 @@ class BackupControllerPage extends HookConsumerWidget {
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
return const SizedBox();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ class DisableMultiSelectButton extends ConsumerWidget {
|
||||
},
|
||||
icon: const Icon(Icons.close_rounded),
|
||||
label: Text(
|
||||
selectedItemCount.toString(),
|
||||
'$selectedItemCount',
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w600, fontSize: 18),
|
||||
)),
|
||||
|
@ -615,7 +615,7 @@ class SlideFadeTransition extends StatelessWidget {
|
||||
return AnimatedBuilder(
|
||||
animation: animation,
|
||||
builder: (context, child) =>
|
||||
animation.value == 0.0 ? Container() : child!,
|
||||
animation.value == 0.0 ? const SizedBox() : child!,
|
||||
child: SlideTransition(
|
||||
position: Tween(
|
||||
begin: const Offset(0.3, 0.0),
|
||||
|
@ -25,18 +25,14 @@ class ImageGrid extends ConsumerWidget {
|
||||
child: Stack(
|
||||
children: [
|
||||
ThumbnailImage(asset: assetGroup[index]),
|
||||
assetType == 'IMAGE'
|
||||
? Container()
|
||||
: Positioned(
|
||||
if (assetType != 'IMAGE')
|
||||
Positioned(
|
||||
top: 5,
|
||||
right: 5,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
assetGroup[index]
|
||||
.duration
|
||||
.toString()
|
||||
.substring(0, 7),
|
||||
assetGroup[index].duration.toString().substring(0, 7),
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 10,
|
||||
@ -48,7 +44,7 @@ class ImageGrid extends ConsumerWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -49,8 +49,8 @@ class ImmichSliverAppBar extends ConsumerWidget {
|
||||
},
|
||||
),
|
||||
),
|
||||
serverInfoState.isVersionMismatch
|
||||
? Positioned(
|
||||
if (serverInfoState.isVersionMismatch)
|
||||
Positioned(
|
||||
bottom: 12,
|
||||
right: 12,
|
||||
child: GestureDetector(
|
||||
@ -71,8 +71,7 @@ class ImmichSliverAppBar extends ConsumerWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
@ -90,8 +89,8 @@ class ImmichSliverAppBar extends ConsumerWidget {
|
||||
Stack(
|
||||
alignment: AlignmentDirectional.center,
|
||||
children: [
|
||||
backupState.backupProgress == BackUpProgressEnum.inProgress
|
||||
? Positioned(
|
||||
if (backupState.backupProgress == BackUpProgressEnum.inProgress)
|
||||
Positioned(
|
||||
top: 10,
|
||||
right: 12,
|
||||
child: SizedBox(
|
||||
@ -103,8 +102,7 @@ class ImmichSliverAppBar extends ConsumerWidget {
|
||||
Theme.of(context).primaryColor),
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
),
|
||||
IconButton(
|
||||
splashRadius: 25,
|
||||
iconSize: 30,
|
||||
@ -129,18 +127,15 @@ class ImmichSliverAppBar extends ConsumerWidget {
|
||||
}
|
||||
},
|
||||
),
|
||||
backupState.backupProgress == BackUpProgressEnum.inProgress
|
||||
? Positioned(
|
||||
if (backupState.backupProgress == BackUpProgressEnum.inProgress)
|
||||
Positioned(
|
||||
bottom: 5,
|
||||
child: Text(
|
||||
(backupState.allUniqueAssets.length -
|
||||
backupState.selectedAlbumsBackupAssetsIds.length)
|
||||
.toString(),
|
||||
style: const TextStyle(
|
||||
fontSize: 9, fontWeight: FontWeight.bold),
|
||||
'${backupState.allUniqueAssets.length - backupState.selectedAlbumsBackupAssetsIds.length}',
|
||||
style:
|
||||
const TextStyle(fontSize: 9, fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container()
|
||||
],
|
||||
),
|
||||
],
|
||||
|
@ -87,7 +87,7 @@ class ProfileDrawer extends HookConsumerWidget {
|
||||
return const ImmichLoadingIndicator();
|
||||
}
|
||||
|
||||
return Container();
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
_pickUserProfileImage() async {
|
||||
|
@ -122,16 +122,13 @@ class ThumbnailImage extends HookConsumerWidget {
|
||||
},
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: isMultiSelectEnable
|
||||
? Padding(
|
||||
if (isMultiSelectEnable)
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(3.0),
|
||||
child: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: _buildSelectionIcon(asset),
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
),
|
||||
Positioned(
|
||||
right: 10,
|
||||
|
@ -38,17 +38,10 @@ class HomePage extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
_buildSelectedItemCountIndicator() {
|
||||
return isMultiSelectEnable
|
||||
? DisableMultiSelectButton(
|
||||
onPressed:
|
||||
ref.watch(homePageStateProvider.notifier).disableMultiSelect,
|
||||
return DisableMultiSelectButton(
|
||||
onPressed: ref.watch(homePageStateProvider.notifier).disableMultiSelect,
|
||||
selectedItemCount: homePageState.selectedItems.length,
|
||||
)
|
||||
: Container();
|
||||
}
|
||||
|
||||
_buildBottomAppBar() {
|
||||
return isMultiSelectEnable ? const ControlBottomAppBar() : Container();
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBody() {
|
||||
@ -121,8 +114,10 @@ class HomePage extends HookConsumerWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isMultiSelectEnable) ...[
|
||||
_buildSelectedItemCountIndicator(),
|
||||
_buildBottomAppBar(),
|
||||
const ControlBottomAppBar(),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -107,19 +107,12 @@ class ServerEndpointInput extends StatelessWidget {
|
||||
: super(key: key);
|
||||
|
||||
String? _validateInput(String? url) {
|
||||
if (url == null) {
|
||||
|
||||
if (url?.startsWith(RegExp(r'https?://')) == true) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (url.isEmpty) {
|
||||
return 'Server endpoint is required';
|
||||
}
|
||||
|
||||
if (!url.startsWith(RegExp(r'https?://'))) {
|
||||
} else {
|
||||
return 'Please specify http:// or https://';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -62,11 +62,7 @@ final getCuratedLocationProvider =
|
||||
final SearchService searchService = ref.watch(searchServiceProvider);
|
||||
|
||||
var curatedLocation = await searchService.getCuratedLocation();
|
||||
if (curatedLocation != null) {
|
||||
return curatedLocation;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
return curatedLocation ?? [];
|
||||
});
|
||||
|
||||
final getCuratedObjectProvider =
|
||||
@ -74,9 +70,6 @@ final getCuratedObjectProvider =
|
||||
final SearchService searchService = ref.watch(searchServiceProvider);
|
||||
|
||||
var curatedObject = await searchService.getCuratedObjects();
|
||||
if (curatedObject != null) {
|
||||
return curatedObject;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
|
||||
return curatedObject ?? [];
|
||||
});
|
||||
|
@ -176,9 +176,8 @@ class SearchPage extends HookConsumerWidget {
|
||||
_buildThings()
|
||||
],
|
||||
),
|
||||
isSearchEnabled
|
||||
? SearchSuggestionList(onSubmitted: _onSearchSubmitted)
|
||||
: Container(),
|
||||
if (isSearchEnabled)
|
||||
SearchSuggestionList(onSubmitted: _onSearchSubmitted),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -166,7 +166,7 @@ class SearchResultPage extends HookConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
return Container();
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
@ -198,9 +198,8 @@ class SearchResultPage extends HookConsumerWidget {
|
||||
child: Stack(
|
||||
children: [
|
||||
_buildSearchResult(),
|
||||
isNewSearch.value
|
||||
? SearchSuggestionList(onSubmitted: _onSearchSubmitted)
|
||||
: Container(),
|
||||
if (isNewSearch.value)
|
||||
SearchSuggestionList(onSubmitted: _onSearchSubmitted),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -72,10 +72,7 @@ class SharedAlbum {
|
||||
albumThumbnailAssetId: map['albumThumbnailAssetId'],
|
||||
sharedUsers:
|
||||
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(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -39,11 +39,7 @@ class SharedAlbumService {
|
||||
"assetIds": assets.map((asset) => asset.id).toList(),
|
||||
});
|
||||
|
||||
if (res == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return res != null;
|
||||
} catch (e) {
|
||||
debugPrint("Error createSharedAlbum ${e.toString()}");
|
||||
return false;
|
||||
@ -71,11 +67,7 @@ class SharedAlbumService {
|
||||
"assetIds": assets.map((asset) => asset.id).toList(),
|
||||
});
|
||||
|
||||
if (res == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return res != null;
|
||||
} catch (e) {
|
||||
debugPrint("Error addAdditionalAssetToAlbum ${e.toString()}");
|
||||
return false;
|
||||
@ -90,11 +82,7 @@ class SharedAlbumService {
|
||||
"sharedUserIds": sharedUserIds,
|
||||
});
|
||||
|
||||
if (res == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return res != null;
|
||||
} catch (e) {
|
||||
debugPrint("Error addAdditionalUserToAlbum ${e.toString()}");
|
||||
return false;
|
||||
|
@ -114,7 +114,7 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget {
|
||||
onTap: () => _onRemoveFromAlbumPressed(albumId),
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
return const SizedBox();
|
||||
}
|
||||
} else {
|
||||
if (_albumInfo.asData?.value.ownerId == userId) {
|
||||
@ -198,8 +198,8 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget {
|
||||
elevation: 0,
|
||||
leading: _buildLeadingButton(),
|
||||
title: isMultiSelectionEnable
|
||||
? Text(selectedAssetsInAlbum.length.toString())
|
||||
: Container(),
|
||||
? Text('${selectedAssetsInAlbum.length}')
|
||||
: null,
|
||||
centerTitle: false,
|
||||
actions: [
|
||||
IconButton(
|
||||
|
@ -71,9 +71,6 @@ class AlbumViewerThumbnail extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
_buildVideoLabel() {
|
||||
if (asset.type == 'IMAGE') {
|
||||
return Container();
|
||||
} else {
|
||||
return Positioned(
|
||||
top: 5,
|
||||
right: 5,
|
||||
@ -94,7 +91,6 @@ class AlbumViewerThumbnail extends HookConsumerWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_buildAssetStoreLocationIcon() {
|
||||
return Positioned(
|
||||
@ -112,7 +108,7 @@ class AlbumViewerThumbnail extends HookConsumerWidget {
|
||||
|
||||
_buildAssetSelectionIcon() {
|
||||
bool isSelected = selectedAssetsInAlbumViewer.contains(asset);
|
||||
if (isMultiSelectionEnable) {
|
||||
|
||||
return Positioned(
|
||||
left: 10,
|
||||
top: 5,
|
||||
@ -126,9 +122,6 @@ class AlbumViewerThumbnail extends HookConsumerWidget {
|
||||
color: Colors.white,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
|
||||
_buildThumbnailImage() {
|
||||
@ -183,8 +176,8 @@ class AlbumViewerThumbnail extends HookConsumerWidget {
|
||||
children: [
|
||||
_buildThumbnailImage(),
|
||||
_buildAssetStoreLocationIcon(),
|
||||
_buildVideoLabel(),
|
||||
_buildAssetSelectionIcon(),
|
||||
if (asset.type != 'IMAGE') _buildVideoLabel(),
|
||||
if (isMultiSelectionEnable) _buildAssetSelectionIcon(),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -131,15 +131,14 @@ class SelectionThumbnailImage extends HookConsumerWidget {
|
||||
child: _buildSelectionIcon(asset),
|
||||
),
|
||||
),
|
||||
asset.type == 'IMAGE'
|
||||
? Container()
|
||||
: Positioned(
|
||||
if (asset.type != 'IMAGE')
|
||||
Positioned(
|
||||
bottom: 5,
|
||||
right: 5,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
asset.duration.toString().substring(0, 7),
|
||||
'${asset.duration?.substring(0, 7)}',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 10,
|
||||
@ -151,7 +150,7 @@ class SelectionThumbnailImage extends HookConsumerWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -14,7 +14,8 @@ class SharingSliverAppBar extends StatelessWidget {
|
||||
floating: false,
|
||||
pinned: true,
|
||||
snap: false,
|
||||
leading: Container(),
|
||||
automaticallyImplyLeading: false,
|
||||
// leading: Container(),
|
||||
// elevation: 0,
|
||||
title: Text(
|
||||
'IMMICH',
|
||||
|
@ -37,7 +37,7 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
/// 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.
|
||||
void _onAddPhotosPressed(SharedAlbum albumInfo) async {
|
||||
if (albumInfo.assets != null && albumInfo.assets!.isNotEmpty) {
|
||||
if (albumInfo.assets?.isNotEmpty == true) {
|
||||
ref
|
||||
.watch(assetSelectionProvider.notifier)
|
||||
.addNewAssets(albumInfo.assets!.toList());
|
||||
@ -109,12 +109,11 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
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);
|
||||
DateTime parsedEndDate = DateTime.parse(
|
||||
albumInfo.assets?.last.createdAt ?? '11111111'); //Need default.
|
||||
|
||||
if (parsedStartDate.year == parsedEndDate.year) {
|
||||
startDate = DateFormat('LLL d').format(parsedStartDate);
|
||||
@ -132,9 +131,6 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
fontSize: 14, fontWeight: FontWeight.bold, color: Colors.grey),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildHeader(SharedAlbum albumInfo) {
|
||||
@ -143,6 +139,7 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildTitle(albumInfo),
|
||||
if (albumInfo.assets?.isNotEmpty == true)
|
||||
_buildAlbumDateRange(albumInfo),
|
||||
SizedBox(
|
||||
height: 60,
|
||||
@ -175,7 +172,7 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
Widget _buildImageGrid(SharedAlbum albumInfo) {
|
||||
if (albumInfo.assets != null && albumInfo.assets!.isNotEmpty) {
|
||||
if (albumInfo.assets?.isNotEmpty == true) {
|
||||
return SliverPadding(
|
||||
padding: const EdgeInsets.only(top: 10.0),
|
||||
sliver: SliverGrid(
|
||||
@ -209,13 +206,12 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
onPressed: () => _onAddPhotosPressed(albumInfo),
|
||||
labelText: "Add photos",
|
||||
),
|
||||
userId == albumInfo.ownerId
|
||||
? AlbumActionOutlinedButton(
|
||||
if (userId == albumInfo.ownerId)
|
||||
AlbumActionOutlinedButton(
|
||||
iconData: Icons.person_add_alt_rounded,
|
||||
onPressed: () => _onAddUsersPressed(albumInfo),
|
||||
labelText: "Add users",
|
||||
)
|
||||
: Container(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -74,9 +74,9 @@ class AssetSelectionPage extends HookConsumerWidget {
|
||||
),
|
||||
centerTitle: false,
|
||||
actions: [
|
||||
(!isAlbumExist && selectedAssets.isNotEmpty) ||
|
||||
(isAlbumExist && newAssetsForAlbum.isNotEmpty)
|
||||
? TextButton(
|
||||
if ((!isAlbumExist && selectedAssets.isNotEmpty) ||
|
||||
(isAlbumExist && newAssetsForAlbum.isNotEmpty))
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
var payload = AssetSelectionPageResult(
|
||||
isAlbumExist: isAlbumExist,
|
||||
@ -89,8 +89,7 @@ class AssetSelectionPage extends HookConsumerWidget {
|
||||
"Add",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
)
|
||||
: Container()
|
||||
),
|
||||
],
|
||||
),
|
||||
body: _buildBody(),
|
||||
|
@ -113,7 +113,6 @@ class CreateSharedAlbumPage extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
_buildControlButton() {
|
||||
if (selectedAssets.isNotEmpty) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 12.0, top: 16, bottom: 16),
|
||||
child: SizedBox(
|
||||
@ -132,9 +131,6 @@ class CreateSharedAlbumPage extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
return Container();
|
||||
}
|
||||
|
||||
_buildSelectedImageGrid() {
|
||||
if (selectedAssets.isNotEmpty) {
|
||||
return SliverPadding(
|
||||
@ -196,7 +192,8 @@ class CreateSharedAlbumPage extends HookConsumerWidget {
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
elevation: 5,
|
||||
leading: Container(),
|
||||
automaticallyImplyLeading: false,
|
||||
// leading: Container(),
|
||||
pinned: true,
|
||||
floating: false,
|
||||
bottom: PreferredSize(
|
||||
@ -204,7 +201,7 @@ class CreateSharedAlbumPage extends HookConsumerWidget {
|
||||
child: Column(
|
||||
children: [
|
||||
_buildTitleInputField(),
|
||||
_buildControlButton(),
|
||||
if (selectedAssets.isNotEmpty) _buildControlButton(),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -104,12 +104,11 @@ class WebsocketNotifier extends StateNotifier<WebscoketState> {
|
||||
disconnect() {
|
||||
debugPrint("[WEBSOCKET] Attempting to disconnect");
|
||||
var socket = state.socket?.disconnect();
|
||||
if (socket != null) {
|
||||
if (socket.disconnected) {
|
||||
|
||||
if (socket?.disconnected == true) {
|
||||
state = WebscoketState(isConnected: false, socket: null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stopListenToEvent(String eventName) {
|
||||
debugPrint("[Websocket] Stop listening to event $eventName");
|
||||
|
@ -34,7 +34,7 @@ class SplashScreenPage extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
useEffect(() {
|
||||
if (loginInfo != null && loginInfo.isSaveLogin) {
|
||||
if (loginInfo?.isSaveLogin == true) {
|
||||
performLoggingIn();
|
||||
} else {
|
||||
AutoRouter.of(context).push(const LoginRoute());
|
||||
|
@ -121,7 +121,7 @@ class VersionAnnouncementOverlay extends HookConsumerWidget {
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
return const SizedBox();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user