After more merge fixing, still no channel lists

This commit is contained in:
Matthew Stratford 2021-06-03 22:43:59 +01:00
parent ae189d9613
commit 000d85d450
11 changed files with 359 additions and 359 deletions

View file

@ -5,7 +5,8 @@
"dependencies": {
"@babel/core": "7.6.0",
"@reduxjs/toolkit": "^1.0.4",
"@sentry/react": "^6.5.0",
"@sentry/react": "^6.3.1",
"@sentry/tracing": "^6.3.1",
"@svgr/webpack": "4.3.2",
"@types/dom-mediacapture-record": "^1.0.4",
"@types/jest": "24.0.22",

View file

@ -68,7 +68,7 @@ class Player extends ((PlayerEmitter as unknown) as { new (): EventEmitter }) {
}
stop() {
if (process.env.REACT_APP_BAPSICLE_INTERFACE) {
if (!process.env.REACT_APP_BAPSICLE_INTERFACE) {
return this.wavesurfer.stop();
}
}
@ -241,7 +241,7 @@ class Player extends ((PlayerEmitter as unknown) as { new (): EventEmitter }) {
if (!process.env.REACT_APP_BAPSICLE_INTERFACE) {
customOutput = outputId !== INTERNAL_OUTPUT_ID;
}
let waveform = document.getElementById("waveform-" + player.toString());
if (waveform == null) {
throw new Error();

View file

@ -32,15 +32,6 @@ import { sendBAPSicleChannel } from "../bapsicle";
import { changeSetting } from "../optionsMenu/settingsState";
import { PLAYER_COUNTER_UPDATE_PERIOD_MS } from "../showplanner/Player";
import { changeSetting } from "../optionsMenu/settingsState";
import {
DEFAULT_TRIM_DB,
OFF_LEVEL_DB,
BED_LEVEL_DB,
FULL_LEVEL_DB,
} from "./audio";
import { PLAYER_COUNTER_UPDATE_PERIOD_MS } from "../showplanner/Player";
const playerGainTweens: Array<{
target: VolumePresetEnum;
tweens: Between[];
@ -609,105 +600,107 @@ export const load = (
if (state.loadedItem && "outro" in state.loadedItem) {
playerInstance.setOutro(state.loadedItem.outro);
}
});
if (process.env.REACT_APP_BAPSICLE_INTERFACE) {
playerInstance.on("timeChangeSeek", (time) => {
if (
Math.abs(time - getState().mixer.players[player].timeCurrent) > 0.5
) {
sendBAPSicleChannel({
channel: player,
command: "SEEK",
time: time,
});
}
});
} else {
playerInstance.on("play", () => {
dispatch(
mixerState.actions.setPlayerState({ player, state: "playing" })
);
const state = getState().mixer.players[player];
// Don't set played on Preview Channel
if (state.loadedItem != null && player !== PLAYER_ID_PREVIEW) {
if (process.env.REACT_APP_BAPSICLE_INTERFACE) {
playerInstance.on("timeChangeSeek", (time) => {
if (
Math.abs(time - getState().mixer.players[player].timeCurrent) > 0.5
) {
sendBAPSicleChannel({
channel: player,
command: "SEEK",
time: time,
});
}
});
} else {
playerInstance.on("play", () => {
dispatch(
dispatch(setItemPlayed(itemId(state.loadedItem), true));
mixerState.actions.setPlayerState({ player, state: "playing" })
);
}
});
playerInstance.on("pause", () => {
dispatch(
mixerState.actions.setPlayerState({
player,
state: playerInstance.currentTime === 0 ? "stopped" : "paused",
})
);
});
playerInstance.on("timeChange", (time) => {
if (
Math.abs(time - getState().mixer.players[player].timeCurrent) >
PLAYER_COUNTER_UPDATE_PERIOD_MS / 1000
) {
const state = getState().mixer.players[player];
// Don't set played on Preview Channel
if (state.loadedItem != null && player !== PLAYER_ID_PREVIEW) {
dispatch(setItemPlayed(itemId(state.loadedItem), true));
}
});
playerInstance.on("pause", () => {
dispatch(
mixerState.actions.setTimeCurrent({
mixerState.actions.setPlayerState({
player,
time,
state: playerInstance.currentTime === 0 ? "stopped" : "paused",
})
);
}
});
playerInstance.on("finish", () => {
// If the Preview Player finishes playing, turn off PFL in the UI.
if (player === PLAYER_ID_PREVIEW) {
dispatch(setChannelPFL(player, false));
}
dispatch(mixerState.actions.setPlayerState({ player, state: "stopped" }));
const state = getState().mixer.players[player];
if (state.tracklistItemID !== -1) {
dispatch(BroadcastState.tracklistEnd(state.tracklistItemID));
}
if (state.repeat === "one") {
playerInstance.play();
} else if (state.repeat === "all") {
if ("channel" in item) {
// it's not in the CML/libraries "column"
const itsChannel = getState()
.showplan.plan!.filter((x) => x.channel === item.channel)
.sort((x, y) => x.weight - y.weight);
const itsIndex = itsChannel.indexOf(item);
if (itsIndex === itsChannel.length - 1) {
dispatch(load(player, itsChannel[0]));
} else if (state.autoAdvance) {
if ("channel" in item) {
// it's not in the CML/libraries "column"
const itsChannel = getState()
.showplan.plan!.filter((x) => x.channel === item.channel)
.sort((x, y) => x.weight - y.weight);
// Sadly, we can't just do .indexOf() item directly,
// since the player's idea of an item may be changed over it's lifecycle (setting played,intro/cue/outro etc.)
// Therefore we'll find the updated item from the plan and match that.
const itsIndex = itsChannel.findIndex(
(x) => itemId(x) === itemId(item)
);
if (itsIndex > -1 && itsIndex !== itsChannel.length - 1) {
dispatch(load(player, itsChannel[itsIndex + 1]));
}
});
playerInstance.on("timeChange", (time) => {
if (
Math.abs(time - getState().mixer.players[player].timeCurrent) >
PLAYER_COUNTER_UPDATE_PERIOD_MS / 1000
) {
dispatch(
mixerState.actions.setTimeCurrent({
player,
time,
})
);
}
});
playerInstance.on("finish", () => {
// If the Preview Player finishes playing, turn off PFL in the UI.
if (player === PLAYER_ID_PREVIEW) {
dispatch(setChannelPFL(player, false));
}
dispatch(
mixerState.actions.setPlayerState({ player, state: "stopped" })
);
const state = getState().mixer.players[player];
if (state.tracklistItemID !== -1) {
dispatch(BroadcastState.tracklistEnd(state.tracklistItemID));
}
if (state.repeat === "one") {
playerInstance.play();
} else if (state.repeat === "all") {
if ("channel" in item) {
// it's not in the CML/libraries "column"
const itsChannel = getState()
.showplan.plan!.filter((x) => x.channel === item.channel)
.sort((x, y) => x.weight - y.weight);
const itsIndex = itsChannel.indexOf(item);
if (itsIndex === itsChannel.length - 1) {
dispatch(load(player, itsChannel[0]));
}
}
});
} else if (state.autoAdvance) {
if ("channel" in item) {
// it's not in the CML/libraries "column"
const itsChannel = getState()
.showplan.plan!.filter((x) => x.channel === item.channel)
.sort((x, y) => x.weight - y.weight);
// Sadly, we can't just do .indexOf() item directly,
// since the player's idea of an item may be changed over it's lifecycle (setting played,intro/cue/outro etc.)
// Therefore we'll find the updated item from the plan and match that.
const itsIndex = itsChannel.findIndex(
(x) => itemId(x) === itemId(item)
);
if (itsIndex > -1 && itsIndex !== itsChannel.length - 1) {
dispatch(load(player, itsChannel[itsIndex + 1]));
}
}
}
});
// Double-check we haven't been aborted since
if (signal.aborted) {
// noinspection ExceptionCaughtLocallyJS
throw new DOMException("abort load", "AbortError");
}
});
// Double-check we haven't been aborted since
if (signal.aborted) {
// noinspection ExceptionCaughtLocallyJS
throw new DOMException("abort load", "AbortError");
playerInstance.setVolume(getState().mixer.players[player].gain);
playerInstance.setTrim(getState().mixer.players[player].trim);
delete loadAbortControllers[player];
}
playerInstance.setVolume(getState().mixer.players[player].gain);
playerInstance.setTrim(getState().mixer.players[player].trim);
delete loadAbortControllers[player];
} catch (e) {
if ("name" in e && e.name === "AbortError") {
// load was aborted, ignore the error
@ -866,9 +859,6 @@ export const {
setRepeat,
setTracklistItemID,
setMicBaseGain,
toggleAutoAdvance,
togglePlayOnLoad,
toggleRepeat,
setPlayerMicAutoDuck,
} = mixerState.actions;

View file

@ -12,6 +12,7 @@ import {
FaCompactDisc,
FaHeadphonesAlt,
} from "react-icons/fa";
import LiveClock from "react-live-clock";
import { RootState } from "../rootReducer";
@ -19,7 +20,7 @@ import * as BroadcastState from "../broadcast/state";
import appLogo from "../assets/images/webstudio.svg";
import myradioLogo from "../assets/images/myradio.svg";
import { MYRADIO_NON_API_BASE } from "../api";
import logo from "../assets/images/navbarlogo.png";
import "./navbar.scss";
import { closeAlert } from "./state";
import { BAPSicleModal } from "./BAPSicleModal";
@ -165,6 +166,33 @@ export function NavBarMyRadio() {
}
export function NavBarMain() {
const [showBAPSicleModal, setShowBAPSicleModal] = useState(true);
if (process.env.REACT_APP_BAPSICLE_INTERFACE) {
return (
<>
<ul className="nav navbar-nav navbar-left">
<Timelord />
</ul>
<ul className="nav navbar-nav navbar-right mr-0 pr-0">
<li
className="btn btn-outline-light rounded-0 pt-2 pb-2 nav-item nav-link"
style={{ color: "white" }}
onClick={() => {
setShowBAPSicleModal(true);
}}
>
<FaCompactDisc size={16} className="mr-2" />
<b>Menu</b>
</li>
</ul>
<BAPSicleModal
close={() => setShowBAPSicleModal(false)}
isOpen={showBAPSicleModal}
/>
</>
);
}
return (
<>
<ul className="nav navbar-nav navbar-left">
@ -217,56 +245,6 @@ function RegisterButton() {
(state: RootState) => state.showplan
);
const [showBAPSicleModal, setShowBAPSicleModal] = useState(true);
if (process.env.REACT_APP_BAPSICLE_INTERFACE) {
return (
<>
<ul className="nav navbar-nav navbar-left">
<li
className="btn rounded-0 py-1 nav-link nav-item"
id="timelord"
onClick={(e) => {
e.preventDefault();
window.open(
"http://ury.org.uk/timelord/",
"URY - Timelord",
"resizable,status"
);
}}
>
<img src={logo} className="mr-2" height={32} alt="Logo" />
<Clock
format={"HH:mm:ss"}
ticking={true}
timezone={"europe/london"}
/>
</li>
</ul>
<div>
<ul className="nav navbar-nav navbar-right mr-0 pr-0">
<li
className="btn btn-outline-light rounded-0 pt-2 pb-2 nav-item nav-link"
style={{ color: "white" }}
onClick={() => {
setShowBAPSicleModal(true);
}}
>
<FaCompactDisc size={16} className="mr-2" />
<b>Menu</b>
</li>
</ul>
</div>
<BAPSicleModal
close={() => setShowBAPSicleModal(false)}
isOpen={showBAPSicleModal}
/>
</>
);
}
// Full WebStudio NavBar
return (
<>
<li className="nav-item" style={{ color: "white" }}>

View file

@ -5,6 +5,7 @@ import { myradioApiRequest } from "../api";
import { useInterval } from "../lib/utils";
import { RootState } from "../rootReducer";
import "./timelord.scss";
import logo from "../assets/images/navbarlogo.png";
const SILENCE_WARN_SECS = 5;
@ -72,6 +73,10 @@ export function Timelord() {
);
}}
>
{process.env.REACT_APP_BAPSICLE_INTERFACE && (
<img src={logo} className="mr-2" height={32} alt="Logo" />
)}
<LiveClock
format={"HH:mm:ss"}
ticking={true}

View file

@ -101,7 +101,9 @@ const setTrackIntro = (
secs = Math.round(secs);
dispatch(MixerState.setLoadedItemIntro(player, secs));
if (getState().settings.saveShowPlanChanges) {
await api.setTrackIntro(item.trackid, secs);
if ("trackid" in item) {
await api.setTrackIntro(item.trackid, secs);
}
}
dispatch(ShowPlanState.setItemTimings({ item: item, intro: secs }));
} catch (e) {
@ -135,7 +137,9 @@ const setTrackOutro = (
secs = Math.round(secs);
dispatch(MixerState.setLoadedItemOutro(player, secs));
if (getState().settings.saveShowPlanChanges) {
await api.setTrackOutro(item.trackid, secs);
if ("trackid" in item) {
await api.setTrackOutro(item.trackid, secs);
}
}
dispatch(ShowPlanState.setItemTimings({ item: item, outro: secs }));
} catch (e) {
@ -391,9 +395,7 @@ export function Player({
: "btn-outline-secondary") +
" btn btn-sm col-4 sp-play-on-load"
}
onClick={() =>
dispatch(MixerState.toggleAutoAdvance({ player: id }))
}
onClick={() => dispatch(MixerState.toggleAutoAdvance(id))}
>
<FaLevelDownAlt />
&nbsp; Auto Advance
@ -405,9 +407,7 @@ export function Player({
: "btn-outline-secondary") +
" btn btn-sm col-4 sp-play-on-load"
}
onClick={() =>
dispatch(MixerState.togglePlayOnLoad({ player: id }))
}
onClick={() => dispatch(MixerState.togglePlayOnLoad(id))}
>
<FaPlayCircle />
&nbsp; Play on Load
@ -419,9 +419,7 @@ export function Player({
: "btn-outline-secondary") +
" btn btn-sm col-4 sp-play-on-load"
}
onClick={() =>
dispatch(MixerState.toggleRepeat({ player: id }))
}
onClick={() => dispatch(MixerState.toggleRepeat(id))}
>
<FaRedo />
&nbsp; Repeat {playerState.repeat}
@ -519,56 +517,63 @@ export function Player({
</div>
</div>
</div>
{!isPreviewChannel && !customOutput && (
<div
className={
"mixer-buttons " +
(playerState.state === "playing"
? playerState.volume === 0 && !playerState.pfl
? "error-animation"
: playerState.pfl && "pfl"
: "")
}
>
{!process.env.REACT_APP_BAPSICLE_INTERFACE &&
!isPreviewChannel &&
!customOutput && (
<div
className="mixer-buttons-backdrop"
style={{
width:
(USE_REAL_GAIN_VALUE ? playerState.gain : playerState.volume) *
100 +
"%",
}}
></div>
<button onClick={() => dispatch(MixerState.setVolume(id, "off"))}>
Off
</button>
<button onClick={() => dispatch(MixerState.setVolume(id, "bed"))}>
Bed
</button>
<button onClick={() => dispatch(MixerState.setVolume(id, "full"))}>
Full
</button>
</div>
)}
{!isPreviewChannel && settings.proMode && settings.channelVUs && (
<div className="channel-vu">
{customOutput ? (
<span className="text-muted">
Custom audio output disables VU meters.
</span>
) : playerState.pfl ? (
<span className="text-muted">This Player is playing in PFL.</span>
) : (
<VUMeter
width={300}
height={40}
source={VUsource(id)}
range={[-40, 0]}
stereo={settings.channelVUsStereo}
/>
)}
</div>
)}
className={
"mixer-buttons " +
(playerState.state === "playing"
? playerState.volume === 0 && !playerState.pfl
? "error-animation"
: playerState.pfl && "pfl"
: "")
}
>
<div
className="mixer-buttons-backdrop"
style={{
width:
(USE_REAL_GAIN_VALUE
? playerState.gain
: playerState.volume) *
100 +
"%",
}}
></div>
<button onClick={() => dispatch(MixerState.setVolume(id, "off"))}>
Off
</button>
<button onClick={() => dispatch(MixerState.setVolume(id, "bed"))}>
Bed
</button>
<button onClick={() => dispatch(MixerState.setVolume(id, "full"))}>
Full
</button>
</div>
)}
{!process.env.REACT_APP_BAPSICLE_INTERFACE &&
!isPreviewChannel &&
settings.proMode &&
settings.channelVUs && (
<div className="channel-vu">
{customOutput ? (
<span className="text-muted">
Custom audio output disables VU meters.
</span>
) : playerState.pfl ? (
<span className="text-muted">This Player is playing in PFL.</span>
) : (
<VUMeter
width={300}
height={40}
source={VUsource(id)}
range={[-40, 0]}
stereo={settings.channelVUsStereo}
/>
)}
</div>
)}
</div>
);
}

View file

@ -226,7 +226,6 @@ const Showplanner: React.FC<{ timeslotId: number }> = function({ timeslotId }) {
dispatch(setItemPlayed(data.id.toString(), false, data.column));
}
// Add support for reloading the show plan from the iFrames.
// There is a similar listener in showplanner/ImporterModal.tsx to handle closing the iframe.
useEffect(() => {
@ -277,18 +276,14 @@ const Showplanner: React.FC<{ timeslotId: number }> = function({ timeslotId }) {
</CtxMenuItem>
<CtxMenuItem
onClick={(args) =>
dispatch(
setItemPlayed({ itemId: (args.props as any).id, played: false })
)
dispatch(setItemPlayed((args.props as any).id, false))
}
>
<FaCircleNotch /> Mark Unplayed
</CtxMenuItem>
<CtxMenuItem
onClick={(args) =>
dispatch(
setItemPlayed({ itemId: (args.props as any).id, played: true })
)
dispatch(setItemPlayed((args.props as any).id, true))
}
>
<FaCircle /> Mark Played
@ -347,7 +342,10 @@ const Showplanner: React.FC<{ timeslotId: number }> = function({ timeslotId }) {
isOpen={showWelcomeModal}
close={() => setShowWelcomeModal(false)}
/>
<PisModal close={() => setShowPisModal(false)} isOpen={showPisModal} />
<PisModal
close={() => setShowPisModal(false)}
isOpen={showPisModal}
/>
<MicLiveIndicator />
</>
)}

View file

@ -79,39 +79,41 @@ export function LibraryColumn() {
<FaBookOpen className="mx-2" size={25} />
Libraries
</h2>
<div className="row m-0 p-1 card-header hover-menu">
<span className="hover-label">Hover for Import &amp; Tools</span>
<Button
className="mr-1"
color="primary"
title="Import From Showplan"
size="sm"
outline={true}
onClick={() => setShowImporterModal(true)}
>
<FaFileImport /> Import
</Button>
<Button
className="mr-1"
color="primary"
title="Upload to Library"
size="sm"
outline={true}
onClick={() => setShowLibraryModal(true)}
>
<FaUpload /> Upload
</Button>
<Button
className="mr-1"
color="primary"
title="Auto Playout"
size="sm"
outline={true}
onClick={() => setAutoPlayoutModal(true)}
>
<FaPlayCircle /> Auto Playout
</Button>
</div>
{!process.env.REACT_APP_BAPSICLE_INTERFACE && (
<div className="row m-0 p-1 card-header hover-menu">
<span className="hover-label">Hover for Import &amp; Tools</span>
<Button
className="mr-1"
color="primary"
title="Import From Showplan"
size="sm"
outline={true}
onClick={() => setShowImporterModal(true)}
>
<FaFileImport /> Import
</Button>
<Button
className="mr-1"
color="primary"
title="Upload to Library"
size="sm"
outline={true}
onClick={() => setShowLibraryModal(true)}
>
<FaUpload /> Upload
</Button>
<Button
className="mr-1"
color="primary"
title="Auto Playout"
size="sm"
outline={true}
onClick={() => setAutoPlayoutModal(true)}
>
<FaPlayCircle /> Auto Playout
</Button>
</div>
)}
</div>
<div className="px-2">
<select
@ -125,12 +127,16 @@ export function LibraryColumn() {
Choose a library
</option>
<option value={"CentralMusicLibrary"}>Central Music Library</option>
<option disabled>Personal Resources</option>
{userPlaylists.map((playlist) => (
<option key={playlist.managedid} value={playlist.managedid}>
{playlist.title}
</option>
))}
{!process.env.REACT_APP_BAPSICLE_INTERFACE && (
<>
<option disabled>Personal Resources</option>
{userPlaylists.map((playlist) => (
<option key={playlist.managedid} value={playlist.managedid}>
{playlist.title}
</option>
))}
</>
)}
<option disabled>Shared Resources</option>
{auxPlaylists.map((playlist) => (
<option

View file

@ -15,9 +15,13 @@ export function Sidebar() {
<div id="sidebar">
<LibraryColumn />
<div className="border-top"></div>
<PflPlayer />
<div className="border-top"></div>
<MicControl />
{!process.env.REACT_APP_BAPSICLE_INTERFACE && (
<>
<PflPlayer />
<div className="border-top"></div>
<MicControl />
</>
)}
</div>
);
}

View file

@ -480,62 +480,64 @@ export const addItem = (
if (process.env.REACT_APP_BAPSICLE_INTERFACE) {
dispatch(showplan.actions.addItem(newItemData));
} else {
if (getState().settings.saveShowPlanChanges) {
const ghostId = Math.random().toString(10);
if (getState().settings.saveShowPlanChanges) {
const ghostId = Math.random().toString(10);
const ghost: ItemGhost = {
ghostid: ghostId,
channel: newItemData.channel,
weight: newItemData.weight,
title: newItemData.title,
artist: newItemData.type === "central" ? newItemData.artist : "",
length: newItemData.length,
clean: newItemData.clean,
intro: newItemData.type === "central" ? newItemData.intro : 0,
outro: newItemData.type === "central" ? newItemData.outro : 0,
cue: 0,
type: "ghost",
};
const ghost: ItemGhost = {
ghostid: ghostId,
channel: newItemData.channel,
weight: newItemData.weight,
title: newItemData.title,
artist: newItemData.type === "central" ? newItemData.artist : "",
length: newItemData.length,
clean: newItemData.clean,
intro: newItemData.type === "central" ? newItemData.intro : 0,
outro: newItemData.type === "central" ? newItemData.outro : 0,
cue: 0,
type: "ghost",
};
const idForServer =
newItemData.type === "central"
? `${newItemData.album.recordid}-${newItemData.trackid}`
: "managedid" in newItemData
? `ManagedDB-${newItemData.managedid}`
: null;
const idForServer =
newItemData.type === "central"
? `${newItemData.album.recordid}-${newItemData.trackid}`
: "managedid" in newItemData
? `ManagedDB-${newItemData.managedid}`
: null;
if (!idForServer) return; // Something went very wrong
if (!idForServer) return; // Something went very wrong
dispatch(showplan.actions.insertGhost(ghost));
ops.push({
op: "AddItem",
channel: newItemData.channel,
weight: newItemData.weight,
id: idForServer,
});
const result = await api.updateShowplan(timeslotId, ops);
if (!result.every((x) => x.status)) {
Sentry.captureException(new Error("Showplan update failure [addItem]"), {
dispatch(showplan.actions.insertGhost(ghost));
ops.push({
op: "AddItem",
channel: newItemData.channel,
weight: newItemData.weight,
id: idForServer,
});
const result = await api.updateShowplan(timeslotId, ops);
if (!result.every((x) => x.status)) {
Sentry.captureException(
new Error("Showplan update failure [addItem]"),
{
contexts: {
updateShowplan: {
ops,
result,
},
},
}
);
});
const lastResult = result[result.length - 1]; // this is the add op
const newItemId = lastResult.timeslotitemid!;
const lastResult = result[result.length - 1]; // this is the add op
const newItemId = lastResult.timeslotitemid!;
newItemData.timeslotitemid = newItemId;
dispatch(
showplan.actions.replaceGhost({
ghostId: "G" + ghostId,
newItemData,
})
);
newItemData.timeslotitemid = newItemId;
dispatch(
showplan.actions.replaceGhost({
ghostId: "G" + ghostId,
newItemData,
})
);
}
} else {
// Just add it straight to the show plan without updating the server.
dispatch(showplan.actions.addItem(newItemData));
@ -577,7 +579,6 @@ export const removeItem = (
movingItem.weight -= 1;
if (!process.env.REACT_APP_BAPSICLE_INTERFACE) {
if (getState().settings.saveShowPlanChanges) {
const result = await api.updateShowplan(timeslotId, ops);
if (!result.every((x) => x.status)) {
@ -592,15 +593,17 @@ export const removeItem = (
},
}
);
dispatch(showplan.actions.planSaveError("Failed to update show plan."));
dispatch(
showplan.actions.planSaveError("Failed to update show plan.")
);
return;
}
}
}
}
dispatch(showplan.actions.applyOps(ops));
dispatch(showplan.actions.setPlanSaving(false));
dispatch(showplan.actions.applyOps(ops));
dispatch(showplan.actions.setPlanSaving(false));
};
export const getShowplan = (timeslotId: number): AppThunk => async (
@ -663,12 +666,12 @@ export const getPlaylists = (): AppThunk => async (dispatch) => {
if (!process.env.REACT_APP_BAPSICLE_INTERFACE) {
try {
const userPlaylists = await api.getUserPlaylists();
dispatch(showplan.actions.addUserPlaylists(userPlaylists));
} catch (e) {
console.error(e);
}
}
try {
const managedPlaylists = await api.getManagedPlaylists();
dispatch(showplan.actions.addManagedPlaylists(managedPlaylists));
@ -678,7 +681,6 @@ export const getPlaylists = (): AppThunk => async (dispatch) => {
try {
const auxPlaylists = await api.getAuxPlaylists();
dispatch(showplan.actions.addAuxPlaylists(auxPlaylists));
} catch (e) {
console.error(e);

101
yarn.lock
View file

@ -1425,68 +1425,79 @@
estree-walker "^1.0.1"
picomatch "^2.2.2"
"@sentry/browser@6.5.0":
version "6.5.0"
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.5.0.tgz#2382493691c3fac5d8b652ae46f09f1b29d288ef"
integrity sha512-n1e8hNKwuVP4bLqRK5J0DHFqnnnrbv6h6+Bc1eNRbf32/e6eZ3Cb36PTplqDCxwnMnnIEEowd5F4ZWeTLPPY3A==
"@sentry/browser@6.3.1":
version "6.3.1"
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.3.1.tgz#6142dd4c72308f4e1a12e585e3300fd54ca058cd"
integrity sha512-Ri4tYsyuJIeLQnvQUqbpGzailUYpbjFSYM0+yEM63gPsjiXdg+W8yKHluA6cs6FLWVN3oWfwHW7Kd61echlGuw==
dependencies:
"@sentry/core" "6.5.0"
"@sentry/types" "6.5.0"
"@sentry/utils" "6.5.0"
"@sentry/core" "6.3.1"
"@sentry/types" "6.3.1"
"@sentry/utils" "6.3.1"
tslib "^1.9.3"
"@sentry/core@6.5.0":
version "6.5.0"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.5.0.tgz#03ecbad7845b31f03a84eddf4884877c999bb6be"
integrity sha512-Hx/WvhM5bXcXqfIiz+505TjYYfPjQ8mrxby/EWl+L7dYUCyI/W6IZKTc/MoHlLuM+JPUW9c1bw/97TzbgTzaAA==
"@sentry/core@6.3.1":
version "6.3.1"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.3.1.tgz#5e32ca919c9be30fec0bb3125a556bc711584bdf"
integrity sha512-aVuvVbaehGeN86jZlLDGGkhEtprdOtB6lvYLfGy40Dj1Tkh2mGWE550QsRXAXAqYvQzIYwQR23r6m3o8FujgVg==
dependencies:
"@sentry/hub" "6.5.0"
"@sentry/minimal" "6.5.0"
"@sentry/types" "6.5.0"
"@sentry/utils" "6.5.0"
"@sentry/hub" "6.3.1"
"@sentry/minimal" "6.3.1"
"@sentry/types" "6.3.1"
"@sentry/utils" "6.3.1"
tslib "^1.9.3"
"@sentry/hub@6.5.0":
version "6.5.0"
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.5.0.tgz#ad3c9bcf83050ea217f3c25cc625e6b447f1d9d7"
integrity sha512-vEChnLoozOJzEJoTUvaAsK/n7IHoQFx8P1TzQmnR+8XGZJZmGHG6bBXUH0iS2a9hhR1WkoEBeiL+t96R9uyf0A==
"@sentry/hub@6.3.1":
version "6.3.1"
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.3.1.tgz#dda07888a82d1c48bbefa00205bfa9d035691f07"
integrity sha512-2er+OeVlsdVZkhl9kXQAANwgjwoCdM1etK2iFuhzX8xkMaJlAuZLyQInv2U1BbXBlIfWjvzRM8B95hCWvVrR3Q==
dependencies:
"@sentry/types" "6.5.0"
"@sentry/utils" "6.5.0"
"@sentry/types" "6.3.1"
"@sentry/utils" "6.3.1"
tslib "^1.9.3"
"@sentry/minimal@6.5.0":
version "6.5.0"
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.5.0.tgz#aa89b8e24c88aa85c99ef64e0b460497c90133f9"
integrity sha512-MT83ONaBhTCFUlDIQFpsG/lq3ZjGK7jwQ10qxGadSg1KW6EvtQRg+OBwULeQ7C+nNEAhseNrC/qomZMT8brncg==
"@sentry/minimal@6.3.1":
version "6.3.1"
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.3.1.tgz#38f71c77e8820555effb6e868336d4f5672018cd"
integrity sha512-0eN9S7HvXsCQEjX/qXHTMgvSb3mwrnZEWS9Qz/Bz5ig9pEGXKgJ1om5NTTHVHhXqd3wFCjdvIo6slufLHoCtSw==
dependencies:
"@sentry/hub" "6.5.0"
"@sentry/types" "6.5.0"
"@sentry/hub" "6.3.1"
"@sentry/types" "6.3.1"
tslib "^1.9.3"
"@sentry/react@^6.5.0":
version "6.5.0"
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-6.5.0.tgz#db2067e080cac24da046af24865b82d3567adbf4"
integrity sha512-NyH+v8MwX+nzuhPRGy3+DHSB0es5yaCUNrtAdCtbe8EhERSoYvqAyWIQ+Fp5++PGjfAtYbz0W0IpsjguZbnT2Q==
"@sentry/react@^6.3.1":
version "6.3.1"
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-6.3.1.tgz#5082aa145972eec38cc8ceea8e5d8ee3f7f5f86a"
integrity sha512-3eFSqdS0QAb4RFNxS0gzVm05q8c5KQp+3TlmqBjoovqWL/FvGvDoqaBmFT+arvPZ88qngveMEk1v6445L0gFTg==
dependencies:
"@sentry/browser" "6.5.0"
"@sentry/minimal" "6.5.0"
"@sentry/types" "6.5.0"
"@sentry/utils" "6.5.0"
"@sentry/browser" "6.3.1"
"@sentry/minimal" "6.3.1"
"@sentry/types" "6.3.1"
"@sentry/utils" "6.3.1"
hoist-non-react-statics "^3.3.2"
tslib "^1.9.3"
"@sentry/types@6.5.0":
version "6.5.0"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.5.0.tgz#2cdb50875bb73d87708b9c0a80d4ca057b3596b5"
integrity sha512-yQpTCIYxBsYT0GenqHNNKeXV8CSkkYlAxB1IGV2eac4IKC5ph5GW6TfDGwvlzQSQ297RsRmOSA8o3I5gGPd2yA==
"@sentry/utils@6.5.0":
version "6.5.0"
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.5.0.tgz#8722542b9a901623195cffaab5d18ce176c1e459"
integrity sha512-CcHuaQN6vRuAsIC+3sA23NmWLRmUN0x/HNQxk0DHJylvYQdEA0AUNoLXogykaXh6NrCx4DNq9yCQTNTSC3mFxg==
"@sentry/tracing@^6.3.1":
version "6.3.1"
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.3.1.tgz#3b96aabf4d9cebadfec070c006db79801a68ee24"
integrity sha512-qveDmoWsXy9qLEblZJwJ1OU/zZRlEd/q7Jhd0Hnwlob8Ci96huABEbYyGdJs18BKVHEFU3gSdVfvrikUE/W17g==
dependencies:
"@sentry/types" "6.5.0"
"@sentry/hub" "6.3.1"
"@sentry/minimal" "6.3.1"
"@sentry/types" "6.3.1"
"@sentry/utils" "6.3.1"
tslib "^1.9.3"
"@sentry/types@6.3.1":
version "6.3.1"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.3.1.tgz#af3b54728b29f633f38fbe51b8c10e3834fbc158"
integrity sha512-BEBn8JX1yaooCAuonbaMci9z0RjwwMbQ3Eny/eyDdd+rjXprZCZaStZnCvSThbNBqAJ8YaUqY2YBMnEwJxarAw==
"@sentry/utils@6.3.1":
version "6.3.1"
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.3.1.tgz#6d8e691139b5b49d8c655ad1dcaf2cb3ff0d0b03"
integrity sha512-cdtl/QWC9FtinAuW3w8QfvSfh/Q9ui5vwvjzVHiS1ga/U38edi2XX+cttY39ZYwz0SQG99cE10GOIhd1p7/mAA==
dependencies:
"@sentry/types" "6.3.1"
tslib "^1.9.3"
"@surma/rollup-plugin-off-main-thread@^1.1.1":