mirror of
https://github.com/immich-app/immich.git
synced 2025-12-12 07:41:02 -08:00
fix(mobile): fix overflow text in backup card (#24448)
* fix(mobile): fix overflow text in backup card * refactor: use intrinsicheight * chore: fix spelling of entitycounttile
This commit is contained in:
@@ -2,26 +2,27 @@ 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/extensions/theme_extensions.dart';
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
|
|
||||||
class EntitiyCountTile extends StatelessWidget {
|
class EntityCountTile extends StatelessWidget {
|
||||||
final int count;
|
final int count;
|
||||||
final String label;
|
final String label;
|
||||||
final IconData icon;
|
final IconData icon;
|
||||||
|
|
||||||
const EntitiyCountTile({super.key, required this.count, required this.label, required this.icon});
|
const EntityCountTile({super.key, required this.count, required this.label, required this.icon});
|
||||||
|
|
||||||
String zeroPadding(int number, int targetWidth) {
|
String zeroPadding(int number, int targetWidth) {
|
||||||
final numStr = number.toString();
|
final numStr = number.toString();
|
||||||
return numStr.length < targetWidth ? "0" * (targetWidth - numStr.length) : "";
|
return numStr.length < targetWidth ? "0" * (targetWidth - numStr.length) : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
int calculateMaxDigits(double availableWidth) {
|
|
||||||
const double charWidth = 11.0;
|
|
||||||
return (availableWidth / charWidth).floor().clamp(1, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
|
final availableWidth = (screenWidth - 32 - 8) / 2;
|
||||||
|
const double charWidth = 11.0;
|
||||||
|
final maxDigits = ((availableWidth - 32) / charWidth).floor().clamp(1, 8);
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
|
height: double.infinity,
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: context.colorScheme.surfaceContainerLow,
|
color: context.colorScheme.surfaceContainerLow,
|
||||||
@@ -29,7 +30,6 @@ class EntitiyCountTile extends StatelessWidget {
|
|||||||
border: Border.all(width: 0.5, color: context.colorScheme.outline.withAlpha(25)),
|
border: Border.all(width: 0.5, color: context.colorScheme.outline.withAlpha(25)),
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
// Icon and Label
|
// Icon and Label
|
||||||
@@ -38,33 +38,30 @@ class EntitiyCountTile extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Icon(icon, color: context.primaryColor),
|
Icon(icon, color: context.primaryColor),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
Text(
|
Flexible(
|
||||||
label,
|
child: Text(
|
||||||
style: TextStyle(color: context.primaryColor, fontWeight: FontWeight.bold, fontSize: 16),
|
label,
|
||||||
|
style: TextStyle(color: context.primaryColor, fontWeight: FontWeight.bold, fontSize: 16),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
|
||||||
// Number
|
// Number
|
||||||
LayoutBuilder(
|
const Spacer(),
|
||||||
builder: (context, constraints) {
|
RichText(
|
||||||
final maxDigits = calculateMaxDigits(constraints.maxWidth);
|
text: TextSpan(
|
||||||
return RichText(
|
style: const TextStyle(fontSize: 18, fontFamily: 'OverpassMono', fontWeight: FontWeight.w600),
|
||||||
text: TextSpan(
|
children: [
|
||||||
style: const TextStyle(fontSize: 18, fontFamily: 'OverpassMono', fontWeight: FontWeight.w600),
|
TextSpan(
|
||||||
children: [
|
text: zeroPadding(count, maxDigits),
|
||||||
TextSpan(
|
style: TextStyle(color: context.colorScheme.onSurfaceSecondary.withAlpha(75)),
|
||||||
text: zeroPadding(count, maxDigits),
|
|
||||||
style: TextStyle(color: context.colorScheme.onSurfaceSecondary.withAlpha(75)),
|
|
||||||
),
|
|
||||||
TextSpan(
|
|
||||||
text: count.toString(),
|
|
||||||
style: TextStyle(color: context.primaryColor),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
TextSpan(
|
||||||
},
|
text: count.toString(),
|
||||||
|
style: TextStyle(color: context.primaryColor),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -282,76 +282,87 @@ class _SyncStatsCounts extends ConsumerWidget {
|
|||||||
_SectionHeaderText(text: "assets".t(context: context)),
|
_SectionHeaderText(text: "assets".t(context: context)),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
|
padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
|
||||||
child: Flex(
|
// 1. Wrap in IntrinsicHeight
|
||||||
direction: Axis.horizontal,
|
child: IntrinsicHeight(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
child: Flex(
|
||||||
spacing: 8.0,
|
direction: Axis.horizontal,
|
||||||
children: [
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
Expanded(
|
// 2. Stretch children vertically to fill the IntrinsicHeight
|
||||||
child: EntitiyCountTile(
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
label: "local".t(context: context),
|
spacing: 8.0,
|
||||||
count: localAssetCount,
|
children: [
|
||||||
icon: Icons.smartphone,
|
Expanded(
|
||||||
|
child: EntityCountTile(
|
||||||
|
label: "local".t(context: context),
|
||||||
|
count: localAssetCount,
|
||||||
|
icon: Icons.smartphone,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Expanded(
|
||||||
Expanded(
|
child: EntityCountTile(
|
||||||
child: EntitiyCountTile(
|
label: "remote".t(context: context),
|
||||||
label: "remote".t(context: context),
|
count: remoteAssetCount,
|
||||||
count: remoteAssetCount,
|
icon: Icons.cloud,
|
||||||
icon: Icons.cloud,
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
_SectionHeaderText(text: "albums".t(context: context)),
|
_SectionHeaderText(text: "albums".t(context: context)),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
|
padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
|
||||||
child: Flex(
|
child: IntrinsicHeight(
|
||||||
direction: Axis.horizontal,
|
child: Flex(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
direction: Axis.horizontal,
|
||||||
spacing: 8.0,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.stretch, // Added
|
||||||
Expanded(
|
spacing: 8.0,
|
||||||
child: EntitiyCountTile(
|
children: [
|
||||||
label: "local".t(context: context),
|
Expanded(
|
||||||
count: localAlbumCount,
|
child: EntityCountTile(
|
||||||
icon: Icons.smartphone,
|
label: "local".t(context: context),
|
||||||
|
count: localAlbumCount,
|
||||||
|
icon: Icons.smartphone,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Expanded(
|
||||||
Expanded(
|
child: EntityCountTile(
|
||||||
child: EntitiyCountTile(
|
label: "remote".t(context: context),
|
||||||
label: "remote".t(context: context),
|
count: remoteAlbumCount,
|
||||||
count: remoteAlbumCount,
|
icon: Icons.cloud,
|
||||||
icon: Icons.cloud,
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
_SectionHeaderText(text: "other".t(context: context)),
|
_SectionHeaderText(text: "other".t(context: context)),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
|
padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
|
||||||
child: Flex(
|
child: IntrinsicHeight(
|
||||||
direction: Axis.horizontal,
|
child: Flex(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
direction: Axis.horizontal,
|
||||||
spacing: 8.0,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.stretch, // Added
|
||||||
Expanded(
|
spacing: 8.0,
|
||||||
child: EntitiyCountTile(
|
children: [
|
||||||
label: "memories".t(context: context),
|
Expanded(
|
||||||
count: memoryCount,
|
child: EntityCountTile(
|
||||||
icon: Icons.calendar_today,
|
label: "memories".t(context: context),
|
||||||
|
count: memoryCount,
|
||||||
|
icon: Icons.calendar_today,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Expanded(
|
||||||
Expanded(
|
child: EntityCountTile(
|
||||||
child: EntitiyCountTile(
|
label: "hashed_assets".t(context: context),
|
||||||
label: "hashed_assets".t(context: context),
|
count: localHashedCount,
|
||||||
count: localHashedCount,
|
icon: Icons.tag,
|
||||||
icon: Icons.tag,
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// To be removed once the experimental feature is stable
|
// To be removed once the experimental feature is stable
|
||||||
@@ -364,26 +375,29 @@ class _SyncStatsCounts extends ConsumerWidget {
|
|||||||
return counts.when(
|
return counts.when(
|
||||||
data: (c) => Padding(
|
data: (c) => Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
|
padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
|
||||||
child: Flex(
|
child: IntrinsicHeight(
|
||||||
direction: Axis.horizontal,
|
child: Flex(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
direction: Axis.horizontal,
|
||||||
spacing: 8.0,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.stretch, // Added
|
||||||
Expanded(
|
spacing: 8.0,
|
||||||
child: EntitiyCountTile(
|
children: [
|
||||||
label: "local".t(context: context),
|
Expanded(
|
||||||
count: c.total,
|
child: EntityCountTile(
|
||||||
icon: Icons.delete_outline,
|
label: "local".t(context: context),
|
||||||
|
count: c.total,
|
||||||
|
icon: Icons.delete_outline,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Expanded(
|
||||||
Expanded(
|
child: EntityCountTile(
|
||||||
child: EntitiyCountTile(
|
label: "hashed_assets".t(context: context),
|
||||||
label: "hashed_assets".t(context: context),
|
count: c.hashed,
|
||||||
count: c.hashed,
|
icon: Icons.tag,
|
||||||
icon: Icons.tag,
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
loading: () => const CircularProgressIndicator(),
|
loading: () => const CircularProgressIndicator(),
|
||||||
|
|||||||
Reference in New Issue
Block a user