Initial commit
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
|
||||
|
||||
part of 'player_page.dart';
|
||||
|
||||
|
||||
bool _isDanmakuLayoutChange(DanmakuPanelSettings a, DanmakuPanelSettings b) {
|
||||
return a.maxRows != b.maxRows ||
|
||||
a.fontSize != b.fontSize ||
|
||||
a.lineHeight != b.lineHeight ||
|
||||
a.fontFamily != b.fontFamily ||
|
||||
a.area != b.area;
|
||||
}
|
||||
|
||||
void _syncDanmakuFeederForSession(
|
||||
DanmakuFeeder feeder,
|
||||
PlaybackSession session,
|
||||
double posSec, {
|
||||
bool clear = false,
|
||||
}) {
|
||||
feeder.seekTo(posSec, clear: clear);
|
||||
if (session.isDanmakuActive) {
|
||||
feeder.playFrom(posSec);
|
||||
} else {
|
||||
feeder.freezeAt(posSec);
|
||||
}
|
||||
}
|
||||
|
||||
extension _PlayerPageDanmaku on _PlayerPageState {
|
||||
DanmakuOption _buildDanmakuOption(DanmakuPanelSettings settings) {
|
||||
final base = settings.toDanmakuOption(screenHeight: _danmakuOverlayHeight);
|
||||
if (_playbackRate == 1.0 || _playbackRate <= 0) return base;
|
||||
return base.copyWith(duration: base.duration / _playbackRate);
|
||||
}
|
||||
|
||||
void _applyDanmakuPanelSettings(DanmakuPanelSettings settings) {
|
||||
_panelSettings = settings;
|
||||
_feeder.setPanelSettings(settings, option: _buildDanmakuOption(settings));
|
||||
}
|
||||
|
||||
|
||||
void _wireDanmakuListeners() {
|
||||
final session = ref.read(danmakuSessionProvider).value;
|
||||
if (session != null) {
|
||||
_sessionState = session;
|
||||
if (session is DanmakuSessionMatched &&
|
||||
session.commentStatus == DanmakuCommentStatus.ready &&
|
||||
!identical(session, _lastSyncedDanmakuSession)) {
|
||||
_lastSyncedDanmakuSession = session;
|
||||
_feeder.setComments(session.comments);
|
||||
final s = _session;
|
||||
if (s != null) {
|
||||
_syncDanmakuFeederForSession(
|
||||
_feeder,
|
||||
s,
|
||||
s.engine.state.position.inMilliseconds / 1000.0,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
final settingsPanel = ref
|
||||
.read(danmakuSettingsProvider)
|
||||
.value
|
||||
?.panelSettings;
|
||||
if (settingsPanel != null && settingsPanel != _panelSettings) {
|
||||
_applyDanmakuPanelSettings(settingsPanel);
|
||||
}
|
||||
|
||||
ref.listen<AsyncValue<DanmakuSessionState>>(danmakuSessionProvider, (
|
||||
prev,
|
||||
next,
|
||||
) {
|
||||
final state = next.value;
|
||||
if (state == null) return;
|
||||
_sessionState = state;
|
||||
|
||||
if (state is DanmakuSessionMatched &&
|
||||
state.commentStatus == DanmakuCommentStatus.ready) {
|
||||
_lastSyncedDanmakuSession = state;
|
||||
_feeder.setComments(state.comments);
|
||||
final s = _session;
|
||||
if (s != null) {
|
||||
final posSec = s.engine.state.position.inMilliseconds / 1000.0;
|
||||
_syncDanmakuFeederForSession(_feeder, s, posSec);
|
||||
}
|
||||
} else {
|
||||
_lastSyncedDanmakuSession = null;
|
||||
_feeder.setComments(const []);
|
||||
}
|
||||
|
||||
_invalidateBottomBar();
|
||||
_refreshPanel();
|
||||
_invalidateDanmakuOverlay();
|
||||
});
|
||||
|
||||
ref.listen<AsyncValue<DanmakuSettingsState>>(danmakuSettingsProvider, (
|
||||
prev,
|
||||
next,
|
||||
) {
|
||||
final settings = next.value;
|
||||
if (settings == null) return;
|
||||
final newPanel = settings.panelSettings;
|
||||
final oldPanel = _panelSettings;
|
||||
final panelChanged = oldPanel != newPanel;
|
||||
final previousSettings = prev?.value;
|
||||
final keywordsChanged =
|
||||
previousSettings != null &&
|
||||
!listEquals(
|
||||
previousSettings.blockedKeywords,
|
||||
settings.blockedKeywords,
|
||||
);
|
||||
|
||||
final enabledChanged = oldPanel.enabled != newPanel.enabled;
|
||||
final offsetChanged = oldPanel.offset != newPanel.offset;
|
||||
final layoutChanged = _isDanmakuLayoutChange(oldPanel, newPanel);
|
||||
|
||||
|
||||
final opacityChanged = oldPanel.opacity != newPanel.opacity;
|
||||
if (panelChanged) {
|
||||
_applyDanmakuPanelSettings(newPanel);
|
||||
if (enabledChanged) {
|
||||
_invalidateBottomBar();
|
||||
}
|
||||
_invalidateDanmakuOverlay();
|
||||
final s = _session;
|
||||
if ((enabledChanged ||
|
||||
offsetChanged ||
|
||||
layoutChanged ||
|
||||
opacityChanged) &&
|
||||
s != null) {
|
||||
final posSec = s.engine.state.position.inMilliseconds / 1000.0;
|
||||
_syncDanmakuFeederForSession(_feeder, s, posSec, clear: true);
|
||||
}
|
||||
}
|
||||
if (panelChanged || keywordsChanged) {
|
||||
_refreshPanel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool get _danmakuLoaded =>
|
||||
_sessionState is DanmakuSessionMatched ||
|
||||
_sessionState is DanmakuSessionEmpty;
|
||||
|
||||
bool get _danmakuSearching =>
|
||||
_sessionState is DanmakuSessionMatching ||
|
||||
(_sessionState is DanmakuSessionMatched &&
|
||||
(_sessionState as DanmakuSessionMatched).commentStatus ==
|
||||
DanmakuCommentStatus.loading);
|
||||
|
||||
List<DanmakuMatchCandidate> get _danmakuMatches {
|
||||
final s = _sessionState;
|
||||
return s is DanmakuSessionMatched ? s.matches : const [];
|
||||
}
|
||||
|
||||
int get _danmakuSelectedMatchIndex {
|
||||
final s = _sessionState;
|
||||
return s is DanmakuSessionMatched ? s.selectedIndex : -1;
|
||||
}
|
||||
|
||||
int get _danmakuCommentCount {
|
||||
final s = _sessionState;
|
||||
return s is DanmakuSessionMatched ? s.comments.length : 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user