chore: fix alternative source list item theme inconsistency

This commit is contained in:
Kingkor Roy Tirtho 2025-01-05 16:50:04 +06:00
parent b734985199
commit dff8fe2e64
2 changed files with 79 additions and 80 deletions

View File

@ -9,6 +9,7 @@ class ButtonTile extends StatelessWidget {
final void Function()? onPressed; final void Function()? onPressed;
final bool selected; final bool selected;
final ButtonVariance style; final ButtonVariance style;
final EdgeInsets? padding;
const ButtonTile({ const ButtonTile({
super.key, super.key,
@ -19,6 +20,7 @@ class ButtonTile extends StatelessWidget {
this.enabled = true, this.enabled = true,
this.onPressed, this.onPressed,
this.selected = false, this.selected = false,
this.padding,
this.style = ButtonVariance.outline, this.style = ButtonVariance.outline,
}); });
@ -30,17 +32,23 @@ class ButtonTile extends StatelessWidget {
enabled: enabled, enabled: enabled,
onPressed: onPressed, onPressed: onPressed,
style: style.copyWith( style: style.copyWith(
padding: padding != null ? (context, states, value) => padding! : null,
decoration: (context, states, value) { decoration: (context, states, value) {
final decoration = style.decoration(context, states) as BoxDecoration; final decoration = style.decoration(context, states) as BoxDecoration;
if (selected && style == ButtonVariance.outline) { if (selected) {
return decoration.copyWith( return switch (style) {
border: Border.all( ButtonVariance.outline => decoration.copyWith(
color: colorScheme.primary, border: Border.all(
width: 1.0, color: colorScheme.primary,
), width: 1.0,
color: colorScheme.primary.withAlpha(25), ),
); color: colorScheme.primary.withAlpha(25),
),
ButtonVariance.ghost || _ => decoration.copyWith(
color: colorScheme.primary.withAlpha(25),
),
};
} }
return decoration; return decoration;

View File

@ -1,14 +1,14 @@
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/material.dart' show ListTile, Material, MaterialType;
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:shadcn_flutter/shadcn_flutter_extension.dart';
import 'package:spotube/collections/assets.gen.dart'; import 'package:spotube/collections/assets.gen.dart';
import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/components/image/universal_image.dart';
import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart'; import 'package:spotube/components/inter_scrollbar/inter_scrollbar.dart';
import 'package:spotube/components/ui/button_tile.dart';
import 'package:spotube/extensions/artist_simple.dart'; import 'package:spotube/extensions/artist_simple.dart';
import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/context.dart';
import 'package:spotube/extensions/duration.dart'; import 'package:spotube/extensions/duration.dart';
@ -18,7 +18,6 @@ import 'package:spotube/provider/audio_player/audio_player.dart';
import 'package:spotube/provider/audio_player/querying_track_info.dart'; import 'package:spotube/provider/audio_player/querying_track_info.dart';
import 'package:spotube/provider/server/active_sourced_track.dart'; import 'package:spotube/provider/server/active_sourced_track.dart';
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
import 'package:spotube/services/sourced_track/models/source_info.dart'; import 'package:spotube/services/sourced_track/models/source_info.dart';
import 'package:spotube/services/sourced_track/models/video_info.dart'; import 'package:spotube/services/sourced_track/models/video_info.dart';
import 'package:spotube/services/sourced_track/sourced_track.dart'; import 'package:spotube/services/sourced_track/sourced_track.dart';
@ -161,40 +160,36 @@ class SiblingTracksSheet extends HookConsumerWidget {
final itemBuilder = useCallback( final itemBuilder = useCallback(
(SourceInfo sourceInfo) { (SourceInfo sourceInfo) {
final icon = sourceInfoToIconMap[sourceInfo.runtimeType]; final icon = sourceInfoToIconMap[sourceInfo.runtimeType];
return ListTile( return ButtonTile(
hoverColor: theme.colorScheme.primary.withOpacity(.1), style: ButtonVariance.ghost,
dense: true, padding: const EdgeInsets.symmetric(horizontal: 8),
subtitleTextStyle: theme.typography.small.copyWith( title: Text(
color: theme.colorScheme.mutedForeground, sourceInfo.title,
maxLines: 2,
overflow: TextOverflow.ellipsis,
), ),
titleTextStyle: theme.typography.normal, leading: UniversalImage(
leadingAndTrailingTextStyle: theme.typography.normal, path: sourceInfo.thumbnail,
title: Text(sourceInfo.title), height: 60,
horizontalTitleGap: 0, width: 60,
leading: Padding(
padding: const EdgeInsets.only(top: 8.0, right: 8.0),
child: UniversalImage(
path: sourceInfo.thumbnail,
height: 60,
width: 60,
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
), ),
trailing: Text(sourceInfo.duration.toHumanReadableString()), trailing: Text(sourceInfo.duration.toHumanReadableString()),
subtitle: Row( subtitle: Row(
children: [ children: [
if (icon != null) icon, if (icon != null) icon,
Text("${sourceInfo.artist}"), Flexible(
child: Text(
"${sourceInfo.artist}",
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
], ],
), ),
enabled: !isFetchingActiveTrack, enabled: !isFetchingActiveTrack,
selected: !isFetchingActiveTrack && selected: !isFetchingActiveTrack &&
sourceInfo.id == (activeTrack as SourcedTrack).sourceInfo.id, sourceInfo.id == (activeTrack as SourcedTrack).sourceInfo.id,
selectedTileColor: theme.colorScheme.primary.withOpacity(.1), onPressed: () {
selectedColor: theme.colorScheme.primary,
onTap: () {
if (!isFetchingActiveTrack && if (!isFetchingActiveTrack &&
sourceInfo.id != (activeTrack as SourcedTrack).sourceInfo.id) { sourceInfo.id != (activeTrack as SourcedTrack).sourceInfo.id) {
activeTrackNotifier.swapSibling(sourceInfo); activeTrackNotifier.swapSibling(sourceInfo);
@ -222,20 +217,17 @@ class SiblingTracksSheet extends HookConsumerWidget {
child: !isSearching.value child: !isSearching.value
? Text( ? Text(
context.l10n.alternative_track_sources, context.l10n.alternative_track_sources,
style: theme.typography.bold, ).bold()
) : ConstrainedBox(
: Flexible( constraints: BoxConstraints(
child: ConstrainedBox( maxWidth: 320 * scale,
constraints: BoxConstraints( maxHeight: 38 * scale,
maxWidth: 320 * scale, ),
maxHeight: 38 * scale, child: TextField(
), autofocus: true,
child: TextField( controller: searchController,
autofocus: true, placeholder: Text(context.l10n.search),
controller: searchController, style: theme.typography.bold,
placeholder: Text(context.l10n.search),
style: theme.typography.bold,
),
), ),
), ),
), ),
@ -290,39 +282,38 @@ class SiblingTracksSheet extends HookConsumerWidget {
FadeTransition(opacity: animation, child: child), FadeTransition(opacity: animation, child: child),
child: InterScrollbar( child: InterScrollbar(
controller: controller, controller: controller,
child: Material( child: switch (isSearching.value) {
type: MaterialType.transparency, false => ListView.separated(
child: switch (isSearching.value) { padding: const EdgeInsets.all(8.0),
false => ListView.builder( controller: controller,
padding: const EdgeInsets.all(8.0), itemCount: siblings.length,
controller: controller, separatorBuilder: (context, index) => const Gap(8),
itemCount: siblings.length, itemBuilder: (context, index) =>
itemBuilder: (context, index) => itemBuilder(siblings[index]),
itemBuilder(siblings[index]), ),
), true => FutureBuilder(
true => FutureBuilder( future: searchRequest,
future: searchRequest, builder: (context, snapshot) {
builder: (context, snapshot) { if (snapshot.hasError) {
if (snapshot.hasError) { return Center(
return Center( child: Text(snapshot.error.toString()),
child: Text(snapshot.error.toString()),
);
} else if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator());
}
return ListView.builder(
padding: const EdgeInsets.all(8.0),
controller: controller,
itemCount: snapshot.data!.length,
itemBuilder: (context, index) =>
itemBuilder(snapshot.data![index]),
); );
}, } else if (!snapshot.hasData) {
), return const Center(
}, child: CircularProgressIndicator());
), }
return ListView.separated(
padding: const EdgeInsets.all(8.0),
controller: controller,
itemCount: snapshot.data!.length,
separatorBuilder: (context, index) => const Gap(8),
itemBuilder: (context, index) =>
itemBuilder(snapshot.data![index]),
);
},
),
},
), ),
), ),
), ),