High Constrast color scheme support added

Download button shows done if already downloaded
Search TextField design improved
This commit is contained in:
Kingkor Roy Tirtho 2022-07-09 02:19:27 +06:00
parent 3702e29135
commit ff4e5df44c
5 changed files with 95 additions and 47 deletions

View File

@ -5,6 +5,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
import 'package:spotube/components/Shared/NotFound.dart';
import 'package:spotube/components/Shared/SpotubeMarqueeText.dart';
import 'package:spotube/components/Shared/TrackTile.dart';
import 'package:spotube/helpers/image-to-url-string.dart';
import 'package:spotube/helpers/zero-pad-num-str.dart';
@ -48,6 +49,9 @@ class PlayerQueue extends HookConsumerWidget {
return null;
}, []);
var titleStyle = Theme.of(context).textTheme.headline4?.copyWith(
fontWeight: FontWeight.bold,
);
return BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 12.0,
@ -76,12 +80,17 @@ class PlayerQueue extends HookConsumerWidget {
borderRadius: BorderRadius.circular(20),
),
),
Text(
"Queue (${playback.playlist?.name})",
style: Theme.of(context).textTheme.headline4?.copyWith(
fontWeight: FontWeight.bold,
),
Text("Queue", style: titleStyle),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
playback.playlist?.name ?? "",
overflow: TextOverflow.ellipsis,
style: Theme.of(context)
.textTheme
.bodyText1
?.copyWith(fontWeight: FontWeight.bold),
),
),
const SizedBox(height: 10),
Flexible(

View File

@ -43,36 +43,30 @@ class Search extends HookConsumerWidget {
color: Theme.of(context).backgroundColor,
child: Column(
children: [
Padding(
Container(
padding:
const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
child: Row(
children: [
Expanded(
color: Theme.of(context).backgroundColor,
child: Expanded(
child: TextField(
controller: controller,
decoration:
const InputDecoration(hintText: "Search..."),
onSubmitted: (value) {
ref.read(searchTermStateProvider.notifier).state =
controller.value.text;
},
),
),
const SizedBox(width: 5),
MaterialButton(
elevation: 3,
splashColor: Theme.of(context).primaryColor,
padding: const EdgeInsets.symmetric(vertical: 21),
color: Theme.of(context).primaryColor,
textColor: Colors.white,
decoration: InputDecoration(
isDense: true,
suffix: ElevatedButton(
child: const Icon(Icons.search_rounded),
onPressed: () {
ref.read(searchTermStateProvider.notifier).state =
controller.value.text;
},
),
],
hintStyle: const TextStyle(height: 2),
hintText: "Search...",
),
onSubmitted: (value) {
ref.read(searchTermStateProvider.notifier).state =
controller.value.text;
},
),
),
),
searchSnapshot.when(

View File

@ -3,6 +3,23 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotube/provider/UserPreferences.dart';
final highContrast = MaterialColor(
const Color.fromARGB(255, 104, 104, 104).value,
const {
50: Colors.white,
100: Color.fromARGB(255, 233, 233, 233),
200: Color.fromARGB(255, 224, 219, 219),
300: Color.fromARGB(255, 207, 207, 207),
400: Color.fromARGB(255, 146, 146, 146),
500: Color.fromARGB(255, 104, 104, 104),
600: Color.fromARGB(255, 78, 78, 78),
700: Color.fromARGB(255, 61, 61, 61),
800: Color.fromARGB(255, 27, 27, 27),
850: Color.fromARGB(255, 20, 20, 20),
900: Colors.black,
},
);
final colorsMap = {
"Red": Colors.red,
"Pink": Colors.pink,
@ -23,6 +40,7 @@ final colorsMap = {
"Brown": Colors.brown,
"BlueGrey": Colors.blueGrey,
"Grey": Colors.grey,
"HighContrast": highContrast,
};
enum ColorSchemeType {

View File

@ -29,8 +29,29 @@ class DownloadTrackButton extends HookConsumerWidget {
final status = useState<TrackStatus>(TrackStatus.idle);
YoutubeExplode yt = useMemoized(() => YoutubeExplode());
final outputFile = useState<File?>(null);
final downloadFolder = useState<String?>(null);
String fileName =
"${track?.name} - ${artistsToString<Artist>(track?.artists ?? [])}";
useEffect(() {
(() async {
downloadFolder.value = path.join(
Platform.isAndroid
? "/storage/emulated/0/Download"
: (await path_provider.getDownloadsDirectory())!.path,
"Spotube");
outputFile.value =
File(path.join(downloadFolder.value!, "$fileName.mp3"));
}());
return null;
}, [fileName, track]);
final _downloadTrack = useCallback(() async {
if (track == null) return;
if (track == null ||
outputFile.value == null ||
downloadFolder.value == null) return;
if ((kIsMobile) &&
!await Permission.storage.isGranted &&
!await Permission.storage.isPermanentlyDenied) {
@ -47,18 +68,10 @@ class DownloadTrackButton extends HookConsumerWidget {
StreamManifest manifest = await yt.videos.streamsClient
.getManifest((track as SpotubeTrack).ytTrack.url);
String downloadFolder = path.join(
Platform.isAndroid
? "/storage/emulated/0/Download"
: (await path_provider.getDownloadsDirectory())!.path,
"Spotube");
String fileName =
"${track?.name} - ${artistsToString<Artist>(track?.artists ?? [])}";
File outputFile = File(path.join(downloadFolder, "$fileName.mp3"));
File outputLyricsFile =
File(path.join(downloadFolder, "$fileName-lyrics.txt"));
File(path.join(downloadFolder.value!, "$fileName-lyrics.txt"));
if (await outputFile.exists()) {
if (await outputFile.value!.exists()) {
final shouldReplace = await showDialog<bool>(
context: context,
builder: (context) {
@ -113,9 +126,11 @@ class DownloadTrackButton extends HookConsumerWidget {
},
);
if (!await outputFile.exists()) await outputFile.create(recursive: true);
if (!await outputFile.value!.exists()) {
await outputFile.value!.create(recursive: true);
}
IOSink outputFileStream = outputFile.openWrite();
IOSink outputFileStream = outputFile.value!.openWrite();
await audioStream.pipe(outputFileStream);
await outputFileStream.flush();
await outputFileStream.close().then((value) async {
@ -157,12 +172,20 @@ class DownloadTrackButton extends HookConsumerWidget {
yt,
preferences.saveTrackLyrics,
playback.track,
outputFile.value,
downloadFolder.value,
fileName
]);
useEffect(() {
return () => yt.close();
}, []);
final outputFileExists = useMemoized(
() => outputFile.value?.existsSync() == true,
[outputFile.value, status.value, track],
);
if (status.value == TrackStatus.downloading) {
return const SizedBox(
child: CircularProgressIndicator.adaptive(
@ -175,7 +198,9 @@ class DownloadTrackButton extends HookConsumerWidget {
return const Icon(Icons.download_done_rounded);
}
return IconButton(
icon: const Icon(Icons.download_rounded),
icon: Icon(
outputFileExists ? Icons.download_done_rounded : Icons.download_rounded,
),
onPressed: track != null && track is SpotubeTrack ? _downloadTrack : null,
);
}

View File

@ -29,6 +29,7 @@ class PlaybuttonCard extends StatelessWidget {
margin: margin,
child: InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(8),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 200),
child: Ink(
@ -40,7 +41,8 @@ class PlaybuttonCard extends StatelessWidget {
blurRadius: 10,
offset: const Offset(0, 3),
spreadRadius: 5,
color: Theme.of(context).shadowColor)
color: Theme.of(context).shadowColor,
)
],
),
child: Column(