Merge pull request #200 from UniversityRadioYork/mstratford/last-call-for-release

Last bugs i've seen.
This commit is contained in:
Matthew Stratford 2021-01-30 20:17:51 +00:00 committed by GitHub
commit 3818d20932
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 62 additions and 22 deletions

View file

@ -1,6 +1,6 @@
{
"name": "webstudio",
"version": "1.4.0",
"version": "1.5.0",
"private": true,
"dependencies": {
"@babel/core": "7.6.0",

View file

@ -30,18 +30,21 @@ export function VUMeter(props: VUMeterProps) {
const FPS = 30; // Limit the FPS so that lower spec machines have a better time juggling CPU.
useEffect(() => {
let isMounted = true; // This VU exists as we're calling useEffect
const animate = () => {
if (!isMic || isMicOpen) {
if ((!isMic || isMicOpen) && isMounted) {
const result = audioEngine.getLevels(
props.source,
props.stereo ? props.stereo : false
);
setPeakL(result[0]);
if (props.stereo) {
if (props.stereo && isMounted) {
setPeakR(result[1]);
}
setTimeout((current = rafRef.current, a = animate) => {
if (isMounted) {
current = requestAnimationFrame(a);
}
}, 1000 / FPS);
}
};
@ -49,6 +52,7 @@ export function VUMeter(props: VUMeterProps) {
rafRef.current = requestAnimationFrame(animate);
}
return () => {
isMounted = false; // Tell the async stuff above to not bother if the VU meter has gone away.
if (rafRef.current !== null) {
cancelAnimationFrame(rafRef.current);
rafRef.current = null;

View file

@ -8,6 +8,7 @@ import * as MixerState from "../mixer/state";
import { Draggable } from "react-beautiful-dnd";
import { contextMenu } from "react-contexify";
import "./item.scss";
import { HHMMTosec, secToHHMM } from "../lib/utils";
import { PLAYER_ID_PREVIEW } from "../mixer/audio";
export const TS_ITEM_MENU_ID = "SongMenu";
@ -80,12 +81,33 @@ export const Item = memo(function Item({
if ("artist" in x && x.artist !== "") data.push("Artist: " + x.artist);
if ("album" in x && x.album.title !== "")
data.push("Album: " + x.album.title);
data.push("Length: " + x.length.toString());
if ("intro" in x) data.push("Intro: " + x.intro + " secs");
if ("cue" in x) data.push("Cue: " + x.cue + " secs");
if ("outro" in x) data.push("Outro: " + x.outro + " secs");
data.push("Length: " + x.length);
if ("intro" in x)
data.push(
"Intro: " + (x.intro > 60 ? secToHHMM(x.intro) : x.intro + " secs")
);
if ("cue" in x)
data.push("Cue: " + (x.cue > 60 ? secToHHMM(x.cue) : x.cue + " secs"));
if ("outro" in x) {
// Outro seconds are counted from end of track, except 0 = no outro;
const outroSecs = x.outro === 0 ? 0 : HHMMTosec(x.length) - x.outro;
data.push(
"Outro: " +
(outroSecs > 60 ? secToHHMM(outroSecs) : outroSecs + " secs")
);
}
data.push("Played: " + ("played" in x ? (x.played ? "Yes" : "No") : "No"));
data.push(
"ID: " + ("trackid" in x ? x.trackid : "managedid" in x && x.managedid)
);
if (showDebug) {
data.push(
"Debug: itemId(): " +
itemId(x) +
" - Channel/weight: " +
("channel" in x && x.channel + "/" + x.weight)
);
}
return data.join("¬"); // Something obscure to split against.
}

View file

@ -246,7 +246,13 @@ function LoadedTrackInfo({ id }: { id: number }) {
);
}
export function Player({ id, pfl }: { id: number; pfl: boolean }) {
export function Player({
id,
isPreviewChannel,
}: {
id: number;
isPreviewChannel: boolean;
}) {
// Define time remaining (secs) when the play icon should flash.
const SECS_REMAINING_WARNING = 20;
@ -295,7 +301,7 @@ export function Player({ id, pfl }: { id: number; pfl: boolean }) {
}
>
<div className="card text-center">
{!pfl && (
{!isPreviewChannel && (
<>
<div className="d-inline mx-1">
<span className="float-left">
@ -353,11 +359,11 @@ export function Player({ id, pfl }: { id: number; pfl: boolean }) {
</div>
</>
)}
{!pfl && settings.proMode && !customOutput && (
{!isPreviewChannel && settings.proMode && !customOutput && (
<ProModeButtons channel={id} />
)}
<div className="card-body p-0">
{!pfl && (
{!isPreviewChannel && (
<>
<LoadedTrackInfo id={id} />
<br />
@ -403,10 +409,10 @@ export function Player({ id, pfl }: { id: number; pfl: boolean }) {
</div>
<div className="p-0 card-footer">
{!pfl && <TimingButtons id={id} />}
{!isPreviewChannel && <TimingButtons id={id} />}
<div className="waveform">
<PlayerNumbers id={id} pfl={pfl} />
{!pfl &&
<PlayerNumbers id={id} pfl={isPreviewChannel} />
{!isPreviewChannel &&
playerState.loadedItem !== null &&
"intro" in playerState.loadedItem && (
<span className="m-0 intro bypass-click">
@ -436,12 +442,14 @@ export function Player({ id, pfl }: { id: number; pfl: boolean }) {
</div>
</div>
</div>
{!pfl && (
{!isPreviewChannel && !customOutput && (
<div
className={
"mixer-buttons " +
(playerState.state === "playing" && playerState.volume === 0
(playerState.state === "playing"
? playerState.volume === 0 && !playerState.pfl
? "error-animation"
: playerState.pfl && "pfl"
: "")
}
>
@ -465,12 +473,14 @@ export function Player({ id, pfl }: { id: number; pfl: boolean }) {
</button>
</div>
)}
{!pfl && settings.proMode && settings.channelVUs && (
{!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}
@ -492,7 +502,7 @@ export function PflPlayer() {
<span className="mx-1 hover-label always-show">
Preview Player (Headphones Only)
</span>
<Player id={PLAYER_ID_PREVIEW} pfl={true} />
<Player id={PLAYER_ID_PREVIEW} isPreviewChannel={true} />
</div>
);
}

View file

@ -41,6 +41,10 @@
animation: red-flash steps(1) 0.5s infinite;
}
&.pfl {
background-color: #dc3545;
}
.mixer-buttons-backdrop {
position: absolute;
top: 0;

View file

@ -69,7 +69,7 @@ function Channel({ id, data }: { id: number; data: PlanItem[] }) {
</div>
)}
</Droppable>
<Player id={id} pfl={false} />
<Player id={id} isPreviewChannel={false} />
</div>
);
}