feat(tablet): clamp remaining screens - settings, queue lists, wizard

- SettingsGroup centers itself at 720dp via its incoming constraint
  (not screen width, so groups inside clamped sheets are never
  over-inset; unbounded-width contexts guarded); priority scaffold,
  bespoke hero cards, and donate page get the same inset - all 18+
  settings pages clamp from shared widgets
- queue list-mode, local/downloaded album track lists, favorite
  artists, home recent-access, and extension detail sections adopt
  wideListInset like the screens fixed earlier
- track metadata content clamped at 720dp, which also tames the
  width-derived spectrogram height
- announcement dialog capped at 480dp wide; setup wizard and
  tutorial content at 560dp with a 400dp action button
This commit is contained in:
zarzet
2026-07-14 09:10:16 +07:00
parent 7573d360bf
commit 1893f3faa8
23 changed files with 499 additions and 321 deletions
+1 -1
View File
@@ -101,7 +101,7 @@ class AppAnnouncementDialog extends StatelessWidget {
],
),
content: ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 260),
constraints: const BoxConstraints(maxHeight: 260, maxWidth: 480),
child: SingleChildScrollView(
child: Text(
announcement.message,
+11 -2
View File
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:spotiflac_android/l10n/l10n.dart';
import 'package:spotiflac_android/utils/adaptive_layout.dart';
import 'package:spotiflac_android/widgets/settings_sliver_app_bar.dart';
class PrioritySettingsScaffold extends StatelessWidget {
@@ -40,6 +41,7 @@ class PrioritySettingsScaffold extends StatelessWidget {
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final wideInset = wideListInset(context);
return PopScope(
canPop: !hasChanges,
@@ -70,7 +72,9 @@ class PrioritySettingsScaffold extends StatelessWidget {
),
SliverToBoxAdapter(
child: Padding(
padding: descriptionPadding,
padding: descriptionPadding.add(
EdgeInsets.symmetric(horizontal: wideInset),
),
child: Text(
description,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
@@ -82,7 +86,12 @@ class PrioritySettingsScaffold extends StatelessWidget {
...slivers,
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(16),
padding: EdgeInsets.fromLTRB(
16 + wideInset,
16,
16 + wideInset,
16,
),
child: Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
+36 -12
View File
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:spotiflac_android/utils/adaptive_layout.dart';
/// Background fill for grouped cards, matching the Settings group look. Blends a
/// translucent overlay over the surface so it stays visible on AMOLED (pure
@@ -28,19 +29,42 @@ class SettingsGroup extends StatelessWidget {
final cardColor = settingsGroupColor(context);
final colorScheme = Theme.of(context).colorScheme;
return Container(
margin: margin ?? const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
decoration: BoxDecoration(
color: cardColor,
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: colorScheme.outlineVariant.withValues(alpha: 0.5),
),
final decoration = BoxDecoration(
color: cardColor,
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: colorScheme.outlineVariant.withValues(alpha: 0.5),
),
clipBehavior: Clip.antiAlias,
child: Material(
color: Colors.transparent,
child: Column(mainAxisSize: MainAxisSize.min, children: children),
);
final child = Material(
color: Colors.transparent,
child: Column(mainAxisSize: MainAxisSize.min, children: children),
);
// Explicit caller margin wins as-is. Otherwise center on wide surfaces
// using the incoming constraint (not screen width) so groups nested in an
// already clamped box, e.g. a bottom sheet, are not over-inset.
if (margin != null) {
return Container(
margin: margin,
decoration: decoration,
clipBehavior: Clip.antiAlias,
child: child,
);
}
return LayoutBuilder(
builder: (context, constraints) => Container(
margin: EdgeInsets.symmetric(
horizontal:
16 +
(constraints.hasBoundedWidth
? wideInsetForWidth(constraints.maxWidth)
: 0),
vertical: 4,
),
decoration: decoration,
clipBehavior: Clip.antiAlias,
child: child,
),
);
}