Compare commits

..

No commits in common. "973ca20c8e9f86891ac6c2e17a57a12a11e454ac" and "66848c78c71a71373881f6597a9de07be0d203c3" have entirely different histories.

10 changed files with 35 additions and 138 deletions

View File

@ -5,7 +5,6 @@ import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:shadcn_flutter/shadcn_flutter_extension.dart';
import 'package:spotube/collections/assets.gen.dart';
import 'package:spotube/collections/routes.dart';
import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/components/ui/button_tile.dart';
import 'package:spotube/extensions/constrains.dart';
@ -60,7 +59,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
rootNavigatorKey.currentContext!,
context,
TrackOptionValue.delete,
playlistId,
);
@ -74,7 +73,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
rootNavigatorKey.currentContext!,
context,
TrackOptionValue.album,
playlistId,
);
@ -98,7 +97,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
rootNavigatorKey.currentContext!,
context,
TrackOptionValue.addToQueue,
playlistId,
);
@ -111,7 +110,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
rootNavigatorKey.currentContext!,
context,
TrackOptionValue.playNext,
playlistId,
);
@ -125,7 +124,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
rootNavigatorKey.currentContext!,
context,
TrackOptionValue.removeFromQueue,
playlistId,
);
@ -140,7 +139,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
rootNavigatorKey.currentContext!,
context,
TrackOptionValue.favorite,
playlistId,
);
@ -163,7 +162,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
rootNavigatorKey.currentContext!,
context,
TrackOptionValue.startRadio,
playlistId,
);
@ -176,7 +175,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
rootNavigatorKey.currentContext!,
context,
TrackOptionValue.addToPlaylist,
playlistId,
);
@ -191,7 +190,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
rootNavigatorKey.currentContext!,
context,
TrackOptionValue.removeFromPlaylist,
playlistId,
);
@ -205,7 +204,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
rootNavigatorKey.currentContext!,
context,
TrackOptionValue.download,
playlistId,
);
@ -227,7 +226,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
rootNavigatorKey.currentContext!,
context,
TrackOptionValue.blacklist,
playlistId,
);
@ -251,7 +250,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
rootNavigatorKey.currentContext!,
context,
TrackOptionValue.share,
playlistId,
);
@ -265,7 +264,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
rootNavigatorKey.currentContext!,
context,
TrackOptionValue.songlink,
playlistId,
);
@ -283,7 +282,7 @@ class TrackOptions extends HookConsumerWidget {
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
rootNavigatorKey.currentContext!,
context,
TrackOptionValue.details,
playlistId,
);

View File

@ -1,4 +1,3 @@
import 'package:flutter/material.dart' show Badge;
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
@ -84,20 +83,14 @@ class GettingStartedPagePlaybackSection extends HookConsumerWidget {
runSpacing: 6,
children: [
for (final source in AudioSource.values)
Badge(
isLabelVisible: source == AudioSource.dabMusic,
label: const Text("NEW"),
backgroundColor: Colors.lime[300],
textColor: Colors.black,
child: RadioCard(
value: source,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
audioSourceToIconMap[source]!,
Text(source.label),
],
),
RadioCard(
value: source,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
audioSourceToIconMap[source]!,
Text(source.label),
],
),
),
],

View File

