mirror of
https://github.com/Dr-Blank/Vaani.git
synced 2026-02-15 22:09:35 +00:00
优化一下通知栏显示
This commit is contained in:
parent
d6894c3191
commit
f4f860f3ec
12 changed files with 133 additions and 69 deletions
|
|
@ -48,6 +48,8 @@ PODS:
|
||||||
- just_audio (0.0.1):
|
- just_audio (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
- media_kit_libs_ios_audio (1.0.4):
|
||||||
|
- Flutter
|
||||||
- package_info_plus (0.4.5):
|
- package_info_plus (0.4.5):
|
||||||
- Flutter
|
- Flutter
|
||||||
- path_provider_foundation (0.0.1):
|
- path_provider_foundation (0.0.1):
|
||||||
|
|
@ -80,6 +82,7 @@ DEPENDENCIES:
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
- isar_flutter_libs (from `.symlinks/plugins/isar_flutter_libs/ios`)
|
- isar_flutter_libs (from `.symlinks/plugins/isar_flutter_libs/ios`)
|
||||||
- just_audio (from `.symlinks/plugins/just_audio/darwin`)
|
- just_audio (from `.symlinks/plugins/just_audio/darwin`)
|
||||||
|
- media_kit_libs_ios_audio (from `.symlinks/plugins/media_kit_libs_ios_audio/ios`)
|
||||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||||
|
|
@ -113,6 +116,8 @@ EXTERNAL SOURCES:
|
||||||
:path: ".symlinks/plugins/isar_flutter_libs/ios"
|
:path: ".symlinks/plugins/isar_flutter_libs/ios"
|
||||||
just_audio:
|
just_audio:
|
||||||
:path: ".symlinks/plugins/just_audio/darwin"
|
:path: ".symlinks/plugins/just_audio/darwin"
|
||||||
|
media_kit_libs_ios_audio:
|
||||||
|
:path: ".symlinks/plugins/media_kit_libs_ios_audio/ios"
|
||||||
package_info_plus:
|
package_info_plus:
|
||||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
|
|
@ -141,6 +146,7 @@ SPEC CHECKSUMS:
|
||||||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||||
isar_flutter_libs: b69f437aeab9c521821c3f376198c4371fa21073
|
isar_flutter_libs: b69f437aeab9c521821c3f376198c4371fa21073
|
||||||
just_audio: a42c63806f16995daf5b219ae1d679deb76e6a79
|
just_audio: a42c63806f16995daf5b219ae1d679deb76e6a79
|
||||||
|
media_kit_libs_ios_audio: 8f39d96a9c630685dfb844c289bd1d114c486fb3
|
||||||
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
|
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
|
||||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||||
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
|
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,6 @@
|
||||||
3E1CA9493996109C19FFDD1A /* Pods-RunnerTests.release.xcconfig */,
|
3E1CA9493996109C19FFDD1A /* Pods-RunnerTests.release.xcconfig */,
|
||||||
9830F7B941AA345666516454 /* Pods-RunnerTests.profile.xcconfig */,
|
9830F7B941AA345666516454 /* Pods-RunnerTests.profile.xcconfig */,
|
||||||
);
|
);
|
||||||
name = Pods;
|
|
||||||
path = Pods;
|
path = Pods;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
|
@ -492,6 +491,7 @@
|
||||||
DEVELOPMENT_TEAM = UV4P38S7RL;
|
DEVELOPMENT_TEAM = UV4P38S7RL;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
|
@ -675,11 +675,12 @@
|
||||||
DEVELOPMENT_TEAM = UV4P38S7RL;
|
DEVELOPMENT_TEAM = UV4P38S7RL;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = dr.blank.vaani;
|
PRODUCT_BUNDLE_IDENTIFIER = dr.blank.vaani.debug;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
|
@ -698,6 +699,7 @@
|
||||||
DEVELOPMENT_TEAM = UV4P38S7RL;
|
DEVELOPMENT_TEAM = UV4P38S7RL;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
|
<true/>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
|
|
@ -24,6 +26,17 @@
|
||||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>NSAppTransportSecurity</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
|
<true/>
|
||||||
|
<key>UIBackgroundModes</key>
|
||||||
|
<array>
|
||||||
|
<string>audio</string>
|
||||||
|
</array>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
<string>LaunchScreen</string>
|
<string>LaunchScreen</string>
|
||||||
<key>UIMainStoryboardFile</key>
|
<key>UIMainStoryboardFile</key>
|
||||||
|
|
@ -41,18 +54,5 @@
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
</array>
|
</array>
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
|
||||||
<true/>
|
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
|
||||||
<true/>
|
|
||||||
<key>NSAppTransportSecurity</key>
|
|
||||||
<dict>
|
|
||||||
<key>NSAllowsArbitraryLoads</key>
|
|
||||||
<true/>
|
|
||||||
</dict>
|
|
||||||
<key>UIBackgroundModes</key>
|
|
||||||
<array>
|
|
||||||
<string>audio</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,45 @@
|
||||||
import 'package:audio_service/audio_service.dart';
|
import 'package:audio_service/audio_service.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:media_kit/media_kit.dart';
|
import 'package:media_kit/media_kit.dart';
|
||||||
|
import 'package:vaani/features/player/providers/abs_provider.dart';
|
||||||
|
|
||||||
class AbsAudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler {
|
class AbsAudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler {
|
||||||
final Player player = Player();
|
final Player player = Player();
|
||||||
|
|
||||||
AbsAudioHandler() {
|
AbsAudioHandler(Ref ref) {
|
||||||
|
playbackState.add(
|
||||||
|
playbackState.value.copyWith(
|
||||||
|
controls: [
|
||||||
|
MediaControl.skipToPrevious,
|
||||||
|
if (player.state.playing) MediaControl.pause else MediaControl.play,
|
||||||
|
// MediaControl.rewind,
|
||||||
|
// MediaControl.fastForward,
|
||||||
|
MediaControl.skipToNext,
|
||||||
|
MediaControl.stop,
|
||||||
|
],
|
||||||
|
systemActions: {
|
||||||
|
MediaAction.play,
|
||||||
|
MediaAction.pause,
|
||||||
|
MediaAction.seek,
|
||||||
|
MediaAction.seekForward,
|
||||||
|
MediaAction.seekBackward,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final absState = ref.read(absStateProvider.notifier);
|
||||||
// 1. 转发播放/暂停状态
|
// 1. 转发播放/暂停状态
|
||||||
player.stream.playing.listen((bool playing) {
|
player.stream.playing.listen((bool playing) {
|
||||||
playbackState.add(playbackState.value.copyWith(
|
playbackState.add(playbackState.value.copyWith(
|
||||||
playing: playing,
|
playing: playing,
|
||||||
// 根据 playing 和实际情况更新 processingState
|
// 根据 playing 和实际情况更新 processingState
|
||||||
processingState:
|
processingState: player.state.completed
|
||||||
playing ? AudioProcessingState.ready : AudioProcessingState.idle,
|
? AudioProcessingState.completed
|
||||||
|
: player.state.buffering
|
||||||
|
? AudioProcessingState.buffering
|
||||||
|
: AudioProcessingState.ready,
|
||||||
));
|
));
|
||||||
|
absState.updataPlaying(playing);
|
||||||
});
|
});
|
||||||
// 2. 转发播放位置
|
// 2. 转发播放位置
|
||||||
player.stream.position.listen((Duration position) {
|
player.stream.position.listen((Duration position) {
|
||||||
|
|
@ -76,6 +103,10 @@ class AbsAudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> setVolume(double volume) async {
|
Future<void> setVolume(double volume) async {
|
||||||
|
final state = player.state;
|
||||||
await player.setVolume(volume);
|
await player.setVolume(volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PlayerStream get stream => player.stream;
|
||||||
|
PlayerState get state => player.state;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,22 +8,26 @@ class AbsPlayerState {
|
||||||
final api.BookChapter? currentChapter;
|
final api.BookChapter? currentChapter;
|
||||||
// 当前音轨序号
|
// 当前音轨序号
|
||||||
final int currentIndex;
|
final int currentIndex;
|
||||||
|
final bool playing;
|
||||||
|
|
||||||
AbsPlayerState({
|
AbsPlayerState({
|
||||||
this.book,
|
this.book,
|
||||||
this.currentChapter,
|
this.currentChapter,
|
||||||
this.currentIndex = 0,
|
this.currentIndex = 0,
|
||||||
|
this.playing = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
AbsPlayerState copyWith({
|
AbsPlayerState copyWith({
|
||||||
api.BookExpanded? book,
|
api.BookExpanded? book,
|
||||||
api.BookChapter? currentChapter,
|
api.BookChapter? currentChapter,
|
||||||
int? currentIndex,
|
int? currentIndex,
|
||||||
|
bool? playing,
|
||||||
}) {
|
}) {
|
||||||
return AbsPlayerState(
|
return AbsPlayerState(
|
||||||
book: book ?? this.book,
|
book: book ?? this.book,
|
||||||
currentChapter: currentChapter ?? this.currentChapter,
|
currentChapter: currentChapter ?? this.currentChapter,
|
||||||
currentIndex: currentIndex ?? this.currentIndex,
|
currentIndex: currentIndex ?? this.currentIndex,
|
||||||
|
playing: playing ?? this.playing,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
import 'package:audio_service/audio_service.dart';
|
|
||||||
import 'package:audio_session/audio_session.dart';
|
|
||||||
import 'package:media_kit/media_kit.dart';
|
|
||||||
import 'package:vaani/features/player/core/abs_audio_handler.dart' as core;
|
|
||||||
|
|
||||||
Future<core.AbsAudioHandler> absAudioHandlerInit() async {
|
|
||||||
// for playing audio on windows, linux
|
|
||||||
MediaKit.ensureInitialized();
|
|
||||||
// for configuring how this app will interact with other audio apps
|
|
||||||
final session = await AudioSession.instance;
|
|
||||||
await session.configure(const AudioSessionConfiguration.speech());
|
|
||||||
|
|
||||||
final audioService = await AudioService.init(
|
|
||||||
builder: () => core.AbsAudioHandler(),
|
|
||||||
config: const AudioServiceConfig(
|
|
||||||
androidNotificationChannelId: 'dr.blank.vaani.channel.audio',
|
|
||||||
androidNotificationChannelName: 'ABSPlayback',
|
|
||||||
androidNotificationChannelDescription:
|
|
||||||
'Needed to control audio from lock screen',
|
|
||||||
androidNotificationOngoing: false,
|
|
||||||
androidStopForegroundOnPause: false,
|
|
||||||
androidNotificationIcon: 'drawable/ic_stat_logo',
|
|
||||||
preloadArtwork: true,
|
|
||||||
// fastForwardInterval: Duration(seconds: 20),
|
|
||||||
// rewindInterval: Duration(seconds: 20),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
return audioService;
|
|
||||||
}
|
|
||||||
|
|
@ -30,7 +30,7 @@ Future<core.AbsAudioHandler> absAudioHandlerInit(Ref ref) async {
|
||||||
await session.configure(const AudioSessionConfiguration.speech());
|
await session.configure(const AudioSessionConfiguration.speech());
|
||||||
|
|
||||||
final audioService = await AudioService.init(
|
final audioService = await AudioService.init(
|
||||||
builder: () => core.AbsAudioHandler(),
|
builder: () => core.AbsAudioHandler(ref),
|
||||||
config: const AudioServiceConfig(
|
config: const AudioServiceConfig(
|
||||||
androidNotificationChannelId: 'dr.blank.vaani.channel.audio',
|
androidNotificationChannelId: 'dr.blank.vaani.channel.audio',
|
||||||
androidNotificationChannelName: 'ABSPlayback',
|
androidNotificationChannelName: 'ABSPlayback',
|
||||||
|
|
@ -91,9 +91,9 @@ class AbsState extends _$AbsState {
|
||||||
final initialIndex = book.tracks.indexOf(trackToPlay);
|
final initialIndex = book.tracks.indexOf(trackToPlay);
|
||||||
final initialPositionInTrack =
|
final initialPositionInTrack =
|
||||||
currentTime != null ? currentTime - trackToPlay.startOffset : null;
|
currentTime != null ? currentTime - trackToPlay.startOffset : null;
|
||||||
final title = appSettings.notificationSettings.primaryTitle
|
final album = appSettings.notificationSettings.primaryTitle
|
||||||
.formatNotificationTitle(book);
|
.formatNotificationTitle(book);
|
||||||
final album = appSettings.notificationSettings.secondaryTitle
|
final artlist = appSettings.notificationSettings.secondaryTitle
|
||||||
.formatNotificationTitle(book);
|
.formatNotificationTitle(book);
|
||||||
|
|
||||||
final id = _getUri(trackToPlay, downloadedUris,
|
final id = _getUri(trackToPlay, downloadedUris,
|
||||||
|
|
@ -101,10 +101,9 @@ class AbsState extends _$AbsState {
|
||||||
.toString();
|
.toString();
|
||||||
final item = MediaItem(
|
final item = MediaItem(
|
||||||
id: id,
|
id: id,
|
||||||
title: title,
|
title: chapterToPlay.title,
|
||||||
album: album,
|
album: album,
|
||||||
displayTitle: title,
|
artist: artlist,
|
||||||
displaySubtitle: album,
|
|
||||||
duration: chapterToPlay.duration,
|
duration: chapterToPlay.duration,
|
||||||
artUri: Uri.parse(
|
artUri: Uri.parse(
|
||||||
'${api.baseUrl}/api/items/${book.libraryItemId}/cover?token=${api.token!}',
|
'${api.baseUrl}/api/items/${book.libraryItemId}/cover?token=${api.token!}',
|
||||||
|
|
@ -154,6 +153,20 @@ class AbsState extends _$AbsState {
|
||||||
Future<void> next() async {}
|
Future<void> next() async {}
|
||||||
|
|
||||||
Future<void> previous() async {}
|
Future<void> previous() async {}
|
||||||
|
void updataPlaying(bool playing) {
|
||||||
|
state = state.copyWith(playing: playing);
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<Duration> get positionStreamInChapter {
|
||||||
|
final player = ref.read(absPlayerProvider);
|
||||||
|
|
||||||
|
return player.stream.position.distinct().map((position) {
|
||||||
|
return position +
|
||||||
|
(state.book?.tracks[state.currentIndex].startOffset ??
|
||||||
|
Duration.zero) -
|
||||||
|
(state.currentChapter?.start ?? Duration.zero);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Uri _getUri(
|
Uri _getUri(
|
||||||
api.AudioTrack track,
|
api.AudioTrack track,
|
||||||
|
|
@ -172,3 +185,8 @@ class AbsState extends _$AbsState {
|
||||||
Uri.parse('${baseUrl.toString()}${track.contentUrl}?token=$token');
|
Uri.parse('${baseUrl.toString()}${track.contentUrl}?token=$token');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@riverpod
|
||||||
|
Stream<Duration> positionChapter(Ref ref) {
|
||||||
|
return ref.watch(absStateProvider.notifier).positionStreamInChapter;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ part of 'abs_provider.dart';
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$absAudioHandlerInitHash() =>
|
String _$absAudioHandlerInitHash() =>
|
||||||
r'8815383b114e5e3da826afdea58bf0a884b1e3f2';
|
r'bb46f715e9d51bb6269d0d77e314665601a6bdb0';
|
||||||
|
|
||||||
/// See also [absAudioHandlerInit].
|
/// See also [absAudioHandlerInit].
|
||||||
@ProviderFor(absAudioHandlerInit)
|
@ProviderFor(absAudioHandlerInit)
|
||||||
|
|
@ -25,6 +25,23 @@ final absAudioHandlerInitProvider =
|
||||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
typedef AbsAudioHandlerInitRef = FutureProviderRef<core.AbsAudioHandler>;
|
typedef AbsAudioHandlerInitRef = FutureProviderRef<core.AbsAudioHandler>;
|
||||||
|
String _$positionChapterHash() => r'b1d19345bceb2e54399e15fbb16a534f4be5ba43';
|
||||||
|
|
||||||
|
/// See also [positionChapter].
|
||||||
|
@ProviderFor(positionChapter)
|
||||||
|
final positionChapterProvider = AutoDisposeStreamProvider<Duration>.internal(
|
||||||
|
positionChapter,
|
||||||
|
name: r'positionChapterProvider',
|
||||||
|
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||||
|
? null
|
||||||
|
: _$positionChapterHash,
|
||||||
|
dependencies: null,
|
||||||
|
allTransitiveDependencies: null,
|
||||||
|
);
|
||||||
|
|
||||||
|
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||||
|
// ignore: unused_element
|
||||||
|
typedef PositionChapterRef = AutoDisposeStreamProviderRef<Duration>;
|
||||||
String _$absPlayerHash() => r'c313a2456bb221b83f3cd2142ae63d6463ef304b';
|
String _$absPlayerHash() => r'c313a2456bb221b83f3cd2142ae63d6463ef304b';
|
||||||
|
|
||||||
/// See also [AbsPlayer].
|
/// See also [AbsPlayer].
|
||||||
|
|
@ -40,7 +57,7 @@ final absPlayerProvider =
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef _$AbsPlayer = Notifier<core.AbsAudioHandler>;
|
typedef _$AbsPlayer = Notifier<core.AbsAudioHandler>;
|
||||||
String _$absStateHash() => r'fb11d9d970e0de2dfd722c1f0de2a3b9b10f2859';
|
String _$absStateHash() => r'6b4ca07c7998304a1522a07b23955c3e54a441e3';
|
||||||
|
|
||||||
/// See also [AbsState].
|
/// See also [AbsState].
|
||||||
@ProviderFor(AbsState)
|
@ProviderFor(AbsState)
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,12 @@ import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:vaani/constants/sizes.dart';
|
import 'package:vaani/constants/sizes.dart';
|
||||||
|
import 'package:vaani/features/player/providers/abs_provider.dart';
|
||||||
import 'package:vaani/features/player/providers/audiobook_player.dart';
|
import 'package:vaani/features/player/providers/audiobook_player.dart';
|
||||||
import 'package:vaani/features/player/providers/currently_playing_provider.dart';
|
import 'package:vaani/features/player/providers/currently_playing_provider.dart';
|
||||||
import 'package:vaani/features/player/view/widgets/player_player_pause_button.dart';
|
import 'package:vaani/features/player/view/widgets/player_player_pause_button.dart';
|
||||||
import 'package:vaani/router/router.dart';
|
import 'package:vaani/router/router.dart';
|
||||||
|
import 'package:vaani/shared/extensions/chapter.dart';
|
||||||
import 'package:vaani/shared/extensions/model_conversions.dart';
|
import 'package:vaani/shared/extensions/model_conversions.dart';
|
||||||
import 'package:vaani/shared/widgets/shelves/book_shelf.dart';
|
import 'package:vaani/shared/widgets/shelves/book_shelf.dart';
|
||||||
|
|
||||||
|
|
@ -19,11 +21,12 @@ class PlayerMinimized extends HookConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final currentBook = ref.watch(currentBookProvider);
|
final currentBook = ref.watch(absStateProvider.select((v) => v.book));
|
||||||
if (currentBook == null) {
|
if (currentBook == null) {
|
||||||
return SizedBox.shrink();
|
return SizedBox.shrink();
|
||||||
}
|
}
|
||||||
final currentChapter = ref.watch(currentChapterProvider);
|
final currentChapter =
|
||||||
|
ref.watch(absStateProvider.select((v) => v.currentChapter));
|
||||||
|
|
||||||
return PlayerMinimizedFramework(
|
return PlayerMinimizedFramework(
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -112,9 +115,14 @@ class PlayerMinimizedFramework extends HookConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final player = ref.watch(playerProvider);
|
// final player = ref.watch(playerProvider);
|
||||||
|
final currentChapter =
|
||||||
|
ref.watch(absStateProvider.select((v) => v.currentChapter));
|
||||||
|
|
||||||
final progress =
|
final progress =
|
||||||
useStream(player.positionStreamInChapter, initialData: Duration.zero);
|
// useStream(player.positionStreamInChapter, initialData: Duration.zero);
|
||||||
|
useStream(ref.read(absStateProvider.notifier).positionStreamInChapter,
|
||||||
|
initialData: Duration.zero);
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (GoRouterState.of(context).topRoute?.name != Routes.player.name) {
|
if (GoRouterState.of(context).topRoute?.name != Routes.player.name) {
|
||||||
|
|
@ -136,7 +144,7 @@ class PlayerMinimizedFramework extends HookConsumerWidget {
|
||||||
height: AppElementSizes.barHeight,
|
height: AppElementSizes.barHeight,
|
||||||
child: LinearProgressIndicator(
|
child: LinearProgressIndicator(
|
||||||
value: (progress.data ?? Duration.zero).inSeconds /
|
value: (progress.data ?? Duration.zero).inSeconds /
|
||||||
(player.chapterDuration?.inSeconds ?? 1),
|
(currentChapter?.duration.inSeconds ?? 1),
|
||||||
// color: Theme.of(context).colorScheme.onPrimaryContainer,
|
// color: Theme.of(context).colorScheme.onPrimaryContainer,
|
||||||
// backgroundColor: Theme.of(context).colorScheme.primaryContainer,
|
// backgroundColor: Theme.of(context).colorScheme.primaryContainer,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import 'package:go_router/go_router.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:vaani/api/library_provider.dart' show currentLibraryProvider;
|
import 'package:vaani/api/library_provider.dart' show currentLibraryProvider;
|
||||||
import 'package:vaani/features/explore/providers/search_controller.dart';
|
import 'package:vaani/features/explore/providers/search_controller.dart';
|
||||||
|
import 'package:vaani/features/player/providers/abs_provider.dart';
|
||||||
import 'package:vaani/features/player/providers/currently_playing_provider.dart';
|
import 'package:vaani/features/player/providers/currently_playing_provider.dart';
|
||||||
import 'package:vaani/features/player/view/player_minimized.dart';
|
import 'package:vaani/features/player/view/player_minimized.dart';
|
||||||
import 'package:vaani/features/you/view/widgets/library_switch_chip.dart';
|
import 'package:vaani/features/you/view/widgets/library_switch_chip.dart';
|
||||||
|
|
@ -50,7 +51,8 @@ class ScaffoldWithNavBar extends HookConsumerWidget {
|
||||||
|
|
||||||
Widget buildNavLeft(BuildContext context, WidgetRef ref) {
|
Widget buildNavLeft(BuildContext context, WidgetRef ref) {
|
||||||
// final isPlayerActive = ref.watch(isPlayerActiveProvider);
|
// final isPlayerActive = ref.watch(isPlayerActiveProvider);
|
||||||
final currentBook = ref.watch(currentBookProvider);
|
// final currentBook = ref.watch(currentBookProvider);
|
||||||
|
final currentBook = ref.watch(absStateProvider.select((v) => v.book));
|
||||||
return Padding(
|
return Padding(
|
||||||
padding:
|
padding:
|
||||||
EdgeInsets.only(bottom: currentBook != null ? playerMinHeight : 0),
|
EdgeInsets.only(bottom: currentBook != null ? playerMinHeight : 0),
|
||||||
|
|
|
||||||
|
|
@ -216,13 +216,13 @@ class _BookOnShelfPlayButton extends HookConsumerWidget {
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final me = ref.watch(meProvider);
|
final me = ref.watch(meProvider);
|
||||||
// final player = ref.watch(audiobookPlayerProvider);
|
// final player = ref.watch(audiobookPlayerProvider);
|
||||||
final currentBook = ref.watch(currentBookProvider);
|
final currentBook = ref.watch(absStateProvider.select((v) => v.book));
|
||||||
final playerStatus = ref.watch(playerStatusProvider);
|
final playing = ref.watch(absStateProvider.select((v) => v.playing));
|
||||||
final isLoading = playerStatus.isLoading(libraryItemId);
|
// final playerStatus = ref.watch(playerStatusProvider);
|
||||||
|
// final isLoading = playerStatus.isLoading(libraryItemId);
|
||||||
final isCurrentBookSetInPlayer =
|
final isCurrentBookSetInPlayer =
|
||||||
currentBook?.libraryItemId == libraryItemId;
|
currentBook?.libraryItemId == libraryItemId;
|
||||||
final isPlayingThisBook =
|
final isPlayingThisBook = playing && isCurrentBookSetInPlayer;
|
||||||
playerStatus.isPlaying() && isCurrentBookSetInPlayer;
|
|
||||||
|
|
||||||
final userProgress = me.valueOrNull?.mediaProgress
|
final userProgress = me.valueOrNull?.mediaProgress
|
||||||
?.firstWhereOrNull((element) => element.libraryItemId == libraryItemId);
|
?.firstWhereOrNull((element) => element.libraryItemId == libraryItemId);
|
||||||
|
|
@ -308,7 +308,7 @@ class _BookOnShelfPlayButton extends HookConsumerWidget {
|
||||||
icon: Hero(
|
icon: Hero(
|
||||||
tag: HeroTagPrefixes.libraryItemPlayButton + libraryItemId,
|
tag: HeroTagPrefixes.libraryItemPlayButton + libraryItemId,
|
||||||
child: DynamicItemPlayIcon(
|
child: DynamicItemPlayIcon(
|
||||||
isLoading: isLoading,
|
// isLoading: isLoading,
|
||||||
isBookCompleted: isBookCompleted,
|
isBookCompleted: isBookCompleted,
|
||||||
isPlayingThisBook: isPlayingThisBook,
|
isPlayingThisBook: isPlayingThisBook,
|
||||||
isCurrentBookSetInPlayer: isCurrentBookSetInPlayer,
|
isCurrentBookSetInPlayer: isCurrentBookSetInPlayer,
|
||||||
|
|
@ -355,7 +355,7 @@ class BookCoverWidget extends HookConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final currentBook = ref.watch(currentBookProvider);
|
final currentBook = ref.watch(absStateProvider.select((v) => v.book));
|
||||||
if (currentBook == null) {
|
if (currentBook == null) {
|
||||||
return const BookCoverSkeleton();
|
return const BookCoverSkeleton();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ PODS:
|
||||||
- just_audio (0.0.1):
|
- just_audio (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
- media_kit_libs_macos_audio (1.0.4):
|
||||||
|
- FlutterMacOS
|
||||||
- package_info_plus (0.0.1):
|
- package_info_plus (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- path_provider_foundation (0.0.1):
|
- path_provider_foundation (0.0.1):
|
||||||
|
|
@ -44,6 +46,7 @@ DEPENDENCIES:
|
||||||
- FlutterMacOS (from `Flutter/ephemeral`)
|
- FlutterMacOS (from `Flutter/ephemeral`)
|
||||||
- isar_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/isar_flutter_libs/macos`)
|
- isar_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/isar_flutter_libs/macos`)
|
||||||
- just_audio (from `Flutter/ephemeral/.symlinks/plugins/just_audio/darwin`)
|
- just_audio (from `Flutter/ephemeral/.symlinks/plugins/just_audio/darwin`)
|
||||||
|
- media_kit_libs_macos_audio (from `Flutter/ephemeral/.symlinks/plugins/media_kit_libs_macos_audio/macos`)
|
||||||
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
|
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
|
||||||
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
|
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
- screen_retriever_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos`)
|
- screen_retriever_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos`)
|
||||||
|
|
@ -70,6 +73,8 @@ EXTERNAL SOURCES:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/isar_flutter_libs/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/isar_flutter_libs/macos
|
||||||
just_audio:
|
just_audio:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/just_audio/darwin
|
:path: Flutter/ephemeral/.symlinks/plugins/just_audio/darwin
|
||||||
|
media_kit_libs_macos_audio:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/media_kit_libs_macos_audio/macos
|
||||||
package_info_plus:
|
package_info_plus:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
|
|
@ -96,6 +101,7 @@ SPEC CHECKSUMS:
|
||||||
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
||||||
isar_flutter_libs: 43385c99864c168fadba7c9adeddc5d38838ca6a
|
isar_flutter_libs: 43385c99864c168fadba7c9adeddc5d38838ca6a
|
||||||
just_audio: a42c63806f16995daf5b219ae1d679deb76e6a79
|
just_audio: a42c63806f16995daf5b219ae1d679deb76e6a79
|
||||||
|
media_kit_libs_macos_audio: 3871782a4f3f84c77f04d7666c87800a781c24da
|
||||||
package_info_plus: 12f1c5c2cfe8727ca46cbd0b26677728972d9a5b
|
package_info_plus: 12f1c5c2cfe8727ca46cbd0b26677728972d9a5b
|
||||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||||
screen_retriever_macos: 776e0fa5d42c6163d2bf772d22478df4b302b161
|
screen_retriever_macos: 776e0fa5d42c6163d2bf772d22478df4b302b161
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue