Files

109 lines
3.2 KiB
Dart
Raw Permalink Normal View History

2026-07-14 11:11:36 +08:00
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;
}
}