0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2025-01-21 00:52:43 -05:00

fix(mobile): inconsistent thumbnail's label (#10589)

* fix(mobile): inconsistent thumbnail with label

* fix: limit person's name width
This commit is contained in:
RanKKI 2024-06-25 00:24:57 +10:00 committed by GitHub
parent c83de5213f
commit 04f0e29df6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 129 additions and 137 deletions

View file

@ -26,7 +26,7 @@ class CuratedPeopleRow extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SizedBox( return SizedBox(
height: imageSize + 30, height: imageSize + 50,
child: ListView.separated( child: ListView.separated(
padding: padding, padding: padding,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
@ -57,7 +57,10 @@ class CuratedPeopleRow extends StatelessWidget {
), ),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
_buildPersonLabel(context, person, index), SizedBox(
width: imageSize,
child: _buildPersonLabel(context, person, index),
),
], ],
); );
}, },
@ -79,6 +82,9 @@ class CuratedPeopleRow extends StatelessWidget {
style: context.textTheme.labelLarge?.copyWith( style: context.textTheme.labelLarge?.copyWith(
color: context.primaryColor, color: context.primaryColor,
), ),
maxLines: 2,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
).tr(), ).tr(),
); );
} }
@ -87,6 +93,7 @@ class CuratedPeopleRow extends StatelessWidget {
textAlign: TextAlign.center, textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: context.textTheme.labelLarge, style: context.textTheme.labelLarge,
maxLines: 2,
); );
} }
} }

View file

