diff --git a/.github/workflows/spotube-nightly.yml b/.github/workflows/spotube-nightly.yml
index 2be5ba27..bed8dacb 100644
--- a/.github/workflows/spotube-nightly.yml
+++ b/.github/workflows/spotube-nightly.yml
@@ -28,6 +28,7 @@ jobs:
curl -sS https://webi.sh/yq | sh
yq -i '.version |= sub("\+\d+", "-nightly-")' pubspec.yaml
yq -i '.version += strenv(GITHUB_RUN_NUMBER)' pubspec.yaml
+ echo '${{ secrets.DOTENV_NIGHTLY }}' > .env
flutter config --enable-linux-desktop
flutter pub get
dart bin/create-secrets.dart '${{ secrets.LYRICS_SECRET }}' '${{ secrets.SPOTIFY_SECRET }}'
@@ -63,6 +64,7 @@ jobs:
curl -sS https://webi.sh/yq | sh
yq -i '.version |= sub("\+\d+", "-nightly-")' pubspec.yaml
yq -i '.version += strenv(GITHUB_RUN_NUMBER)' pubspec.yaml
+ echo '${{ secrets.DOTENV_NIGHTLY }}' > .env
flutter pub get
dart bin/create-secrets.dart '${{ secrets.LYRICS_SECRET }}' '${{ secrets.SPOTIFY_SECRET }}'
echo '${{ secrets.KEYSTORE }}' | base64 --decode > android/app/upload-keystore.jks
@@ -93,6 +95,7 @@ jobs:
yq -i '.version |= sub("\+\d+", "-nightly-")' pubspec.yaml
yq -i '.version += strenv(GITHUB_RUN_NUMBER)' pubspec.yaml
sed -i "s/%{{SPOTUBE_VERSION}}%/${{ env.GITHUB_RUN_NUMBER }}/" windows/runner/Runner.rc
+ echo '${{ secrets.DOTENV_NIGHTLY }}' > .env
flutter config --enable-windows-desktop
flutter pub get
dart bin/create-secrets.dart '${{ secrets.LYRICS_SECRET }}' '${{ secrets.SPOTIFY_SECRET }}'
@@ -120,6 +123,7 @@ jobs:
- run: brew install yq
- run: yq -i '.version |= sub("\+\d+", "-nightly-")' pubspec.yaml
- run: yq -i '.version += strenv(GITHUB_RUN_NUMBER)' pubspec.yaml
+ - run: echo '${{ secrets.DOTENV_NIGHTLY }}' > .env
- run: flutter config --enable-macos-desktop
- run: flutter pub get
- run: dart bin/create-secrets.dart '${{ secrets.LYRICS_SECRET }}' '${{ secrets.SPOTIFY_SECRET }}'
diff --git a/.github/workflows/spotube-release.yml b/.github/workflows/spotube-release.yml
index f00d20a9..4d78d2b5 100644
--- a/.github/workflows/spotube-release.yml
+++ b/.github/workflows/spotube-release.yml
@@ -31,6 +31,7 @@ jobs:
with:
cache: true
- run: |
+ echo '${{ secrets.DOTENV_RELEASE }}' > .env
flutter config --enable-windows-desktop
flutter pub get
dart bin/create-secrets.dart '${{ secrets.LYRICS_SECRET }}' '${{ secrets.SPOTIFY_SECRET }}'
@@ -72,6 +73,7 @@ jobs:
- uses: subosito/flutter-action@v2.8.0
with:
cache: true
+ - run: echo '${{ secrets.DOTENV_RELEASE }}' > .env
- run: flutter config --enable-macos-desktop
- run: flutter pub get
- run: dart bin/create-secrets.dart '${{ secrets.LYRICS_SECRET }}' '${{ secrets.SPOTIFY_SECRET }}'
@@ -112,6 +114,7 @@ jobs:
# replacing & adding new release version with older version
- run: |
sed -i 's|%{{APPDATA_RELEASE}}%||' linux/com.github.KRTirtho.Spotube.appdata.xml
+ echo '${{ secrets.DOTENV_RELEASE }}' > .env
- run: |
flutter config --enable-linux-desktop
@@ -146,6 +149,7 @@ jobs:
sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev make python3-pip python3-setuptools patchelf desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace fuse
- run: |
+ echo '${{ secrets.DOTENV_RELEASE }}' > .env
flutter pub get
dart bin/create-secrets.dart '${{ secrets.LYRICS_SECRET }}' '${{ secrets.SPOTIFY_SECRET }}'
echo '${{ secrets.KEYSTORE }}' | base64 --decode > android/app/upload-keystore.jks
diff --git a/.gitignore b/.gitignore
index 55a9a29f..1782ec11 100644
--- a/.gitignore
+++ b/.gitignore
@@ -75,3 +75,5 @@ appimage-build
android/key.properties
.fvm/flutter_sdk
+
+**/pb_data
\ No newline at end of file
diff --git a/android/app/build.gradle b/android/app/build.gradle
index b767c01c..1d519014 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -77,6 +77,6 @@ flutter {
}
dependencies {
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
- implementation 'com.android.support:multidex:1.0.3'
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
+ implementation 'com.android.support:multidex:2.0.1'
}
diff --git a/android/build.gradle b/android/build.gradle
index a4d7066f..f820e957 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -1,5 +1,5 @@
buildscript {
- ext.kotlin_version = '1.6.10'
+ ext.kotlin_version = '1.7.21'
repositories {
google()
mavenCentral()
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
index 562c5e44..02e5f581 100644
--- a/android/gradle/wrapper/gradle-wrapper.properties
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip
diff --git a/lib/collections/env.dart b/lib/collections/env.dart
new file mode 100644
index 00000000..2d3965f4
--- /dev/null
+++ b/lib/collections/env.dart
@@ -0,0 +1,15 @@
+import 'package:flutter/foundation.dart';
+import 'package:flutter_dotenv/flutter_dotenv.dart';
+
+abstract class Env {
+ static final String pocketbaseUrl =
+ dotenv.get('POCKETBASE_URL', fallback: 'http://localhost:8090');
+ static final String username = dotenv.get('USERNAME', fallback: 'root');
+ static final String password = dotenv.get('PASSWORD', fallback: '12345678');
+
+ static configure() async {
+ if (kReleaseMode) {
+ await dotenv.load(fileName: ".env");
+ }
+ }
+}
diff --git a/lib/collections/intents.dart b/lib/collections/intents.dart
index 42e5ace7..ad60a7fa 100644
--- a/lib/collections/intents.dart
+++ b/lib/collections/intents.dart
@@ -2,11 +2,10 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
-import 'package:spotify/spotify.dart';
import 'package:spotube/components/player/player_controls.dart';
import 'package:spotube/collections/routes.dart';
import 'package:spotube/models/logger.dart';
-import 'package:spotube/provider/playback_provider.dart';
+import 'package:spotube/provider/playlist_queue_provider.dart';
import 'package:spotube/utils/platform.dart';
import 'package:window_manager/window_manager.dart';
@@ -23,23 +22,22 @@ class PlayPauseAction extends Action {
if (PlayerControls.focusNode.canRequestFocus) {
PlayerControls.focusNode.requestFocus();
}
- final playback = intent.ref.read(playbackProvider);
- if (playback.track == null) {
+ final playlist = intent.ref.read(PlaylistQueueNotifier.provider);
+ final playlistNotifier = intent.ref.read(PlaylistQueueNotifier.notifier);
+ if (playlist == null) {
return null;
- } else if (playback.track != null &&
- playback.currentDuration == Duration.zero &&
- await playback.player.getCurrentPosition() == Duration.zero) {
- if (playback.track!.ytUri.startsWith("http")) {
- final track = Track.fromJson(playback.track!.toJson());
- playback.track = null;
- await playback.play(track);
- } else {
- final track = playback.track;
- playback.track = null;
- await playback.play(track!);
- }
+ } else if (!PlaylistQueueNotifier.isPlaying) {
+ // if (playlist.activeTrack is SpotubeTrack &&
+ // (playlist.activeTrack as SpotubeTrack).ytUri.startsWith("http")) {
+ // final track =
+ // Track.fromJson((playlist.activeTrack as SpotubeTrack).toJson());
+
+ // await playlistNotifier.play(track);
+ // } else {
+ // }
+ await playlistNotifier.play();
} else {
- await playback.togglePlayPause();
+ await playlistNotifier.pause();
}
return null;
}
@@ -102,9 +100,9 @@ class SeekIntent extends Intent {
class SeekAction extends Action {
@override
invoke(intent) async {
- final playback = intent.ref.read(playbackProvider);
- if ((playback.playlist == null && playback.track == null) ||
- playback.status == PlaybackStatus.loading) {
+ final playlist = intent.ref.read(PlaylistQueueNotifier.provider);
+ final playlistNotifier = intent.ref.read(PlaylistQueueNotifier.notifier);
+ if (playlist == null || playlist.isLoading) {
DirectionalFocusAction().invoke(
DirectionalFocusIntent(
intent.forward ? TraversalDirection.right : TraversalDirection.left,
@@ -113,8 +111,8 @@ class SeekAction extends Action {
return null;
}
final position =
- (await playback.player.getCurrentPosition() ?? Duration.zero).inSeconds;
- await playback.seekPosition(
+ (await audioPlayer.getCurrentPosition() ?? Duration.zero).inSeconds;
+ await playlistNotifier.seek(
Duration(
seconds: intent.forward ? position + 5 : position - 5,
),
diff --git a/lib/components/album/album_card.dart b/lib/components/album/album_card.dart
index 5c9f5537..14da1354 100644
--- a/lib/components/album/album_card.dart
+++ b/lib/components/album/album_card.dart
@@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotify/spotify.dart';
import 'package:spotube/components/shared/playbutton_card.dart';
import 'package:spotube/hooks/use_breakpoint_value.dart';
-import 'package:spotube/models/current_playlist.dart';
-import 'package:spotube/provider/playback_provider.dart';
import 'package:spotube/provider/spotify_provider.dart';
+import 'package:spotube/provider/playlist_queue_provider.dart';
import 'package:spotube/utils/service_utils.dart';
import 'package:spotube/utils/type_conversion_utils.dart';
@@ -20,9 +20,10 @@ class AlbumCard extends HookConsumerWidget {
@override
Widget build(BuildContext context, ref) {
- Playback playback = ref.watch(playbackProvider);
- bool isPlaylistPlaying =
- playback.playlist != null && playback.playlist!.id == album.id;
+ final playlist = ref.watch(PlaylistQueueNotifier.provider);
+ final playing = useStream(PlaylistQueueNotifier.playing).data ?? false;
+ final playlistNotifier = ref.watch(PlaylistQueueNotifier.notifier);
+ bool isPlaylistPlaying = playlistNotifier.isPlayingPlaylist(album.tracks!);
final int marginH =
useBreakpointValue(sm: 10, md: 15, lg: 20, xl: 20, xxl: 20);
return PlaybuttonCard(
@@ -32,9 +33,8 @@ class AlbumCard extends HookConsumerWidget {
),
viewType: viewType,
margin: EdgeInsets.symmetric(horizontal: marginH.toDouble()),
- isPlaying: isPlaylistPlaying && playback.isPlaying,
- isLoading: playback.status == PlaybackStatus.loading &&
- playback.playlist?.id == album.id,
+ isPlaying: isPlaylistPlaying && playing,
+ isLoading: isPlaylistPlaying && playlist?.isLoading == true,
title: album.name!,
description:
"Album • ${TypeConversionUtils.artists_X_String(album.artists ?? [])}",
@@ -43,10 +43,10 @@ class AlbumCard extends HookConsumerWidget {
},
onPlaybuttonPressed: () async {
SpotifyApi spotify = ref.read(spotifyProvider);
- if (isPlaylistPlaying && playback.isPlaying) {
- return playback.pause();
- } else if (isPlaylistPlaying && !playback.isPlaying) {
- return playback.resume();
+ if (isPlaylistPlaying && playing) {
+ return playlistNotifier.pause();
+ } else if (isPlaylistPlaying && !playing) {
+ return playlistNotifier.resume();
}
List