refactor(ui): unify theme styling and enlarge profile button

Centralize existing Material and Mornye layout metrics in AppTokens and share adaptive icon selection. Enlarge the Home profile avatar to 44 dp with a 56 dp touch target.
This commit is contained in:
zarzet
2026-09-23 21:53:15 +07:00
parent 39273edd85
commit 146b2acd4d
20 changed files with 191 additions and 65 deletions
+2 -1
View File
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:spotiflac_android/theme/app_tokens.dart';
import 'package:spotiflac_android/theme/mornye_theme.dart';
/// Wraps a child in a staggered fade-in + slide-up animation.
@@ -841,7 +842,7 @@ class HomeSearchSkeleton extends StatelessWidget {
return Padding(
padding: EdgeInsets.symmetric(
horizontal: mornye ? 12 : 16,
vertical: mornye ? 12 : 10,
vertical: context.tokens.trackRowPaddingV,
),
child: Row(
children: [
+2 -1
View File
@@ -1,5 +1,6 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:spotiflac_android/theme/app_tokens.dart';
import 'package:spotiflac_android/theme/mornye_theme.dart';
import 'package:spotiflac_android/widgets/mornye_chrome.dart';
@@ -53,7 +54,7 @@ class AppDialogSurface extends StatelessWidget {
elevation: mornye ? 0 : null,
shape: shape,
insetPadding: EdgeInsets.symmetric(
horizontal: mornye ? 24 : 40,
horizontal: context.tokens.dialogInsetH,
vertical: 24,
),
child: ConstrainedBox(
+3 -2
View File
@@ -6,6 +6,7 @@ import 'package:spotiflac_android/providers/music_player_provider.dart';
import 'package:spotiflac_android/providers/player_motion_artwork_provider.dart';
import 'package:spotiflac_android/providers/player_artwork_video_provider.dart';
import 'package:spotiflac_android/providers/runtime_profile_provider.dart';
import 'package:spotiflac_android/theme/app_tokens.dart';
import 'package:spotiflac_android/theme/mornye_theme.dart';
import 'package:spotiflac_android/screens/now_playing_screen.dart';
import 'package:spotiflac_android/utils/string_utils.dart';
@@ -108,8 +109,8 @@ class _MiniPlayerState extends ConsumerState<MiniPlayer> {
child: ClipRRect(
borderRadius: BorderRadius.circular(6),
child: SizedBox(
width: mornye ? 38 : 44,
height: mornye ? 38 : 44,
width: context.tokens.coverMini,
height: context.tokens.coverMini,
child: PlayerArtwork(
artUri: mediaItem.artUri?.toString(),
colorScheme: colorScheme,
+5 -1
View File
@@ -92,11 +92,15 @@ class HomeProfileButton extends ConsumerWidget {
final profile = ref.watch(userProfileProvider).value;
return IconButton(
tooltip: context.l10n.settingsTitle,
iconSize: 44,
padding: const EdgeInsets.all(6),
constraints: const BoxConstraints(minWidth: 56, minHeight: 56),
visualDensity: VisualDensity.standard,
onPressed: () => ShellNavigationService.requestTab(ShellTab.settings),
icon: ProfileAvatar(
name: profile?.name ?? '',
photoPath: profile?.photoPath,
size: 34,
size: 44,
),
);
}
+22 -29
View File
@@ -296,22 +296,24 @@ class SettingsItem extends StatelessWidget {
highlightColor: Colors.transparent,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: context.isMornye ? 16 : 20,
vertical: context.isMornye ? 10 : 16,
horizontal: context.tokens.rowPaddingH,
vertical: context.tokens.rowPaddingV,
),
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: context.isMornye ? 28 : 0),
constraints: BoxConstraints(
minHeight: context.tokens.rowMinHeight,
),
child: Row(
children: [
if (icon != null) ...[
Icon(
context.isMornye ? mornyeIconFor(icon!) : icon,
context.adaptiveIcon(icon!),
color: context.isMornye
? colorScheme.primary
: colorScheme.onSurfaceVariant,
size: 24,
),
SizedBox(width: context.isMornye ? 12 : 16),
SizedBox(width: context.tokens.rowIconGap),
],
Expanded(
child: Column(
@@ -359,7 +361,7 @@ class SettingsItem extends StatelessWidget {
context.isMornye
? CupertinoIcons.chevron_forward
: Icons.chevron_right,
size: context.isMornye ? 18 : 24,
size: context.tokens.rowChevronSize,
color: colorScheme.onSurfaceVariant,
),
],
@@ -371,11 +373,10 @@ class SettingsItem extends StatelessWidget {
if (showDivider)
Divider(
height: 1,
thickness: context.isMornye ? 0.5 : 1,
indent: context.isMornye
? (icon != null ? 52 : 16)
: (icon != null ? 56 : 20),
endIndent: context.isMornye ? 16 : 20,
indent: icon != null
? context.tokens.rowIconDividerIndent
: context.tokens.rowPaddingH,
endIndent: context.tokens.rowPaddingH,
color: context.isMornye
? colorScheme.outlineVariant
: colorScheme.outlineVariant.withValues(alpha: 0.3),
@@ -424,14 +425,14 @@ class SettingsSwitchItem extends StatelessWidget {
highlightColor: Colors.transparent,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: context.isMornye ? 16 : 20,
vertical: context.isMornye ? 8 : 12,
horizontal: context.tokens.rowPaddingH,
vertical: context.tokens.rowPaddingVCompact,
),
child: Row(
children: [
if (icon != null) ...[
Icon(
context.isMornye ? mornyeIconFor(icon!) : icon,
context.adaptiveIcon(icon!),
color: isDisabled
? colorScheme.outline
: context.isMornye
@@ -439,7 +440,7 @@ class SettingsSwitchItem extends StatelessWidget {
: colorScheme.onSurfaceVariant,
size: 24,
),
SizedBox(width: context.isMornye ? 12 : 16),
SizedBox(width: context.tokens.rowIconGap),
],
Expanded(
child: Column(
@@ -494,11 +495,10 @@ class SettingsSwitchItem extends StatelessWidget {
if (showDivider)
Divider(
height: 1,
thickness: context.isMornye ? 0.5 : 1,
indent: context.isMornye
? (icon != null ? 52 : 16)
: (icon != null ? 56 : 20),
endIndent: context.isMornye ? 16 : 20,
indent: icon != null
? context.tokens.rowIconDividerIndent
: context.tokens.rowPaddingH,
endIndent: context.tokens.rowPaddingH,
color: context.isMornye
? colorScheme.outlineVariant
: colorScheme.outlineVariant.withValues(alpha: 0.3),
@@ -608,10 +608,7 @@ class SettingsChoiceChip extends StatelessWidget {
content = Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
context.isMornye ? mornyeIconFor(icon!) : icon,
color: foreground,
),
Icon(context.adaptiveIcon(icon!), color: foreground),
SizedBox(height: tokens.gapXs + 2),
labelText,
],
@@ -620,11 +617,7 @@ class SettingsChoiceChip extends StatelessWidget {
content = Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
context.isMornye ? mornyeIconFor(icon!) : icon,
size: 18,
color: foreground,
),
Icon(context.adaptiveIcon(icon!), size: 18, color: foreground),
SizedBox(width: tokens.gapSm),
Flexible(child: labelText),
],