mirror of
https://github.com/immich-app/immich.git
synced 2026-02-28 17:49:05 +03:00
feat(mobile): dynamic multi-line album name (#26040)
* feat(mobile): dynamic multi-line album name Album names are currently limited to a single line, and scroll on overflow. It would be better if album names were multi-line, and even better if the font size was dynamic depending on how many lines there are. The album name should then overflow with an ellipsis. This is actually quite similar to how Google Photos handles album names. * lint --------- Co-authored-by: timonrieger <mail@timonrieger.de>
This commit is contained in:
@@ -3,7 +3,7 @@ import 'dart:io';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:easy_localization/easy_localization.dart' hide TextDirection;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||
@@ -254,22 +254,9 @@ class _ExpandedBackgroundState extends ConsumerState<_ExpandedBackground> with S
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: widget.onEditTitle,
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Text(
|
||||
currentAlbum.name,
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 36,
|
||||
fontWeight: FontWeight.bold,
|
||||
letterSpacing: 0.5,
|
||||
shadows: [Shadow(offset: Offset(0, 2), blurRadius: 12, color: Colors.black54)],
|
||||
),
|
||||
),
|
||||
),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) =>
|
||||
_DynamicText(text: currentAlbum.name, maxWidth: constraints.maxWidth),
|
||||
),
|
||||
),
|
||||
if (currentAlbum.description.isNotEmpty)
|
||||
@@ -549,3 +536,46 @@ class _RandomAssetBackgroundState extends State<_RandomAssetBackground> with Tic
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _DynamicText extends StatelessWidget {
|
||||
final String text;
|
||||
final double maxWidth;
|
||||
|
||||
const _DynamicText({required this.text, required this.maxWidth});
|
||||
|
||||
static const _baseTextStyle = TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
letterSpacing: 0.5,
|
||||
shadows: [Shadow(offset: Offset(0, 2), blurRadius: 12, color: Colors.black54)],
|
||||
overflow: TextOverflow.ellipsis,
|
||||
);
|
||||
|
||||
int _lineCount(double fontSize) {
|
||||
final textPainter = TextPainter(
|
||||
text: TextSpan(
|
||||
text: text,
|
||||
style: _baseTextStyle.copyWith(fontSize: fontSize),
|
||||
),
|
||||
maxLines: 3,
|
||||
textDirection: TextDirection.ltr,
|
||||
)..layout(maxWidth: maxWidth);
|
||||
return textPainter.computeLineMetrics().length;
|
||||
}
|
||||
|
||||
double _fontSize() {
|
||||
final fontSizes = [44.0, 36.0];
|
||||
for (final fontSize in fontSizes) {
|
||||
final lineCount = _lineCount(fontSize);
|
||||
if (lineCount == 1) {
|
||||
return fontSize;
|
||||
}
|
||||
}
|
||||
return 28;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Text(text, style: _baseTextStyle.copyWith(fontSize: _fontSize()), maxLines: 3);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user