@theoplayer/react-native-ui
Version:
A React Native UI for @theoplayer/react-native
167 lines • 6 kB
JavaScript
import React, { PureComponent } from 'react';
import { PlayerEventType } from 'react-native-theoplayer';
import { PlayerContext } from '../util/PlayerContext';
import { LanguageSvg } from '../button/svg/LanguageSvg';
import { ScrollableMenu } from './common/ScrollableMenu';
import { MenuRadioButton } from './common/MenuRadioButton';
import { MenuButton } from './common/MenuButton';
import { filterRenderableTracks, getTrackLabel } from '../util/TrackUtils';
import { MenuView } from './common/MenuView';
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/**
* A button component that opens a language selection menu (audio/text) for the `react-native-theoplayer` UI.
*/
export class LanguageMenuButton extends PureComponent {
constructor(props) {
super(props);
this.state = {
audioTracks: [],
textTracks: []
};
}
componentDidMount() {
const player = this.context.player;
player.addEventListener(PlayerEventType.MEDIA_TRACK_LIST, this._updateTrackLists);
player.addEventListener(PlayerEventType.TEXT_TRACK_LIST, this._updateTrackLists);
this._updateTrackLists();
}
componentWillUnmount() {
const player = this.context.player;
player.removeEventListener(PlayerEventType.MEDIA_TRACK_LIST, this._updateTrackLists);
player.removeEventListener(PlayerEventType.TEXT_TRACK_LIST, this._updateTrackLists);
}
_updateTrackLists = () => {
const player = this.context.player;
this.setState({
audioTracks: player.audioTracks,
textTracks: player.textTracks
});
};
render() {
const {
audioTracks,
textTracks
} = this.state;
const {
menuStyle,
icon
} = this.props;
const selectableTextTracks = filterRenderableTracks(textTracks);
if (audioTracks.length < 2 && selectableTextTracks.length === 0) {
return /*#__PURE__*/_jsx(_Fragment, {});
}
const createMenu = () => {
return /*#__PURE__*/_jsx(LanguageMenuView, {
style: menuStyle
});
};
return /*#__PURE__*/_jsx(MenuButton, {
svg: icon ?? /*#__PURE__*/_jsx(LanguageSvg, {}),
menuConstructor: createMenu
});
}
}
export class LanguageMenuView extends PureComponent {
constructor(props) {
super(props);
this.state = {
audioTracks: [],
textTracks: [],
selectedAudioTrack: undefined,
selectedTextTrack: undefined
};
}
_updateTrackLists = () => {
const player = this.context.player;
this.setState({
audioTracks: player.audioTracks,
textTracks: player.textTracks,
selectedAudioTrack: player.selectedAudioTrack,
selectedTextTrack: player.selectedTextTrack
});
};
componentDidMount() {
const player = this.context.player;
// The track lists might change while the menu is open, so we need to monitor them.
player.addEventListener(PlayerEventType.MEDIA_TRACK_LIST, this._updateTrackLists);
player.addEventListener(PlayerEventType.TEXT_TRACK_LIST, this._updateTrackLists);
this._updateTrackLists();
}
componentWillUnmount() {
const player = this.context.player;
player.removeEventListener(PlayerEventType.MEDIA_TRACK_LIST, this._updateTrackLists);
player.removeEventListener(PlayerEventType.TEXT_TRACK_LIST, this._updateTrackLists);
}
onSelectTextTrack = uid => {
const {
textTracks
} = this.state;
const textTrack = textTracks.find(track => track.uid === uid);
const context = this.context;
context.player.selectedTextTrack = textTrack?.uid;
this.setState({
selectedTextTrack: textTrack?.uid
});
};
selectAudioTrack = uid => {
const {
audioTracks
} = this.state;
const audioTrack = audioTracks.find(track => track.uid === uid);
if (audioTrack) {
const context = this.context;
context.player.selectedAudioTrack = audioTrack.uid;
this.setState({
selectedAudioTrack: audioTrack.uid
});
}
};
render() {
const {
style
} = this.props;
const {
audioTracks,
textTracks,
selectedAudioTrack,
selectedTextTrack
} = this.state;
// The sort is needed because tracks are returned in different order on the native SDKs.
const selectableTextTracks = filterRenderableTracks(textTracks).sort((first, second) => first.uid - second.uid);
const selectableAudioTracks = audioTracks.sort((first, second) => first.uid - second.uid);
return /*#__PURE__*/_jsx(PlayerContext.Consumer, {
children: context => /*#__PURE__*/_jsx(MenuView, {
style: style,
menu: /*#__PURE__*/_jsxs(_Fragment, {
children: [selectableAudioTracks.length > 1 && /*#__PURE__*/_jsx(ScrollableMenu, {
title: context.locale.audioTitle,
items: selectableAudioTracks.map((track, id) => /*#__PURE__*/_jsx(MenuRadioButton, {
label: getTrackLabel(track),
uid: track.uid,
onSelect: this.selectAudioTrack,
selected: track.uid === selectedAudioTrack
}, id))
}), selectableTextTracks.length > 0 && /*#__PURE__*/_jsx(ScrollableMenu, {
title: context.locale.subtitleTitle,
items: /*#__PURE__*/_jsxs(_Fragment, {
children: [/*#__PURE__*/_jsx(MenuRadioButton, {
label: 'off',
uid: undefined,
onSelect: this.onSelectTextTrack,
selected: selectedTextTrack === undefined
}, 0), selectableTextTracks.map((track, id) => /*#__PURE__*/_jsx(MenuRadioButton, {
label: getTrackLabel(track),
uid: track.uid,
onSelect: this.onSelectTextTrack,
selected: track.uid === selectedTextTrack
}, id + 1))]
})
})]
})
})
});
}
}
LanguageMenuButton.contextType = PlayerContext;
LanguageMenuView.contextType = PlayerContext;
//# sourceMappingURL=LanguageMenuButton.js.map