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
Widget build(BuildContext context) {
return SizedBox(
height: imageSize + 30,
height: imageSize + 50,
child: ListView.separated(
padding: padding,
scrollDirection: Axis.horizontal,
@ -57,7 +57,10 @@ class CuratedPeopleRow extends StatelessWidget {
),
),
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(
color: context.primaryColor,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
).tr(),
);
}
@ -87,6 +93,7 @@ class CuratedPeopleRow extends StatelessWidget {
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: context.textTheme.labelLarge,
maxLines: 2,
);
}
}

View File

@ -28,32 +28,30 @@ class CuratedPlacesRow extends StatelessWidget {
return SizedBox(
height: imageSize,
child: ListView.builder(
child: ListView.separated(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric(
horizontal: 16,
),
separatorBuilder: (context, index) => const SizedBox(width: 10),
itemBuilder: (context, index) {
// Injecting Map thumbnail as the first element
if (isMapEnabled && index == 0) {
return SearchMapThumbnail(
size: imageSize,
return SizedBox.square(
dimension: imageSize,
child: SearchMapThumbnail(size: imageSize),
);
}
final actualIndex = index - actualContentIndex;
final object = content[actualIndex];
final thumbnailRequestUrl =
'${Store.get(StoreKey.serverEndpoint)}/assets/${object.id}/thumbnail';
return SizedBox(
width: imageSize,
height: imageSize,
child: Padding(
padding: const EdgeInsets.only(right: 10.0),
child: ThumbnailWithInfo(
imageUrl: thumbnailRequestUrl,
textInfo: object.label,
onTap: () => onTap?.call(object, actualIndex),
),
return SizedBox.square(
dimension: imageSize,
child: ThumbnailWithInfo(
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:immich_mobile/routing/router.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';
class SearchMapThumbnail extends StatelessWidget {
@ -15,60 +16,21 @@ class SearchMapThumbnail extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => context.pushRoute(
const MapRoute(),
),
child: SizedBox.square(
dimension: size,
child: Stack(
children: [
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: MapThumbnail(
zoom: 2,
centre: const LatLng(
47,
5,
),
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(),
),
),
],
return ThumbnailWithInfoContainer(
label: 'search_page_your_map'.tr(),
onTap: () {
context.pushRoute(const MapRoute());
},
child: IgnorePointer(
child: MapThumbnail(
zoom: 2,
centre: const LatLng(
47,
5,
),
height: size,
width: size,
showAttribution: false,
),
),
);

View File

@ -2,94 +2,53 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.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 {
ThumbnailWithInfo({
const ThumbnailWithInfo({
super.key,
required this.textInfo,
this.imageUrl,
this.noImageIcon,
this.borderRadius = 10,
required this.onTap,
this.onTap,
});
final String textInfo;
final String? imageUrl;
final Function onTap;
final VoidCallback? onTap;
final IconData? noImageIcon;
double borderRadius;
final double borderRadius;
@override
Widget build(BuildContext context) {
var textAndIconColor =
context.isDarkTheme ? Colors.grey[100] : Colors.grey[700];
return GestureDetector(
onTap: () {
onTap();
},
child: Stack(
alignment: Alignment.bottomCenter,
children: [
Container(
decoration: BoxDecoration(
return ThumbnailWithInfoContainer(
onTap: onTap,
borderRadius: borderRadius,
label: textInfo,
child: imageUrl != null
? ClipRRect(
borderRadius: BorderRadius.circular(borderRadius),
color: context.isDarkTheme ? Colors.grey[900] : Colors.grey[100],
),
child: imageUrl != null
? ClipRRect(
borderRadius: BorderRadius.circular(borderRadius),
child: CachedNetworkImage(
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
imageUrl: imageUrl!,
httpHeaders: {
"x-immich-user-token": Store.get(StoreKey.accessToken),
},
errorWidget: (context, url, error) =>
const Icon(Icons.image_not_supported_outlined),
),
)
: 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],
child: CachedNetworkImage(
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
imageUrl: imageUrl!,
httpHeaders: {
"x-immich-user-token": Store.get(StoreKey.accessToken),
},
errorWidget: (context, url, error) =>
const Icon(Icons.image_not_supported_outlined),
),
)
: Center(
child: Icon(
noImageIcon ?? Icons.not_listed_location,
color: textAndIconColor,
),
),
),
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,
),
),
],
),
);
}
}