@ -259,14 +259,11 @@ class AudioPlayerNotifier extends Notifier<AudioPlayerState> {
return addTracks(tracks);
}
final addableTracks = _blacklist
.filter(tracks)
.where(
final addableTracks = _blacklist.filter(tracks).where(
(track) =>
allowDuplicates ||
!state.tracks.any((element) => _compareTracks(element, track)),
)
.toList();
);
state = state.copyWith(
tracks: [...addableTracks, ...state.tracks],
@ -374,12 +371,13 @@ class AudioPlayerNotifier extends Notifier<AudioPlayerState> {
}
bool _compareTracks(SpotubeTrackObject a, SpotubeTrackObject b) {
if (a.runtimeType != b.runtimeType) {
if ((a is SpotubeLocalTrackObject && b is! SpotubeLocalTrackObject) ||
(a is! SpotubeLocalTrackObject && b is SpotubeLocalTrackObject)) {
return false;
}
return a is SpotubeLocalTrackObject && b is SpotubeLocalTrackObject
? a.path == b.path
? (a).path == (b).path
: a.id == b.id;
}

View File

@ -214,7 +214,7 @@ class MetadataPluginNotifier extends AsyncNotifier<MetadataPluginState> {
/// Root directory where all metadata plugins are stored.
Future<Directory> _getPluginRootDir() async => Directory(
join(
(await getApplicationSupportDirectory()).path,
(await getApplicationCacheDirectory()).path,
"metadata-plugins",
),
);

View File

@ -166,7 +166,7 @@ class TrackOptionsActions {
}
break;
case TrackOptionValue.playNext:
await playback.addTracksAtFirst([track]);
playback.addTracksAtFirst([track]);
if (context.mounted) {
showToast(

View File

@ -57,7 +57,6 @@ abstract class AudioPlayerInterface {
title: "Spotube",
logLevel: kDebugMode ? mk.MPVLogLevel.info : mk.MPVLogLevel.error,
bufferSize: 4 * 1024 * 1024, // 4MB buffer
async: true,
),
) {
_mkPlayer.stream.error.listen((event) {

View File

@ -121,23 +121,9 @@ class CustomPlayer extends Player {
NativePlayer get nativePlayer => platform as NativePlayer;
Future<void> insert(int index, Media media) async {
final addedMediaCompleter = Completer<int>();
final playlistStream = stream.playlist.listen(
(event) {
final mediaAddedIndex =
event.medias.indexWhere((m) => m.uri == media.uri);
if (mediaAddedIndex != -1 && !addedMediaCompleter.isCompleted) {
addedMediaCompleter.complete(mediaAddedIndex);
}
},
);
try {
await add(media);
final mediaAddedIndex = await addedMediaCompleter.future;
await move(mediaAddedIndex, index);
} finally {
playlistStream.cancel();
}
await add(media);
await Future.delayed(const Duration(milliseconds: 100));
await move(state.playlist.medias.length - 1, index);
}
Future<void> setAudioNormalization(bool normalize) async {

View File

@ -1,12 +1,8 @@
import 'dart:convert';
import 'package:collection/collection.dart';
import 'package:dio/dio.dart';
import 'package:drift/drift.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotube/models/database/database.dart';
import 'package:spotube/models/playback/track_sources.dart';
import 'package:spotube/provider/database/database.dart';
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
import 'package:spotube/services/logger/logger.dart';
import 'package:spotube/services/sourced_track/enums.dart';
@ -36,68 +32,11 @@ class DABMusicSourcedTrack extends SourcedTrack {
required Ref ref,
}) async {
try {
final database = ref.read(databaseProvider);
final cachedSource = await (database.select(database.sourceMatchTable)
..where((s) => s.trackId.equals(query.id))
..limit(1)
..orderBy([
(s) => OrderingTerm(
expression: s.createdAt,
mode: OrderingMode.desc,
),
]))
.get()
.then((s) => s.firstOrNull);
if (cachedSource != null &&
cachedSource.sourceType == SourceType.dabMusic) {
final json = jsonDecode(cachedSource.sourceId);
final info = TrackSourceInfo.fromJson(json["info"]);
final source = (json["sources"] as List?)
?.map((s) => TrackSource.fromJson(s))
.toList();
final [updatedSource] = await fetchSources(
info.id,
ref.read(userPreferencesProvider).audioQuality,
const AudioQuality(
isHiRes: true,
maximumBitDepth: 16,
maximumSamplingRate: 44.1,
),
);
return DABMusicSourcedTrack(
ref: ref,
source: AudioSource.dabMusic,
siblings: [],
info: info,
query: query,
sources: [
source!.first.copyWith(url: updatedSource.url),
],
);
}
final siblings = await fetchSiblings(ref: ref, query: query);
if (siblings.isEmpty) {
throw TrackNotFoundError(query);
}
await database.into(database.sourceMatchTable).insert(
SourceMatchTableCompanion.insert(
trackId: query.id,
sourceId: jsonEncode({
"info": siblings.first.info.toJson(),
"sources": (siblings.first.source ?? [])
.map((s) => s.toJson())
.toList(),
}),
sourceType: const Value(SourceType.dabMusic),
),
);
return DABMusicSourcedTrack(
ref: ref,
siblings: siblings.map((s) => s.info).skip(1).toList(),
@ -268,23 +207,6 @@ class DABMusicSourcedTrack extends SourcedTrack {
),
);
final database = ref.read(databaseProvider);
await database.into(database.sourceMatchTable).insert(
SourceMatchTableCompanion.insert(
trackId: query.id,
sourceId: jsonEncode({
"info": newSourceInfo.toJson(),
"sources": source.map((s) => s.toJson()).toList(),
}),
sourceType: const Value(SourceType.dabMusic),
// Because we're sorting by createdAt in the query
// we have to update it to indicate priority
createdAt: Value(DateTime.now()),
),
mode: InsertMode.replace,
);
return DABMusicSourcedTrack(
ref: ref,
siblings: newSiblings,

View File

@ -1412,10 +1412,10 @@ packages:
dependency: "direct main"
description:
name: invidious
sha256: "0da8ebc4c4110057f03302bbd54514b10642154d7be569e7994172f2202dcfe8"
sha256: "27ef3a001df875665de15535dbc9099f44d12a59480018fb1e17377d4af0308d"
url: "https://pub.dev"
source: hosted
version: "0.1.2"
version: "0.1.1"
io:
dependency: "direct dev"
description:

View File

@ -81,7 +81,7 @@ dependencies:
http: ^1.2.1
image_picker: ^1.1.0
intl: any
invidious: ^0.1.2
invidious: ^0.1.1
jiosaavn: ^0.1.0
json_annotation: ^4.8.1
local_notifier: ^0.1.6