Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(desktop): webview based login support #1688

Merged
merged 32 commits into from
Jul 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
3fb003e
refactor(preferences): use Drift sql db for preferences
KRTirtho Jun 13, 2024
52d4f60
refactor: use drift for skip segments and source matches
KRTirtho Jun 14, 2024
bf6cec8
refactor(blacklist): use drift sql db instead of hive
KRTirtho Jun 14, 2024
a799ca5
chore: add encrypted text column support
KRTirtho Jun 16, 2024
d18f74f
refactor: use drift db based authentication
KRTirtho Jun 16, 2024
b9b7d5c
refactor: lastfm scrobbling to drift db
KRTirtho Jun 17, 2024
5936f08
refactor(volumeProvider): use notifier and kvstore for persistence
KRTirtho Jun 17, 2024
59041a2
chore: use .value for scrobble encrypted text
KRTirtho Jun 20, 2024
f79fede
chore: create new audio player centric playback notifier with drift p…
KRTirtho Jun 23, 2024
a83dd64
refactor: replace all instances of proxy playlist
KRTirtho Jun 24, 2024
75173e5
refactor: use provider based is track loading implementation
KRTirtho Jun 24, 2024
a621a45
chore: fix alternative track sources not showing up
KRTirtho Jun 24, 2024
1b420e6
chore: player skipping all tracks from cache
KRTirtho Jun 24, 2024
6c5cab9
chore: fix use SpotubeMedia to avoid duplicate sourceTrackProvider in…
KRTirtho Jun 25, 2024
4441886
chore: fix volume not being set after launch
KRTirtho Jun 25, 2024
08ac29c
refactor(stats): migrate stats to use drift db
KRTirtho Jun 29, 2024
1cfd377
refactor: synced lyric cache to use drift db
KRTirtho Jun 30, 2024
a3021e4
chore: removed unused files
KRTirtho Jun 30, 2024
ffb3a33
chore: add migration script to migrate hive to drift
KRTirtho Jun 30, 2024
261e1b6
chore: fix queue collections not being loaded
KRTirtho Jun 30, 2024
4c5564f
chore: use enum properties for history duration in top stats
KRTirtho Jun 30, 2024
3bdc46d
feat(stats): add lazy loading support
KRTirtho Jun 30, 2024
15bd58a
feat(desktop): implement webview based login
KRTirtho Jul 5, 2024
1284b40
chore: add linux dependencies and update CI + docker config
KRTirtho Jul 5, 2024
79b842d
chore: use flutter 3.19.6 to avoid window stretching error in windows
KRTirtho Jul 5, 2024
f2f35bd
chore: fix windows webview2 trying to store data in admin folders
KRTirtho Jul 5, 2024
7dd76d2
chore: fix windows cookie invalid characters
KRTirtho Jul 5, 2024
359b918
chore: fix windows playback not working for loop back ipv4
KRTirtho Jul 5, 2024
2f46fa3
chore: fix webview and app window freezing after successful login
KRTirtho Jul 6, 2024
2ce4853
chore: fix while loading playlists/album already playing ones doesn't…
KRTirtho Jul 6, 2024
ccea4a0
fix: changed source doesn't get saved and uses the wrong once again
KRTirtho Jul 6, 2024
86f5b80
chore: fix insert failing to invalid conflict check
KRTirtho Jul 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/Dockerfile.flutter_distributor
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ ARG FLUTTER_VERSION

