mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 16:05:18 +00:00
Fixed status color issue created by the new theme
ChooseColorSchemeDialog now scrollable Initial FutureProvider integration
This commit is contained in:
parent
066baa3745
commit
3f36c049f9
@ -1 +1,50 @@
|
|||||||
{"version":1,"script":["rm -rf AppDir || true","cp -r build/linux/x64/release/bundle AppDir","mkdir -p AppDir/usr/share/icons/hicolor/64x64/apps/","cp assets/spotube-logo.png AppDir/usr/share/icons/hicolor/"],"AppDir":{"path":"AppDir","app_info":{"id":"oss.krtirtho.spotube","icon":"spotube-logo","name":"spotube","version":"2.0.0+8","exec":"spotube","exec_args":"$@"},"apt":{"arch":"amd64","allow_unauthenticated":true,"sources":[{"sourceline":"deb http://archive.ubuntu.com/ubuntu/ hirsute main restricted"},{"sourceline":"deb http://archive.ubuntu.com/ubuntu/ hirsute-updates main restricted"},{"sourceline":"deb http://archive.ubuntu.com/ubuntu/ hirsute universe"},{"sourceline":"deb http://archive.ubuntu.com/ubuntu/ hirsute-updates universe"},{"sourceline":"deb http://archive.ubuntu.com/ubuntu/ hirsute multiverse"},{"sourceline":"deb http://archive.ubuntu.com/ubuntu/ hirsute-updates multiverse"},{"sourceline":"deb http://archive.ubuntu.com/ubuntu/ hirsute-backports main restricted universe multiverse"},{"sourceline":"deb http://security.ubuntu.com/ubuntu hirsute-security main restricted"},{"sourceline":"deb http://security.ubuntu.com/ubuntu hirsute-security universe"},{"sourceline":"deb http://security.ubuntu.com/ubuntu hirsute-security multiverse"}],"include":["libkeybinder-3.0-0"],"exclude":["libx11-6","libgtk-3-0","libglib2.0-0","libc6"]},"files":{"include":[],"exclude":[]}},"AppImage":{"arch":"x86_64","update-information":"guess"}}
|
# appimage-builder recipe see https://appimage-builder.readthedocs.io for details
|
||||||
|
version: 1
|
||||||
|
script:
|
||||||
|
- rm -rf AppDir || true
|
||||||
|
- cp -r build/linux/x64/release/bundle AppDir
|
||||||
|
- mkdir -p AppDir/usr/share/icons/hicolor/64x64/apps/
|
||||||
|
- cp assets/spotube-logo.png AppDir/usr/share/icons/hicolor/64x64/apps/
|
||||||
|
AppDir:
|
||||||
|
path: ./AppDir
|
||||||
|
app_info:
|
||||||
|
id: oss.krtirtho.spotube
|
||||||
|
name: Spotube
|
||||||
|
icon: spotube-logo
|
||||||
|
version: 2.0.0
|
||||||
|
exec: spotube
|
||||||
|
exec_args: $@
|
||||||
|
apt:
|
||||||
|
arch: amd64
|
||||||
|
allow_unauthenticated: true
|
||||||
|
sources:
|
||||||
|
- sourceline: deb http://bd.archive.ubuntu.com/ubuntu/ hirsute main restricted
|
||||||
|
- sourceline: deb http://bd.archive.ubuntu.com/ubuntu/ hirsute-updates main restricted
|
||||||
|
- sourceline: deb http://bd.archive.ubuntu.com/ubuntu/ hirsute universe
|
||||||
|
- sourceline: deb http://bd.archive.ubuntu.com/ubuntu/ hirsute-updates universe
|
||||||
|
- sourceline: deb http://bd.archive.ubuntu.com/ubuntu/ hirsute multiverse
|
||||||
|
- sourceline: deb http://bd.archive.ubuntu.com/ubuntu/ hirsute-updates multiverse
|
||||||
|
- sourceline:
|
||||||
|
deb http://bd.archive.ubuntu.com/ubuntu/ hirsute-backports main
|
||||||
|
restricted universe multiverse
|
||||||
|
- sourceline: deb http://security.ubuntu.com/ubuntu hirsute-security main restricted
|
||||||
|
- sourceline: deb http://security.ubuntu.com/ubuntu hirsute-security universe
|
||||||
|
- sourceline: deb http://security.ubuntu.com/ubuntu hirsute-security multiverse
|
||||||
|
include:
|
||||||
|
- libkeybinder-3.0-0
|
||||||
|
exclude:
|
||||||
|
- libx11-6
|
||||||
|
- libgtk-3-0
|
||||||
|
- libglib2.0-0
|
||||||
|
- libc6
|
||||||
|
files:
|
||||||
|
include: []
|
||||||
|
exclude:
|
||||||
|
- usr/share/man
|
||||||
|
- usr/share/doc/*/README.*
|
||||||
|
- usr/share/doc/*/changelog.*
|
||||||
|
- usr/share/doc/*/NEWS.*
|
||||||
|
- usr/share/doc/*/TODO.*
|
||||||
|
AppImage:
|
||||||
|
arch: x86_64
|
||||||
|
update-information: guess
|
||||||
|
@ -1,16 +1,21 @@
|
|||||||
// Generated file.
|
// Generated file.
|
||||||
|
//
|
||||||
// If you wish to remove Flutter's multidex support, delete this entire file.
|
// If you wish to remove Flutter's multidex support, delete this entire file.
|
||||||
|
//
|
||||||
|
// Modifications to this file should be done in a copy under a different name
|
||||||
|
// as this file may be regenerated.
|
||||||
|
|
||||||
package io.flutter.app;
|
package io.flutter.app;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
import androidx.multidex.MultiDex;
|
import androidx.multidex.MultiDex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension of {@link io.flutter.app.FlutterApplication}, adding multidex support.
|
* Extension of {@link android.app.Application}, adding multidex support.
|
||||||
*/
|
*/
|
||||||
public class FlutterMultiDexApplication extends FlutterApplication {
|
public class FlutterMultiDexApplication extends Application {
|
||||||
@Override
|
@Override
|
||||||
@CallSuper
|
@CallSuper
|
||||||
protected void attachBaseContext(Context base) {
|
protected void attachBaseContext(Context base) {
|
||||||
|
@ -127,21 +127,19 @@ class Home extends HookConsumerWidget {
|
|||||||
],
|
],
|
||||||
));
|
));
|
||||||
|
|
||||||
final brightness = Theme.of(context).brightness;
|
final backgroundColor = Theme.of(context).backgroundColor;
|
||||||
|
|
||||||
useEffect(() {
|
useEffect(() {
|
||||||
SystemChrome.setSystemUIOverlayStyle(
|
SystemChrome.setSystemUIOverlayStyle(
|
||||||
SystemUiOverlayStyle(
|
SystemUiOverlayStyle(
|
||||||
statusBarColor: brightness == Brightness.dark
|
statusBarColor: backgroundColor, // status bar color
|
||||||
? Colors.blueGrey[900]
|
statusBarIconBrightness: backgroundColor.computeLuminance() > 0.179
|
||||||
: Colors.white, // status bar color
|
? Brightness.dark
|
||||||
statusBarIconBrightness: brightness == Brightness.dark
|
: Brightness.light,
|
||||||
? Brightness.light
|
|
||||||
: Brightness.dark,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}, [brightness]);
|
}, [backgroundColor]);
|
||||||
|
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
|
@ -1,37 +1,32 @@
|
|||||||
import 'package:flutter/material.dart' hide Image;
|
import 'package:flutter/material.dart' hide Image;
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:spotify/spotify.dart';
|
|
||||||
import 'package:spotube/components/Album/AlbumCard.dart';
|
import 'package:spotube/components/Album/AlbumCard.dart';
|
||||||
import 'package:spotube/helpers/simple-album-to-album.dart';
|
import 'package:spotube/helpers/simple-album-to-album.dart';
|
||||||
import 'package:spotube/provider/SpotifyDI.dart';
|
import 'package:spotube/provider/SpotifyRequests.dart';
|
||||||
|
|
||||||
class UserAlbums extends ConsumerWidget {
|
class UserAlbums extends ConsumerWidget {
|
||||||
const UserAlbums({Key? key}) : super(key: key);
|
const UserAlbums({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
SpotifyApi spotifyApi = ref.watch(spotifyProvider);
|
final albums = ref.watch(currentUserAlbumsQuery);
|
||||||
|
|
||||||
return FutureBuilder<Iterable<AlbumSimple>>(
|
return albums.when(
|
||||||
future: spotifyApi.me.savedAlbums().all(),
|
data: (data) => SingleChildScrollView(
|
||||||
builder: (context, snapshot) {
|
|
||||||
if (!snapshot.hasData && snapshot.data == null) {
|
|
||||||
return const Center(child: CircularProgressIndicator.adaptive());
|
|
||||||
}
|
|
||||||
return SingleChildScrollView(
|
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Wrap(
|
child: Wrap(
|
||||||
spacing: 20, // gap between adjacent chips
|
spacing: 20, // gap between adjacent chips
|
||||||
runSpacing: 20, // gap between lines
|
runSpacing: 20, // gap between lines
|
||||||
alignment: WrapAlignment.center,
|
alignment: WrapAlignment.center,
|
||||||
children: snapshot.data!
|
children: data
|
||||||
.map((album) => AlbumCard(simpleAlbumToAlbum(album)))
|
.map((album) => AlbumCard(simpleAlbumToAlbum(album)))
|
||||||
.toList(),
|
.toList(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
},
|
loading: () => const Center(child: CircularProgressIndicator.adaptive()),
|
||||||
|
error: (_, __) => const Text("Failure is the pillar of success"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,21 +3,19 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
import 'package:spotube/components/Playlist/PlaylistCard.dart';
|
import 'package:spotube/components/Playlist/PlaylistCard.dart';
|
||||||
import 'package:spotube/components/Playlist/PlaylistCreateDialog.dart';
|
import 'package:spotube/components/Playlist/PlaylistCreateDialog.dart';
|
||||||
import 'package:spotube/provider/SpotifyDI.dart';
|
import 'package:spotube/provider/SpotifyRequests.dart';
|
||||||
|
|
||||||
class UserPlaylists extends ConsumerWidget {
|
class UserPlaylists extends ConsumerWidget {
|
||||||
const UserPlaylists({Key? key}) : super(key: key);
|
const UserPlaylists({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
SpotifyApi spotifyApi = ref.watch(spotifyProvider);
|
final playlists = ref.watch(currentUserPlaylistsQuery);
|
||||||
|
|
||||||
return FutureBuilder<Iterable<PlaylistSimple>>(
|
return playlists.when(
|
||||||
future: spotifyApi.playlists.me.all(),
|
loading: () =>
|
||||||
builder: (context, snapshot) {
|
const Center(child: CircularProgressIndicator.adaptive()),
|
||||||
if (!snapshot.hasData) {
|
data: (data) {
|
||||||
return const Center(child: CircularProgressIndicator.adaptive());
|
|
||||||
}
|
|
||||||
Image image = Image();
|
Image image = Image();
|
||||||
image.height = 300;
|
image.height = 300;
|
||||||
image.width = 300;
|
image.width = 300;
|
||||||
@ -40,14 +38,12 @@ class UserPlaylists extends ConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
const PlaylistCreateDialog(),
|
const PlaylistCreateDialog(),
|
||||||
PlaylistCard(likedTracksPlaylist),
|
PlaylistCard(likedTracksPlaylist),
|
||||||
...snapshot.data!
|
...data.map((playlist) => PlaylistCard(playlist)).toList(),
|
||||||
.map((playlist) => PlaylistCard(playlist))
|
|
||||||
.toList(),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
error: (_, __) => const Text("Failure is the pillar of success"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ class PlayerView extends HookConsumerWidget {
|
|||||||
|
|
||||||
final PaletteColor paletteColor = usePaletteColor(context, albumArt);
|
final PaletteColor paletteColor = usePaletteColor(context, albumArt);
|
||||||
|
|
||||||
final brightness = Theme.of(context).brightness;
|
final backgroundColor = Theme.of(context).backgroundColor;
|
||||||
|
|
||||||
useEffect(() {
|
useEffect(() {
|
||||||
SystemChrome.setSystemUIOverlayStyle(
|
SystemChrome.setSystemUIOverlayStyle(
|
||||||
@ -61,12 +61,10 @@ class PlayerView extends HookConsumerWidget {
|
|||||||
return () {
|
return () {
|
||||||
SystemChrome.setSystemUIOverlayStyle(
|
SystemChrome.setSystemUIOverlayStyle(
|
||||||
SystemUiOverlayStyle(
|
SystemUiOverlayStyle(
|
||||||
statusBarColor: brightness == Brightness.dark
|
statusBarColor: backgroundColor, // status bar color
|
||||||
? Colors.blueGrey[900]
|
statusBarIconBrightness: backgroundColor.computeLuminance() > 0.179
|
||||||
: Colors.white, // status bar color
|
? Brightness.dark
|
||||||
statusBarIconBrightness: brightness == Brightness.dark
|
: Brightness.light,
|
||||||
? Brightness.light
|
|
||||||
: Brightness.dark,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -75,6 +75,7 @@ class ColorSchemePickerDialog extends HookConsumerWidget {
|
|||||||
content: SizedBox(
|
content: SizedBox(
|
||||||
height: 200,
|
height: 200,
|
||||||
width: 400,
|
width: 400,
|
||||||
|
child: SingleChildScrollView(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Wrap(
|
child: Wrap(
|
||||||
spacing: 10,
|
spacing: 10,
|
||||||
@ -94,6 +95,7 @@ class ColorSchemePickerDialog extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,10 @@ final logger = getLogger("ServerIPC");
|
|||||||
Future<String?> connectIpc(String authUri, String redirectUri) async {
|
Future<String?> connectIpc(String authUri, String redirectUri) async {
|
||||||
try {
|
try {
|
||||||
logger.i("[Launching]: $authUri");
|
logger.i("[Launching]: $authUri");
|
||||||
await launchUrl(Uri.parse(authUri));
|
await launchUrl(
|
||||||
|
Uri.parse(authUri),
|
||||||
|
mode: LaunchMode.externalApplication,
|
||||||
|
);
|
||||||
|
|
||||||
HttpServer server =
|
HttpServer server =
|
||||||
await HttpServer.bind(InternetAddress.loopbackIPv4, 4304);
|
await HttpServer.bind(InternetAddress.loopbackIPv4, 4304);
|
||||||
@ -37,4 +40,5 @@ Future<String?> connectIpc(String authUri, String redirectUri) async {
|
|||||||
logger.e("connectIpc", e, stack);
|
logger.e("connectIpc", e, stack);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
30
lib/provider/SpotifyRequests.dart
Normal file
30
lib/provider/SpotifyRequests.dart
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:spotube/provider/SpotifyDI.dart';
|
||||||
|
import 'package:spotify/spotify.dart';
|
||||||
|
import 'package:spotube/provider/UserPreferences.dart';
|
||||||
|
|
||||||
|
final categoriesQuery = FutureProvider.family<Page<Category>, int>(
|
||||||
|
(ref, pageKey) {
|
||||||
|
final spotify = ref.watch(spotifyProvider);
|
||||||
|
final recommendationMarket = ref.watch(
|
||||||
|
userPreferencesProvider.select((s) => s.recommendationMarket),
|
||||||
|
);
|
||||||
|
return spotify.categories
|
||||||
|
.list(country: recommendationMarket)
|
||||||
|
.getPage(15, pageKey);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
final currentUserPlaylistsQuery = FutureProvider<Iterable<PlaylistSimple>>(
|
||||||
|
(ref) {
|
||||||
|
final spotify = ref.watch(spotifyProvider);
|
||||||
|
return spotify.playlists.me.all();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
final currentUserAlbumsQuery = FutureProvider<Iterable<AlbumSimple>>(
|
||||||
|
(ref) {
|
||||||
|
final spotify = ref.watch(spotifyProvider);
|
||||||
|
return spotify.me.savedAlbums().all();
|
||||||
|
},
|
||||||
|
);
|
Loading…
Reference in New Issue
Block a user