mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 16:05:18 +00:00
fix(mobile): SafeArea bugs and back button color
This commit is contained in:
parent
3b6bf27a98
commit
a8330ef2e1
@ -11,6 +11,7 @@ import 'package:spotube/components/Shared/Waypoint.dart';
|
|||||||
import 'package:spotube/provider/SpotifyDI.dart';
|
import 'package:spotube/provider/SpotifyDI.dart';
|
||||||
import 'package:spotube/provider/SpotifyRequests.dart';
|
import 'package:spotube/provider/SpotifyRequests.dart';
|
||||||
import 'package:spotube/provider/UserPreferences.dart';
|
import 'package:spotube/provider/UserPreferences.dart';
|
||||||
|
import 'package:spotube/utils/platform.dart';
|
||||||
|
|
||||||
class Genres extends HookConsumerWidget {
|
class Genres extends HookConsumerWidget {
|
||||||
const Genres({Key? key}) : super(key: key);
|
const Genres({Key? key}) : super(key: key);
|
||||||
@ -43,7 +44,7 @@ class Genres extends HookConsumerWidget {
|
|||||||
];
|
];
|
||||||
|
|
||||||
return PlatformScaffold(
|
return PlatformScaffold(
|
||||||
appBar: PageWindowTitleBar(),
|
appBar: kIsDesktop ? PageWindowTitleBar() : null,
|
||||||
body: ListView.builder(
|
body: ListView.builder(
|
||||||
itemCount: categories.length,
|
itemCount: categories.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
|
@ -23,26 +23,28 @@ class UserLibrary extends HookConsumerWidget {
|
|||||||
const UserAlbums(),
|
const UserAlbums(),
|
||||||
][index.value];
|
][index.value];
|
||||||
|
|
||||||
return PlatformScaffold(
|
return SafeArea(
|
||||||
appBar: PageWindowTitleBar(
|
child: PlatformScaffold(
|
||||||
titleWidth: 347,
|
appBar: PageWindowTitleBar(
|
||||||
centerTitle: true,
|
titleWidth: 347,
|
||||||
center: PlatformTabBar(
|
centerTitle: true,
|
||||||
androidIsScrollable: true,
|
center: PlatformTabBar(
|
||||||
selectedIndex: index.value,
|
androidIsScrollable: true,
|
||||||
onSelectedIndexChanged: (value) => index.value = value,
|
selectedIndex: index.value,
|
||||||
isNavigational:
|
onSelectedIndexChanged: (value) => index.value = value,
|
||||||
PlatformProperty.byPlatformGroup(mobile: false, desktop: true),
|
isNavigational:
|
||||||
tabs: [
|
PlatformProperty.byPlatformGroup(mobile: false, desktop: true),
|
||||||
PlatformTab(label: 'Playlists', icon: const SizedBox.shrink()),
|
tabs: [
|
||||||
PlatformTab(label: 'Tracks', icon: const SizedBox.shrink()),
|
PlatformTab(label: 'Playlists', icon: const SizedBox.shrink()),
|
||||||
PlatformTab(label: 'Downloads', icon: const SizedBox.shrink()),
|
PlatformTab(label: 'Tracks', icon: const SizedBox.shrink()),
|
||||||
PlatformTab(label: 'Artists', icon: const SizedBox.shrink()),
|
PlatformTab(label: 'Downloads', icon: const SizedBox.shrink()),
|
||||||
PlatformTab(label: 'Albums', icon: const SizedBox.shrink()),
|
PlatformTab(label: 'Artists', icon: const SizedBox.shrink()),
|
||||||
],
|
PlatformTab(label: 'Albums', icon: const SizedBox.shrink()),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
body: body,
|
||||||
),
|
),
|
||||||
body: body,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ class PlayerOverlay extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
PlatformIconButton(
|
IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.skip_previous_rounded,
|
Icons.skip_previous_rounded,
|
||||||
color: paletteColor.bodyTextColor,
|
color: paletteColor.bodyTextColor,
|
||||||
@ -91,7 +91,7 @@ class PlayerOverlay extends HookConsumerWidget {
|
|||||||
}),
|
}),
|
||||||
Consumer(
|
Consumer(
|
||||||
builder: (context, ref, _) {
|
builder: (context, ref, _) {
|
||||||
return PlatformIconButton(
|
return IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
ref.read(playbackProvider).isPlaying
|
ref.read(playbackProvider).isPlaying
|
||||||
? Icons.pause_rounded
|
? Icons.pause_rounded
|
||||||
@ -105,7 +105,7 @@ class PlayerOverlay extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
PlatformIconButton(
|
IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.skip_next_rounded,
|
Icons.skip_next_rounded,
|
||||||
color: paletteColor.bodyTextColor,
|
color: paletteColor.bodyTextColor,
|
||||||
|
@ -73,292 +73,299 @@ class Search extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PlatformScaffold(
|
return SafeArea(
|
||||||
appBar: !kIsMacOS ? PageWindowTitleBar() : null,
|
child: PlatformScaffold(
|
||||||
body: auth.isAnonymous
|
appBar: kIsDesktop && !kIsMacOS ? PageWindowTitleBar() : null,
|
||||||
? const AnonymousFallback()
|
body: auth.isAnonymous
|
||||||
: Column(
|
? const AnonymousFallback()
|
||||||
children: [
|
: Column(
|
||||||
Container(
|
children: [
|
||||||
padding: const EdgeInsets.symmetric(
|
Container(
|
||||||
horizontal: 20,
|
padding: const EdgeInsets.symmetric(
|
||||||
vertical: 10,
|
horizontal: 20,
|
||||||
|
vertical: 10,
|
||||||
|
),
|
||||||
|
child: PlatformTextField(
|
||||||
|
onChanged: (value) {
|
||||||
|
ref.read(searchTermStateProvider.notifier).state =
|
||||||
|
value;
|
||||||
|
},
|
||||||
|
prefixIcon: Icons.search_rounded,
|
||||||
|
prefixIconColor: PlatformProperty.only(
|
||||||
|
ios:
|
||||||
|
PlatformTheme.of(context).textTheme?.caption?.color,
|
||||||
|
other: null,
|
||||||
|
).resolve(platform!),
|
||||||
|
placeholder: "Search...",
|
||||||
|
onSubmitted: (value) {
|
||||||
|
onSearch();
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: PlatformTextField(
|
HookBuilder(
|
||||||
onChanged: (value) {
|
builder: (context) {
|
||||||
ref.read(searchTermStateProvider.notifier).state = value;
|
Playback playback = ref.watch(playbackProvider);
|
||||||
},
|
List<AlbumSimple> albums = [];
|
||||||
prefixIcon: Icons.search_rounded,
|
List<Artist> artists = [];
|
||||||
prefixIconColor: PlatformProperty.only(
|
List<Track> tracks = [];
|
||||||
ios: PlatformTheme.of(context).textTheme?.caption?.color,
|
List<PlaylistSimple> playlists = [];
|
||||||
other: null,
|
final pages = [
|
||||||
).resolve(platform!),
|
...searchTrack.pages,
|
||||||
placeholder: "Search...",
|
...searchAlbum.pages,
|
||||||
onSubmitted: (value) {
|
...searchPlaylist.pages,
|
||||||
onSearch();
|
...searchArtist.pages,
|
||||||
},
|
].expand<Page>((page) => page ?? []).toList();
|
||||||
),
|
for (MapEntry<int, Page> page in pages.asMap().entries) {
|
||||||
),
|
for (var item in page.value.items ?? []) {
|
||||||
HookBuilder(
|
if (item is AlbumSimple) {
|
||||||
builder: (context) {
|
albums.add(item);
|
||||||
Playback playback = ref.watch(playbackProvider);
|
} else if (item is PlaylistSimple) {
|
||||||
List<AlbumSimple> albums = [];
|
playlists.add(item);
|
||||||
List<Artist> artists = [];
|
} else if (item is Artist) {
|
||||||
List<Track> tracks = [];
|
artists.add(item);
|
||||||
List<PlaylistSimple> playlists = [];
|
} else if (item is Track) {
|
||||||
final pages = [
|
tracks.add(item);
|
||||||
...searchTrack.pages,
|
}
|
||||||
...searchAlbum.pages,
|
|
||||||
...searchPlaylist.pages,
|
|
||||||
...searchArtist.pages,
|
|
||||||
].expand<Page>((page) => page ?? []).toList();
|
|
||||||
for (MapEntry<int, Page> page in pages.asMap().entries) {
|
|
||||||
for (var item in page.value.items ?? []) {
|
|
||||||
if (item is AlbumSimple) {
|
|
||||||
albums.add(item);
|
|
||||||
} else if (item is PlaylistSimple) {
|
|
||||||
playlists.add(item);
|
|
||||||
} else if (item is Artist) {
|
|
||||||
artists.add(item);
|
|
||||||
} else if (item is Track) {
|
|
||||||
tracks.add(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return Expanded(
|
||||||
return Expanded(
|
child: SingleChildScrollView(
|
||||||
child: SingleChildScrollView(
|
child: Padding(
|
||||||
child: Padding(
|
padding: const EdgeInsets.symmetric(
|
||||||
padding: const EdgeInsets.symmetric(
|
vertical: 8,
|
||||||
vertical: 8,
|
horizontal: 20,
|
||||||
horizontal: 20,
|
),
|
||||||
),
|
child: Column(
|
||||||
child: Column(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
children: [
|
||||||
children: [
|
if (tracks.isNotEmpty)
|
||||||
if (tracks.isNotEmpty)
|
PlatformText.headline("Songs"),
|
||||||
PlatformText.headline("Songs"),
|
if (searchTrack.isLoading &&
|
||||||
if (searchTrack.isLoading &&
|
!searchTrack.isFetchingNextPage)
|
||||||
!searchTrack.isFetchingNextPage)
|
const PlatformCircularProgressIndicator()
|
||||||
const PlatformCircularProgressIndicator()
|
else if (searchTrack.hasError)
|
||||||
else if (searchTrack.hasError)
|
PlatformText(searchTrack
|
||||||
PlatformText(searchTrack
|
.error?[searchTrack.pageParams.last])
|
||||||
.error?[searchTrack.pageParams.last])
|
else
|
||||||
else
|
...tracks.asMap().entries.map((track) {
|
||||||
...tracks.asMap().entries.map((track) {
|
String duration =
|
||||||
String duration =
|
"${track.value.duration?.inMinutes.remainder(60)}:${PrimitiveUtils.zeroPadNumStr(track.value.duration?.inSeconds.remainder(60) ?? 0)}";
|
||||||
"${track.value.duration?.inMinutes.remainder(60)}:${PrimitiveUtils.zeroPadNumStr(track.value.duration?.inSeconds.remainder(60) ?? 0)}";
|
return TrackTile(
|
||||||
return TrackTile(
|
playback,
|
||||||
playback,
|
track: track,
|
||||||
track: track,
|
duration: duration,
|
||||||
duration: duration,
|
isActive:
|
||||||
isActive:
|
playback.track?.id == track.value.id,
|
||||||
playback.track?.id == track.value.id,
|
onTrackPlayButtonPressed:
|
||||||
onTrackPlayButtonPressed:
|
(currentTrack) async {
|
||||||
(currentTrack) async {
|
var isPlaylistPlaying =
|
||||||
var isPlaylistPlaying =
|
playback.playlist?.id != null &&
|
||||||
playback.playlist?.id != null &&
|
playback.playlist?.id ==
|
||||||
playback.playlist?.id ==
|
currentTrack.id;
|
||||||
currentTrack.id;
|
if (!isPlaylistPlaying) {
|
||||||
if (!isPlaylistPlaying) {
|
playback.playPlaylist(
|
||||||
playback.playPlaylist(
|
CurrentPlaylist(
|
||||||
CurrentPlaylist(
|
tracks: [currentTrack],
|
||||||
tracks: [currentTrack],
|
id: currentTrack.id!,
|
||||||
id: currentTrack.id!,
|
name: currentTrack.name!,
|
||||||
name: currentTrack.name!,
|
thumbnail: TypeConversionUtils
|
||||||
thumbnail: TypeConversionUtils
|
.image_X_UrlString(
|
||||||
.image_X_UrlString(
|
currentTrack.album?.images,
|
||||||
currentTrack.album?.images,
|
placeholder:
|
||||||
placeholder:
|
ImagePlaceholder.albumArt,
|
||||||
ImagePlaceholder.albumArt,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else if (isPlaylistPlaying &&
|
|
||||||
currentTrack.id != null &&
|
|
||||||
currentTrack.id !=
|
|
||||||
playback.track?.id) {
|
|
||||||
playback.play(currentTrack);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
if (searchTrack.hasNextPage && tracks.isNotEmpty)
|
|
||||||
Center(
|
|
||||||
child: PlatformTextButton(
|
|
||||||
onPressed: searchTrack.isFetchingNextPage
|
|
||||||
? null
|
|
||||||
: () => searchTrack.fetchNextPage(),
|
|
||||||
child: searchTrack.isFetchingNextPage
|
|
||||||
? const PlatformCircularProgressIndicator()
|
|
||||||
: const PlatformText("Load more"),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (playlists.isNotEmpty)
|
|
||||||
PlatformText.headline("Playlists"),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
if (searchPlaylist.isLoading &&
|
|
||||||
!searchPlaylist.isFetchingNextPage)
|
|
||||||
const PlatformCircularProgressIndicator()
|
|
||||||
else if (searchPlaylist.hasError)
|
|
||||||
PlatformText(searchPlaylist
|
|
||||||
.error?[searchPlaylist.pageParams.last])
|
|
||||||
else
|
|
||||||
ScrollConfiguration(
|
|
||||||
behavior:
|
|
||||||
ScrollConfiguration.of(context).copyWith(
|
|
||||||
dragDevices: {
|
|
||||||
PointerDeviceKind.touch,
|
|
||||||
PointerDeviceKind.mouse,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
child: Scrollbar(
|
|
||||||
scrollbarOrientation:
|
|
||||||
breakpoint > Breakpoints.md
|
|
||||||
? ScrollbarOrientation.bottom
|
|
||||||
: ScrollbarOrientation.top,
|
|
||||||
controller: playlistController,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
controller: playlistController,
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
...playlists.mapIndexed(
|
|
||||||
(i, playlist) {
|
|
||||||
if (i == playlists.length - 1 &&
|
|
||||||
searchPlaylist.hasNextPage) {
|
|
||||||
return Waypoint(
|
|
||||||
onEnter: () {
|
|
||||||
searchPlaylist
|
|
||||||
.fetchNextPage();
|
|
||||||
},
|
|
||||||
child:
|
|
||||||
const ShimmerPlaybuttonCard(
|
|
||||||
count: 1),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return PlaylistCard(playlist);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
if (artists.isNotEmpty)
|
|
||||||
PlatformText.headline("Artists"),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
if (searchArtist.isLoading &&
|
|
||||||
!searchArtist.isFetchingNextPage)
|
|
||||||
const PlatformCircularProgressIndicator()
|
|
||||||
else if (searchArtist.hasError)
|
|
||||||
PlatformText(searchArtist
|
|
||||||
.error?[searchArtist.pageParams.last])
|
|
||||||
else
|
|
||||||
ScrollConfiguration(
|
|
||||||
behavior:
|
|
||||||
ScrollConfiguration.of(context).copyWith(
|
|
||||||
dragDevices: {
|
|
||||||
PointerDeviceKind.touch,
|
|
||||||
PointerDeviceKind.mouse,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
child: Scrollbar(
|
|
||||||
controller: artistController,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
controller: artistController,
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
...artists.mapIndexed(
|
|
||||||
(i, artist) {
|
|
||||||
if (i == artists.length - 1 &&
|
|
||||||
searchArtist.hasNextPage) {
|
|
||||||
return Waypoint(
|
|
||||||
onEnter: () {
|
|
||||||
searchArtist
|
|
||||||
.fetchNextPage();
|
|
||||||
},
|
|
||||||
child:
|
|
||||||
const ShimmerPlaybuttonCard(
|
|
||||||
count: 1),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return Container(
|
|
||||||
margin:
|
|
||||||
const EdgeInsets.symmetric(
|
|
||||||
horizontal: 15),
|
|
||||||
child: ArtistCard(artist),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
if (albums.isNotEmpty)
|
|
||||||
PlatformText(
|
|
||||||
"Albums",
|
|
||||||
style: Theme.of(context).textTheme.headline5,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
if (searchAlbum.isLoading &&
|
|
||||||
!searchAlbum.isFetchingNextPage)
|
|
||||||
const PlatformCircularProgressIndicator()
|
|
||||||
else if (searchAlbum.hasError)
|
|
||||||
PlatformText(searchAlbum
|
|
||||||
.error?[searchAlbum.pageParams.last])
|
|
||||||
else
|
|
||||||
ScrollConfiguration(
|
|
||||||
behavior:
|
|
||||||
ScrollConfiguration.of(context).copyWith(
|
|
||||||
dragDevices: {
|
|
||||||
PointerDeviceKind.touch,
|
|
||||||
PointerDeviceKind.mouse,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
child: Scrollbar(
|
|
||||||
controller: albumController,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
controller: albumController,
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
...albums.mapIndexed((i, album) {
|
|
||||||
if (i == albums.length - 1 &&
|
|
||||||
searchAlbum.hasNextPage) {
|
|
||||||
return Waypoint(
|
|
||||||
onEnter: () {
|
|
||||||
searchAlbum.fetchNextPage();
|
|
||||||
},
|
|
||||||
child:
|
|
||||||
const ShimmerPlaybuttonCard(
|
|
||||||
count: 1),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return AlbumCard(
|
|
||||||
TypeConversionUtils
|
|
||||||
.simpleAlbum_X_Album(
|
|
||||||
album,
|
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
}),
|
);
|
||||||
],
|
} else if (isPlaylistPlaying &&
|
||||||
|
currentTrack.id != null &&
|
||||||
|
currentTrack.id !=
|
||||||
|
playback.track?.id) {
|
||||||
|
playback.play(currentTrack);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
if (searchTrack.hasNextPage &&
|
||||||
|
tracks.isNotEmpty)
|
||||||
|
Center(
|
||||||
|
child: PlatformTextButton(
|
||||||
|
onPressed: searchTrack.isFetchingNextPage
|
||||||
|
? null
|
||||||
|
: () => searchTrack.fetchNextPage(),
|
||||||
|
child: searchTrack.isFetchingNextPage
|
||||||
|
? const PlatformCircularProgressIndicator()
|
||||||
|
: const PlatformText("Load more"),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (playlists.isNotEmpty)
|
||||||
|
PlatformText.headline("Playlists"),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
if (searchPlaylist.isLoading &&
|
||||||
|
!searchPlaylist.isFetchingNextPage)
|
||||||
|
const PlatformCircularProgressIndicator()
|
||||||
|
else if (searchPlaylist.hasError)
|
||||||
|
PlatformText(searchPlaylist
|
||||||
|
.error?[searchPlaylist.pageParams.last])
|
||||||
|
else
|
||||||
|
ScrollConfiguration(
|
||||||
|
behavior: ScrollConfiguration.of(context)
|
||||||
|
.copyWith(
|
||||||
|
dragDevices: {
|
||||||
|
PointerDeviceKind.touch,
|
||||||
|
PointerDeviceKind.mouse,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
child: Scrollbar(
|
||||||
|
scrollbarOrientation:
|
||||||
|
breakpoint > Breakpoints.md
|
||||||
|
? ScrollbarOrientation.bottom
|
||||||
|
: ScrollbarOrientation.top,
|
||||||
|
controller: playlistController,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
controller: playlistController,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
...playlists.mapIndexed(
|
||||||
|
(i, playlist) {
|
||||||
|
if (i == playlists.length - 1 &&
|
||||||
|
searchPlaylist
|
||||||
|
.hasNextPage) {
|
||||||
|
return Waypoint(
|
||||||
|
onEnter: () {
|
||||||
|
searchPlaylist
|
||||||
|
.fetchNextPage();
|
||||||
|
},
|
||||||
|
child:
|
||||||
|
const ShimmerPlaybuttonCard(
|
||||||
|
count: 1),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return PlaylistCard(playlist);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(height: 20),
|
||||||
],
|
if (artists.isNotEmpty)
|
||||||
|
PlatformText.headline("Artists"),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
if (searchArtist.isLoading &&
|
||||||
|
!searchArtist.isFetchingNextPage)
|
||||||
|
const PlatformCircularProgressIndicator()
|
||||||
|
else if (searchArtist.hasError)
|
||||||
|
PlatformText(searchArtist
|
||||||
|
.error?[searchArtist.pageParams.last])
|
||||||
|
else
|
||||||
|
ScrollConfiguration(
|
||||||
|
behavior: ScrollConfiguration.of(context)
|
||||||
|
.copyWith(
|
||||||
|
dragDevices: {
|
||||||
|
PointerDeviceKind.touch,
|
||||||
|
PointerDeviceKind.mouse,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
child: Scrollbar(
|
||||||
|
controller: artistController,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
controller: artistController,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
...artists.mapIndexed(
|
||||||
|
(i, artist) {
|
||||||
|
if (i == artists.length - 1 &&
|
||||||
|
searchArtist.hasNextPage) {
|
||||||
|
return Waypoint(
|
||||||
|
onEnter: () {
|
||||||
|
searchArtist
|
||||||
|
.fetchNextPage();
|
||||||
|
},
|
||||||
|
child:
|
||||||
|
const ShimmerPlaybuttonCard(
|
||||||
|
count: 1),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Container(
|
||||||
|
margin: const EdgeInsets
|
||||||
|
.symmetric(
|
||||||
|
horizontal: 15),
|
||||||
|
child: ArtistCard(artist),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
if (albums.isNotEmpty)
|
||||||
|
PlatformText(
|
||||||
|
"Albums",
|
||||||
|
style:
|
||||||
|
Theme.of(context).textTheme.headline5,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
if (searchAlbum.isLoading &&
|
||||||
|
!searchAlbum.isFetchingNextPage)
|
||||||
|
const PlatformCircularProgressIndicator()
|
||||||
|
else if (searchAlbum.hasError)
|
||||||
|
PlatformText(searchAlbum
|
||||||
|
.error?[searchAlbum.pageParams.last])
|
||||||
|
else
|
||||||
|
ScrollConfiguration(
|
||||||
|
behavior: ScrollConfiguration.of(context)
|
||||||
|
.copyWith(
|
||||||
|
dragDevices: {
|
||||||
|
PointerDeviceKind.touch,
|
||||||
|
PointerDeviceKind.mouse,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
child: Scrollbar(
|
||||||
|
controller: albumController,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
controller: albumController,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
...albums.mapIndexed((i, album) {
|
||||||
|
if (i == albums.length - 1 &&
|
||||||
|
searchAlbum.hasNextPage) {
|
||||||
|
return Waypoint(
|
||||||
|
onEnter: () {
|
||||||
|
searchAlbum.fetchNextPage();
|
||||||
|
},
|
||||||
|
child:
|
||||||
|
const ShimmerPlaybuttonCard(
|
||||||
|
count: 1),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return AlbumCard(
|
||||||
|
TypeConversionUtils
|
||||||
|
.simpleAlbum_X_Album(
|
||||||
|
album,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
},
|
||||||
},
|
)
|
||||||
)
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,11 +114,7 @@ class TrackCollectionView<T> extends HookConsumerWidget {
|
|||||||
? PageWindowTitleBar(
|
? PageWindowTitleBar(
|
||||||
backgroundColor: color?.color,
|
backgroundColor: color?.color,
|
||||||
foregroundColor: color?.titleTextColor,
|
foregroundColor: color?.titleTextColor,
|
||||||
leading: Row(
|
leading: PlatformBackButton(color: color?.titleTextColor),
|
||||||
children: [
|
|
||||||
PlatformBackButton(color: color?.titleTextColor)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
body: CustomScrollView(
|
body: CustomScrollView(
|
||||||
@ -130,6 +126,9 @@ class TrackCollectionView<T> extends HookConsumerWidget {
|
|||||||
pinned: true,
|
pinned: true,
|
||||||
expandedHeight: 400,
|
expandedHeight: 400,
|
||||||
automaticallyImplyLeading: kIsMobile,
|
automaticallyImplyLeading: kIsMobile,
|
||||||
|
leading: kIsMobile
|
||||||
|
? PlatformBackButton(color: color?.titleTextColor)
|
||||||
|
: null,
|
||||||
iconTheme: IconThemeData(color: color?.titleTextColor),
|
iconTheme: IconThemeData(color: color?.titleTextColor),
|
||||||
primary: true,
|
primary: true,
|
||||||
backgroundColor: color?.color,
|
backgroundColor: color?.color,
|
||||||
|
@ -235,13 +235,15 @@ class SpotubeState extends ConsumerState<Spotube> with WidgetsBindingObserver {
|
|||||||
macosTheme: macosTheme,
|
macosTheme: macosTheme,
|
||||||
macosDarkTheme: macosDarkTheme,
|
macosDarkTheme: macosDarkTheme,
|
||||||
themeMode: themeMode,
|
themeMode: themeMode,
|
||||||
windowButtonConfig: PlatformWindowButtonConfig(
|
windowButtonConfig: kIsDesktop
|
||||||
isMaximized: () => appWindow.isMaximized,
|
? PlatformWindowButtonConfig(
|
||||||
onClose: appWindow.close,
|
isMaximized: () => appWindow.isMaximized,
|
||||||
onRestore: appWindow.restore,
|
onClose: appWindow.close,
|
||||||
onMaximize: appWindow.maximize,
|
onRestore: appWindow.restore,
|
||||||
onMinimize: appWindow.minimize,
|
onMaximize: appWindow.maximize,
|
||||||
),
|
onMinimize: appWindow.minimize,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
shortcuts: PlatformProperty.all({
|
shortcuts: PlatformProperty.all({
|
||||||
...WidgetsApp.defaultShortcuts.map((key, value) {
|
...WidgetsApp.defaultShortcuts.map((key, value) {
|
||||||
return MapEntry(
|
return MapEntry(
|
||||||
|
Loading…
Reference in New Issue
Block a user