IT PLAYS SOUND
This commit is contained in:
parent
f2928ab266
commit
752838315b
5 changed files with 99 additions and 54 deletions
12
src/App.css
12
src/App.css
|
@ -37,11 +37,15 @@
|
|||
.sp-col {
|
||||
display: block;
|
||||
flex: 1;
|
||||
border: 1px solid black;
|
||||
height: calc(100% - 60px);
|
||||
/*height: calc(100% - 60px);*/
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.sp-col-inner {
|
||||
border: 1px solid black;
|
||||
height: 90%;
|
||||
}
|
||||
|
||||
.sp-track {
|
||||
display: block;
|
||||
/* overflow-x: hidden; */
|
||||
|
@ -56,6 +60,10 @@
|
|||
background-color: #78acf1;
|
||||
}
|
||||
|
||||
.sp-track-active {
|
||||
background-color: #10c998;
|
||||
}
|
||||
|
||||
html, body, #root {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
|
12
src/api.ts
12
src/api.ts
|
@ -1,8 +1,9 @@
|
|||
import qs from "qs";
|
||||
import { convertModelToFormData, urlEncode } from "./lib/utils";
|
||||
|
||||
const MYRADIO_BASE_URL =
|
||||
process.env.REACT_APP_MYRADIO_BASE || "https://ury.org.uk/api/v2";
|
||||
export const MYRADIO_NON_API_BASE = process.env.REACT_APP_MYRADIO_NONAPI_BASE || "https://ury.org.uk/myradio-staging";
|
||||
export const MYRADIO_BASE_URL =
|
||||
process.env.REACT_APP_MYRADIO_BASE || "https://ury.org.uk/api-staging/v2";
|
||||
const MYRADIO_API_KEY = process.env.REACT_APP_MYRADIO_KEY!;
|
||||
|
||||
class ApiException extends Error {}
|
||||
|
@ -23,7 +24,8 @@ export async function myradioApiRequest(
|
|||
api_key: MYRADIO_API_KEY
|
||||
},
|
||||
{ addQueryPrefix: true }
|
||||
)
|
||||
),
|
||||
{ credentials: "include" }
|
||||
);
|
||||
} else {
|
||||
const body = JSON.stringify(params);
|
||||
|
@ -33,7 +35,8 @@ export async function myradioApiRequest(
|
|||
body,
|
||||
headers: {
|
||||
"Content-Type": "application/json; charset=UTF-8"
|
||||
}
|
||||
},
|
||||
credentials: "include"
|
||||
});
|
||||
}
|
||||
const json = await (await req).json();
|
||||
|
@ -76,6 +79,7 @@ interface TimeslotItemCentral {
|
|||
interface TimeslotItemAux {
|
||||
type: "aux";
|
||||
summary: string;
|
||||
managedid: number;
|
||||
recordid: string;
|
||||
auxid: string;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { combineReducers } from "@reduxjs/toolkit";
|
||||
|
||||
import ShowplanReducer from "./showplanner/state";
|
||||
import PlayerReducer from "./showplanner/player/state";
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
showplan: ShowplanReducer
|
||||
showplan: ShowplanReducer,
|
||||
player: PlayerReducer
|
||||
});
|
||||
|
||||
export type RootState = ReturnType<typeof rootReducer>;
|
||||
|
|
|
@ -31,21 +31,34 @@ import {
|
|||
removeItem
|
||||
} from "./state";
|
||||
|
||||
import * as PlayerState from "./player/state";
|
||||
|
||||
const CML_CACHE: { [recordid_trackid: string]: Track } = {};
|
||||
|
||||
const TS_ITEM_MENU_ID = "SongMenu";
|
||||
|
||||
function Item({ item: x, index }: { item: PlanItem | Track; index: number }) {
|
||||
function Item({ item: x, index, column }: { item: PlanItem | Track; index: number; column: number }) {
|
||||
const dispatch = useDispatch();
|
||||
const id = itemId(x);
|
||||
const isReal = "timeslotitemid" in x;
|
||||
const isGhost = "ghostid" in x;
|
||||
|
||||
const playerState = useSelector((state: RootState) => state.player.players[column]);
|
||||
|
||||
function triggerClick() {
|
||||
if (column > -1) {
|
||||
dispatch(PlayerState.load(column, x));
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Draggable draggableId={id} index={index} isDragDisabled={isGhost}>
|
||||
{(provided, snapshot) => (
|
||||
<div
|
||||
ref={provided.innerRef}
|
||||
key={id}
|
||||
className="sp-track"
|
||||
className={`sp-track ${(playerState.loadedItem !== null && itemId(playerState.loadedItem) === id) ? "sp-track-active" : ""}`}
|
||||
onClick={triggerClick}
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
>
|
||||
|
@ -62,27 +75,45 @@ function Item({ item: x, index }: { item: PlanItem | Track; index: number }) {
|
|||
);
|
||||
}
|
||||
|
||||
function Player({ id }: { id: number }) {
|
||||
const playerState = useSelector((state: RootState) => state.player.players[id]);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
return (
|
||||
<div>
|
||||
{playerState.loadedItem !== null && (<div>{playerState.loadedItem.title}</div>)}
|
||||
{playerState.loading && <b>LOADING</b>}
|
||||
<button onClick={() => dispatch(PlayerState.play(id))}>p</button>
|
||||
<button onClick={() => dispatch(PlayerState.pause(id))}>u</button>
|
||||
<button onClick={() => dispatch(PlayerState.stop(id))}>s</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Column({ id, data }: { id: number; data: PlanItem[] }) {
|
||||
return (
|
||||
<Droppable droppableId={id.toString(10)}>
|
||||
{(provided, snapshot) => (
|
||||
<div
|
||||
className="sp-col"
|
||||
ref={provided.innerRef}
|
||||
{...provided.droppableProps}
|
||||
>
|
||||
{typeof data[id] === "undefined"
|
||||
? null
|
||||
: data
|
||||
.filter(x => x.channel === id)
|
||||
.sort((a, b) => a.weight - b.weight)
|
||||
.map((x, index) => (
|
||||
<Item key={itemId(x)} item={x} index={index} />
|
||||
))}
|
||||
{provided.placeholder}
|
||||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
<div className="sp-col">
|
||||
<Droppable droppableId={id.toString(10)}>
|
||||
{(provided, snapshot) => (
|
||||
<div
|
||||
className="sp-col-inner"
|
||||
ref={provided.innerRef}
|
||||
{...provided.droppableProps}
|
||||
>
|
||||
{typeof data[id] === "undefined"
|
||||
? null
|
||||
: data
|
||||
.filter(x => x.channel === id)
|
||||
.sort((a, b) => a.weight - b.weight)
|
||||
.map((x, index) => (
|
||||
<Item key={itemId(x)} item={x} index={index} column={id} />
|
||||
))}
|
||||
{provided.placeholder}
|
||||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
<Player id={id} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -116,7 +147,7 @@ function CentralMusicLibrary() {
|
|||
{(provided, snapshot) => (
|
||||
<div ref={provided.innerRef} {...provided.droppableProps}>
|
||||
{items.map((item, index) => (
|
||||
<Item key={itemId(item)} item={item} index={index} />
|
||||
<Item key={itemId(item)} item={item} index={index} column={-1} />
|
||||
))}
|
||||
{provided.placeholder}
|
||||
</div>
|
||||
|
@ -211,7 +242,7 @@ const Showplanner: React.FC<{ timeslotId: number }> = function({ timeslotId }) {
|
|||
}
|
||||
return (
|
||||
<div className="sp-container">
|
||||
<h1>Show Planner</h1>
|
||||
<h1>baps3 ayy lmao</h1>
|
||||
<div className="sp-status">
|
||||
{planSaving && <em>Plan saving...</em>}
|
||||
{planSaveError && (
|
||||
|
|
|
@ -230,12 +230,12 @@ export const moveItem = (
|
|||
});
|
||||
|
||||
dispatch(showplan.actions.applyOps(ops));
|
||||
const result = await api.updateShowplan(timeslotid, ops);
|
||||
if (!result.every(x => x.status)) {
|
||||
dispatch(showplan.actions.planSaveError("Server says no!"));
|
||||
} else {
|
||||
// const result = await api.updateShowplan(timeslotid, ops);
|
||||
// if (!result.every(x => x.status)) {
|
||||
// dispatch(showplan.actions.planSaveError("Server says no!"));
|
||||
// } else {
|
||||
dispatch(showplan.actions.setPlanSaving(false));
|
||||
}
|
||||
// }
|
||||
};
|
||||
|
||||
export const addItem = (
|
||||
|
@ -293,21 +293,21 @@ export const addItem = (
|
|||
weight: newItemData.weight,
|
||||
id: idForServer
|
||||
});
|
||||
const result = await api.updateShowplan(timeslotId, ops);
|
||||
if (!result.every(x => x.status)) {
|
||||
dispatch(showplan.actions.planSaveError("Server says no!"));
|
||||
return;
|
||||
}
|
||||
const lastResult = result[result.length - 1]; // this is the add op
|
||||
const newItemId = lastResult.timeslotitemid!;
|
||||
// const result = await api.updateShowplan(timeslotId, ops);
|
||||
// if (!result.every(x => x.status)) {
|
||||
// dispatch(showplan.actions.planSaveError("Server says no!"));
|
||||
// return;
|
||||
// }
|
||||
// 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
|
||||
// })
|
||||
// );
|
||||
};
|
||||
|
||||
export const removeItem = (
|
||||
|
@ -342,11 +342,11 @@ export const removeItem = (
|
|||
movingItem.weight -= 1;
|
||||
}
|
||||
|
||||
const result = await api.updateShowplan(timeslotId, ops);
|
||||
if (!result.every(x => x.status)) {
|
||||
dispatch(showplan.actions.planSaveError("Server says no!"));
|
||||
return;
|
||||
}
|
||||
// const result = await api.updateShowplan(timeslotId, ops);
|
||||
// if (!result.every(x => x.status)) {
|
||||
// dispatch(showplan.actions.planSaveError("Server says no!"));
|
||||
// return;
|
||||
// }
|
||||
dispatch(showplan.actions.applyOps(ops));
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue