Initial commit
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
|
||||
|
||||
part of 'player_page.dart';
|
||||
|
||||
extension _PlayerPageVersionBar on _PlayerPageState {
|
||||
|
||||
|
||||
Widget _buildVersionBarLayer(PlaybackSession session) {
|
||||
return ValueListenableBuilder<bool>(
|
||||
valueListenable: _versionBarOpen,
|
||||
builder: (context, open, _) {
|
||||
return Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
if (open)
|
||||
Positioned.fill(
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () => _versionBarOpen.value = false,
|
||||
child: const SizedBox.expand(),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: 16,
|
||||
right: 16,
|
||||
bottom: Platform.isAndroid ? 96 : 72,
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
switchInCurve: Curves.easeOutCubic,
|
||||
switchOutCurve: Curves.easeInCubic,
|
||||
transitionBuilder: (child, anim) => FadeTransition(
|
||||
opacity: anim,
|
||||
child: SlideTransition(
|
||||
position: Tween<Offset>(
|
||||
begin: const Offset(0, 0.15),
|
||||
end: Offset.zero,
|
||||
).animate(anim),
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
child: open
|
||||
? _buildVersionBar(session)
|
||||
: const SizedBox.shrink(key: ValueKey('version-bar-empty')),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Widget _buildVersionBar(PlaybackSession session) {
|
||||
final entries = _buildVersionCardData(session);
|
||||
if (entries.isEmpty) {
|
||||
return const SizedBox.shrink(key: ValueKey('version-bar-empty'));
|
||||
}
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {},
|
||||
child: KeyedSubtree(
|
||||
key: const ValueKey('version-bar'),
|
||||
child: VersionPanel(
|
||||
entries: entries,
|
||||
onClose: () => _versionBarOpen.value = false,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
List<VersionSourceCardData> _buildVersionCardData(PlaybackSession session) {
|
||||
final ctx = session.context;
|
||||
final localSources = ctx.allMediaSources;
|
||||
final currentSourceId = ctx.mediaSourceId;
|
||||
final currentServerName =
|
||||
_lastRequest?.targetServer?.serverName ??
|
||||
ref.read(activeSessionProvider)?.serverName ??
|
||||
'本服务器';
|
||||
|
||||
final entries = <VersionSourceCardData>[];
|
||||
for (final src in localSources) {
|
||||
final isCurrent = src.Id != null && src.Id == currentSourceId;
|
||||
final sourceId = src.Id;
|
||||
entries.add(
|
||||
VersionSourceCardData.fromLocalSource(
|
||||
src,
|
||||
serverName: currentServerName,
|
||||
serverKey: ctx.serverId,
|
||||
isCurrent: isCurrent,
|
||||
tooltip: isCurrent ? null : '以该版本播放',
|
||||
onTap: (isCurrent || sourceId == null)
|
||||
? null
|
||||
: () => _switchVersion(sourceId),
|
||||
),
|
||||
);
|
||||
}
|
||||
for (final card in _crossServerCards) {
|
||||
entries.add(
|
||||
VersionSourceCardData.fromCrossServer(
|
||||
card,
|
||||
onTap: () => _switchToCrossServer(card),
|
||||
),
|
||||
);
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user