mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
Android SafeArea issues fixed
configurations for different plugin for android added adjusted platform bound opertations
This commit is contained in:
parent
39a92a56f3
commit
c64f329c42
@ -1,34 +1,30 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="oss.krtirtho.spotube">
|
||||||
package="oss.krtirtho.spotube">
|
|
||||||
<application
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
android:label="spotube"
|
|
||||||
android:name="${applicationName}"
|
<queries>
|
||||||
android:icon="@mipmap/ic_launcher">
|
<!-- If your app opens https URLs -->
|
||||||
<activity
|
<intent>
|
||||||
android:name=".MainActivity"
|
<action android:name="android.intent.action.VIEW" />
|
||||||
android:exported="true"
|
<data android:scheme="https" />
|
||||||
android:launchMode="singleTop"
|
</intent>
|
||||||
android:theme="@style/LaunchTheme"
|
</queries>
|
||||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
|
||||||
android:hardwareAccelerated="true"
|
<application android:label="spotube" android:name="${applicationName}" android:icon="@mipmap/ic_launcher" android:usesCleartextTraffic="true">
|
||||||
android:windowSoftInputMode="adjustResize">
|
<activity android:name=".MainActivity" android:exported="true" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize">
|
||||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||||
the Android process has started. This theme is visible to the user
|
the Android process has started. This theme is visible to the user
|
||||||
while the Flutter UI initializes. After that, this theme continues
|
while the Flutter UI initializes. After that, this theme continues
|
||||||
to determine the Window background behind the Flutter UI. -->
|
to determine the Window background behind the Flutter UI. -->
|
||||||
<meta-data
|
<meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" />
|
||||||
android:name="io.flutter.embedding.android.NormalTheme"
|
|
||||||
android:resource="@style/NormalTheme"
|
|
||||||
/>
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
</activity>
|
</activity>
|
||||||
<!-- Don't delete the meta-data below.
|
<!-- Don't delete the meta-data below.
|
||||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||||
<meta-data
|
<meta-data android:name="flutterEmbedding" android:value="2" />
|
||||||
android:name="flutterEmbedding"
|
|
||||||
android:value="2" />
|
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
@ -1,5 +1,5 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.3.50'
|
ext.kotlin_version = '1.6.10'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@ -37,5 +37,11 @@ end
|
|||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
installer.pods_project.targets.each do |target|
|
installer.pods_project.targets.each do |target|
|
||||||
flutter_additional_ios_build_settings(target)
|
flutter_additional_ios_build_settings(target)
|
||||||
|
target.build_configurations.each do |config|
|
||||||
|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
|
||||||
|
'$(inherited)',
|
||||||
|
'AUDIO_SESSION_MICROPHONE=0'
|
||||||
|
]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -43,5 +43,12 @@
|
|||||||
</array>
|
</array>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<true />
|
<true />
|
||||||
|
<key>NSAppTransportSecurity</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
|
<true />
|
||||||
|
<key>NSAllowsArbitraryLoadsForMedia</key>
|
||||||
|
<true />
|
||||||
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
@ -38,7 +38,8 @@ class AlbumView extends ConsumerWidget {
|
|||||||
|
|
||||||
var isPlaylistPlaying = playback.currentPlaylist?.id == album.id;
|
var isPlaylistPlaying = playback.currentPlaylist?.id == album.id;
|
||||||
SpotifyApi spotify = ref.watch(spotifyProvider);
|
SpotifyApi spotify = ref.watch(spotifyProvider);
|
||||||
return Scaffold(
|
return SafeArea(
|
||||||
|
child: Scaffold(
|
||||||
body: FutureBuilder<Iterable<TrackSimple>>(
|
body: FutureBuilder<Iterable<TrackSimple>>(
|
||||||
future: spotify.albums.getTracks(album.id!).all(),
|
future: spotify.albums.getTracks(album.id!).all(),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
@ -95,6 +96,7 @@ class AlbumView extends ConsumerWidget {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,8 @@ class _ArtistAlbumViewState extends ConsumerState<ArtistAlbumView> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return SafeArea(
|
||||||
|
child: Scaffold(
|
||||||
appBar: const PageWindowTitleBar(leading: BackButton()),
|
appBar: const PageWindowTitleBar(leading: BackButton()),
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
@ -86,6 +87,7 @@ class _ArtistAlbumViewState extends ConsumerState<ArtistAlbumView> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,8 @@ class ArtistProfile extends HookConsumerWidget {
|
|||||||
|
|
||||||
final breakpoint = useBreakpoints();
|
final breakpoint = useBreakpoints();
|
||||||
|
|
||||||
return Scaffold(
|
return SafeArea(
|
||||||
|
child: Scaffold(
|
||||||
appBar: const PageWindowTitleBar(
|
appBar: const PageWindowTitleBar(
|
||||||
leading: BackButton(),
|
leading: BackButton(),
|
||||||
),
|
),
|
||||||
@ -128,7 +129,8 @@ class ArtistProfile extends HookConsumerWidget {
|
|||||||
text: snapshot
|
text: snapshot
|
||||||
.data?.externalUrls?.spotify),
|
.data?.externalUrls?.spotify),
|
||||||
).then((val) {
|
).then((val) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context)
|
||||||
|
.showSnackBar(
|
||||||
const SnackBar(
|
const SnackBar(
|
||||||
width: 300,
|
width: 300,
|
||||||
behavior: SnackBarBehavior.floating,
|
behavior: SnackBarBehavior.floating,
|
||||||
@ -198,8 +200,8 @@ class ArtistProfile extends HookConsumerWidget {
|
|||||||
: Icons.play_arrow_rounded),
|
: Icons.play_arrow_rounded),
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
onPressed: trackSnapshot.hasData
|
onPressed: trackSnapshot.hasData
|
||||||
? () =>
|
? () => playPlaylist(
|
||||||
playPlaylist(trackSnapshot.data!.toList())
|
trackSnapshot.data!.toList())
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -310,6 +312,7 @@ class ArtistProfile extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,8 @@ class Home extends HookConsumerWidget {
|
|||||||
return const Login();
|
return const Login();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Scaffold(
|
return SafeArea(
|
||||||
|
child: Scaffold(
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
WindowTitleBarBox(
|
WindowTitleBarBox(
|
||||||
@ -165,8 +166,9 @@ class Home extends HookConsumerWidget {
|
|||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
maxWidth: titleBarDragMaxWidth.toDouble(),
|
maxWidth: titleBarDragMaxWidth.toDouble(),
|
||||||
),
|
),
|
||||||
color:
|
color: Theme.of(context)
|
||||||
Theme.of(context).navigationRailTheme.backgroundColor,
|
.navigationRailTheme
|
||||||
|
.backgroundColor,
|
||||||
child: MoveWindow(),
|
child: MoveWindow(),
|
||||||
),
|
),
|
||||||
Expanded(child: MoveWindow()),
|
Expanded(child: MoveWindow()),
|
||||||
@ -212,6 +214,7 @@ class Home extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,8 @@ class PlayerView extends HookConsumerWidget {
|
|||||||
[currentTrack?.album?.images],
|
[currentTrack?.album?.images],
|
||||||
);
|
);
|
||||||
|
|
||||||
return Scaffold(
|
return SafeArea(
|
||||||
|
child: Scaffold(
|
||||||
appBar: const PageWindowTitleBar(
|
appBar: const PageWindowTitleBar(
|
||||||
leading: BackButton(),
|
leading: BackButton(),
|
||||||
),
|
),
|
||||||
@ -94,6 +95,7 @@ class PlayerView extends HookConsumerWidget {
|
|||||||
PlayerControls(iconColor: paletteColor.bodyTextColor),
|
PlayerControls(iconColor: paletteColor.bodyTextColor),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,8 @@ class PlaylistView extends ConsumerWidget {
|
|||||||
SpotifyApi spotifyApi = ref.watch(spotifyProvider);
|
SpotifyApi spotifyApi = ref.watch(spotifyProvider);
|
||||||
var isPlaylistPlaying = playback.currentPlaylist?.id != null &&
|
var isPlaylistPlaying = playback.currentPlaylist?.id != null &&
|
||||||
playback.currentPlaylist?.id == playlist.id;
|
playback.currentPlaylist?.id == playlist.id;
|
||||||
return Scaffold(
|
return SafeArea(
|
||||||
|
child: Scaffold(
|
||||||
body: FutureBuilder<Iterable<Track>>(
|
body: FutureBuilder<Iterable<Track>>(
|
||||||
future: playlist.id != "user-liked-tracks"
|
future: playlist.id != "user-liked-tracks"
|
||||||
? spotifyApi.playlists.getTracksByPlaylistId(playlist.id).all()
|
? spotifyApi.playlists.getTracksByPlaylistId(playlist.id).all()
|
||||||
@ -96,6 +97,7 @@ class PlaylistView extends ConsumerWidget {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,8 @@ class Settings extends HookConsumerWidget {
|
|||||||
geniusAccessToken.value = textEditingController.value.text;
|
geniusAccessToken.value = textEditingController.value.text;
|
||||||
});
|
});
|
||||||
|
|
||||||
return Scaffold(
|
return SafeArea(
|
||||||
|
child: Scaffold(
|
||||||
appBar: PageWindowTitleBar(
|
appBar: PageWindowTitleBar(
|
||||||
leading: const BackButton(),
|
leading: const BackButton(),
|
||||||
center: Text(
|
center: Text(
|
||||||
@ -62,8 +63,8 @@ class Settings extends HookConsumerWidget {
|
|||||||
? () async {
|
? () async {
|
||||||
SharedPreferences localStorage =
|
SharedPreferences localStorage =
|
||||||
await SharedPreferences.getInstance();
|
await SharedPreferences.getInstance();
|
||||||
preferences
|
preferences.setGeniusAccessToken(
|
||||||
.setGeniusAccessToken(geniusAccessToken.value);
|
geniusAccessToken.value);
|
||||||
localStorage.setString(
|
localStorage.setString(
|
||||||
LocalStorageKeys.geniusAccessToken,
|
LocalStorageKeys.geniusAccessToken,
|
||||||
geniusAccessToken.value ?? "");
|
geniusAccessToken.value ?? "");
|
||||||
@ -193,6 +194,7 @@ class Settings extends HookConsumerWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,10 +52,23 @@ class PageWindowTitleBar extends StatelessWidget
|
|||||||
const PageWindowTitleBar({Key? key, this.leading, this.center})
|
const PageWindowTitleBar({Key? key, this.leading, this.center})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
@override
|
@override
|
||||||
Size get preferredSize => Size.fromHeight(appWindow.titleBarHeight);
|
Size get preferredSize => Size.fromHeight(
|
||||||
|
!Platform.isIOS && !Platform.isAndroid ? appWindow.titleBarHeight : 0,
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
if (Platform.isIOS || Platform.isAndroid) {
|
||||||
|
return PreferredSize(
|
||||||
|
preferredSize: const Size.fromHeight(70),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
if (leading != null) leading!,
|
||||||
|
Expanded(child: Center(child: center)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
return WindowTitleBarBox(
|
return WindowTitleBarBox(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
|
@ -28,7 +28,6 @@ Future<void> Function() usePreviousTrack(Playback playback) {
|
|||||||
|
|
||||||
Future<void> Function([dynamic]) useTogglePlayPause(Playback playback) {
|
Future<void> Function([dynamic]) useTogglePlayPause(Playback playback) {
|
||||||
return ([key]) async {
|
return ([key]) async {
|
||||||
print("CLICK CLICK");
|
|
||||||
try {
|
try {
|
||||||
if (playback.currentTrack == null) return;
|
if (playback.currentTrack == null) return;
|
||||||
playback.isPlaying
|
playback.isPlaying
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:hotkey_manager/hotkey_manager.dart';
|
import 'package:hotkey_manager/hotkey_manager.dart';
|
||||||
@ -18,6 +20,7 @@ useHotKeys(WidgetRef ref) {
|
|||||||
final _playOrPause = useTogglePlayPause(playback);
|
final _playOrPause = useTogglePlayPause(playback);
|
||||||
|
|
||||||
useEffect(() {
|
useEffect(() {
|
||||||
|
if (Platform.isIOS || Platform.isAndroid) return null;
|
||||||
_hotKeys = [
|
_hotKeys = [
|
||||||
GlobalKeyActions(
|
GlobalKeyActions(
|
||||||
HotKey(KeyCode.space, scope: HotKeyScope.inapp),
|
HotKey(KeyCode.space, scope: HotKeyScope.inapp),
|
||||||
|
@ -14,9 +14,9 @@ import 'package:spotube/provider/ThemeProvider.dart';
|
|||||||
import 'package:spotube/provider/YouTube.dart';
|
import 'package:spotube/provider/YouTube.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
|
if (!Platform.isAndroid && !Platform.isIOS) {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
await hotKeyManager.unregisterAll();
|
await hotKeyManager.unregisterAll();
|
||||||
runApp(ProviderScope(child: MyApp()));
|
|
||||||
doWhenWindowReady(() {
|
doWhenWindowReady(() {
|
||||||
appWindow.minSize =
|
appWindow.minSize =
|
||||||
Size(Platform.isAndroid || Platform.isIOS ? 280 : 359, 700);
|
Size(Platform.isAndroid || Platform.isIOS ? 280 : 359, 700);
|
||||||
@ -26,9 +26,13 @@ void main() async {
|
|||||||
appWindow.show();
|
appWindow.show();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
runApp(ProviderScope(child: MyApp()));
|
||||||
|
}
|
||||||
|
|
||||||
class MyApp extends HookConsumerWidget {
|
class MyApp extends HookConsumerWidget {
|
||||||
final GoRouter _router = createGoRouter();
|
final GoRouter _router = createGoRouter();
|
||||||
|
|
||||||
|
MyApp({Key? key}) : super(key: key);
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
var themeMode = ref.watch(themeProvider);
|
var themeMode = ref.watch(themeProvider);
|
||||||
|
@ -5,7 +5,6 @@ import 'package:spotube/components/Album/AlbumView.dart';
|
|||||||
import 'package:spotube/components/Artist/ArtistAlbumView.dart';
|
import 'package:spotube/components/Artist/ArtistAlbumView.dart';
|
||||||
import 'package:spotube/components/Artist/ArtistProfile.dart';
|
import 'package:spotube/components/Artist/ArtistProfile.dart';
|
||||||
import 'package:spotube/components/Home/Home.dart';
|
import 'package:spotube/components/Home/Home.dart';
|
||||||
import 'package:spotube/components/Player/PlayerControls.dart';
|
|
||||||
import 'package:spotube/components/Player/PlayerView.dart';
|
import 'package:spotube/components/Player/PlayerView.dart';
|
||||||
import 'package:spotube/components/Playlist/PlaylistView.dart';
|
import 'package:spotube/components/Playlist/PlaylistView.dart';
|
||||||
import 'package:spotube/components/Settings.dart';
|
import 'package:spotube/components/Settings.dart';
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:audio_session/audio_session.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:just_audio/just_audio.dart';
|
import 'package:just_audio/just_audio.dart';
|
||||||
@ -60,9 +61,11 @@ class Playback extends ChangeNotifier {
|
|||||||
StreamSubscription<bool>? _playingStreamListener;
|
StreamSubscription<bool>? _playingStreamListener;
|
||||||
StreamSubscription<Duration?>? _durationStreamListener;
|
StreamSubscription<Duration?>? _durationStreamListener;
|
||||||
StreamSubscription<ProcessingState>? _processingStateStreamListener;
|
StreamSubscription<ProcessingState>? _processingStateStreamListener;
|
||||||
|
StreamSubscription<AudioInterruptionEvent>? _audioInterruptionEventListener;
|
||||||
|
|
||||||
AudioPlayer player;
|
AudioPlayer player;
|
||||||
YoutubeExplode youtube;
|
YoutubeExplode youtube;
|
||||||
|
AudioSession? _audioSession;
|
||||||
Playback({
|
Playback({
|
||||||
required this.player,
|
required this.player,
|
||||||
required this.youtube,
|
required this.youtube,
|
||||||
@ -107,6 +110,14 @@ class Playback extends ChangeNotifier {
|
|||||||
print(stack);
|
print(stack);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AudioSession.instance.then((session) async {
|
||||||
|
_audioSession = session;
|
||||||
|
await session.configure(const AudioSessionConfiguration.music());
|
||||||
|
_audioInterruptionEventListener = session.interruptionEventStream.listen(
|
||||||
|
(AudioInterruptionEvent event) {},
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentPlaylist? get currentPlaylist => _currentPlaylist;
|
CurrentPlaylist? get currentPlaylist => _currentPlaylist;
|
||||||
@ -175,6 +186,8 @@ class Playback extends ChangeNotifier {
|
|||||||
_processingStateStreamListener?.cancel();
|
_processingStateStreamListener?.cancel();
|
||||||
_durationStreamListener?.cancel();
|
_durationStreamListener?.cancel();
|
||||||
_playingStreamListener?.cancel();
|
_playingStreamListener?.cancel();
|
||||||
|
_audioInterruptionEventListener?.cancel();
|
||||||
|
_audioSession?.setActive(false);
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +219,7 @@ class Playback extends ChangeNotifier {
|
|||||||
// the track is already playing so no need to change that
|
// the track is already playing so no need to change that
|
||||||
if (track != null && track.id == _currentTrack?.id) return;
|
if (track != null && track.id == _currentTrack?.id) return;
|
||||||
track ??= _currentTrack;
|
track ??= _currentTrack;
|
||||||
if (track != null) {
|
if (track != null && await _audioSession?.setActive(true) == true) {
|
||||||
Uri? parsedUri = Uri.tryParse(track.uri ?? "");
|
Uri? parsedUri = Uri.tryParse(track.uri ?? "");
|
||||||
if (parsedUri != null && parsedUri.hasAbsolutePath) {
|
if (parsedUri != null && parsedUri.hasAbsolutePath) {
|
||||||
await player
|
await player
|
||||||
|
@ -30,7 +30,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "2.8.2"
|
version: "2.8.2"
|
||||||
audio_session:
|
audio_session:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: audio_session
|
name: audio_session
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
@ -323,7 +323,7 @@ packages:
|
|||||||
name: just_audio_web
|
name: just_audio_web
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.4"
|
version: "0.4.7"
|
||||||
libwinmedia:
|
libwinmedia:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -54,6 +54,7 @@ dependencies:
|
|||||||
hooks_riverpod: ^1.0.3
|
hooks_riverpod: ^1.0.3
|
||||||
go_router: ^3.0.4
|
go_router: ^3.0.4
|
||||||
palette_generator: ^0.3.3
|
palette_generator: ^0.3.3
|
||||||
|
audio_session: ^0.1.6+1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
Reference in New Issue
Block a user