mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-14 16:25:16 +00:00
feat: failsafe pocketbase requests, removal of unneeded preferences options & vertical playbutton actions
This commit is contained in:
parent
ee46d0970b
commit
d68d150d3f
@ -142,13 +142,13 @@ class PlaybuttonCard extends HookWidget {
|
||||
textDirection: TextDirection.ltr,
|
||||
bottom: 10,
|
||||
end: 5,
|
||||
child: Row(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
if (!isPlaying) addToQueueButton,
|
||||
if (platform != TargetPlatform.linux)
|
||||
const SizedBox(width: 5),
|
||||
const SizedBox(height: 5),
|
||||
playButton,
|
||||
],
|
||||
),
|
||||
|
@ -1,7 +1,9 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:catcher/catcher.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||
import 'package:pocketbase/pocketbase.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/extensions/video.dart';
|
||||
import 'package:spotube/extensions/album_simple.dart';
|
||||
@ -65,7 +67,7 @@ class SpotubeTrack extends Track {
|
||||
uri = track.uri;
|
||||
}
|
||||
|
||||
static Future<SpotubeTrack> fromFetchTrack(
|
||||
static Future<SpotubeTrack> fetchFromTrack(
|
||||
Track track, UserPreferences preferences) async {
|
||||
final artists = (track.artists ?? [])
|
||||
.map((ar) => ar.name)
|
||||
@ -79,16 +81,17 @@ class SpotubeTrack extends Track {
|
||||
onlyCleanArtist: true,
|
||||
).trim();
|
||||
|
||||
final cachedTracks = await pb.collection(BackendTrack.collection).getList(
|
||||
filter: "spotify_id = '${track.id}'",
|
||||
sort: "-votes",
|
||||
page: 0,
|
||||
perPage: 1,
|
||||
);
|
||||
final cachedTracks = await Future<RecordModel?>.value(
|
||||
pb
|
||||
.collection(BackendTrack.collection)
|
||||
.getFirstListItem("spotify_id = '${track.id}'"),
|
||||
).catchError((e, stack) {
|
||||
Catcher.reportCheckedError(e, stack);
|
||||
return null;
|
||||
});
|
||||
|
||||
final cachedTrack = cachedTracks.items.isNotEmpty
|
||||
? BackendTrack.fromRecord(cachedTracks.items.first)
|
||||
: null;
|
||||
final cachedTrack =
|
||||
cachedTracks != null ? BackendTrack.fromRecord(cachedTracks) : null;
|
||||
|
||||
Video ytVideo;
|
||||
List<Video> siblings = [];
|
||||
@ -127,13 +130,17 @@ class SpotubeTrack extends Track {
|
||||
final ytUri = chosenStreamInfo.url.toString();
|
||||
|
||||
if (cachedTrack == null) {
|
||||
await pb.collection(BackendTrack.collection).create(
|
||||
body: BackendTrack(
|
||||
spotifyId: track.id!,
|
||||
youtubeId: ytVideo.id.value,
|
||||
votes: 0,
|
||||
).toJson(),
|
||||
);
|
||||
await Future<RecordModel?>.value(
|
||||
pb.collection(BackendTrack.collection).create(
|
||||
body: BackendTrack(
|
||||
spotifyId: track.id!,
|
||||
youtubeId: ytVideo.id.value,
|
||||
votes: 0,
|
||||
).toJson(),
|
||||
)).catchError((e, stack) {
|
||||
Catcher.reportCheckedError(e, stack);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
if (preferences.predownload &&
|
||||
@ -205,32 +212,38 @@ class SpotubeTrack extends Track {
|
||||
|
||||
final ytUri = chosenStreamInfo.url.toString();
|
||||
|
||||
final cachedTracks = await pb.collection(BackendTrack.collection).getList(
|
||||
filter: "spotify_id = '$id' && youtube_id = '${video.id.value}'",
|
||||
sort: "-votes",
|
||||
page: 0,
|
||||
perPage: 1,
|
||||
);
|
||||
final cachedTracks = await Future<RecordModel?>.value(
|
||||
pb.collection(BackendTrack.collection).getFirstListItem(
|
||||
"spotify_id = '$id' && youtube_id = '${video.id.value}'"),
|
||||
).catchError((e, stack) {
|
||||
Catcher.reportCheckedError(e, stack);
|
||||
return null;
|
||||
});
|
||||
|
||||
final cachedTrack = cachedTracks.items.isNotEmpty
|
||||
? BackendTrack.fromRecord(cachedTracks.items.first)
|
||||
: null;
|
||||
final cachedTrack =
|
||||
cachedTracks != null ? BackendTrack.fromRecord(cachedTracks) : null;
|
||||
|
||||
if (cachedTrack == null) {
|
||||
await pb.collection(BackendTrack.collection).create(
|
||||
body: BackendTrack(
|
||||
spotifyId: id!,
|
||||
youtubeId: video.id.value,
|
||||
votes: 1,
|
||||
).toJson(),
|
||||
);
|
||||
await Future<RecordModel?>.value(
|
||||
pb.collection(BackendTrack.collection).create(
|
||||
body: BackendTrack(
|
||||
spotifyId: id!,
|
||||
youtubeId: video.id.value,
|
||||
votes: 1,
|
||||
).toJson(),
|
||||
)).catchError((e, stack) {
|
||||
Catcher.reportCheckedError(e, stack);
|
||||
return null;
|
||||
});
|
||||
} else {
|
||||
await pb.collection(BackendTrack.collection).update(
|
||||
await Future<RecordModel?>.value(
|
||||
pb.collection(BackendTrack.collection).update(
|
||||
cachedTrack.id,
|
||||
body: {
|
||||
"votes": cachedTrack.votes + 1,
|
||||
},
|
||||
);
|
||||
body: {"votes": cachedTrack.votes + 1},
|
||||
)).catchError((e, stack) {
|
||||
Catcher.reportCheckedError(e, stack);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
if (preferences.predownload &&
|
||||
|
@ -9,10 +9,8 @@ import 'package:spotube/collections/spotube_icons.dart';
|
||||
import 'package:spotube/components/settings/color_scheme_picker_dialog.dart';
|
||||
import 'package:spotube/components/shared/adaptive/adaptive_list_tile.dart';
|
||||
import 'package:spotube/components/shared/page_window_title_bar.dart';
|
||||
import 'package:spotube/hooks/use_breakpoints.dart';
|
||||
import 'package:spotube/main.dart';
|
||||
import 'package:spotube/collections/spotify_markets.dart';
|
||||
import 'package:spotube/models/spotube_track.dart';
|
||||
import 'package:spotube/provider/auth_provider.dart';
|
||||
import 'package:spotube/provider/user_preferences_provider.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
@ -41,10 +39,6 @@ class SettingsPage extends HookConsumerWidget {
|
||||
preferences.setDownloadLocation(dirStr);
|
||||
}, [preferences.downloadLocation]);
|
||||
|
||||
var ytSearchFormatController = useTextEditingController(
|
||||
text: preferences.ytSearchFormat,
|
||||
);
|
||||
|
||||
return SafeArea(
|
||||
child: PlatformScaffold(
|
||||
appBar: PageWindowTitleBar(
|
||||
@ -379,83 +373,6 @@ class SettingsPage extends HookConsumerWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
AdaptiveListTile(
|
||||
leading: const Icon(SpotubeIcons.screenSearch),
|
||||
title: const SizedBox(
|
||||
height: 50,
|
||||
width: 200,
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: AutoSizeText(
|
||||
"Format of the YouTube Search term",
|
||||
maxLines: 2,
|
||||
),
|
||||
),
|
||||
),
|
||||
subtitle: const PlatformText("(Case sensitive)"),
|
||||
breakOn: Breakpoints.lg,
|
||||
trailing: (context, update) => ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 450),
|
||||
child: PlatformTextField(
|
||||
controller: ytSearchFormatController,
|
||||
suffix: PlatformFilledButton(
|
||||
child: const Icon(SpotubeIcons.save),
|
||||
onPressed: () {
|
||||
preferences.setYtSearchFormat(
|
||||
ytSearchFormatController.value.text,
|
||||
);
|
||||
},
|
||||
),
|
||||
onSubmitted: (value) {
|
||||
preferences.setYtSearchFormat(value);
|
||||
update?.call(() {});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
AdaptiveListTile(
|
||||
leading: const Icon(SpotubeIcons.barChart),
|
||||
title: SizedBox(
|
||||
height: 50,
|
||||
width: 180,
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: AutoSizeText(
|
||||
"Track Match Algorithm",
|
||||
maxLines: 1,
|
||||
style: PlatformTextTheme.of(context).body,
|
||||
),
|
||||
),
|
||||
),
|
||||
trailing: (context, update) =>
|
||||
PlatformDropDownMenu<SpotubeTrackMatchAlgorithm>(
|
||||
value: preferences.trackMatchAlgorithm,
|
||||
items: [
|
||||
PlatformDropDownMenuItem(
|
||||
value: SpotubeTrackMatchAlgorithm.authenticPopular,
|
||||
child: const PlatformText(
|
||||
"Popular from Author",
|
||||
),
|
||||
),
|
||||
PlatformDropDownMenuItem(
|
||||
value: SpotubeTrackMatchAlgorithm.popular,
|
||||
child: const PlatformText(
|
||||
"Accurately Popular",
|
||||
),
|
||||
),
|
||||
PlatformDropDownMenuItem(
|
||||
value: SpotubeTrackMatchAlgorithm.youtube,
|
||||
child: const PlatformText("YouTube's Top choice"),
|
||||
),
|
||||
],
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
preferences.setTrackMatchAlgorithm(value);
|
||||
update?.call(() {});
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
PlatformText(
|
||||
" Downloads",
|
||||
style: PlatformTextTheme.of(context)
|
||||
|
@ -52,7 +52,7 @@ class Downloader with ChangeNotifier {
|
||||
// Using android Audio Focus to keep the app run in background
|
||||
// _playback.mobileAudioService?.session?.setActive(true);
|
||||
grabberQueue.add(() async {
|
||||
final track = await SpotubeTrack.fromFetchTrack(
|
||||
final track = await SpotubeTrack.fetchFromTrack(
|
||||
baseTrack,
|
||||
ref.read(userPreferencesProvider),
|
||||
);
|
||||
|
@ -40,7 +40,7 @@ class PlaylistQueue {
|
||||
if (e["path"] != null) {
|
||||
return LocalTrack.fromJson(jsonTrack);
|
||||
} else if (i == json["active"] && !json.containsKey("path")) {
|
||||
return await SpotubeTrack.fromFetchTrack(
|
||||
return await SpotubeTrack.fetchFromTrack(
|
||||
Track.fromJson(jsonTrack),
|
||||
preferences,
|
||||
);
|
||||
@ -63,7 +63,7 @@ class PlaylistQueue {
|
||||
if (e["path"] != null) {
|
||||
return LocalTrack.fromJson(jsonTrack);
|
||||
} else if (i == json["active"] && !json.containsKey("path")) {
|
||||
return await SpotubeTrack.fromFetchTrack(
|
||||
return await SpotubeTrack.fetchFromTrack(
|
||||
Track.fromJson(jsonTrack),
|
||||
preferences,
|
||||
);
|
||||
@ -196,7 +196,7 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
|
||||
!isPreSearching) {
|
||||
isPreSearching = true;
|
||||
final tracks = state!.tracks.toList();
|
||||
tracks[state!.active + 1] = await SpotubeTrack.fromFetchTrack(
|
||||
tracks[state!.active + 1] = await SpotubeTrack.fetchFromTrack(
|
||||
state!.tracks.elementAt(state!.active + 1),
|
||||
preferences,
|
||||
);
|
||||
@ -355,7 +355,7 @@ class PlaylistQueueNotifier extends PersistedStateNotifier<PlaylistQueue?> {
|
||||
}
|
||||
if (state!.activeTrack is! SpotubeTrack) {
|
||||
final tracks = state!.tracks.toList();
|
||||
tracks[state!.active] = await SpotubeTrack.fromFetchTrack(
|
||||
tracks[state!.active] = await SpotubeTrack.fetchFromTrack(
|
||||
state!.activeTrack,
|
||||
preferences,
|
||||
);
|
||||
|
@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:spotube/components/settings/color_scheme_picker_dialog.dart';
|
||||
import 'package:spotube/models/spotube_track.dart';
|
||||
import 'package:spotube/models/generated_secrets.dart';
|
||||
import 'package:spotube/utils/persisted_change_notifier.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
@ -25,12 +24,10 @@ enum AudioQuality {
|
||||
|
||||
class UserPreferences extends PersistedChangeNotifier {
|
||||
ThemeMode themeMode;
|
||||
String ytSearchFormat;
|
||||
String recommendationMarket;
|
||||
bool saveTrackLyrics;
|
||||
String geniusAccessToken;
|
||||
bool checkUpdate;
|
||||
SpotubeTrackMatchAlgorithm trackMatchAlgorithm;
|
||||
AudioQuality audioQuality;
|
||||
|
||||
MaterialColor accentColorScheme;
|
||||
@ -48,14 +45,12 @@ class UserPreferences extends PersistedChangeNotifier {
|
||||
required this.geniusAccessToken,
|
||||
required this.recommendationMarket,
|
||||
required this.themeMode,
|
||||
required this.ytSearchFormat,
|
||||
required this.layoutMode,
|
||||
required this.predownload,
|
||||
this.saveTrackLyrics = false,
|
||||
this.accentColorScheme = Colors.green,
|
||||
this.backgroundColorScheme = Colors.grey,
|
||||
this.checkUpdate = true,
|
||||
this.trackMatchAlgorithm = SpotubeTrackMatchAlgorithm.youtube,
|
||||
this.audioQuality = AudioQuality.high,
|
||||
this.skipSponsorSegments = true,
|
||||
this.downloadLocation = "",
|
||||
@ -100,12 +95,6 @@ class UserPreferences extends PersistedChangeNotifier {
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setYtSearchFormat(String format) {
|
||||
ytSearchFormat = format;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setAccentColorScheme(MaterialColor color) {
|
||||
accentColorScheme = color;
|
||||
notifyListeners();
|
||||
@ -124,12 +113,6 @@ class UserPreferences extends PersistedChangeNotifier {
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setTrackMatchAlgorithm(SpotubeTrackMatchAlgorithm algorithm) {
|
||||
trackMatchAlgorithm = algorithm;
|
||||
notifyListeners();
|
||||
updatePersistence();
|
||||
}
|
||||
|
||||
void setAudioQuality(AudioQuality quality) {
|
||||
audioQuality = quality;
|
||||
notifyListeners();
|
||||
@ -181,7 +164,6 @@ class UserPreferences extends PersistedChangeNotifier {
|
||||
geniusAccessToken = map["geniusAccessToken"] ??
|
||||
PrimitiveUtils.getRandomElement(lyricsSecrets);
|
||||
|
||||
ytSearchFormat = map["ytSearchFormat"] ?? ytSearchFormat;
|
||||
themeMode = ThemeMode.values[map["themeMode"] ?? 0];
|
||||
backgroundColorScheme = colorsMap.values
|
||||
.firstWhereOrNull((e) => e.value == map["backgroundColorScheme"]) ??
|
||||
@ -189,9 +171,6 @@ class UserPreferences extends PersistedChangeNotifier {
|
||||
accentColorScheme = colorsMap.values
|
||||
.firstWhereOrNull((e) => e.value == map["accentColorScheme"]) ??
|
||||
accentColorScheme;
|
||||
trackMatchAlgorithm = map["trackMatchAlgorithm"] != null
|
||||
? SpotubeTrackMatchAlgorithm.values[map["trackMatchAlgorithm"]]
|
||||
: trackMatchAlgorithm;
|
||||
audioQuality = map["audioQuality"] != null
|
||||
? AudioQuality.values[map["audioQuality"]]
|
||||
: audioQuality;
|
||||
@ -213,12 +192,10 @@ class UserPreferences extends PersistedChangeNotifier {
|
||||
"saveTrackLyrics": saveTrackLyrics,
|
||||
"recommendationMarket": recommendationMarket,
|
||||
"geniusAccessToken": geniusAccessToken,
|
||||
"ytSearchFormat": ytSearchFormat,
|
||||
"themeMode": themeMode.index,
|
||||
"backgroundColorScheme": backgroundColorScheme.value,
|
||||
"accentColorScheme": accentColorScheme.value,
|
||||
"checkUpdate": checkUpdate,
|
||||
"trackMatchAlgorithm": trackMatchAlgorithm.index,
|
||||
"audioQuality": audioQuality.index,
|
||||
"skipSponsorSegments": skipSponsorSegments,
|
||||
"downloadLocation": downloadLocation,
|
||||
@ -234,7 +211,6 @@ final userPreferencesProvider = ChangeNotifierProvider(
|
||||
geniusAccessToken: "",
|
||||
recommendationMarket: 'US',
|
||||
themeMode: ThemeMode.system,
|
||||
ytSearchFormat: "\$MAIN_ARTIST - \$TITLE \$FEATURED_ARTISTS",
|
||||
layoutMode: kIsMobile ? LayoutMode.compact : LayoutMode.adaptive,
|
||||
predownload: kIsMobile,
|
||||
),
|
||||
|
Loading…
Reference in New Issue
Block a user