mirror of
https://github.com/openmhz/trunk-server.git
synced 2026-11-12 08:47:40 -05:00
background autoplaying
This commit is contained in:
@@ -43,11 +43,12 @@ function CallPlayer(props) {
|
||||
threshold: 0.5
|
||||
});
|
||||
|
||||
const backgroundAutoplay = useSelector((state) => state.callPlayer.backgroundAutoplay);
|
||||
const { data: talkgroupsData, isSuccess: isTalkgroupsSuccess } = useGetTalkgroupsQuery(shortName);
|
||||
const [autoPlay, setAutoPlay] = useState(true);
|
||||
const [currentCall, setCurrentCall] = useState(false);
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
|
||||
const [silenceCount, setSilenceCount] = useState(0);
|
||||
const { callLink, callDownload, callTweet } = useCallLink(currentCall)
|
||||
|
||||
const dispatch = useDispatch();
|
||||
@@ -76,16 +77,27 @@ function CallPlayer(props) {
|
||||
setIsPlaying(true);
|
||||
}
|
||||
|
||||
|
||||
/* This function gets called whenever the currently playing call ends.*/
|
||||
|
||||
const callEnded = () => {
|
||||
if (callsData) {
|
||||
const currentIndex = callsData.ids.findIndex(callId => callId === currentCallId);
|
||||
if (autoPlay && (currentIndex > 0)) {
|
||||
const nextCallId = callsData.ids[currentIndex - 1];
|
||||
const nextCall = callsData.entities[nextCallId];
|
||||
console.log("Autoplaying next call, current Index is: " + currentIndex + " isPlaying is: " + isPlaying )
|
||||
setCurrentCall(nextCall);
|
||||
dispatch(playedCall(nextCall._id));
|
||||
setIsPlaying(true);
|
||||
if (autoPlay) {
|
||||
if (currentIndex > 0) {
|
||||
const nextCallId = callsData.ids[currentIndex - 1];
|
||||
const nextCall = callsData.entities[nextCallId];
|
||||
console.log("Autoplaying next call, current Index is: " + currentIndex + " isPlaying is: " + isPlaying )
|
||||
setCurrentCall(nextCall);
|
||||
dispatch(playedCall(nextCall._id));
|
||||
setIsPlaying(true);
|
||||
} else if (backgroundAutoplay) {
|
||||
// there are no more calls to play, but we want to keep playing something so the webpage is not put to sleep, so we play silence!
|
||||
setSilenceCount(silenceCount+1);
|
||||
} else {
|
||||
// there are no more calls to play and backgroundAutoplay is disabled
|
||||
setIsPlaying(false);
|
||||
}
|
||||
} else {
|
||||
if (!autoPlay) {
|
||||
console.log("Not playing because Autoplay is false - current index is: " + currentIndex)
|
||||
@@ -153,7 +165,7 @@ function CallPlayer(props) {
|
||||
|
||||
<Menu fixed="bottom" compact inverted >
|
||||
<Menu.Item active={autoPlay} onClick={() => handleAutoPlay(autoPlay)}><Icon name="level up" /><span className="desktop-only">Autoplay</span></Menu.Item>
|
||||
<MediaPlayer call={currentCall} onEnded={callEnded} onPlayPause={handlePlayPause} />
|
||||
<MediaPlayer call={currentCall} playSilence={silenceCount} onEnded={callEnded} onPlayPause={handlePlayPause} />
|
||||
<Menu.Menu position="right" className="desktop-only">
|
||||
<Menu.Item><SupportModal /></Menu.Item>
|
||||
<Menu.Item><a href={callDownload}><Icon name="download" />Download</a></Menu.Item>
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import { useGetGroupsQuery } from '../features/api/apiSlice'
|
||||
import { setGroupFilter } from "../features/callPlayer/callPlayerSlice";
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
|
||||
import {
|
||||
Modal,
|
||||
Button,
|
||||
Icon,
|
||||
Dropdown
|
||||
} from "semantic-ui-react";
|
||||
import "./FilterModal.css";
|
||||
|
||||
function GroupModal (props) {
|
||||
const { data, isError, isLoading, isSuccess,error } = useGetGroupsQuery(props.shortName);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [selectedGroup, setSelectedGroup] = useState(false);
|
||||
const dispatch = useDispatch()
|
||||
const onClose = props.onClose;
|
||||
|
||||
function handleDone(onClose) {
|
||||
|
||||
if (selectedGroup) {
|
||||
dispatch(setGroupFilter(selectedGroup))
|
||||
//dispatch({type: types.SET_GROUP_FILTER, groupId: selectedGroup })
|
||||
onClose(true);
|
||||
} else {
|
||||
onClose(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let groupOptions = []
|
||||
|
||||
if (isSuccess) {
|
||||
|
||||
for (const num in data) {
|
||||
const group = data[num];
|
||||
var obj = {
|
||||
key: group._id,
|
||||
value: group._id,
|
||||
text: group.groupName
|
||||
}
|
||||
groupOptions.push(obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
|
||||
<Modal open={props.open} onClose={() => setOpen(false)} onOpen={() => setOpen(true)} size='tiny'>
|
||||
|
||||
<Modal.Header>Select a Group</Modal.Header>
|
||||
<Modal.Content >
|
||||
<Modal.Description>
|
||||
<p>Choose the type of calls you want to listen to</p>
|
||||
<Dropdown placeholder='Group...' fluid selection options={groupOptions} name='selectedGroup' onChange={(e, data) => setSelectedGroup(data.value)} />
|
||||
|
||||
</Modal.Description>
|
||||
|
||||
</Modal.Content>
|
||||
<Modal.Actions>
|
||||
<Button onClick={()=> handleDone(onClose)} >
|
||||
<Icon name='headphones' /> Listen
|
||||
</Button>
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
|
||||
)
|
||||
}
|
||||
/*
|
||||
class GroupModal extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.handleInputChange = this.handleInputChange.bind(this);
|
||||
this.handleDone = this.handleDone.bind(this);
|
||||
this.handleClose = this.handleClose.bind(this);
|
||||
|
||||
this.state = {
|
||||
open: false,
|
||||
selectedGroup: false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
handleInputChange = (e, { name, value }) => this.setState({ [name]: value });
|
||||
handleClose = () => this.props.onClose(false);
|
||||
|
||||
handleDone(event) {
|
||||
|
||||
if (this.state.selectedGroup) {
|
||||
this.props.callActions.setGroupFilter(this.state.selectedGroup);
|
||||
this.props.onClose(true);
|
||||
} else {
|
||||
this.props.onClose(false);
|
||||
}
|
||||
|
||||
}
|
||||
componentDidUpdate(prevProps) {
|
||||
|
||||
const filterChanged = (prevProps.selectedGroup !== this.props.selectedGroup);
|
||||
if (filterChanged) {
|
||||
this.setState({ selectedGroup: this.props.selectedGroup});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
|
||||
var groupList = [];
|
||||
if (this.props.groups) {
|
||||
for (const num in this.props.groups) {
|
||||
const group = this.props.groups[num];
|
||||
var obj = {
|
||||
key: group._id,
|
||||
value: group._id,
|
||||
text: group.groupName
|
||||
}
|
||||
groupList.push(obj);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
<Modal open={this.props.open} onClose={this.handleClose} size='tiny' >
|
||||
<Modal.Header>Select a Group</Modal.Header>
|
||||
<Modal.Content >
|
||||
<Modal.Description>
|
||||
<p>Choose the type of calls you want to listen to</p>
|
||||
<Dropdown placeholder='Group...' fluid selection options={groupList} name='selectedGroup' onChange={this.handleInputChange} />
|
||||
|
||||
</Modal.Description>
|
||||
|
||||
</Modal.Content>
|
||||
<Modal.Actions>
|
||||
<Button onClick={this.handleDone} >
|
||||
<Icon name='headphones' /> Listen
|
||||
</Button>
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
|
||||
)
|
||||
}
|
||||
}*/
|
||||
|
||||
export default GroupModal;
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { Component, useState, useEffect } from "react";
|
||||
import { useGetGroupsQuery, useGetSystemsQuery, } from '../../features/api/apiSlice'
|
||||
import { setGroupFilter, setCenterCall } from "../../features/callPlayer/callPlayerSlice";
|
||||
import { setGroupFilter, setCenterCall, setBackgroundAutoplay } from "../../features/callPlayer/callPlayerSlice";
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
|
||||
import {
|
||||
@@ -15,11 +15,14 @@ import "./FilterModal.css";
|
||||
|
||||
function GroupModal(props) {
|
||||
const shortName = useSelector((state) => state.callPlayer.shortName);
|
||||
const backgroundAutoplay = useSelector((state) => state.callPlayer.backgroundAutoplay);
|
||||
const centerCall = useSelector((state) => state.callPlayer.centerCall);
|
||||
const { data: groupData, isSuccess } = useGetGroupsQuery(props.shortName);
|
||||
const { data: allSystems } = useGetSystemsQuery();
|
||||
const [selectedGroup, setSelectedGroup] = useState(false);
|
||||
const [groupOptions, setGroupOptions] = useState([]);
|
||||
const [centerCall, setLocalCenterCall] = useState(true);
|
||||
const [localCenterCall, setLocalCenterCall] = useState(centerCall);
|
||||
const [localBackgroundAutoplay, setLocalBackgroundAutoplay] = useState(backgroundAutoplay);
|
||||
const dispatch = useDispatch()
|
||||
const onClose = props.onClose;
|
||||
let system = false;
|
||||
@@ -30,7 +33,8 @@ function GroupModal(props) {
|
||||
}
|
||||
|
||||
function handleDone(onClose) {
|
||||
dispatch(setCenterCall(centerCall));
|
||||
dispatch(setCenterCall(localCenterCall));
|
||||
dispatch(setBackgroundAutoplay(localBackgroundAutoplay));
|
||||
if (selectedGroup && (selectedGroup!="all")) {
|
||||
dispatch(setGroupFilter(selectedGroup))
|
||||
|
||||
@@ -83,7 +87,8 @@ function GroupModal(props) {
|
||||
<p>Choose the type of calls you want to listen to</p>
|
||||
<Form>
|
||||
<Form.Select placeholder='All Calls' fluid selection options={groupOptions} name='selectedGroup' onChange={(e, data) => setSelectedGroup(data.value)} />
|
||||
<Form.Checkbox label='Center playing call ' checked={centerCall} onChange={(e, data) => setLocalCenterCall(data.value)} />
|
||||
<Form.Checkbox label='Focus on call playing' checked={localCenterCall} onChange={(e, data) => setLocalCenterCall(data.checked)} />
|
||||
<Form.Checkbox label='Background autoplay' checked={localBackgroundAutoplay} onChange={(e, data) => setLocalBackgroundAutoplay(data.checked)} />
|
||||
</Form>
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
|
||||
@@ -17,6 +17,7 @@ const MediaPlayer = (props) => {
|
||||
const [playTime, setPlayTime] = useState(0);
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
const parentHandlePlayPause = props.onPlayPause
|
||||
const playSilence = props.playSilence;
|
||||
|
||||
const handlePause = () => { setIsPlaying(false); }
|
||||
const handlePlay = () => { setIsPlaying(true); }
|
||||
@@ -61,6 +62,38 @@ const MediaPlayer = (props) => {
|
||||
}
|
||||
}, [call]);
|
||||
|
||||
useEffect(() => {
|
||||
const audio = audioRef.current.audioEl.current;
|
||||
|
||||
setSourceIndex(0);
|
||||
navigator.mediaSession.metadata = new MediaMetadata({
|
||||
title: "Waiting for Call...",
|
||||
album: 'OpenMHz',
|
||||
artwork: [
|
||||
{ src: '/favicon-32x32.png', sizes: '32x32', type: 'image/png' },
|
||||
{ src: '/android-chrome-192x192.png', sizes: '192x192', type: 'image/png' },
|
||||
{ src: '/android-chrome-192x192.png', sizes: '512x512', type: 'image/png' },
|
||||
]
|
||||
});
|
||||
audio.src = "data:audio/mpeg;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4Ljc2LjEwMAAAAAAAAAAAAAAA/+M4wAAAAAAAAAAAAEluZm8AAAAPAAAAAwAAAbAAqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV////////////////////////////////////////////AAAAAExhdmM1OC4xMwAAAAAAAAAAAAAAACQDkAAAAAAAAAGw9wrNaQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+MYxAAAAANIAAAAAExBTUUzLjEwMFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/+MYxDsAAANIAAAAAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/+MYxHYAAANIAAAAAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV";
|
||||
const playPromise = audio.play();
|
||||
|
||||
// In browsers that don’t yet support this functionality,
|
||||
// playPromise won’t be defined.
|
||||
if (playPromise !== undefined) {
|
||||
playPromise.then(function () {
|
||||
|
||||
}).catch(function (error) {
|
||||
console.log("Automatic playback failed: " + error);
|
||||
// Show a UI element to let the user manually start playback.
|
||||
});
|
||||
} else {
|
||||
audio.src = false;
|
||||
}
|
||||
|
||||
}, [playSilence]);
|
||||
|
||||
|
||||
const updatePlayProgress = () => {
|
||||
const audio = audioRef.current.audioEl.current;
|
||||
const { currentTime, duration } = audio;
|
||||
|
||||
@@ -15,7 +15,8 @@ const initialState = {
|
||||
currentCallId: false,
|
||||
playlist: [],
|
||||
live: false,
|
||||
centerCall: true
|
||||
centerCall: true,
|
||||
backgroundAutoplay: false
|
||||
}
|
||||
|
||||
const compareCalls = (a, b) => {
|
||||
@@ -77,6 +78,9 @@ export const callPlayerSlice = createSlice({
|
||||
setCenterCall: (state,action) => {
|
||||
state.centerCall = action.payload;
|
||||
},
|
||||
setBackgroundAutoplay: (state,action) => {
|
||||
state.backgroundAutoplay = action.payload;
|
||||
},
|
||||
setShortName: (state, action) => {
|
||||
state.shortName = action.payload;
|
||||
},
|
||||
@@ -106,7 +110,7 @@ export const callPlayerSlice = createSlice({
|
||||
})
|
||||
|
||||
// Action creators are generated for each case reducer function
|
||||
export const { setCurrentCallId, setCallTime, setFilter, setLive, setCenterCall, setPlaylist, removeFromPLaylist, addToPlaylist, setShortName, setDateFilter, setStarredFilter, setAllFilter, setGroupFilter, setTalkgroupFilter } = callPlayerSlice.actions
|
||||
export const { setCurrentCallId, setCallTime, setFilter, setLive, setCenterCall, setBackgroundAutoplay, setPlaylist, removeFromPLaylist, addToPlaylist, setShortName, setDateFilter, setStarredFilter, setAllFilter, setGroupFilter, setTalkgroupFilter } = callPlayerSlice.actions
|
||||
|
||||
export default callPlayerSlice.reducer
|
||||
|
||||
|
||||
Reference in New Issue
Block a user