Merge pull request #169 from UniversityRadioYork/mstratford-played
This commit is contained in:
commit
529f86bcc6
8 changed files with 71 additions and 10 deletions
|
@ -7,6 +7,7 @@ import * as NavbarState from "../navbar/state";
|
|||
import { ConnectionStateEnum } from "./streamer";
|
||||
import { RecordingStreamer } from "./recording_streamer";
|
||||
import { audioEngine } from "../mixer/audio";
|
||||
import { setItemPlayed } from "../showplanner/state";
|
||||
|
||||
export let streamer: WebRTCStreamer | null = null;
|
||||
|
||||
|
@ -315,6 +316,8 @@ export const goOnAir = (): AppThunk => async (dispatch, getState) => {
|
|||
} else if (state === "CONNECTED") {
|
||||
// okay, we've connected
|
||||
dispatch(registerForShow());
|
||||
} else if (state === "LIVE") {
|
||||
dispatch(setItemPlayed({ itemId: "all", played: false }));
|
||||
}
|
||||
});
|
||||
await streamer.start();
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
} from "@reduxjs/toolkit";
|
||||
import fetchProgress, { FetchProgressData } from "fetch-progress";
|
||||
import Between from "between.js";
|
||||
import { itemId, PlanItem } from "../showplanner/state";
|
||||
import { itemId, PlanItem, setItemPlayed } from "../showplanner/state";
|
||||
import * as BroadcastState from "../broadcast/state";
|
||||
import Keys from "keymaster";
|
||||
import { Track, MYRADIO_NON_API_BASE, AuxItem } from "../api";
|
||||
|
@ -447,6 +447,13 @@ export const load = (
|
|||
|
||||
playerInstance.on("play", () => {
|
||||
dispatch(mixerState.actions.setPlayerState({ player, state: "playing" }));
|
||||
|
||||
const state = getState().mixer.players[player];
|
||||
if (state.loadedItem != null) {
|
||||
dispatch(
|
||||
setItemPlayed({ itemId: itemId(state.loadedItem), played: true })
|
||||
);
|
||||
}
|
||||
});
|
||||
playerInstance.on("pause", () => {
|
||||
dispatch(
|
||||
|
|
|
@ -23,7 +23,7 @@ import "./navbar.scss";
|
|||
import { closeAlert } from "./state";
|
||||
import { ConnectionStateEnum } from "../broadcast/streamer";
|
||||
import { VUMeter } from "../optionsMenu/helpers/VUMeter";
|
||||
import { getShowplan } from "../showplanner/state";
|
||||
import { getShowplan, setItemPlayed } from "../showplanner/state";
|
||||
|
||||
import * as OptionsMenuState from "../optionsMenu/state";
|
||||
|
||||
|
@ -107,6 +107,15 @@ export function NavBarMyRadio() {
|
|||
>
|
||||
Reload Show Plan
|
||||
</button>
|
||||
<button
|
||||
className="dropdown-item"
|
||||
onClick={() =>
|
||||
sessionState.currentTimeslot !== null &&
|
||||
dispatch(setItemPlayed({ itemId: "all", played: false }))
|
||||
}
|
||||
>
|
||||
Mark All Items Unplayed
|
||||
</button>
|
||||
<h6 className="dropdown-header">
|
||||
{sessionState.currentTimeslot?.title}
|
||||
</h6>
|
||||
|
|
|
@ -57,6 +57,7 @@ export const Item = memo(function Item({
|
|||
data-itemid={id}
|
||||
className={
|
||||
"item " +
|
||||
("played" in x ? (x.played ? "played " : "") : "") +
|
||||
x.type +
|
||||
`${
|
||||
column >= 0 &&
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
FaMicrophone,
|
||||
FaTrash,
|
||||
FaUpload,
|
||||
FaCircleNotch,
|
||||
} from "react-icons/fa";
|
||||
import { VUMeter } from "../optionsMenu/helpers/VUMeter";
|
||||
import Stopwatch from "react-stopwatch";
|
||||
|
@ -31,7 +32,9 @@ import {
|
|||
moveItem,
|
||||
addItem,
|
||||
removeItem,
|
||||
setItemPlayed,
|
||||
getPlaylists,
|
||||
PlanItemBase,
|
||||
} from "./state";
|
||||
|
||||
import * as MixerState from "../mixer/state";
|
||||
|
@ -333,10 +336,11 @@ const Showplanner: React.FC<{ timeslotId: number }> = function({ timeslotId }) {
|
|||
// this is a track from the CML
|
||||
// TODO: this is ugly, should be in redux
|
||||
const data = CML_CACHE[result.draggableId];
|
||||
const newItem: TimeslotItem = {
|
||||
const newItem: TimeslotItem & PlanItemBase = {
|
||||
timeslotitemid: "I" + insertIndex,
|
||||
channel: parseInt(result.destination.droppableId, 10),
|
||||
weight: result.destination.index,
|
||||
played: false,
|
||||
cue: 0,
|
||||
...data,
|
||||
};
|
||||
|
@ -346,11 +350,12 @@ const Showplanner: React.FC<{ timeslotId: number }> = function({ timeslotId }) {
|
|||
// this is an aux resource
|
||||
// TODO: this is ugly, should be in redux
|
||||
const data = AUX_CACHE[result.draggableId];
|
||||
const newItem: TimeslotItem = {
|
||||
const newItem: TimeslotItem & PlanItemBase = {
|
||||
timeslotitemid: "I" + insertIndex,
|
||||
channel: parseInt(result.destination.droppableId, 10),
|
||||
weight: result.destination.index,
|
||||
clean: true,
|
||||
played: false,
|
||||
cue: 0,
|
||||
...data,
|
||||
} as any;
|
||||
|
@ -377,6 +382,9 @@ const Showplanner: React.FC<{ timeslotId: number }> = function({ timeslotId }) {
|
|||
async function onCtxRemoveClick(e: any, data: { id: string }) {
|
||||
dispatch(removeItem(timeslotId, data.id));
|
||||
}
|
||||
async function onCtxUnPlayedClick(e: any, data: { id: string }) {
|
||||
dispatch(setItemPlayed({ itemId: data.id, played: false }));
|
||||
}
|
||||
|
||||
// Add support for reloading the show plan from the iFrames.
|
||||
// There is a similar listener in showplanner/ImporterModal.tsx to handle closing the iframe.
|
||||
|
@ -434,6 +442,9 @@ const Showplanner: React.FC<{ timeslotId: number }> = function({ timeslotId }) {
|
|||
<MenuItem onClick={onCtxRemoveClick}>
|
||||
<FaTrash /> Remove
|
||||
</MenuItem>
|
||||
<MenuItem onClick={onCtxUnPlayedClick}>
|
||||
<FaCircleNotch /> Mark Unplayed
|
||||
</MenuItem>
|
||||
</ContextMenu>
|
||||
<OptionsMenu />
|
||||
<WelcomeModal
|
||||
|
|
|
@ -15,11 +15,18 @@
|
|||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&.played {
|
||||
background-color: #ddd;
|
||||
.icon {
|
||||
border: 4px black solid;
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin: auto auto;
|
||||
margin-top: 2px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
margin-bottom: -3px;
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
|
||||
|
|
|
@ -19,7 +19,10 @@ export interface ItemGhost {
|
|||
clean: boolean;
|
||||
}
|
||||
|
||||
export type PlanItem = TimeslotItem | ItemGhost;
|
||||
export interface PlanItemBase {
|
||||
played?: boolean;
|
||||
}
|
||||
export type PlanItem = (TimeslotItem | ItemGhost) & PlanItemBase;
|
||||
|
||||
export type Plan = PlanItem[][];
|
||||
|
||||
|
@ -174,6 +177,23 @@ const showplan = createSlice({
|
|||
}
|
||||
});
|
||||
},
|
||||
// Set the item as being played/unplayed in this session.
|
||||
setItemPlayed(
|
||||
state,
|
||||
action: PayloadAction<{ itemId: string; played: boolean }>
|
||||
) {
|
||||
// Used for the nav menu
|
||||
if (action.payload.itemId === "all") {
|
||||
state.plan!.forEach((x) => {
|
||||
x.played = action.payload.played;
|
||||
});
|
||||
return;
|
||||
}
|
||||
const idx = state.plan!.findIndex(
|
||||
(x) => itemId(x) === action.payload.itemId
|
||||
);
|
||||
state.plan![idx].played = action.payload.played;
|
||||
},
|
||||
replaceGhost(
|
||||
state,
|
||||
action: PayloadAction<{ ghostId: string; newItemData: TimeslotItem }>
|
||||
|
@ -200,7 +220,11 @@ const showplan = createSlice({
|
|||
|
||||
export default showplan.reducer;
|
||||
|
||||
export const { setItemTimings, planSaveError } = showplan.actions;
|
||||
export const {
|
||||
setItemTimings,
|
||||
setItemPlayed,
|
||||
planSaveError,
|
||||
} = showplan.actions;
|
||||
|
||||
export const moveItem = (
|
||||
timeslotid: number,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import raygun from "raygun4js";
|
||||
import {
|
||||
configureStore,
|
||||
Action,
|
||||
|
|
Loading…
Reference in a new issue