💄 Adjust UI

This commit is contained in:
2025-12-16 22:44:31 +08:00
parent da71c31e2a
commit 2c56de7b06
3 changed files with 83 additions and 78 deletions

View File

@@ -23,6 +23,11 @@ class MyApp extends StatelessWidget {
brightness: Brightness.light, brightness: Brightness.light,
), ),
useMaterial3: true, useMaterial3: true,
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(12)),
),
),
), ),
darkTheme: ThemeData( darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed( colorScheme: ColorScheme.fromSeed(
@@ -30,6 +35,11 @@ class MyApp extends StatelessWidget {
brightness: Brightness.dark, brightness: Brightness.dark,
), ),
useMaterial3: true, useMaterial3: true,
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(12)),
),
),
), ),
themeMode: ThemeMode.system, themeMode: ThemeMode.system,
home: const Shell(), home: const Shell(),

View File

@@ -458,6 +458,7 @@ class LibraryScreen extends HookConsumerWidget {
builder: (context) => AlertDialog( builder: (context) => AlertDialog(
title: const Text('Edit Track'), title: const Text('Edit Track'),
content: Column( content: Column(
spacing: 16,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
TextField( TextField(

View File

@@ -23,25 +23,25 @@ class PlayerScreen extends HookConsumerWidget {
final tabController = useTabController(initialLength: 2); final tabController = useTabController(initialLength: 2);
final isMobile = MediaQuery.sizeOf(context).width <= 640; final isMobile = MediaQuery.sizeOf(context).width <= 640;
return Scaffold( return StreamBuilder<Playlist>(
body: Stack( stream: player.stream.playlist,
children: [ initialData: player.state.playlist,
// Main content (StreamBuilder) builder: (context, snapshot) {
StreamBuilder<Playlist>( final index = snapshot.data?.index ?? 0;
stream: player.stream.playlist, final medias = snapshot.data?.medias ?? [];
initialData: player.state.playlist, if (medias.isEmpty || index < 0 || index >= medias.length) {
builder: (context, snapshot) { return const Center(child: Text('No media selected'));
final index = snapshot.data?.index ?? 0; }
final medias = snapshot.data?.medias ?? []; final media = medias[index];
if (medias.isEmpty || index < 0 || index >= medias.length) {
return const Center(child: Text('No media selected'));
}
final media = medias[index];
final path = Uri.decodeFull(Uri.parse(media.uri).path);
final metadataAsync = ref.watch(trackMetadataProvider(path)); final path = Uri.decodeFull(Uri.parse(media.uri).path);
final metadataAsync = ref.watch(trackMetadataProvider(path));
return Builder( return Scaffold(
body: Stack(
children: [
// Main content (StreamBuilder)
Builder(
builder: (context) { builder: (context) {
if (isMobile) { if (isMobile) {
return Padding( return Padding(
@@ -65,41 +65,45 @@ class PlayerScreen extends HookConsumerWidget {
); );
} }
}, },
);
},
),
// IconButton
Positioned(
top: MediaQuery.of(context).padding.top + 16,
left: 16,
child: IconButton(
icon: const Icon(Icons.keyboard_arrow_down),
onPressed: () => Navigator.of(context).pop(),
padding: EdgeInsets.zero,
iconSize: 24,
),
),
// TabBar (if mobile)
if (isMobile)
Positioned(
top: MediaQuery.of(context).padding.top + 14,
left: 54,
right: 54,
child: TabBar(
controller: tabController,
tabAlignment: TabAlignment.fill,
tabs: const [
Tab(text: 'Cover'),
Tab(text: 'Lyrics'),
],
dividerHeight: 0,
indicatorColor: Colors.transparent,
overlayColor: WidgetStatePropertyAll(Colors.transparent),
splashFactory: NoSplash.splashFactory,
), ),
), // IconButton
], Positioned(
), top: MediaQuery.of(context).padding.top + 16,
left: 16,
child: IconButton(
icon: const Icon(Icons.keyboard_arrow_down),
onPressed: () => Navigator.of(context).pop(),
padding: EdgeInsets.zero,
iconSize: 24,
),
),
// TabBar (if mobile)
if (isMobile)
Positioned(
top: MediaQuery.of(context).padding.top + 14,
left: 54,
right: 54,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: TabBar(
controller: tabController,
tabAlignment: TabAlignment.fill,
tabs: const [
Tab(text: 'Cover'),
Tab(text: 'Lyrics'),
],
dividerHeight: 0,
indicatorColor: Colors.transparent,
overlayColor: WidgetStatePropertyAll(Colors.transparent),
splashFactory: NoSplash.splashFactory,
),
),
),
_LyricsRefreshButton(trackPath: path),
],
),
);
},
); );
} }
} }
@@ -370,36 +374,26 @@ class _PlayerLyrics extends HookConsumerWidget {
final lyricsData = LyricsData.fromJsonString(track.lyrics!); final lyricsData = LyricsData.fromJsonString(track.lyrics!);
if (lyricsData.type == 'timed') { if (lyricsData.type == 'timed') {
return Stack( return _TimedLyricsView(
children: [ lyrics: lyricsData,
_TimedLyricsView( player: player,
lyrics: lyricsData, trackPath: trackPath!,
player: player,
trackPath: trackPath!,
),
_LyricsRefreshButton(trackPath: trackPath!),
],
); );
} else { } else {
// Plain text lyrics // Plain text lyrics
return Stack( return ListView.builder(
children: [ padding: const EdgeInsets.all(16),
ListView.builder( itemCount: lyricsData.lines.length,
padding: const EdgeInsets.all(16), itemBuilder: (context, index) {
itemCount: lyricsData.lines.length, return Padding(
itemBuilder: (context, index) { padding: const EdgeInsets.symmetric(vertical: 4),
return Padding( child: Text(
padding: const EdgeInsets.symmetric(vertical: 4), lyricsData.lines[index].text,
child: Text( style: Theme.of(context).textTheme.bodyLarge,
lyricsData.lines[index].text, textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyLarge, ),
textAlign: TextAlign.center, );
), },
);
},
),
_LyricsRefreshButton(trackPath: trackPath!),
],
); );
} }
} catch (e) { } catch (e) {