@ -28,32 +28,30 @@ class CuratedPlacesRow extends StatelessWidget {
return SizedBox( return SizedBox(
height: imageSize, height: imageSize,
child: ListView.builder( child: ListView.separated(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
horizontal: 16, horizontal: 16,
), ),
separatorBuilder: (context, index) => const SizedBox(width: 10),
itemBuilder: (context, index) { itemBuilder: (context, index) {
// Injecting Map thumbnail as the first element // Injecting Map thumbnail as the first element
if (isMapEnabled && index == 0) { if (isMapEnabled && index == 0) {
return SearchMapThumbnail( return SizedBox.square(
size: imageSize, dimension: imageSize,
child: SearchMapThumbnail(size: imageSize),
); );
} }
final actualIndex = index - actualContentIndex; final actualIndex = index - actualContentIndex;
final object = content[actualIndex]; final object = content[actualIndex];
final thumbnailRequestUrl = final thumbnailRequestUrl =
'${Store.get(StoreKey.serverEndpoint)}/assets/${object.id}/thumbnail'; '${Store.get(StoreKey.serverEndpoint)}/assets/${object.id}/thumbnail';
return SizedBox( return SizedBox.square(
width: imageSize, dimension: imageSize,
height: imageSize, child: ThumbnailWithInfo(
child: Padding( imageUrl: thumbnailRequestUrl,
padding: const EdgeInsets.only(right: 10.0), textInfo: object.label,
child: ThumbnailWithInfo( onTap: () => onTap?.call(object, actualIndex),
imageUrl: thumbnailRequestUrl,
textInfo: object.label,
onTap: () => onTap?.call(object, actualIndex),
),
), ),
); );
}, },

View file

@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/widgets/map/map_thumbnail.dart'; import 'package:immich_mobile/widgets/map/map_thumbnail.dart';
import 'package:immich_mobile/widgets/search/thumbnail_with_info_container.dart';
import 'package:maplibre_gl/maplibre_gl.dart'; import 'package:maplibre_gl/maplibre_gl.dart';
class SearchMapThumbnail extends StatelessWidget { class SearchMapThumbnail extends StatelessWidget {
@ -15,60 +16,21 @@ class SearchMapThumbnail extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GestureDetector( return ThumbnailWithInfoContainer(
onTap: () => context.pushRoute( label: 'search_page_your_map'.tr(),
const MapRoute(), onTap: () {
), context.pushRoute(const MapRoute());
child: SizedBox.square( },
dimension: size, child: IgnorePointer(
child: Stack( child: MapThumbnail(
children: [ zoom: 2,
Padding( centre: const LatLng(
padding: const EdgeInsets.only(right: 10.0), 47,
child: MapThumbnail( 5,
zoom: 2, ),
centre: const LatLng( height: size,
47, width: size,
5, showAttribution: false,
),
height: size,
width: size,
showAttribution: false,
),
),
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.black,
gradient: LinearGradient(
begin: FractionalOffset.topCenter,
end: FractionalOffset.bottomCenter,
colors: [
Colors.blueGrey.withOpacity(0.0),
Colors.black.withOpacity(0.4),
],
stops: const [0.0, 0.4],
),
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.only(bottom: 10),
child: const Text(
"search_page_your_map",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14,
),
).tr(),
),
),
],
), ),
), ),
); );

View file

@ -2,94 +2,53 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/entities/store.entity.dart';
import 'package:immich_mobile/extensions/string_extensions.dart'; import 'package:immich_mobile/widgets/search/thumbnail_with_info_container.dart';
// ignore: must_be_immutable
class ThumbnailWithInfo extends StatelessWidget { class ThumbnailWithInfo extends StatelessWidget {
ThumbnailWithInfo({ const ThumbnailWithInfo({
super.key, super.key,
required this.textInfo, required this.textInfo,
this.imageUrl, this.imageUrl,
this.noImageIcon, this.noImageIcon,
this.borderRadius = 10, this.borderRadius = 10,
required this.onTap, this.onTap,
}); });
final String textInfo; final String textInfo;
final String? imageUrl; final String? imageUrl;
final Function onTap; final VoidCallback? onTap;
final IconData? noImageIcon; final IconData? noImageIcon;
double borderRadius; final double borderRadius;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var textAndIconColor = var textAndIconColor =
context.isDarkTheme ? Colors.grey[100] : Colors.grey[700]; context.isDarkTheme ? Colors.grey[100] : Colors.grey[700];
return GestureDetector( return ThumbnailWithInfoContainer(
onTap: () { onTap: onTap,
onTap(); borderRadius: borderRadius,
}, label: textInfo,
child: Stack( child: imageUrl != null
alignment: Alignment.bottomCenter, ? ClipRRect(
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(borderRadius), borderRadius: BorderRadius.circular(borderRadius),
color: context.isDarkTheme ? Colors.grey[900] : Colors.grey[100], child: CachedNetworkImage(
), width: double.infinity,
child: imageUrl != null height: double.infinity,
? ClipRRect( fit: BoxFit.cover,
borderRadius: BorderRadius.circular(borderRadius), imageUrl: imageUrl!,
child: CachedNetworkImage( httpHeaders: {
width: double.infinity, "x-immich-user-token": Store.get(StoreKey.accessToken),
height: double.infinity, },
fit: BoxFit.cover, errorWidget: (context, url, error) =>
imageUrl: imageUrl!, const Icon(Icons.image_not_supported_outlined),
httpHeaders: { ),
"x-immich-user-token": Store.get(StoreKey.accessToken), )
}, : Center(
errorWidget: (context, url, error) => child: Icon(
const Icon(Icons.image_not_supported_outlined), noImageIcon ?? Icons.not_listed_location,
), color: textAndIconColor,
)
: Center(
child: Icon(
noImageIcon ?? Icons.not_listed_location,
color: textAndIconColor,
),
),
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(borderRadius),
color: Colors.white,
gradient: LinearGradient(
begin: FractionalOffset.topCenter,
end: FractionalOffset.bottomCenter,
colors: [
Colors.grey.withOpacity(0.0),
textInfo == ''
? Colors.black.withOpacity(0.1)
: Colors.black.withOpacity(0.5),
],
stops: const [0.0, 1.0],
), ),
), ),
),
Positioned(
bottom: 12,
left: 14,
child: Text(
textInfo == '' ? textInfo : textInfo.capitalize(),
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14,
),
),
),
],
),
); );
} }
} }

View file

@ -0,0 +1,66 @@
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
class ThumbnailWithInfoContainer extends StatelessWidget {
const ThumbnailWithInfoContainer({
super.key,
this.onTap,
this.borderRadius = 10,
required this.label,
required this.child,
});
final VoidCallback? onTap;
final double borderRadius;
final String label;
final Widget child;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Stack(
alignment: Alignment.bottomLeft,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(borderRadius),
color: context.isDarkTheme ? Colors.grey[900] : Colors.grey[100],
),
foregroundDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(borderRadius),
color: Colors.white,
gradient: LinearGradient(
begin: FractionalOffset.topCenter,
end: FractionalOffset.bottomCenter,
colors: [
Colors.grey.withOpacity(0.0),
label == ''
? Colors.black.withOpacity(0.1)
: Colors.black.withOpacity(0.5),
],
stops: const [0.0, 1.0],
),
),
child: child,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8) +
const EdgeInsets.only(bottom: 8),
child: Text(
label,
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14,
),
maxLines: 2,
softWrap: false,
overflow: TextOverflow.ellipsis,
),
),
],
),
);
}
}