Refactor news cues code
This commit is contained in:
parent
6e3aab988d
commit
cb0e091c30
4 changed files with 93 additions and 85 deletions
|
@ -9,6 +9,7 @@
|
||||||
"@types/dom-mediacapture-record": "^1.0.4",
|
"@types/dom-mediacapture-record": "^1.0.4",
|
||||||
"@types/jest": "24.0.22",
|
"@types/jest": "24.0.22",
|
||||||
"@types/keymaster": "^1.6.28",
|
"@types/keymaster": "^1.6.28",
|
||||||
|
"@types/later": "^1.2.6",
|
||||||
"@types/lodash": "^4.14.149",
|
"@types/lodash": "^4.14.149",
|
||||||
"@types/node": "^13.11.0",
|
"@types/node": "^13.11.0",
|
||||||
"@types/qs": "^6.9.0",
|
"@types/qs": "^6.9.0",
|
||||||
|
@ -35,7 +36,6 @@
|
||||||
"camelcase": "^5.2.0",
|
"camelcase": "^5.2.0",
|
||||||
"case-sensitive-paths-webpack-plugin": "2.2.0",
|
"case-sensitive-paths-webpack-plugin": "2.2.0",
|
||||||
"css-loader": "2.1.1",
|
"css-loader": "2.1.1",
|
||||||
"date-fns": "^2.12.0",
|
|
||||||
"dotenv": "6.2.0",
|
"dotenv": "6.2.0",
|
||||||
"dotenv-expand": "5.1.0",
|
"dotenv-expand": "5.1.0",
|
||||||
"eslint": "^6.1.0",
|
"eslint": "^6.1.0",
|
||||||
|
@ -57,6 +57,7 @@
|
||||||
"jest-resolve": "24.9.0",
|
"jest-resolve": "24.9.0",
|
||||||
"jest-watch-typeahead": "0.4.0",
|
"jest-watch-typeahead": "0.4.0",
|
||||||
"keymaster": "^1.6.2",
|
"keymaster": "^1.6.2",
|
||||||
|
"later": "^1.2.0",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.15",
|
||||||
"mini-css-extract-plugin": "0.8.0",
|
"mini-css-extract-plugin": "0.8.0",
|
||||||
"optimize-css-assets-webpack-plugin": "5.0.3",
|
"optimize-css-assets-webpack-plugin": "5.0.3",
|
||||||
|
|
75
src/api.ts
75
src/api.ts
|
@ -1,11 +1,8 @@
|
||||||
import qs from "qs";
|
import qs from "qs";
|
||||||
|
|
||||||
export const MYRADIO_NON_API_BASE =
|
export const MYRADIO_NON_API_BASE = process.env.REACT_APP_MYRADIO_NONAPI_BASE!;
|
||||||
process.env.REACT_APP_MYRADIO_NONAPI_BASE!;
|
export const MYRADIO_BASE_URL = process.env.REACT_APP_MYRADIO_BASE!;
|
||||||
export const MYRADIO_BASE_URL =
|
export const BROADCAST_API_BASE_URL = process.env.REACT_APP_BROADCAST_API_BASE!;
|
||||||
process.env.REACT_APP_MYRADIO_BASE!;
|
|
||||||
export const BROADCAST_API_BASE_URL =
|
|
||||||
process.env.REACT_APP_BROADCAST_API_BASE!;
|
|
||||||
const MYRADIO_API_KEY = process.env.REACT_APP_MYRADIO_KEY!;
|
const MYRADIO_API_KEY = process.env.REACT_APP_MYRADIO_KEY!;
|
||||||
|
|
||||||
export class ApiException extends Error {}
|
export class ApiException extends Error {}
|
||||||
|
@ -19,7 +16,7 @@ export async function apiRequest(
|
||||||
let req = null;
|
let req = null;
|
||||||
if (method === "GET") {
|
if (method === "GET") {
|
||||||
req = fetch(url + qs.stringify(params, { addQueryPrefix: true }), {
|
req = fetch(url + qs.stringify(params, { addQueryPrefix: true }), {
|
||||||
credentials: (need_auth ? "include" : "omit")
|
credentials: need_auth ? "include" : "omit"
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const body = JSON.stringify(params);
|
const body = JSON.stringify(params);
|
||||||
|
@ -30,7 +27,7 @@ export async function apiRequest(
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
"Content-Type": "application/json; charset=UTF-8"
|
||||||
},
|
},
|
||||||
credentials: (need_auth ? "include" : "omit")
|
credentials: need_auth ? "include" : "omit"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return await req;
|
return await req;
|
||||||
|
@ -51,12 +48,17 @@ export async function myradioApiRequest(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function broadcastApiRequest(
|
export async function broadcastApiRequest<TRes = any>(
|
||||||
endpoint: string,
|
endpoint: string,
|
||||||
method: "GET" | "POST" | "PUT",
|
method: "GET" | "POST" | "PUT",
|
||||||
params: any
|
params: any
|
||||||
): Promise<any> {
|
): Promise<TRes> {
|
||||||
const res = await apiRequest(BROADCAST_API_BASE_URL + endpoint, method, params, false);
|
const res = await apiRequest(
|
||||||
|
BROADCAST_API_BASE_URL + endpoint,
|
||||||
|
method,
|
||||||
|
params,
|
||||||
|
false
|
||||||
|
);
|
||||||
const json = await res.json();
|
const json = await res.json();
|
||||||
if (json.status === "OK") {
|
if (json.status === "OK") {
|
||||||
return json.payload;
|
return json.payload;
|
||||||
|
@ -184,7 +186,6 @@ export function searchForTracks(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface ManagedPlaylist {
|
export interface ManagedPlaylist {
|
||||||
type: "userPlaylist";
|
type: "userPlaylist";
|
||||||
title: string;
|
title: string;
|
||||||
|
@ -193,7 +194,11 @@ export interface ManagedPlaylist {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUserPlaylists(): Promise<Array<ManagedPlaylist>> {
|
export function getUserPlaylists(): Promise<Array<ManagedPlaylist>> {
|
||||||
return myradioApiRequest("/nipswebUserPlaylist/allmanageduserplaylists", "GET", {});
|
return myradioApiRequest(
|
||||||
|
"/nipswebUserPlaylist/allmanageduserplaylists",
|
||||||
|
"GET",
|
||||||
|
{}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAuxPlaylists(): Promise<Array<ManagedPlaylist>> {
|
export function getAuxPlaylists(): Promise<Array<ManagedPlaylist>> {
|
||||||
|
@ -242,42 +247,34 @@ export function updateShowplan(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export interface Timeslot {
|
export interface Timeslot {
|
||||||
timeslot_id: number,
|
timeslot_id: number;
|
||||||
time: number,
|
time: number;
|
||||||
start_time: string,
|
start_time: string;
|
||||||
title: string
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function getCurrentApiTimeslot(): Promise<Timeslot> {
|
export function getCurrentApiTimeslot(): Promise<Timeslot> {
|
||||||
return myradioApiRequest(`/timeslot/userselectedtimeslot`, "GET", {}
|
return myradioApiRequest(`/timeslot/userselectedtimeslot`, "GET", {}).then(
|
||||||
).then(res => {
|
res => {
|
||||||
return res;
|
return res;
|
||||||
});
|
}
|
||||||
};
|
);
|
||||||
|
|
||||||
|
|
||||||
export interface User {
|
|
||||||
memberid: number,
|
|
||||||
fname: string,
|
|
||||||
sname: string,
|
|
||||||
url: string,
|
|
||||||
photo: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface User {
|
||||||
|
memberid: number;
|
||||||
|
fname: string;
|
||||||
|
sname: string;
|
||||||
|
url: string;
|
||||||
|
photo: string;
|
||||||
|
}
|
||||||
|
|
||||||
export function getCurrentApiUser(): Promise<User> {
|
export function getCurrentApiUser(): Promise<User> {
|
||||||
return myradioApiRequest(`/user/currentuser`, "GET", {}
|
return myradioApiRequest(`/user/currentuser`, "GET", {}).then(res => {
|
||||||
).then(res => {
|
|
||||||
return res;
|
return res;
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
export function doesCurrentUserHavePermission(id: number): Promise<boolean> {
|
export function doesCurrentUserHavePermission(id: number): Promise<boolean> {
|
||||||
return myradioApiRequest("/auth/haspermission/" + id.toString(10), "GET", {});
|
return myradioApiRequest("/auth/haspermission/" + id.toString(10), "GET", {});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import SdpTransform from "sdp-transform";
|
import SdpTransform from "sdp-transform";
|
||||||
import * as DateFns from "date-fns";
|
import * as later from "later";
|
||||||
|
|
||||||
import * as BroadcastState from "./state";
|
import * as BroadcastState from "./state";
|
||||||
import * as MixerState from "../mixer/state";
|
import * as MixerState from "../mixer/state";
|
||||||
|
@ -10,6 +10,7 @@ import {
|
||||||
ConnectionStateEnum
|
ConnectionStateEnum
|
||||||
} from "./streamer";
|
} from "./streamer";
|
||||||
import { Dispatch } from "redux";
|
import { Dispatch } from "redux";
|
||||||
|
import { broadcastApiRequest } from "../api";
|
||||||
|
|
||||||
type StreamerState = "HELLO" | "OFFER" | "ANSWER" | "CONNECTED";
|
type StreamerState = "HELLO" | "OFFER" | "ANSWER" | "CONNECTED";
|
||||||
|
|
||||||
|
@ -22,9 +23,7 @@ export class WebRTCStreamer extends Streamer {
|
||||||
dispatch: Dispatch<any>;
|
dispatch: Dispatch<any>;
|
||||||
unexpectedDeath = false;
|
unexpectedDeath = false;
|
||||||
|
|
||||||
newsInTimeout?: number;
|
newsInterval?: later.Timer;
|
||||||
newsOutTimeout?: number;
|
|
||||||
newsInterval?: number;
|
|
||||||
|
|
||||||
constructor(stream: MediaStream, dispatch: Dispatch<any>) {
|
constructor(stream: MediaStream, dispatch: Dispatch<any>) {
|
||||||
super();
|
super();
|
||||||
|
@ -67,9 +66,15 @@ export class WebRTCStreamer extends Streamer {
|
||||||
|
|
||||||
this.addConnectionStateListener(state => {
|
this.addConnectionStateListener(state => {
|
||||||
if (state === "CONNECTED") {
|
if (state === "CONNECTED") {
|
||||||
this.newsInterval = window.setInterval(this.doTheNews, 1000 * 60);
|
this.newsInterval = later.setInterval(
|
||||||
|
this.doTheNews,
|
||||||
|
later.parse
|
||||||
|
.recur()
|
||||||
|
.on(59)
|
||||||
|
.minute()
|
||||||
|
);
|
||||||
} else if (state === "CONNECTION_LOST" || state === "NOT_CONNECTED") {
|
} else if (state === "CONNECTION_LOST" || state === "NOT_CONNECTED") {
|
||||||
window.clearInterval(this.newsInterval);
|
this.newsInterval?.clear();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -99,41 +104,41 @@ export class WebRTCStreamer extends Streamer {
|
||||||
this.unexpectedDeath = false;
|
this.unexpectedDeath = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
doTheNews() {
|
async doTheNews() {
|
||||||
window.clearTimeout(this.newsInTimeout);
|
const transition = await broadcastApiRequest<{
|
||||||
window.clearTimeout(this.newsOutTimeout);
|
autoNews: boolean;
|
||||||
const now = new Date();
|
selSource: number;
|
||||||
if (
|
switchAudioAtMin: number;
|
||||||
now.getMinutes() < 59 ||
|
}>("/nextTransition", "GET", {});
|
||||||
(now.getMinutes() === 59 && now.getSeconds() < 44)
|
if (transition.autoNews) {
|
||||||
) {
|
// Sanity check
|
||||||
const newsTime = DateFns.set(now, {
|
const now = new Date();
|
||||||
minutes: 59,
|
if (now.getSeconds() < 45) {
|
||||||
seconds: 45
|
later.setTimeout(
|
||||||
});
|
async () => {
|
||||||
console.log("news time", newsTime);
|
await MixerState.playNewsIntro();
|
||||||
const delta = newsTime.valueOf() - now.valueOf();
|
},
|
||||||
this.newsInTimeout = window.setTimeout(async () => {
|
later.parse
|
||||||
await MixerState.playNewsIntro();
|
.recur()
|
||||||
}, delta);
|
.on(59)
|
||||||
}
|
.minute()
|
||||||
if (
|
.on(45)
|
||||||
now.getMinutes() < 1 ||
|
.second()
|
||||||
now.getMinutes() >= 2 ||
|
);
|
||||||
(now.getMinutes() === 1 && now.getSeconds() < 54)
|
}
|
||||||
) {
|
if (now.getMinutes() <= 1 && now.getSeconds() < 55) {
|
||||||
let newsEndTime = DateFns.set(now, {
|
later.setTimeout(
|
||||||
minutes: 1,
|
async () => {
|
||||||
seconds: 55
|
await MixerState.playNewsEnd();
|
||||||
});
|
},
|
||||||
if (now.getMinutes() > 2) {
|
later.parse
|
||||||
newsEndTime = DateFns.add(newsEndTime, { hours: 1 });
|
.recur()
|
||||||
|
.on(1)
|
||||||
|
.minute()
|
||||||
|
.on(55)
|
||||||
|
.second()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
console.log("end time", newsEndTime);
|
|
||||||
const delta = newsEndTime.valueOf() - now.valueOf();
|
|
||||||
this.newsOutTimeout = window.setTimeout(async () => {
|
|
||||||
await MixerState.playNewsEnd();
|
|
||||||
}, delta);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
yarn.lock
15
yarn.lock
|
@ -1439,6 +1439,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/keymaster/-/keymaster-1.6.28.tgz#093fc6fe49deff4ee17d36935a49230edb1c935f"
|
resolved "https://registry.yarnpkg.com/@types/keymaster/-/keymaster-1.6.28.tgz#093fc6fe49deff4ee17d36935a49230edb1c935f"
|
||||||
integrity sha1-CT/G/kne/07hfTaTWkkjDtsck18=
|
integrity sha1-CT/G/kne/07hfTaTWkkjDtsck18=
|
||||||
|
|
||||||
|
"@types/later@^1.2.6":
|
||||||
|
version "1.2.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/later/-/later-1.2.6.tgz#8ea70d292e5fb880039a7ed13da19a24c9e35a56"
|
||||||
|
integrity sha512-a+wmsrP4FJCOt3xq+bjMkNloUtk7O7MnjYGTa6HxANSHRRPxcfhougk5+pl5B9Qr/w7cC7a4Ku9LM8frizr2Lw==
|
||||||
|
|
||||||
"@types/lodash@^4.14.149":
|
"@types/lodash@^4.14.149":
|
||||||
version "4.14.149"
|
version "4.14.149"
|
||||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.149.tgz#1342d63d948c6062838fbf961012f74d4e638440"
|
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.149.tgz#1342d63d948c6062838fbf961012f74d4e638440"
|
||||||
|
@ -3530,11 +3535,6 @@ data-urls@^1.0.0, data-urls@^1.1.0:
|
||||||
whatwg-mimetype "^2.2.0"
|
whatwg-mimetype "^2.2.0"
|
||||||
whatwg-url "^7.0.0"
|
whatwg-url "^7.0.0"
|
||||||
|
|
||||||
date-fns@^2.12.0:
|
|
||||||
version "2.12.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.12.0.tgz#01754c8a2f3368fc1119cf4625c3dad8c1845ee6"
|
|
||||||
integrity sha512-qJgn99xxKnFgB1qL4jpxU7Q2t0LOn1p8KMIveef3UZD7kqjT3tpFNNdXJelEHhE+rUgffriXriw/sOSU+cS1Hw==
|
|
||||||
|
|
||||||
debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9:
|
debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9:
|
||||||
version "2.6.9"
|
version "2.6.9"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||||
|
@ -6447,6 +6447,11 @@ last-call-webpack-plugin@^3.0.0:
|
||||||
lodash "^4.17.5"
|
lodash "^4.17.5"
|
||||||
webpack-sources "^1.1.0"
|
webpack-sources "^1.1.0"
|
||||||
|
|
||||||
|
later@^1.2.0:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/later/-/later-1.2.0.tgz#f2cf6c4dd7956dd2f520adf0329836e9876bad0f"
|
||||||
|
integrity sha1-8s9sTdeVbdL1IK3wMpg26YdrrQ8=
|
||||||
|
|
||||||
lazy-cache@^0.2.3:
|
lazy-cache@^0.2.3:
|
||||||
version "0.2.7"
|
version "0.2.7"
|
||||||
resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65"
|
resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65"
|
||||||
|
|
Loading…
Reference in a new issue