Files
discord-decomp/modules/media/native/MediaPlayerManager.tsx
T
2026-11-01 12:12:55 +02:00

408 lines
16 KiB
TypeScript

// Metro module 13590 (f13591).
import { NativeEventEmitter, NativeModules } from "react-native";
import EmbeddedActivitiesStore from "../../activities/EmbeddedActivitiesStore";
import VoicePanelStore from "../../voice_panel/VoicePanelStore";
import ChannelStore from "../../../stores/ChannelStore";
import MessageStore from "../../../stores/MessageStore";
import PermissionStore from "../../../stores/PermissionStore";
import AppStateStore from "../../../stores/native/AppStateStore";
import { AppStates } from "../../../Constants";
import { ActivityPanelModes } from "../../activities/panel/ActivityPanelConstants";
import { PLAYBACK_COMPLETION_DETECTION_TOLERANCE, PLAYBACK_PROGRESS_UPDATE_INTERVAL } from "../../media_panel/native/MediaPlaybackPanelConstants";
import { Permissions } from "../../../_bundle/Module505";
import Logger from "../../debug/Logger";
import { create } from "../../../_bundle/Module644";
import { batchUpdates } from "../../../_bundle/Module705";
import LifecycleManager from "../../../lib/LifecycleManager";
import { getRootNavigationRef } from "../../main_tabs_v2/RootNavigationRef.native";
import Dispatcher from "../../../Dispatcher";
import { isIOS } from "../../../utils/PlatformUtils";
import shallowEqual from "../../../_bundle/shallowEqual";
import MessageActionCreators from "../../../actions/MessageActionCreators";
import { getFocusedChannelId } from "../../panels/isChannelFocused.native";
import { $callWithNewTarget } from "../../../_hermes/prelude";
let c9437_16 = new Logger("MediaPlayerManager");
let c9437_17 = create((c20557_0) => ({
activeMediaPlayerSource: void 0,
mediaSourceMessage: void 0,
canAccessMedia: true,
isPlaying: false,
wasPipClosedByUser: false,
progress: void 0,
rate: 0,
showPip: false,
closePip: () => {
batchUpdates(() => c20557_0({
showPip: false
}));
},
displayedMediaItemIdsPerChannel: {},
currentlyDisplayedChannelId: void 0
}));
class MediaPlayerManager extends LifecycleManager {
subscriptions = [];
voicePanelStoreUnsubscribe = void 0;
showPipUnsubscribe = void 0;
pauseAndClosePip = this.pauseAndClosePip.bind(this);
handleVoicePanelStateUpdated = this.handleVoicePanelStateUpdated.bind(this);
handleEmbeddedActivitiesUpdated = this.handleEmbeddedActivitiesUpdated.bind(this);
handleMediaPlayerPlaybackRateChanged = this.handleMediaPlayerPlaybackRateChanged.bind(this);
handleMediaPlayerPlaybackSourceChanged = this.handleMediaPlayerPlaybackSourceChanged.bind(this);
handleMediaPlayerViewWillAppear = this.handleMediaPlayerViewWillAppear.bind(this);
handleMediaPlayerViewDidDisappear = this.handleMediaPlayerViewDidDisappear.bind(this);
updateDisplayState = this.updateDisplayState.bind(this);
updateMediaPermissions = this.updateMediaPermissions.bind(this);
constructor() {
super();
}
_initialize() {
const nativeEventEmitter = new NativeEventEmitter(NativeModules.MediaPlayerManager);
this.subscriptions = [nativeEventEmitter.addListener("MediaPlayerPlaybackSourceChanged", this.handleMediaPlayerPlaybackSourceChanged), nativeEventEmitter.addListener("MediaPlayerPlaybackProgressUpdated", this.handleMediaPlayerPlaybackProgressUpdated), nativeEventEmitter.addListener("MediaPlayerPlaybackRateChanged", this.handleMediaPlayerPlaybackRateChanged), nativeEventEmitter.addListener("MediaPlayerViewWillAppear", this.handleMediaPlayerViewWillAppear), nativeEventEmitter.addListener("MediaPlayerViewDidDisappear", this.handleMediaPlayerViewDidDisappear)];
NativeModules.MediaPlayerManager.subscribeToPlaybackEvents();
const rootNavigationRef = getRootNavigationRef();
if (rootNavigationRef != null) {
rootNavigationRef.addListener("state", this.updateDisplayState);
}
this.voicePanelStoreUnsubscribe = VoicePanelStore.subscribe(this.handleVoicePanelStateUpdated);
EmbeddedActivitiesStore.addChangeListener(this.handleEmbeddedActivitiesUpdated);
ChannelStore.addChangeListener(this.updateMediaPermissions);
PermissionStore.addChangeListener(this.updateMediaPermissions);
Dispatcher.subscribe("LOGOUT", this.userDidClosePip);
if (isIOS()) {
this.showPipUnsubscribe = c9437_17.subscribe((a0, a1) => {
if (a1.showPip && !a0.showPip) {
NativeModules.MediaPlayerManager.clearNowPlayingInfo();
} else if (a1.rate !== 0 && a0.rate === 0 && !a0.showPip && AppStateStore.getState() === AppStates.ACTIVE) {
NativeModules.MediaPlayerManager.clearNowPlayingInfo();
}
});
}
c9437_16.verbose("Initialized and subscribed to playback events");
}
updateMediaPermissions() {
batchUpdates(() => {
let r10 = c9437_17.getState().activeMediaPlayerSource?.channelId;
if (r10 == null) {
r10 = null;
}
const channel = ChannelStore.getChannel(r10);
if (channel != null && (!channel.isPrivate() && !PermissionStore.can(Permissions.VIEW_CHANNEL, channel))) {
c9437_17.setState({
canAccessMedia: false
});
this.pauseCurrentPlayer();
} else {
c9437_17.setState({
canAccessMedia: true
});
}
});
}
_terminate() {
this.subscriptions.forEach((subscription) => subscription.remove());
this.subscriptions = [];
const rootNavigationRef = getRootNavigationRef();
if (rootNavigationRef != null) {
rootNavigationRef.removeListener("state", this.updateDisplayState);
}
const voicePanelStoreUnsubscribe = this.voicePanelStoreUnsubscribe;
if (voicePanelStoreUnsubscribe != null) {
voicePanelStoreUnsubscribe.call(this);
}
const showPipUnsubscribe = this.showPipUnsubscribe;
if (showPipUnsubscribe != null) {
showPipUnsubscribe.call(this);
}
EmbeddedActivitiesStore.removeChangeListener(this.handleEmbeddedActivitiesUpdated);
ChannelStore.removeChangeListener(this.updateMediaPermissions);
PermissionStore.removeChangeListener(this.updateMediaPermissions);
Dispatcher.unsubscribe("LOGOUT", this.userDidClosePip);
}
pauseCurrentPlayer() {
NativeModules.MediaPlayerManager.pauseCurrentPlayer();
}
playCurrentPlayer() {
NativeModules.MediaPlayerManager.playCurrentPlayer();
}
userDidClosePip() {
batchUpdates(() => c9437_17.setState({
wasPipClosedByUser: true,
showPip: false
}));
}
pauseAndClosePip() {
batchUpdates(() => {
this.pauseCurrentPlayer();
c9437_17.setState({
wasPipClosedByUser: true,
showPip: false
});
});
}
handleVoicePanelStateUpdated() {
const state = VoicePanelStore.getState();
if (state.isVoicePanelFullscreen() || state.voicePanelsPIP.size > 0) {
this.pauseAndClosePip();
}
}
handleEmbeddedActivitiesUpdated() {
if (EmbeddedActivitiesStore.getActivityPanelMode() === ActivityPanelModes.PIP) {
this.pauseAndClosePip();
}
}
handleMediaPlayerPlaybackRateChanged({ source, rate }) {
batchUpdates(() => {
if (source == null) {
c9437_17.setState({
rate: 0,
isPlaying: false
});
}
c9437_16.verbose(`Playback rate changed to ${rate}: ${source?.id}`);
const state = c9437_17.getState();
const { activeMediaPlayerSource, isPlaying, wasPipClosedByUser } = state;
if (shallowEqual(activeMediaPlayerSource, source == null ? void 0 : source)) {
const r48 = isPlaying === false && rate > 0;
c9437_17.setState({
rate,
isPlaying: rate !== 0,
wasPipClosedByUser: r48 ? !r48 : wasPipClosedByUser
});
this.updateDisplayState();
return void 0;
}
this.handleMediaPlayerPlaybackSourceChanged({
source
});
this.handleMediaPlayerPlaybackRateChanged({
source,
rate
});
});
}
handleMediaPlayerPlaybackProgressUpdated({ source: source2, time, duration }) {
batchUpdates(() => {
const state = c9437_17.getState();
const activeMediaPlayerSource = state.activeMediaPlayerSource;
const r16 = source2 == null ? void 0 : source2;
L22: {
if (shallowEqual(activeMediaPlayerSource, r16)) {
const currentlyDisplayedChannelId = state.currentlyDisplayedChannelId;
if (!state.showPip) {
if (currentlyDisplayedChannelId == null) {
break L22;
}
if (currentlyDisplayedChannelId !== source2?.channelId) {
break L22;
}
}
const r22 = duration > 0;
let progress2 = void 0;
if (r22) {
let isCompleted = duration <= 0 ? void 0 : duration - time <= PLAYBACK_COMPLETION_DETECTION_TOLERANCE;
if (isCompleted == null) {
isCompleted = false;
}
progress2 = {
time,
duration,
isCompleted
};
}
const progress = state.progress;
if (!(progress != null && progress2 != null && Math.abs(progress2.time - progress.time) < PLAYBACK_PROGRESS_UPDATE_INTERVAL && progress2.time !== progress2.duration)) {
c9437_17.setState({
progress: progress2
});
}
}
}
});
}
handleMediaPlayerPlaybackSourceChanged({ source: source3 }) {
batchUpdates(() => {
const state = c9437_17.getState();
c9437_16.verbose(`Playback source changed: ${source3?.id}`);
let activeMediaPlayerSource = state.activeMediaPlayerSource;
if (activeMediaPlayerSource == null) {
activeMediaPlayerSource = void 0;
}
if (!shallowEqual(activeMediaPlayerSource, source3 == null ? void 0 : source3)) {
c9437_17.setState({
activeMediaPlayerSource: source3 == null ? void 0 : source3,
mediaSourceMessage: source3 != null ? this.getOrFetchMediaSourceMessage(source3) : void 0,
progress: void 0,
rate: 0,
isPlaying: false,
wasPipClosedByUser: false
});
this.updateMediaPermissions();
this.updateDisplayState();
}
});
}
getOrFetchMediaSourceMessage({ channelId: channelId3, messageId, assetUrl }) {
if (messageId != null && channelId3 != null) {
const message = MessageStore.getMessage(channelId3, messageId);
if (message != null) {
return message;
}
if (assetUrl != null) {
const r17 = MessageStore.getMessages(channelId3).toArray().find((item) => {
const contentMessage = item.getContentMessage();
const r2 = contentMessage == null;
let r8 = void 0;
if (!r2) {
const attachments = contentMessage.attachments;
r8 = attachments == null ? void 0 : attachments.some((attachment) => attachment.url === assetUrl);
}
return r8;
});
if (r17 != null) {
return r17;
}
}
MessageActionCreators.fetchMessage({
channelId: channelId3,
messageId
}).then((result) => {
if (result != null) {
this.handleMediaSourceMessageUpdated(result);
}
});
}
}
handleMediaSourceMessageUpdated(mediaSourceMessage) {
batchUpdates(() => {
if (c9437_17.getState().activeMediaPlayerSource?.messageId === mediaSourceMessage.id) {
c9437_17.setState({
mediaSourceMessage
});
}
});
}
handleMediaPlayerViewWillAppear({ mediaItemIds, channelId }) {
batchUpdates(() => {
const displayedMediaItemIdsPerChannel = c9437_17.getState().displayedMediaItemIdsPerChannel;
let r7 = displayedMediaItemIdsPerChannel[channelId];
if (r7 == null) {
r7 = [];
}
displayedMediaItemIdsPerChannel[channelId] = new Set([...r7, ...mediaItemIds]);
c9437_17.setState({
displayedMediaItemIdsPerChannel
});
this.updateDisplayState();
});
}
handleMediaPlayerViewDidDisappear({ mediaItemIds: mediaItemIds2, channelId: channelId2 }) {
batchUpdates(() => {
const displayedMediaItemIdsPerChannel = c9437_17.getState().displayedMediaItemIdsPerChannel;
const r9 = Set;
let r5 = displayedMediaItemIdsPerChannel[channelId2];
if (r5 == null) {
r5 = new Set();
}
const r27 = new r9([...r5].filter((item) => !mediaItemIds2.includes(item)));
if (r27.size === 0) {
delete displayedMediaItemIdsPerChannel[channelId2];
} else {
displayedMediaItemIdsPerChannel[channelId2] = r27;
}
c9437_17.setState({
displayedMediaItemIdsPerChannel
});
this.updateDisplayState();
});
}
updateDisplayState() {
batchUpdates(() => {
const state = c9437_17.getState();
const { displayedMediaItemIdsPerChannel, currentlyDisplayedChannelId, activeMediaPlayerSource = {} } = state;
L27: {
const id = activeMediaPlayerSource.id;
const { wasPipClosedByUser, progress } = state;
let isPlaying = state.isPlaying;
const showPip = state.showPip;
if (wasPipClosedByUser) {
c9437_17.setState({
showPip: false
});
} else {
if (!isPlaying && !showPip) {
break L27;
}
if (!isPlaying) {
isPlaying = progress != null && !(progress.duration <= 0 ? void 0 : progress.duration - progress.time <= PLAYBACK_COMPLETION_DETECTION_TOLERANCE);
}
const focusedChannelId = getFocusedChannelId();
if (focusedChannelId != null && currentlyDisplayedChannelId !== focusedChannelId) {
for (const key in displayedMediaItemIdsPerChannel) {
if (key !== focusedChannelId) {
delete displayedMediaItemIdsPerChannel[key];
}
}
}
if (id != null) {
if (focusedChannelId != null) {
const r45 = displayedMediaItemIdsPerChannel[focusedChannelId];
if (r45 != null) {
if (isPlaying) {
isPlaying = !r45.has(id);
}
c9437_17.setState({
showPip: isPlaying,
currentlyDisplayedChannelId: focusedChannelId,
displayedMediaItemIdsPerChannel
});
} else {
c9437_17.setState({
showPip: isPlaying,
currentlyDisplayedChannelId: focusedChannelId,
displayedMediaItemIdsPerChannel
});
}
} else {
c9437_17.setState({
showPip: isPlaying,
currentlyDisplayedChannelId: focusedChannelId,
displayedMediaItemIdsPerChannel
});
}
} else {
c9437_17.setState({
showPip: isPlaying,
currentlyDisplayedChannelId: focusedChannelId,
displayedMediaItemIdsPerChannel
});
}
}
}
});
}
}
const prototypeOf = Object.getPrototypeOf(MediaPlayerManager);
const r95 = Object.create(MediaPlayerManager.prototype);
const r97 = $callWithNewTarget(prototypeOf, r95, MediaPlayerManager);
const r98 = r97 instanceof Object ? r97 : r95;
r98.subscriptions = [];
r98.voicePanelStoreUnsubscribe = void 0;
r98.showPipUnsubscribe = void 0;
r98.pauseAndClosePip = r98.pauseAndClosePip.bind(r98);
r98.handleVoicePanelStateUpdated = r98.handleVoicePanelStateUpdated.bind(r98);
r98.handleEmbeddedActivitiesUpdated = r98.handleEmbeddedActivitiesUpdated.bind(r98);
r98.handleMediaPlayerPlaybackRateChanged = r98.handleMediaPlayerPlaybackRateChanged.bind(r98);
r98.handleMediaPlayerPlaybackSourceChanged = r98.handleMediaPlayerPlaybackSourceChanged.bind(r98);
r98.handleMediaPlayerViewWillAppear = r98.handleMediaPlayerViewWillAppear.bind(r98);
r98.handleMediaPlayerViewDidDisappear = r98.handleMediaPlayerViewDidDisappear.bind(r98);
r98.updateDisplayState = r98.updateDisplayState.bind(r98);
r98.updateMediaPermissions = r98.updateMediaPermissions.bind(r98);
export default r98;
export { c9437_17 as useMediaPlayerManagerStore };
export function isPlaybackComplete(a0) {
if (a0.duration <= 0) {
return void 0;
}
return a0.duration - a0.time <= PLAYBACK_COMPLETION_DETECTION_TOLERANCE;
}