mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 16:05:18 +00:00
feat: artist card redesign
chore: add license as asset for about
This commit is contained in:
parent
dcdb16676d
commit
92a418c8a8
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
BSD-4-Clause License
|
BSD-4-Clause License
|
||||||
|
|
||||||
Copyright (c) 2022 Kingkor Roy Tirtho. All rights reserved.
|
Copyright (c) 2023 Kingkor Roy Tirtho. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
@ -3,8 +3,9 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
|
||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
import 'package:spotube/components/shared/hover_builder.dart';
|
|
||||||
import 'package:spotube/components/shared/image/universal_image.dart';
|
import 'package:spotube/components/shared/image/universal_image.dart';
|
||||||
|
import 'package:spotube/hooks/use_breakpoint_value.dart';
|
||||||
|
import 'package:spotube/hooks/use_brightness_value.dart';
|
||||||
import 'package:spotube/provider/blacklist_provider.dart';
|
import 'package:spotube/provider/blacklist_provider.dart';
|
||||||
import 'package:spotube/utils/service_utils.dart';
|
import 'package:spotube/utils/service_utils.dart';
|
||||||
import 'package:spotube/utils/type_conversion_utils.dart';
|
import 'package:spotube/utils/type_conversion_utils.dart';
|
||||||
@ -15,6 +16,7 @@ class ArtistCard extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
final backgroundImage = UniversalImage.imageProvider(
|
final backgroundImage = UniversalImage.imageProvider(
|
||||||
TypeConversionUtils.image_X_UrlString(
|
TypeConversionUtils.image_X_UrlString(
|
||||||
artist.images,
|
artist.images,
|
||||||
@ -29,46 +31,53 @@ class ArtistCard extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
return SizedBox(
|
final radius = BorderRadius.circular(15);
|
||||||
height: 240,
|
|
||||||
width: 200,
|
final double size = useBreakpointValue<double>(
|
||||||
|
sm: 130,
|
||||||
|
md: 150,
|
||||||
|
others: 170,
|
||||||
|
);
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
width: size,
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 5),
|
||||||
|
child: Material(
|
||||||
|
shadowColor: theme.colorScheme.background,
|
||||||
|
color: Color.lerp(
|
||||||
|
theme.colorScheme.surfaceVariant,
|
||||||
|
theme.colorScheme.surface,
|
||||||
|
useBrightnessValue(.9, .7),
|
||||||
|
),
|
||||||
|
elevation: 3,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: radius,
|
||||||
|
side: isBlackListed
|
||||||
|
? const BorderSide(
|
||||||
|
color: Colors.red,
|
||||||
|
width: 2,
|
||||||
|
)
|
||||||
|
: BorderSide.none,
|
||||||
|
),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
ServiceUtils.navigate(context, "/artist/${artist.id}");
|
ServiceUtils.navigate(context, "/artist/${artist.id}");
|
||||||
},
|
},
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: radius,
|
||||||
child: HoverBuilder(builder: (context, isHovering) {
|
|
||||||
return Ink(
|
|
||||||
width: 200,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context).cardColor,
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
blurRadius: 10,
|
|
||||||
offset: const Offset(0, 3),
|
|
||||||
spreadRadius: 5,
|
|
||||||
color: Theme.of(context).colorScheme.shadow,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
border: isBlackListed
|
|
||||||
? Border.all(
|
|
||||||
color: Colors.red[400]!,
|
|
||||||
width: 2,
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(15),
|
padding: const EdgeInsets.all(12),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
|
||||||
children: [
|
children: [
|
||||||
Stack(
|
Stack(
|
||||||
children: [
|
children: [
|
||||||
CircleAvatar(
|
ConstrainedBox(
|
||||||
maxRadius: 80,
|
constraints: BoxConstraints(
|
||||||
minRadius: 20,
|
maxHeight: size,
|
||||||
|
),
|
||||||
|
child: CircleAvatar(
|
||||||
backgroundImage: backgroundImage,
|
backgroundImage: backgroundImage,
|
||||||
|
radius: size / 2,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
right: 0,
|
right: 0,
|
||||||
@ -92,19 +101,19 @@ class ArtistCard extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
AutoSizeText(
|
AutoSizeText(
|
||||||
artist.name!,
|
artist.name!,
|
||||||
maxLines: 2,
|
maxLines: 1,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: theme.textTheme.bodyMedium?.copyWith(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
)),
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ class UserArtists extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
final auth = ref.watch(AuthenticationNotifier.provider);
|
final auth = ref.watch(AuthenticationNotifier.provider);
|
||||||
|
|
||||||
final artistQuery = useQueries.artist.followedByMe(ref);
|
final artistQuery = useQueries.artist.followedByMe(ref);
|
||||||
@ -46,6 +47,8 @@ class UserArtists extends HookConsumerWidget {
|
|||||||
.toList();
|
.toList();
|
||||||
}, [artistQuery.pages, searchText.value]);
|
}, [artistQuery.pages, searchText.value]);
|
||||||
|
|
||||||
|
final controller = useScrollController();
|
||||||
|
|
||||||
if (auth == null) {
|
if (auth == null) {
|
||||||
return const AnonymousFallback();
|
return const AnonymousFallback();
|
||||||
}
|
}
|
||||||
@ -56,7 +59,7 @@ class UserArtists extends HookConsumerWidget {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
child: ColoredBox(
|
child: ColoredBox(
|
||||||
color: Theme.of(context).scaffoldBackgroundColor,
|
color: theme.scaffoldBackgroundColor,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
onChanged: (value) => searchText.value = value,
|
onChanged: (value) => searchText.value = value,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
@ -67,7 +70,7 @@ class UserArtists extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
backgroundColor: theme.scaffoldBackgroundColor,
|
||||||
body: artistQuery.pages.isEmpty
|
body: artistQuery.pages.isEmpty
|
||||||
? Padding(
|
? Padding(
|
||||||
padding: const EdgeInsets.all(20),
|
padding: const EdgeInsets.all(20),
|
||||||
@ -84,33 +87,30 @@ class UserArtists extends HookConsumerWidget {
|
|||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
await artistQuery.refreshAll();
|
await artistQuery.refreshAll();
|
||||||
},
|
},
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
controller: controller,
|
||||||
|
child: SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
child: GridView.builder(
|
child: Center(
|
||||||
itemCount: filteredArtists.length,
|
child: Wrap(
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
spacing: 15,
|
||||||
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
|
runSpacing: 5,
|
||||||
maxCrossAxisExtent: 200,
|
children: filteredArtists.mapIndexed((index, artist) {
|
||||||
mainAxisExtent: 250,
|
|
||||||
crossAxisSpacing: 20,
|
|
||||||
mainAxisSpacing: 20,
|
|
||||||
),
|
|
||||||
padding: const EdgeInsets.all(10),
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
return HookBuilder(builder: (context) {
|
|
||||||
if (index == artistQuery.pages.length - 1 &&
|
if (index == artistQuery.pages.length - 1 &&
|
||||||
hasNextPage) {
|
hasNextPage) {
|
||||||
return Waypoint(
|
return Waypoint(
|
||||||
controller: useScrollController(),
|
controller: controller,
|
||||||
isGrid: true,
|
isGrid: true,
|
||||||
onTouchEdge: () {
|
onTouchEdge: artistQuery.fetchNext,
|
||||||
artistQuery.fetchNext();
|
child: ArtistCard(artist),
|
||||||
},
|
|
||||||
child: ArtistCard(filteredArtists[index]),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return ArtistCard(filteredArtists[index]);
|
return ArtistCard(artist);
|
||||||
});
|
}).toList(),
|
||||||
},
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -79,7 +79,6 @@ class UserPlaylists extends HookConsumerWidget {
|
|||||||
onRefresh: playlistsQuery.refresh,
|
onRefresh: playlistsQuery.refresh,
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
@ -41,6 +41,7 @@ class PlayerControls extends HookConsumerWidget {
|
|||||||
final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier);
|
final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier);
|
||||||
final playing = useStream(PlaylistQueueNotifier.playing).data ??
|
final playing = useStream(PlaylistQueueNotifier.playing).data ??
|
||||||
PlaylistQueueNotifier.isPlaying;
|
PlaylistQueueNotifier.isPlaying;
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
behavior: HitTestBehavior.translucent,
|
behavior: HitTestBehavior.translucent,
|
||||||
@ -139,7 +140,7 @@ class PlayerControls extends HookConsumerWidget {
|
|||||||
icon: Icon(
|
icon: Icon(
|
||||||
SpotubeIcons.shuffle,
|
SpotubeIcons.shuffle,
|
||||||
color: playlist?.isShuffled == true
|
color: playlist?.isShuffled == true
|
||||||
? Theme.of(context).primaryColor
|
? theme.colorScheme.primary
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
onPressed: playlist == null
|
onPressed: playlist == null
|
||||||
@ -194,7 +195,7 @@ class PlayerControls extends HookConsumerWidget {
|
|||||||
? SpotubeIcons.repeatOne
|
? SpotubeIcons.repeatOne
|
||||||
: SpotubeIcons.repeat,
|
: SpotubeIcons.repeat,
|
||||||
color: playlist?.isLooping == true
|
color: playlist?.isLooping == true
|
||||||
? Theme.of(context).primaryColor
|
? theme.colorScheme.primary
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
onPressed: playlist == null || playlist.isLoading
|
onPressed: playlist == null || playlist.isLoading
|
||||||
|
@ -30,7 +30,8 @@ class PlayerOverlay extends HookConsumerWidget {
|
|||||||
final playing = useStream(PlaylistQueueNotifier.playing).data ??
|
final playing = useStream(PlaylistQueueNotifier.playing).data ??
|
||||||
PlaylistQueueNotifier.isPlaying;
|
PlaylistQueueNotifier.isPlaying;
|
||||||
|
|
||||||
final textColor = Theme.of(context).colorScheme.primary;
|
final theme = Theme.of(context);
|
||||||
|
final textColor = theme.colorScheme.primary;
|
||||||
|
|
||||||
const radius = BorderRadius.only(
|
const radius = BorderRadius.only(
|
||||||
topLeft: Radius.circular(10),
|
topLeft: Radius.circular(10),
|
||||||
@ -54,10 +55,7 @@ class PlayerOverlay extends HookConsumerWidget {
|
|||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
height: canShow ? 53 : 0,
|
height: canShow ? 53 : 0,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context)
|
color: theme.colorScheme.secondaryContainer.withOpacity(.8),
|
||||||
.colorScheme
|
|
||||||
.secondaryContainer
|
|
||||||
.withOpacity(.8),
|
|
||||||
borderRadius: radius,
|
borderRadius: radius,
|
||||||
),
|
),
|
||||||
child: AnimatedOpacity(
|
child: AnimatedOpacity(
|
||||||
@ -81,7 +79,7 @@ class PlayerOverlay extends HookConsumerWidget {
|
|||||||
minHeight: 2,
|
minHeight: 2,
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
valueColor: AlwaysStoppedAnimation(
|
valueColor: AlwaysStoppedAnimation(
|
||||||
Theme.of(context).colorScheme.primary,
|
theme.colorScheme.primary,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -36,7 +36,8 @@ class PlayerQueue extends HookConsumerWidget {
|
|||||||
topLeft: Radius.circular(10),
|
topLeft: Radius.circular(10),
|
||||||
topRight: Radius.circular(10),
|
topRight: Radius.circular(10),
|
||||||
);
|
);
|
||||||
final headlineColor = Theme.of(context).textTheme.headlineSmall?.color;
|
final theme = Theme.of(context);
|
||||||
|
final headlineColor = theme.textTheme.headlineSmall?.color;
|
||||||
|
|
||||||
useEffect(() {
|
useEffect(() {
|
||||||
if (playlist == null) return null;
|
if (playlist == null) return null;
|
||||||
@ -60,7 +61,7 @@ class PlayerQueue extends HookConsumerWidget {
|
|||||||
top: 5.0,
|
top: 5.0,
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).scaffoldBackgroundColor.withOpacity(0.5),
|
color: theme.scaffoldBackgroundColor.withOpacity(0.5),
|
||||||
borderRadius: borderRadius,
|
borderRadius: borderRadius,
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -88,11 +89,9 @@ class PlayerQueue extends HookConsumerWidget {
|
|||||||
const Spacer(),
|
const Spacer(),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
style: FilledButton.styleFrom(
|
style: FilledButton.styleFrom(
|
||||||
backgroundColor: Theme.of(context)
|
backgroundColor:
|
||||||
.scaffoldBackgroundColor
|
theme.scaffoldBackgroundColor.withOpacity(0.5),
|
||||||
.withOpacity(0.5),
|
foregroundColor: theme.textTheme.headlineSmall?.color,
|
||||||
foregroundColor:
|
|
||||||
Theme.of(context).textTheme.headlineSmall?.color,
|
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: const [
|
children: const [
|
||||||
|
@ -16,6 +16,7 @@ class PlayerTrackDetails extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
final breakpoint = useBreakpoints();
|
final breakpoint = useBreakpoints();
|
||||||
final playback = ref.watch(PlaylistQueueNotifier.provider);
|
final playback = ref.watch(PlaylistQueueNotifier.provider);
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ class PlayerTrackDetails extends HookConsumerWidget {
|
|||||||
Text(
|
Text(
|
||||||
playback?.activeTrack.name ?? "",
|
playback?.activeTrack.name ?? "",
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
style: theme.textTheme.bodyMedium?.copyWith(
|
||||||
color: color,
|
color: color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -59,10 +60,7 @@ class PlayerTrackDetails extends HookConsumerWidget {
|
|||||||
playback?.activeTrack.artists ?? [],
|
playback?.activeTrack.artists ?? [],
|
||||||
),
|
),
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: Theme.of(context)
|
style: theme.textTheme.bodySmall!.copyWith(color: color),
|
||||||
.textTheme
|
|
||||||
.bodySmall!
|
|
||||||
.copyWith(color: color),
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -19,6 +19,7 @@ class SiblingTracksSheet extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
final playlist = ref.watch(PlaylistQueueNotifier.provider);
|
final playlist = ref.watch(PlaylistQueueNotifier.provider);
|
||||||
final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier);
|
final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier);
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ class SiblingTracksSheet extends HookConsumerWidget {
|
|||||||
margin: const EdgeInsets.all(8.0),
|
margin: const EdgeInsets.all(8.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: borderRadius,
|
borderRadius: borderRadius,
|
||||||
color: Theme.of(context).scaffoldBackgroundColor.withOpacity(.3),
|
color: theme.scaffoldBackgroundColor.withOpacity(.3),
|
||||||
),
|
),
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
@ -58,7 +59,7 @@ class SiblingTracksSheet extends HookConsumerWidget {
|
|||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
title: Text(
|
title: Text(
|
||||||
'Alternative Tracks Sources',
|
'Alternative Tracks Sources',
|
||||||
style: Theme.of(context).textTheme.headlineSmall,
|
style: theme.textTheme.headlineSmall,
|
||||||
),
|
),
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
@ -96,7 +97,7 @@ class SiblingTracksSheet extends HookConsumerWidget {
|
|||||||
.ytTrack
|
.ytTrack
|
||||||
.id
|
.id
|
||||||
.value,
|
.value,
|
||||||
selectedTileColor: Theme.of(context).popupMenuTheme.color,
|
selectedTileColor: theme.popupMenuTheme.color,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (playlist?.isLoading == false &&
|
if (playlist?.isLoading == false &&
|
||||||
video.id.value !=
|
video.id.value !=
|
||||||
|
@ -40,7 +40,8 @@ class BottomPlayer extends HookConsumerWidget {
|
|||||||
[playlist?.activeTrack.album?.images],
|
[playlist?.activeTrack.album?.images],
|
||||||
);
|
);
|
||||||
|
|
||||||
final bg = Theme.of(context).colorScheme.surfaceVariant;
|
final theme = Theme.of(context);
|
||||||
|
final bg = theme.colorScheme.surfaceVariant;
|
||||||
|
|
||||||
final bgColor = useBrightnessValue(
|
final bgColor = useBrightnessValue(
|
||||||
Color.lerp(bg, Colors.white, 0.7),
|
Color.lerp(bg, Colors.white, 0.7),
|
||||||
@ -62,7 +63,7 @@ class BottomPlayer extends HookConsumerWidget {
|
|||||||
decoration: BoxDecoration(color: bgColor?.withOpacity(0.8)),
|
decoration: BoxDecoration(color: bgColor?.withOpacity(0.8)),
|
||||||
child: Material(
|
child: Material(
|
||||||
type: MaterialType.transparency,
|
type: MaterialType.transparency,
|
||||||
textStyle: Theme.of(context).textTheme.bodyMedium!,
|
textStyle: theme.textTheme.bodyMedium!,
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
children: [
|
children: [
|
||||||
|
@ -61,7 +61,8 @@ class Sidebar extends HookConsumerWidget {
|
|||||||
extended: breakpoints > Breakpoints.md,
|
extended: breakpoints > Breakpoints.md,
|
||||||
);
|
);
|
||||||
|
|
||||||
final bg = Theme.of(context).colorScheme.surfaceVariant;
|
final theme = Theme.of(context);
|
||||||
|
final bg = theme.colorScheme.surfaceVariant;
|
||||||
|
|
||||||
final bgColor = useBrightnessValue(
|
final bgColor = useBrightnessValue(
|
||||||
Color.lerp(bg, Colors.white, 0.7),
|
Color.lerp(bg, Colors.white, 0.7),
|
||||||
@ -98,7 +99,7 @@ class Sidebar extends HookConsumerWidget {
|
|||||||
(e) {
|
(e) {
|
||||||
return SidebarXItem(
|
return SidebarXItem(
|
||||||
// iconWidget: Badge(
|
// iconWidget: Badge(
|
||||||
// backgroundColor: Theme.of(context).primaryColor,
|
// backgroundColor: theme.colorScheme.primary,
|
||||||
// isLabelVisible: e.title == "Library" && downloadCount > 0,
|
// isLabelVisible: e.title == "Library" && downloadCount > 0,
|
||||||
// label: Text(
|
// label: Text(
|
||||||
// downloadCount.toString(),
|
// downloadCount.toString(),
|
||||||
@ -125,10 +126,10 @@ class Sidebar extends HookConsumerWidget {
|
|||||||
margin: EdgeInsets.only(bottom: 10, top: kIsMacOS ? 35 : 5),
|
margin: EdgeInsets.only(bottom: 10, top: kIsMacOS ? 35 : 5),
|
||||||
selectedItemDecoration: BoxDecoration(
|
selectedItemDecoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
color: Theme.of(context).colorScheme.primary.withOpacity(0.1),
|
color: theme.colorScheme.primary.withOpacity(0.1),
|
||||||
),
|
),
|
||||||
selectedIconTheme: IconThemeData(
|
selectedIconTheme: IconThemeData(
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: theme.colorScheme.primary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
extendedTheme: SidebarXTheme(
|
extendedTheme: SidebarXTheme(
|
||||||
@ -148,14 +149,13 @@ class Sidebar extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
selectedItemDecoration: BoxDecoration(
|
selectedItemDecoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
color: Theme.of(context).colorScheme.primary.withOpacity(0.1),
|
color: theme.colorScheme.primary.withOpacity(0.1),
|
||||||
),
|
),
|
||||||
selectedIconTheme: IconThemeData(
|
selectedIconTheme: IconThemeData(
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: theme.colorScheme.primary,
|
||||||
),
|
),
|
||||||
selectedTextStyle:
|
selectedTextStyle: theme.textTheme.bodyMedium?.copyWith(
|
||||||
Theme.of(context).textTheme.bodyMedium?.copyWith(
|
color: theme.colorScheme.primary,
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
),
|
),
|
||||||
itemTextPadding: const EdgeInsets.only(left: 10),
|
itemTextPadding: const EdgeInsets.only(left: 10),
|
||||||
@ -175,6 +175,7 @@ class SidebarHeader extends HookWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final breakpoint = useBreakpoints();
|
final breakpoint = useBreakpoints();
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
|
||||||
if (breakpoint <= Breakpoints.md) {
|
if (breakpoint <= Breakpoints.md) {
|
||||||
return Container(
|
return Container(
|
||||||
@ -196,7 +197,7 @@ class SidebarHeader extends HookWidget {
|
|||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Text(
|
Text(
|
||||||
"Spotube",
|
"Spotube",
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
style: theme.textTheme.titleLarge,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -213,6 +214,7 @@ class SidebarFooter extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
final breakpoint = useBreakpoints();
|
final breakpoint = useBreakpoints();
|
||||||
final me = useQueries.user.me(ref);
|
final me = useQueries.user.me(ref);
|
||||||
final data = me.data;
|
final data = me.data;
|
||||||
@ -260,9 +262,7 @@ class SidebarFooter extends HookConsumerWidget {
|
|||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
softWrap: false,
|
softWrap: false,
|
||||||
overflow: TextOverflow.fade,
|
overflow: TextOverflow.fade,
|
||||||
style: Theme.of(context)
|
style: theme.textTheme.bodyMedium
|
||||||
.textTheme
|
|
||||||
.bodyMedium
|
|
||||||
?.copyWith(fontWeight: FontWeight.bold),
|
?.copyWith(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -13,6 +13,7 @@ class ReplaceDownloadedDialog extends ConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
final groupValue = ref.watch(replaceDownloadedFileState);
|
final groupValue = ref.watch(replaceDownloadedFileState);
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: Text("Track ${track.name} Already Exists"),
|
title: Text("Track ${track.name} Already Exists"),
|
||||||
@ -23,7 +24,7 @@ class ReplaceDownloadedDialog extends ConsumerWidget {
|
|||||||
RadioListTile<bool>(
|
RadioListTile<bool>(
|
||||||
dense: true,
|
dense: true,
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
activeColor: Theme.of(context).primaryColor,
|
activeColor: theme.colorScheme.primary,
|
||||||
value: true,
|
value: true,
|
||||||
groupValue: groupValue,
|
groupValue: groupValue,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
@ -36,7 +37,7 @@ class ReplaceDownloadedDialog extends ConsumerWidget {
|
|||||||
RadioListTile<bool>(
|
RadioListTile<bool>(
|
||||||
dense: true,
|
dense: true,
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
activeColor: Theme.of(context).primaryColor,
|
activeColor: theme.colorScheme.primary,
|
||||||
value: false,
|
value: false,
|
||||||
groupValue: groupValue,
|
groupValue: groupValue,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
|
@ -7,6 +7,7 @@ class NotFound extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
final widgets = [
|
final widgets = [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 150,
|
height: 150,
|
||||||
@ -17,10 +18,10 @@ class NotFound extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text("Nothing found", style: Theme.of(context).textTheme.headline6),
|
Text("Nothing found", style: theme.textTheme.titleLarge),
|
||||||
Text(
|
Text(
|
||||||
"The box is empty",
|
"The box is empty",
|
||||||
style: Theme.of(context).textTheme.subtitle1,
|
style: theme.textTheme.titleMedium,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -37,11 +37,6 @@ class PlaybuttonCard extends HookWidget {
|
|||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
final radius = BorderRadius.circular(15);
|
final radius = BorderRadius.circular(15);
|
||||||
|
|
||||||
final shadowColor = useBrightnessValue(
|
|
||||||
theme.colorScheme.background,
|
|
||||||
theme.colorScheme.background,
|
|
||||||
);
|
|
||||||
|
|
||||||
final double size = useBreakpointValue<double>(
|
final double size = useBreakpointValue<double>(
|
||||||
sm: 130,
|
sm: 130,
|
||||||
md: 150,
|
md: 150,
|
||||||
@ -64,7 +59,7 @@ class PlaybuttonCard extends HookWidget {
|
|||||||
useBrightnessValue(.9, .7),
|
useBrightnessValue(.9, .7),
|
||||||
),
|
),
|
||||||
borderRadius: radius,
|
borderRadius: radius,
|
||||||
shadowColor: shadowColor,
|
shadowColor: theme.colorScheme.background,
|
||||||
elevation: 3,
|
elevation: 3,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
mouseCursor: SystemMouseCursors.click,
|
mouseCursor: SystemMouseCursors.click,
|
||||||
|
@ -91,7 +91,7 @@ class ShimmerPlaybuttonCard extends HookWidget {
|
|||||||
others: const Size(170, 240),
|
others: const Size(170, 240),
|
||||||
);
|
);
|
||||||
|
|
||||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
final isDark = theme.brightness == Brightness.dark;
|
||||||
final bgColor = theme.colorScheme.surfaceVariant.withOpacity(.2);
|
final bgColor = theme.colorScheme.surfaceVariant.withOpacity(.2);
|
||||||
final fgColor = Color.lerp(
|
final fgColor = Color.lerp(
|
||||||
theme.colorScheme.surfaceVariant,
|
theme.colorScheme.surfaceVariant,
|
||||||
|
@ -67,7 +67,8 @@ class ShimmerTrackTile extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
final theme = Theme.of(context);
|
||||||
|
final isDark = theme.brightness == Brightness.dark;
|
||||||
final shimmerTheme = ShimmerColorTheme(
|
final shimmerTheme = ShimmerColorTheme(
|
||||||
shimmerBackgroundColor: isDark ? Colors.grey[700] : Colors.grey[200],
|
shimmerBackgroundColor: isDark ? Colors.grey[700] : Colors.grey[200],
|
||||||
shimmerColor: isDark ? Colors.grey[800] : Colors.grey[300],
|
shimmerColor: isDark ? Colors.grey[800] : Colors.grey[300],
|
||||||
@ -83,9 +84,8 @@ class ShimmerTrackTile extends StatelessWidget {
|
|||||||
size: const Size(double.infinity, 50),
|
size: const Size(double.infinity, 50),
|
||||||
painter: ShimmerTrackTilePainter(
|
painter: ShimmerTrackTilePainter(
|
||||||
background: shimmerTheme.shimmerBackgroundColor ??
|
background: shimmerTheme.shimmerBackgroundColor ??
|
||||||
Theme.of(context).scaffoldBackgroundColor,
|
theme.scaffoldBackgroundColor,
|
||||||
foreground:
|
foreground: shimmerTheme.shimmerColor ?? theme.cardColor,
|
||||||
shimmerTheme.shimmerColor ?? Theme.of(context).cardColor,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -101,9 +101,8 @@ class ShimmerTrackTile extends StatelessWidget {
|
|||||||
size: const Size(double.infinity, 50),
|
size: const Size(double.infinity, 50),
|
||||||
painter: ShimmerTrackTilePainter(
|
painter: ShimmerTrackTilePainter(
|
||||||
background: shimmerTheme.shimmerBackgroundColor ??
|
background: shimmerTheme.shimmerBackgroundColor ??
|
||||||
Theme.of(context).scaffoldBackgroundColor,
|
theme.scaffoldBackgroundColor,
|
||||||
foreground:
|
foreground: shimmerTheme.shimmerColor ?? theme.cardColor,
|
||||||
shimmerTheme.shimmerColor ?? Theme.of(context).cardColor,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -11,9 +11,10 @@ class ThemedButtonsTabBar extends HookWidget implements PreferredSizeWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
final bgColor = useBrightnessValue(
|
final bgColor = useBrightnessValue(
|
||||||
Theme.of(context).colorScheme.primaryContainer,
|
theme.colorScheme.primaryContainer,
|
||||||
Color.lerp(Theme.of(context).colorScheme.primary, Colors.black, 0.7)!,
|
Color.lerp(theme.colorScheme.primary, Colors.black, 0.7)!,
|
||||||
);
|
);
|
||||||
|
|
||||||
final breakpoint = useBreakpointValue(
|
final breakpoint = useBreakpointValue(
|
||||||
@ -34,17 +35,17 @@ class ThemedButtonsTabBar extends HookWidget implements PreferredSizeWidget {
|
|||||||
color: bgColor,
|
color: bgColor,
|
||||||
borderRadius: BorderRadius.circular(15),
|
borderRadius: BorderRadius.circular(15),
|
||||||
),
|
),
|
||||||
labelStyle: Theme.of(context).textTheme.labelLarge?.copyWith(
|
labelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: theme.colorScheme.primary,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
borderWidth: 0,
|
borderWidth: 0,
|
||||||
unselectedDecoration: BoxDecoration(
|
unselectedDecoration: BoxDecoration(
|
||||||
color: Theme.of(context).colorScheme.background,
|
color: theme.colorScheme.background,
|
||||||
borderRadius: BorderRadius.circular(15),
|
borderRadius: BorderRadius.circular(15),
|
||||||
),
|
),
|
||||||
unselectedLabelStyle: Theme.of(context).textTheme.labelLarge?.copyWith(
|
unselectedLabelStyle: theme.textTheme.labelLarge?.copyWith(
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: theme.colorScheme.primary,
|
||||||
),
|
),
|
||||||
tabs: tabs.map((tab) {
|
tabs: tabs.map((tab) {
|
||||||
return Tab(text: " $tab ");
|
return Tab(text: " $tab ");
|
||||||
|
@ -64,6 +64,7 @@ class TrackCollectionView<T> extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
final auth = ref.watch(AuthenticationNotifier.provider);
|
final auth = ref.watch(AuthenticationNotifier.provider);
|
||||||
final color = usePaletteGenerator(
|
final color = usePaletteGenerator(
|
||||||
context,
|
context,
|
||||||
@ -101,7 +102,7 @@ class TrackCollectionView<T> extends HookConsumerWidget {
|
|||||||
// play playlist
|
// play playlist
|
||||||
IconButton(
|
IconButton(
|
||||||
style: IconButton.styleFrom(
|
style: IconButton.styleFrom(
|
||||||
backgroundColor: Theme.of(context).primaryColor,
|
backgroundColor: theme.colorScheme.primary,
|
||||||
),
|
),
|
||||||
onPressed: tracksSnapshot.data != null ? onPlay : null,
|
onPressed: tracksSnapshot.data != null ? onPlay : null,
|
||||||
icon: Icon(isPlaying ? SpotubeIcons.stop : SpotubeIcons.play),
|
icon: Icon(isPlaying ? SpotubeIcons.stop : SpotubeIcons.play),
|
||||||
@ -138,7 +139,7 @@ class TrackCollectionView<T> extends HookConsumerWidget {
|
|||||||
}, [tracksSnapshot.data, searchText.value]);
|
}, [tracksSnapshot.data, searchText.value]);
|
||||||
|
|
||||||
useCustomStatusBarColor(
|
useCustomStatusBarColor(
|
||||||
color?.color ?? Theme.of(context).scaffoldBackgroundColor,
|
color?.color ?? theme.scaffoldBackgroundColor,
|
||||||
GoRouter.of(context).location == routePath,
|
GoRouter.of(context).location == routePath,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -168,7 +169,7 @@ class TrackCollectionView<T> extends HookConsumerWidget {
|
|||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: "Search tracks...",
|
hintText: "Search tracks...",
|
||||||
hintStyle: TextStyle(color: color?.titleTextColor),
|
hintStyle: TextStyle(color: color?.titleTextColor),
|
||||||
border: Theme.of(context).inputDecorationTheme.border?.copyWith(
|
border: theme.inputDecorationTheme.border?.copyWith(
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: color?.titleTextColor ?? Colors.white,
|
color: color?.titleTextColor ?? Colors.white,
|
||||||
),
|
),
|
||||||
@ -228,8 +229,7 @@ class TrackCollectionView<T> extends HookConsumerWidget {
|
|||||||
title: collapsed.value
|
title: collapsed.value
|
||||||
? Text(
|
? Text(
|
||||||
title,
|
title,
|
||||||
style:
|
style: theme.textTheme.titleLarge!.copyWith(
|
||||||
Theme.of(context).textTheme.titleLarge!.copyWith(
|
|
||||||
color: color?.titleTextColor,
|
color: color?.titleTextColor,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
),
|
),
|
||||||
@ -242,7 +242,7 @@ class TrackCollectionView<T> extends HookConsumerWidget {
|
|||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
colors: [
|
colors: [
|
||||||
color?.color ?? Colors.transparent,
|
color?.color ?? Colors.transparent,
|
||||||
Theme.of(context).canvasColor,
|
theme.canvasColor,
|
||||||
],
|
],
|
||||||
begin: const FractionalOffset(0, 0),
|
begin: const FractionalOffset(0, 0),
|
||||||
end: const FractionalOffset(0, 1),
|
end: const FractionalOffset(0, 1),
|
||||||
@ -282,10 +282,7 @@ class TrackCollectionView<T> extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
title,
|
title,
|
||||||
style: Theme.of(context)
|
style: theme.textTheme.titleLarge!.copyWith(
|
||||||
.textTheme
|
|
||||||
.titleLarge!
|
|
||||||
.copyWith(
|
|
||||||
color: color?.titleTextColor,
|
color: color?.titleTextColor,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
),
|
),
|
||||||
|
@ -174,6 +174,7 @@ class TrackTile extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final toggler = useTrackToggleLike(track.value, ref);
|
final toggler = useTrackToggleLike(track.value, ref);
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
|
||||||
return AnimatedContainer(
|
return AnimatedContainer(
|
||||||
duration: const Duration(milliseconds: 500),
|
duration: const Duration(milliseconds: 500),
|
||||||
@ -181,7 +182,7 @@ class TrackTile extends HookConsumerWidget {
|
|||||||
color: isBlackListed
|
color: isBlackListed
|
||||||
? Colors.red[100]
|
? Colors.red[100]
|
||||||
: isActive
|
: isActive
|
||||||
? Theme.of(context).popupMenuTheme.color
|
? theme.popupMenuTheme.color
|
||||||
: Colors.transparent,
|
: Colors.transparent,
|
||||||
borderRadius: BorderRadius.circular(isActive ? 10 : 0),
|
borderRadius: BorderRadius.circular(isActive ? 10 : 0),
|
||||||
),
|
),
|
||||||
@ -234,8 +235,8 @@ class TrackTile extends HookConsumerWidget {
|
|||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
style: IconButton.styleFrom(
|
style: IconButton.styleFrom(
|
||||||
backgroundColor: Theme.of(context).primaryColor,
|
backgroundColor: theme.colorScheme.primary,
|
||||||
hoverColor: Theme.of(context).primaryColor.withOpacity(0.5),
|
hoverColor: theme.colorScheme.primary.withOpacity(0.5),
|
||||||
),
|
),
|
||||||
onPressed: !isBlackListed
|
onPressed: !isBlackListed
|
||||||
? () => onTrackPlayButtonPressed?.call(
|
? () => onTrackPlayButtonPressed?.call(
|
||||||
|
@ -33,7 +33,8 @@ class ArtistPage extends HookConsumerWidget {
|
|||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
SpotifyApi spotify = ref.watch(spotifyProvider);
|
SpotifyApi spotify = ref.watch(spotifyProvider);
|
||||||
final parentScrollController = useScrollController();
|
final parentScrollController = useScrollController();
|
||||||
final textTheme = Theme.of(context).textTheme;
|
final theme = Theme.of(context);
|
||||||
|
final textTheme = theme.textTheme;
|
||||||
final chipTextVariant = useBreakpointValue(
|
final chipTextVariant = useBreakpointValue(
|
||||||
sm: textTheme.bodySmall,
|
sm: textTheme.bodySmall,
|
||||||
md: textTheme.bodyMedium,
|
md: textTheme.bodyMedium,
|
||||||
@ -42,12 +43,14 @@ class ArtistPage extends HookConsumerWidget {
|
|||||||
xxl: textTheme.titleMedium,
|
xxl: textTheme.titleMedium,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final mediaQuery = MediaQuery.of(context);
|
||||||
|
|
||||||
final avatarWidth = useBreakpointValue(
|
final avatarWidth = useBreakpointValue(
|
||||||
sm: MediaQuery.of(context).size.width * 0.50,
|
sm: mediaQuery.size.width * 0.50,
|
||||||
md: MediaQuery.of(context).size.width * 0.40,
|
md: mediaQuery.size.width * 0.40,
|
||||||
lg: MediaQuery.of(context).size.width * 0.18,
|
lg: mediaQuery.size.width * 0.18,
|
||||||
xl: MediaQuery.of(context).size.width * 0.18,
|
xl: mediaQuery.size.width * 0.18,
|
||||||
xxl: MediaQuery.of(context).size.width * 0.18,
|
xxl: mediaQuery.size.width * 0.18,
|
||||||
);
|
);
|
||||||
|
|
||||||
final breakpoint = useBreakpoints();
|
final breakpoint = useBreakpoints();
|
||||||
@ -316,8 +319,7 @@ class ArtistPage extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Top Tracks",
|
"Top Tracks",
|
||||||
style:
|
style: theme.textTheme.headlineSmall,
|
||||||
Theme.of(context).textTheme.headlineSmall,
|
|
||||||
),
|
),
|
||||||
if (!isPlaylistPlaying)
|
if (!isPlaylistPlaying)
|
||||||
IconButton(
|
IconButton(
|
||||||
@ -347,8 +349,7 @@ class ArtistPage extends HookConsumerWidget {
|
|||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
style: IconButton.styleFrom(
|
style: IconButton.styleFrom(
|
||||||
backgroundColor:
|
backgroundColor: theme.colorScheme.primary,
|
||||||
Theme.of(context).primaryColor,
|
|
||||||
),
|
),
|
||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
playPlaylist(topTracks.toList()),
|
playPlaylist(topTracks.toList()),
|
||||||
@ -377,14 +378,14 @@ class ArtistPage extends HookConsumerWidget {
|
|||||||
const SizedBox(height: 50),
|
const SizedBox(height: 50),
|
||||||
Text(
|
Text(
|
||||||
"Albums",
|
"Albums",
|
||||||
style: Theme.of(context).textTheme.headlineSmall,
|
style: theme.textTheme.headlineSmall,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
ArtistAlbumList(artistId),
|
ArtistAlbumList(artistId),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
Text(
|
Text(
|
||||||
"Fans also likes",
|
"Fans also likes",
|
||||||
style: Theme.of(context).textTheme.headlineSmall,
|
style: theme.textTheme.headlineSmall,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
HookBuilder(
|
HookBuilder(
|
||||||
|
@ -13,6 +13,8 @@ class DesktopLoginPage extends HookConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
final breakpoint = useBreakpoints();
|
final breakpoint = useBreakpoints();
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
final color = theme.colorScheme.surfaceVariant.withOpacity(.3);
|
||||||
|
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
@ -25,7 +27,7 @@ class DesktopLoginPage extends HookConsumerWidget {
|
|||||||
margin: const EdgeInsets.all(10),
|
margin: const EdgeInsets.all(10),
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).cardColor,
|
color: color,
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -36,11 +38,11 @@ class DesktopLoginPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
"Add your spotify credentials to get started",
|
"Add your spotify credentials to get started",
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
style: theme.textTheme.titleMedium,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
"Don't worry, any of your credentials won't be collected or shared with anyone",
|
"Don't worry, any of your credentials won't be collected or shared with anyone",
|
||||||
style: Theme.of(context).textTheme.labelMedium,
|
style: theme.textTheme.labelMedium,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
TokenLoginForm(
|
TokenLoginForm(
|
||||||
|
@ -19,10 +19,11 @@ class LoginTutorial extends ConsumerWidget {
|
|||||||
final authenticationNotifier =
|
final authenticationNotifier =
|
||||||
ref.watch(AuthenticationNotifier.provider.notifier);
|
ref.watch(AuthenticationNotifier.provider.notifier);
|
||||||
final key = GlobalKey<State<IntroductionScreen>>();
|
final key = GlobalKey<State<IntroductionScreen>>();
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
|
||||||
final pageDecoration = PageDecoration(
|
final pageDecoration = PageDecoration(
|
||||||
bodyTextStyle: Theme.of(context).textTheme.bodyMedium!,
|
bodyTextStyle: theme.textTheme.bodyMedium!,
|
||||||
titleTextStyle: Theme.of(context).textTheme.headlineMedium!,
|
titleTextStyle: theme.textTheme.headlineMedium!,
|
||||||
);
|
);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: PageWindowTitleBar(
|
appBar: PageWindowTitleBar(
|
||||||
@ -35,7 +36,7 @@ class LoginTutorial extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
body: IntroductionScreen(
|
body: IntroductionScreen(
|
||||||
key: key,
|
key: key,
|
||||||
globalBackgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
globalBackgroundColor: theme.scaffoldBackgroundColor,
|
||||||
overrideBack: OutlinedButton(
|
overrideBack: OutlinedButton(
|
||||||
child: const Center(child: Text("Previous")),
|
child: const Center(child: Text("Previous")),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -113,7 +114,7 @@ class LoginTutorial extends ConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Paste the copied \"sp_dc\" and \"sp_key\" values in the respective fields",
|
"Paste the copied \"sp_dc\" and \"sp_key\" values in the respective fields",
|
||||||
style: Theme.of(context).textTheme.labelMedium,
|
style: theme.textTheme.labelMedium,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
TokenLoginForm(
|
TokenLoginForm(
|
||||||
|
@ -28,6 +28,7 @@ class PlayerView extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
final currentTrack = ref.watch(PlaylistQueueNotifier.provider.select(
|
final currentTrack = ref.watch(PlaylistQueueNotifier.provider.select(
|
||||||
(value) => value?.activeTrack,
|
(value) => value?.activeTrack,
|
||||||
));
|
));
|
||||||
@ -94,10 +95,7 @@ class PlayerView extends HookConsumerWidget {
|
|||||||
height: 30,
|
height: 30,
|
||||||
child: Text(
|
child: Text(
|
||||||
currentTrack?.name ?? "Not playing",
|
currentTrack?.name ?? "Not playing",
|
||||||
style: Theme.of(context)
|
style: theme.textTheme.headlineSmall?.copyWith(
|
||||||
.textTheme
|
|
||||||
.headlineSmall
|
|
||||||
?.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: paletteColor.titleTextColor,
|
color: paletteColor.titleTextColor,
|
||||||
),
|
),
|
||||||
@ -108,10 +106,7 @@ class PlayerView extends HookConsumerWidget {
|
|||||||
TypeConversionUtils.artists_X_String<Artist>(
|
TypeConversionUtils.artists_X_String<Artist>(
|
||||||
currentTrack?.artists ?? [],
|
currentTrack?.artists ?? [],
|
||||||
),
|
),
|
||||||
style: Theme.of(context)
|
style: theme.textTheme.titleLarge!.copyWith(
|
||||||
.textTheme
|
|
||||||
.titleLarge!
|
|
||||||
.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: paletteColor.bodyTextColor,
|
color: paletteColor.bodyTextColor,
|
||||||
),
|
),
|
||||||
@ -119,10 +114,7 @@ class PlayerView extends HookConsumerWidget {
|
|||||||
else
|
else
|
||||||
TypeConversionUtils.artists_X_ClickableArtists(
|
TypeConversionUtils.artists_X_ClickableArtists(
|
||||||
currentTrack?.artists ?? [],
|
currentTrack?.artists ?? [],
|
||||||
textStyle: Theme.of(context)
|
textStyle: theme.textTheme.titleLarge!.copyWith(
|
||||||
.textTheme
|
|
||||||
.titleLarge!
|
|
||||||
.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: paletteColor.bodyTextColor,
|
color: paletteColor.bodyTextColor,
|
||||||
),
|
),
|
||||||
|
@ -33,6 +33,7 @@ class SearchPage extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
ref.watch(AuthenticationNotifier.provider);
|
ref.watch(AuthenticationNotifier.provider);
|
||||||
final authenticationNotifier =
|
final authenticationNotifier =
|
||||||
ref.watch(AuthenticationNotifier.provider.notifier);
|
ref.watch(AuthenticationNotifier.provider.notifier);
|
||||||
@ -74,7 +75,7 @@ class SearchPage extends HookConsumerWidget {
|
|||||||
horizontal: 20,
|
horizontal: 20,
|
||||||
vertical: 10,
|
vertical: 10,
|
||||||
),
|
),
|
||||||
color: Theme.of(context).scaffoldBackgroundColor,
|
color: theme.scaffoldBackgroundColor,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
prefixIcon: Icon(SpotubeIcons.search),
|
prefixIcon: Icon(SpotubeIcons.search),
|
||||||
@ -134,9 +135,7 @@ class SearchPage extends HookConsumerWidget {
|
|||||||
if (tracks.isNotEmpty)
|
if (tracks.isNotEmpty)
|
||||||
Text(
|
Text(
|
||||||
"Songs",
|
"Songs",
|
||||||
style: Theme.of(context)
|
style: theme.textTheme.titleLarge!,
|
||||||
.textTheme
|
|
||||||
.titleLarge!,
|
|
||||||
),
|
),
|
||||||
if (searchTrack.isLoadingPage)
|
if (searchTrack.isLoadingPage)
|
||||||
const CircularProgressIndicator()
|
const CircularProgressIndicator()
|
||||||
@ -198,9 +197,7 @@ class SearchPage extends HookConsumerWidget {
|
|||||||
if (playlists.isNotEmpty)
|
if (playlists.isNotEmpty)
|
||||||
Text(
|
Text(
|
||||||
"Playlists",
|
"Playlists",
|
||||||
style: Theme.of(context)
|
style: theme.textTheme.titleLarge!,
|
||||||
.textTheme
|
|
||||||
.titleLarge!,
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
ScrollConfiguration(
|
ScrollConfiguration(
|
||||||
@ -258,9 +255,7 @@ class SearchPage extends HookConsumerWidget {
|
|||||||
if (artists.isNotEmpty)
|
if (artists.isNotEmpty)
|
||||||
Text(
|
Text(
|
||||||
"Artists",
|
"Artists",
|
||||||
style: Theme.of(context)
|
style: theme.textTheme.titleLarge!,
|
||||||
.textTheme
|
|
||||||
.titleLarge!,
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
ScrollConfiguration(
|
ScrollConfiguration(
|
||||||
@ -317,9 +312,7 @@ class SearchPage extends HookConsumerWidget {
|
|||||||
if (albums.isNotEmpty)
|
if (albums.isNotEmpty)
|
||||||
Text(
|
Text(
|
||||||
"Albums",
|
"Albums",
|
||||||
style: Theme.of(context)
|
style: theme.textTheme.titleMedium!,
|
||||||
.textTheme
|
|
||||||
.titleMedium!,
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
ScrollConfiguration(
|
ScrollConfiguration(
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:spotube/collections/assets.gen.dart';
|
import 'package:spotube/collections/assets.gen.dart';
|
||||||
import 'package:spotube/components/shared/image/universal_image.dart';
|
import 'package:spotube/components/shared/image/universal_image.dart';
|
||||||
import 'package:spotube/components/shared/page_window_title_bar.dart';
|
import 'package:spotube/components/shared/page_window_title_bar.dart';
|
||||||
@ -9,12 +10,18 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:url_launcher/url_launcher_string.dart';
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
|
final _licenseProvider = FutureProvider<String>((ref) async {
|
||||||
|
return await rootBundle.loadString("LICENSE");
|
||||||
|
});
|
||||||
|
|
||||||
class AboutSpotube extends HookConsumerWidget {
|
class AboutSpotube extends HookConsumerWidget {
|
||||||
const AboutSpotube({Key? key}) : super(key: key);
|
const AboutSpotube({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
final packageInfo = usePackageInfo();
|
final packageInfo = usePackageInfo();
|
||||||
|
final license = ref.watch(_licenseProvider);
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: const PageWindowTitleBar(
|
appBar: const PageWindowTitleBar(
|
||||||
@ -36,7 +43,7 @@ class AboutSpotube extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Spotube, a light-weight, cross-platform, free-for-all spotify client",
|
"Spotube, a light-weight, cross-platform, free-for-all spotify client",
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
style: theme.textTheme.titleLarge,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
Row(
|
Row(
|
||||||
@ -181,21 +188,35 @@ class AboutSpotube extends HookConsumerWidget {
|
|||||||
Text(
|
Text(
|
||||||
"Made with ❤️ in Bangladesh🇧🇩",
|
"Made with ❤️ in Bangladesh🇧🇩",
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: Theme.of(context).textTheme.bodySmall,
|
style: theme.textTheme.bodySmall,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
"© 2021-${DateTime.now().year} Kingkor Roy Tirtho",
|
"© 2021-${DateTime.now().year} Kingkor Roy Tirtho",
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: Theme.of(context).textTheme.bodySmall,
|
style: theme.textTheme.bodySmall,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
ConstrainedBox(
|
ConstrainedBox(
|
||||||
constraints: const BoxConstraints(maxWidth: 750),
|
constraints: const BoxConstraints(maxWidth: 750),
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
child: Text(
|
child: license.when(
|
||||||
licenseText,
|
data: (data) {
|
||||||
textAlign: TextAlign.justify,
|
return Text(
|
||||||
style: Theme.of(context).textTheme.bodySmall,
|
data,
|
||||||
|
style: theme.textTheme.bodySmall,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
loading: () {
|
||||||
|
return const Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
error: (e, s) {
|
||||||
|
return Text(
|
||||||
|
e.toString(),
|
||||||
|
style: theme.textTheme.bodySmall,
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -206,18 +227,3 @@ class AboutSpotube extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const licenseText = """
|
|
||||||
BSD-4-Clause License
|
|
||||||
|
|
||||||
Copyright (c) 2022 Kingkor Roy Tirtho. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
||||||
3. All advertising materials mentioning features or use of this software must display the following acknowledgement:
|
|
||||||
This product includes software developed by Kingkor Roy Tirtho.
|
|
||||||
4. Neither the name of the Software nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
||||||
THIS SOFTWARE IS PROVIDED BY KINGKOR ROY TIRTHO AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KINGKOR ROY TIRTHO AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
""";
|
|
||||||
|
@ -21,6 +21,7 @@ class SettingsPage extends HookConsumerWidget {
|
|||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
final UserPreferences preferences = ref.watch(userPreferencesProvider);
|
final UserPreferences preferences = ref.watch(userPreferencesProvider);
|
||||||
final auth = ref.watch(AuthenticationNotifier.provider);
|
final auth = ref.watch(AuthenticationNotifier.provider);
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
|
||||||
final pickColorScheme = useCallback((ColorSchemeType schemeType) {
|
final pickColorScheme = useCallback((ColorSchemeType schemeType) {
|
||||||
return () => showDialog(
|
return () => showDialog(
|
||||||
@ -57,16 +58,14 @@ class SettingsPage extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
" Account",
|
" Account",
|
||||||
style: Theme.of(context)
|
style: theme.textTheme.headlineSmall
|
||||||
.textTheme
|
|
||||||
.headlineSmall
|
|
||||||
?.copyWith(fontWeight: FontWeight.bold),
|
?.copyWith(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
if (auth == null)
|
if (auth == null)
|
||||||
AdaptiveListTile(
|
AdaptiveListTile(
|
||||||
leading: Icon(
|
leading: Icon(
|
||||||
SpotubeIcons.login,
|
SpotubeIcons.login,
|
||||||
color: Theme.of(context).primaryColor,
|
color: theme.colorScheme.primary,
|
||||||
),
|
),
|
||||||
title: SizedBox(
|
title: SizedBox(
|
||||||
height: 50,
|
height: 50,
|
||||||
@ -77,7 +76,7 @@ class SettingsPage extends HookConsumerWidget {
|
|||||||
"Login with your Spotify account",
|
"Login with your Spotify account",
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).primaryColor,
|
color: theme.colorScheme.primary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -131,9 +130,7 @@ class SettingsPage extends HookConsumerWidget {
|
|||||||
}),
|
}),
|
||||||
Text(
|
Text(
|
||||||
" Appearance",
|
" Appearance",
|
||||||
style: Theme.of(context)
|
style: theme.textTheme.headlineSmall
|
||||||
.textTheme
|
|
||||||
.headlineSmall
|
|
||||||
?.copyWith(fontWeight: FontWeight.bold),
|
?.copyWith(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
AdaptiveListTile(
|
AdaptiveListTile(
|
||||||
@ -217,9 +214,7 @@ class SettingsPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
" Playback",
|
" Playback",
|
||||||
style: Theme.of(context)
|
style: theme.textTheme.headlineSmall
|
||||||
.textTheme
|
|
||||||
.headlineSmall
|
|
||||||
?.copyWith(fontWeight: FontWeight.bold),
|
?.copyWith(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
AdaptiveListTile(
|
AdaptiveListTile(
|
||||||
@ -279,9 +274,7 @@ class SettingsPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
" Search",
|
" Search",
|
||||||
style: Theme.of(context)
|
style: theme.textTheme.headlineSmall
|
||||||
.textTheme
|
|
||||||
.headlineSmall
|
|
||||||
?.copyWith(fontWeight: FontWeight.bold),
|
?.copyWith(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
AdaptiveListTile(
|
AdaptiveListTile(
|
||||||
@ -312,9 +305,7 @@ class SettingsPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
" Downloads",
|
" Downloads",
|
||||||
style: Theme.of(context)
|
style: theme.textTheme.headlineSmall
|
||||||
.textTheme
|
|
||||||
.headlineSmall
|
|
||||||
?.copyWith(fontWeight: FontWeight.bold),
|
?.copyWith(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
@ -337,9 +328,7 @@ class SettingsPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
" About",
|
" About",
|
||||||
style: Theme.of(context)
|
style: theme.textTheme.headlineSmall
|
||||||
.textTheme
|
|
||||||
.headlineSmall
|
|
||||||
?.copyWith(fontWeight: FontWeight.bold),
|
?.copyWith(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
AdaptiveListTile(
|
AdaptiveListTile(
|
||||||
|
@ -102,6 +102,7 @@ flutter:
|
|||||||
- assets/
|
- assets/
|
||||||
- assets/tutorial/
|
- assets/tutorial/
|
||||||
- .env
|
- .env
|
||||||
|
- LICENSE
|
||||||
|
|
||||||
flutter_icons:
|
flutter_icons:
|
||||||
android: true
|
android: true
|
||||||
|
Loading…
Reference in New Issue
Block a user