RUN apt-get clean &&\
apt-get update &&\
apt-get install -y bash curl file git unzip xz-utils zip libglu1-mesa cmake tar clang ninja-build pkg-config libgtk-3-dev make python3-pip python3-setuptools desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace fuse libunwind-dev locate patchelf gir1.2-appindicator3-0.1 libappindicator3-1 libappindicator3-dev libsecret-1-0 libjsoncpp25 libsecret-1-dev libjsoncpp-dev libnotify-bin libnotify-dev mpv libmpv-dev rpm && \
apt-get install -y bash curl file git unzip xz-utils zip libglu1-mesa cmake tar clang ninja-build pkg-config libgtk-3-dev make python3-pip python3-setuptools desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace fuse libunwind-dev locate patchelf gir1.2-appindicator3-0.1 libappindicator3-1 libappindicator3-dev libsecret-1-0 libjsoncpp25 libsecret-1-dev libjsoncpp-dev libnotify-bin libnotify-dev mpv libmpv-dev rpm libwebkit2gtk-4.1-0 libwebkit2gtk-4.1-dev libsoup-3.0-0 libsoup-3.0-dev && \
rm -rf /var/lib/apt/lists/*

WORKDIR /home/flutter
Expand Down
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ body:
description: Where did you install Spotube from?
multiple: true
options:
- "Website (spotube.netlify.app) or (spotube.krtirtho.dev)"
- "Website (spotube.krtirtho.dev)"
- "GitHub Releases (Binary)"
- "GitHub Actions (Nightly Binary)"
- "Play Store (Android)"
Expand All @@ -77,4 +77,4 @@ body:
description: If you are a developer and want to work on this issue yourself, you can check this box and wait for maintainer response. We welcome contributions!
options:
- label: I'm ready to work on this issue!
required: false
required: false
2 changes: 1 addition & 1 deletion .github/workflows/spotube-release-binary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ on:
description: Dry run without uploading to release

env:
FLUTTER_VERSION: 3.22.1
FLUTTER_VERSION: 3.19.6

permissions:
contents: write
Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,16 @@ Do the following:
- Install Development dependencies in linux
- Debian (>=12/Bookworm)/Ubuntu
```bash
$ apt-get install mpv libmpv-dev libappindicator3-1 gir1.2-appindicator3-0.1 libappindicator3-dev libsecret-1-0 libjsoncpp25 libsecret-1-dev libjsoncpp-dev libnotify-bin libnotify-dev avahi-daemon avahi-discover avahi-utils libnss-mdns mdns-scan
$ apt-get install mpv libmpv-dev libappindicator3-1 gir1.2-appindicator3-0.1 libappindicator3-dev libsecret-1-0 libjsoncpp25 libsecret-1-dev libjsoncpp-dev libnotify-bin libnotify-dev avahi-daemon avahi-discover avahi-utils libnss-mdns mdns-scan libwebkit2gtk-4.1-0 libwebkit2gtk-4.1-dev libsoup-3.0-0 libsoup-3.0-dev
```
- Use `libjsoncpp1` instead of `libjsoncpp25` (for Ubuntu < 22.04)
- Arch/Manjaro
```bash
yay -S mpv libappindicator-gtk3 libsecret jsoncpp libnotify avahi nss-mdns mdns-scan
yay -S mpv libappindicator-gtk3 libsecret jsoncpp libnotify avahi nss-mdns mdns-scan webkit2gtk-4.1 libsoup3
```
- Fedora
```bash
dnf install mpv mpv-devel libappindicator-gtk3 libappindicator-gtk3-devel libsecret libsecret-devel jsoncpp jsoncpp-devel libnotify libnotify-devel avahi mdns-scan nss-mdns
dnf install mpv mpv-devel libappindicator-gtk3 libappindicator-gtk3-devel libsecret libsecret-devel jsoncpp jsoncpp-devel libnotify libnotify-devel avahi mdns-scan nss-mdns webkit2gtk4.1 webkit2gtk4.1-devel libsoup3 libsoup3-devel
```
- Clone the Repo
- Create a `.env` in root of the project following the `.env.example` template
Expand Down
7 changes: 7 additions & 0 deletions build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,10 @@ targets:
options:
any_map: true
explicit_to_json: true
drift_dev:
options:
sql:
dialect: sqlite
options:
modules:
- json1
2 changes: 1 addition & 1 deletion cli/commands/install-dependencies.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class InstallDependenciesCommand extends Command {
await shell.run(
"""
sudo apt-get update -y
sudo apt-get install -y tar clang cmake ninja-build pkg-config libgtk-3-dev make python3-pip python3-setuptools desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace fuse libunwind-dev locate patchelf gir1.2-appindicator3-0.1 libappindicator3-1 libappindicator3-dev libsecret-1-0 libjsoncpp25 libsecret-1-dev libjsoncpp-dev libnotify-bin libnotify-dev mpv libmpv-dev
sudo apt-get install -y tar clang cmake ninja-build pkg-config libgtk-3-dev make python3-pip python3-setuptools desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace fuse libunwind-dev locate patchelf gir1.2-appindicator3-0.1 libappindicator3-1 libappindicator3-dev libsecret-1-0 libjsoncpp25 libsecret-1-dev libjsoncpp-dev libnotify-bin libnotify-dev mpv libmpv-dev libwebkit2gtk-4.1-0 libwebkit2gtk-4.1-dev libsoup-3.0-0 libsoup-3.0-dev
""",
);
break;
Expand Down
21 changes: 0 additions & 21 deletions lib/collections/cache_keys.dart

This file was deleted.

34 changes: 34 additions & 0 deletions lib/collections/fake.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'package:spotify/spotify.dart';
import 'package:spotube/models/database/database.dart';
import 'package:spotube/models/spotify/home_feed.dart';
import 'package:spotube/models/spotify_friends.dart';
import 'package:spotube/provider/history/summary.dart';

abstract class FakeData {
static final Image image = Image()
Expand Down Expand Up @@ -222,4 +224,36 @@ abstract class FakeData {
)
],
);

static const historySummary = PlaybackHistorySummary(
albums: 1,
artists: 1,
duration: Duration(seconds: 1),
playlists: 1,
tracks: 1,
fees: 1,
);

static final historyRecentlyPlayedPlaylist = HistoryTableData(
id: 0,
type: HistoryEntryType.track,
createdAt: DateTime.now(),
itemId: "1",
data: playlist.toJson(),
);

static final historyRecentlyPlayedAlbum = HistoryTableData(
id: 0,
type: HistoryEntryType.track,
createdAt: DateTime.now(),
itemId: "1",
data: album.toJson(),
);

static final historyRecentlyPlayedItems = List.generate(
10,
(index) => index % 2 == 0
? historyRecentlyPlayedPlaylist
: historyRecentlyPlayedAlbum,
);
}
8 changes: 4 additions & 4 deletions lib/collections/intents.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import 'package:spotube/pages/home/home.dart';
import 'package:spotube/pages/library/library.dart';
import 'package:spotube/pages/lyrics/lyrics.dart';
import 'package:spotube/pages/search/search.dart';
import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart';
import 'package:spotube/provider/audio_player/querying_track_info.dart';
import 'package:spotube/services/audio_player/audio_player.dart';
import 'package:spotube/utils/platform.dart';

Expand Down Expand Up @@ -96,16 +96,16 @@ class SeekIntent extends Intent {
class SeekAction extends Action<SeekIntent> {
@override
invoke(intent) async {
final playlist = intent.ref.read(proxyPlaylistProvider);
if (playlist.isFetching) {
final isFetchingActiveTrack = intent.ref.read(queryingTrackInfoProvider);
if (isFetchingActiveTrack) {
DirectionalFocusAction().invoke(
DirectionalFocusIntent(
intent.forward ? TraversalDirection.right : TraversalDirection.left,
),
);
return null;
}
final position = (await audioPlayer.position ?? Duration.zero).inSeconds;
final position = audioPlayer.position.inSeconds;
await audioPlayer.seek(
Duration(
seconds: intent.forward ? position + 5 : position - 5,
Expand Down
21 changes: 4 additions & 17 deletions lib/collections/routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,11 @@ import 'package:spotube/pages/stats/playlists/playlists.dart';
import 'package:spotube/pages/stats/stats.dart';
import 'package:spotube/pages/stats/streams/streams.dart';
import 'package:spotube/pages/track/track.dart';
import 'package:spotube/provider/authentication_provider.dart';
import 'package:spotube/provider/authentication/authentication.dart';
import 'package:spotube/services/kv_store/kv_store.dart';
import 'package:spotube/utils/platform.dart';
import 'package:spotube/components/spotube_page_route.dart';
import 'package:spotube/pages/artist/artist.dart';
import 'package:spotube/pages/library/library.dart';
import 'package:spotube/pages/desktop_login/login_tutorial.dart';
import 'package:spotube/pages/desktop_login/desktop_login.dart';
import 'package:spotube/pages/lyrics/lyrics.dart';
import 'package:spotube/pages/root/root_app.dart';
import 'package:spotube/pages/settings/settings.dart';
Expand All @@ -59,11 +56,9 @@ final routerProvider = Provider((ref) {
path: "/",
name: HomePage.name,
redirect: (context, state) async {
final authNotifier = ref.read(authenticationProvider.notifier);
final json = await authNotifier.box.get(authNotifier.cacheKey);
final auth = await ref.read(authenticationProvider.future);

if (json?["cookie"] == null &&
!KVStoreService.doneGettingStarted) {
if (auth == null && !KVStoreService.doneGettingStarted) {
return "/getting-started";
}

Expand Down Expand Up @@ -315,16 +310,8 @@ final routerProvider = Provider((ref) {
path: "/login",
name: WebViewLogin.name,
parentNavigatorKey: rootNavigatorKey,
pageBuilder: (context, state) => SpotubePage(
child: kIsMobile ? const WebViewLogin() : const DesktopLoginPage(),
),
),
GoRoute(
path: "/login-tutorial",
name: LoginTutorial.name,
parentNavigatorKey: rootNavigatorKey,
pageBuilder: (context, state) => const SpotubePage(
child: LoginTutorial(),
child: WebViewLogin(),
),
),
GoRoute(
Expand Down
2 changes: 1 addition & 1 deletion lib/components/fallbacks/anonymous_fallback.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/pages/settings/settings.dart';

import 'package:spotube/provider/authentication_provider.dart';
import 'package:spotube/provider/authentication/authentication.dart';
import 'package:spotube/utils/service_utils.dart';

class AnonymousFallback extends ConsumerWidget {
Expand Down
4 changes: 2 additions & 2 deletions lib/components/heart_button/heart_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotify/spotify.dart';
import 'package:spotube/components/heart_button/use_track_toggle_like.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/provider/authentication_provider.dart';
import 'package:spotube/provider/authentication/authentication.dart';
import 'package:spotube/provider/spotify/spotify.dart';

class HeartButton extends HookConsumerWidget {
Expand All @@ -26,7 +26,7 @@ class HeartButton extends HookConsumerWidget {
Widget build(BuildContext context, ref) {
final auth = ref.watch(authenticationProvider);

if (auth == null) return const SizedBox.shrink();
if (auth.asData?.value == null) return const SizedBox.shrink();

return IconButton(
tooltip: tooltip,
Expand Down
2 changes: 1 addition & 1 deletion lib/components/heart_button/use_track_toggle_like.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotify/spotify.dart';
import 'package:spotube/provider/scrobbler_provider.dart';
import 'package:spotube/provider/scrobbler/scrobbler.dart';
import 'package:spotube/provider/spotify/spotify.dart';

typedef UseTrackToggleLike = ({
Expand Down
45 changes: 23 additions & 22 deletions lib/components/track_tile/track_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ import 'package:spotube/components/links/artist_link.dart';
import 'package:spotube/extensions/constrains.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/extensions/image.dart';
import 'package:spotube/models/database/database.dart';
import 'package:spotube/models/local_track.dart';
import 'package:spotube/provider/authentication_provider.dart';
import 'package:spotube/provider/authentication/authentication.dart';
import 'package:spotube/provider/blacklist_provider.dart';
import 'package:spotube/provider/download_manager_provider.dart';
import 'package:spotube/provider/local_tracks/local_tracks_provider.dart';
import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart';
import 'package:spotube/provider/audio_player/audio_player.dart';
import 'package:spotube/provider/spotify/spotify.dart';
import 'package:spotube/provider/spotify_provider.dart';

Expand Down Expand Up @@ -95,8 +96,8 @@ class TrackOptions extends HookConsumerWidget {
WidgetRef ref,
Track track,
) async {
final playback = ref.read(proxyPlaylistProvider.notifier);
final playlist = ref.read(proxyPlaylistProvider);
final playback = ref.read(audioPlayerProvider.notifier);
final playlist = ref.read(audioPlayerProvider);
final spotify = ref.read(spotifyProvider);
final query = "${track.name} Radio";
final pages =
Expand Down Expand Up @@ -159,8 +160,8 @@ class TrackOptions extends HookConsumerWidget {
final router = GoRouter.of(context);
final ThemeData(:colorScheme) = Theme.of(context);

final playlist = ref.watch(proxyPlaylistProvider);
final playback = ref.watch(proxyPlaylistProvider.notifier);
final playlist = ref.watch(audioPlayerProvider);
final playback = ref.watch(audioPlayerProvider.notifier);
final auth = ref.watch(authenticationProvider);
ref.watch(downloadManagerProvider);
final downloadManager = ref.watch(downloadManagerProvider.notifier);
Expand All @@ -170,11 +171,8 @@ class TrackOptions extends HookConsumerWidget {
final favorites = useTrackToggleLike(track, ref);

final isBlackListed = useMemoized(
() => blacklist.contains(
BlacklistedElement.track(
track.id!,
track.name!,
),
() => blacklist.asData?.value.any(
(element) => element.elementId == track.id,
),
[blacklist, track],
);
Expand Down Expand Up @@ -258,13 +256,16 @@ class TrackOptions extends HookConsumerWidget {
.removeTracks(playlistId ?? "", [track.id!]);
break;
case TrackOptionValue.blacklist:
if (isBlackListed) {
ref.read(blacklistProvider.notifier).remove(
BlacklistedElement.track(track.id!, track.name!),
);
if (isBlackListed == null) break;
if (isBlackListed == true) {
await ref.read(blacklistProvider.notifier).remove(track.id!);
} else {
ref.read(blacklistProvider.notifier).add(
BlacklistedElement.track(track.id!, track.name!),
await ref.read(blacklistProvider.notifier).add(
BlacklistTableCompanion.insert(
name: track.name!,
elementId: track.id!,
elementType: BlacklistedType.track,
),
);
}
break;
Expand Down Expand Up @@ -363,7 +364,7 @@ class TrackOptions extends HookConsumerWidget {
: context.l10n.save_as_favorite,
),
),
if (auth != null && !isLocalTrack) ...[
if (auth.asData?.value != null && !isLocalTrack) ...[
PopSheetEntry(
value: TrackOptionValue.startRadio,
leading: const Icon(SpotubeIcons.radio),
Expand All @@ -375,7 +376,7 @@ class TrackOptions extends HookConsumerWidget {
title: Text(context.l10n.add_to_playlist),
),
],
if (userPlaylist && auth != null && !isLocalTrack)
if (userPlaylist && auth.asData?.value != null && !isLocalTrack)
PopSheetEntry(
value: TrackOptionValue.removeFromPlaylist,
leading: const Icon(SpotubeIcons.removeFilled),
Expand All @@ -399,10 +400,10 @@ class TrackOptions extends HookConsumerWidget {
PopSheetEntry(
value: TrackOptionValue.blacklist,
leading: const Icon(SpotubeIcons.playlistRemove),
iconColor: !isBlackListed ? Colors.red[400] : null,
textColor: !isBlackListed ? Colors.red[400] : null,
iconColor: isBlackListed != true ? Colors.red[400] : null,
textColor: isBlackListed != true ? Colors.red[400] : null,
title: Text(
isBlackListed
isBlackListed == true
? context.l10n.remove_from_blacklist
: context.l10n.add_to_blacklist,
),
Expand Down
Loading