Migrate react-contextmenu to react-contexify
This commit is contained in:
parent
1e5aae0b51
commit
feccb3155e
6 changed files with 82 additions and 48 deletions
|
@ -76,7 +76,7 @@
|
|||
"react-app-polyfill": "^1.0.4",
|
||||
"react-beautiful-dnd": "^12.1.1",
|
||||
"react-beforeunload": "^2.1.0",
|
||||
"react-contextmenu": "^2.13.0",
|
||||
"react-contexify": "^4.1.1",
|
||||
"react-dev-utils": "^9.1.0",
|
||||
"react-dnd": "^9.4.0",
|
||||
"react-dnd-html5-backend": "^9.4.0",
|
||||
|
|
|
@ -77,7 +77,7 @@ interface Album {
|
|||
// TODO
|
||||
}
|
||||
|
||||
interface TimeslotItemBase {
|
||||
export interface TimeslotItemBase {
|
||||
timeslotitemid: string;
|
||||
channel: number;
|
||||
weight: number;
|
||||
|
@ -88,7 +88,7 @@ interface TimeslotItemBase {
|
|||
cue: number;
|
||||
}
|
||||
|
||||
interface TimeslotItemCentral {
|
||||
export interface TimeslotItemCentral {
|
||||
type: "central";
|
||||
artist: string;
|
||||
intro: number;
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import React, { memo } from "react";
|
||||
import { PlanItem, itemId } from "./state";
|
||||
import { PlanItem, itemId, isTrack, isAux } from "./state";
|
||||
import { Track, AuxItem } from "../api";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { RootState } from "../rootReducer";
|
||||
|
||||
import * as MixerState from "../mixer/state";
|
||||
import { Draggable } from "react-beautiful-dnd";
|
||||
import { ContextMenuTrigger } from "react-contextmenu";
|
||||
import { contextMenu } from "react-contexify";
|
||||
import "./item.scss";
|
||||
|
||||
export const TS_ITEM_MENU_ID = "SongMenu";
|
||||
export const TS_ITEM_AUX_ID = "AuxMenu";
|
||||
|
||||
export const Item = memo(function Item({
|
||||
item: x,
|
||||
|
@ -22,7 +23,6 @@ export const Item = memo(function Item({
|
|||
}) {
|
||||
const dispatch = useDispatch();
|
||||
const id = itemId(x);
|
||||
const isReal = "timeslotitemid" in x;
|
||||
const isGhost = "ghostid" in x;
|
||||
|
||||
const playerState = useSelector((state: RootState) =>
|
||||
|
@ -44,6 +44,30 @@ export const Item = memo(function Item({
|
|||
}
|
||||
}
|
||||
|
||||
function openContextMenu(e: React.MouseEvent<HTMLDivElement, MouseEvent>) {
|
||||
e.preventDefault();
|
||||
if (isTrack(x)) {
|
||||
contextMenu.show({
|
||||
id: TS_ITEM_MENU_ID,
|
||||
event: e,
|
||||
props: {
|
||||
id,
|
||||
title: x.title,
|
||||
artist: x.artist,
|
||||
},
|
||||
});
|
||||
} else if (isAux(x)) {
|
||||
contextMenu.show({
|
||||
id: TS_ITEM_MENU_ID,
|
||||
event: e,
|
||||
props: {
|
||||
id,
|
||||
title: x.title,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Draggable
|
||||
draggableId={id}
|
||||
|
@ -69,31 +93,27 @@ export const Item = memo(function Item({
|
|||
}`
|
||||
}
|
||||
onClick={triggerClick}
|
||||
onContextMenu={openContextMenu}
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
>
|
||||
<ContextMenuTrigger
|
||||
id={isReal ? TS_ITEM_MENU_ID : ""}
|
||||
collect={() => ({ id })}
|
||||
<span className={"icon " + x.type} />
|
||||
|
||||
{x.title.toString()}
|
||||
{"artist" in x && x.artist !== "" && " - " + x.artist}
|
||||
<small
|
||||
className={
|
||||
"border rounded border-danger text-danger p-1 m-1" +
|
||||
("clean" in x && x.clean === false ? "" : " d-none")
|
||||
}
|
||||
>
|
||||
<span className={"icon " + x.type} />
|
||||
|
||||
{x.title.toString()}
|
||||
{"artist" in x && x.artist !== "" && " - " + x.artist}
|
||||
<small
|
||||
className={
|
||||
"border rounded border-danger text-danger p-1 m-1" +
|
||||
("clean" in x && x.clean === false ? "" : " d-none")
|
||||
}
|
||||
>
|
||||
Explicit
|
||||
</small>
|
||||
{showDebug && (
|
||||
<code>
|
||||
{itemId(x)} {"channel" in x && x.channel + "/" + x.weight}
|
||||
</code>
|
||||
)}
|
||||
</ContextMenuTrigger>
|
||||
Explicit
|
||||
</small>
|
||||
{showDebug && (
|
||||
<code>
|
||||
{itemId(x)} {"channel" in x && x.channel + "/" + x.weight}
|
||||
</code>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</Draggable>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React, { useState, useReducer, useEffect } from "react";
|
||||
import { ContextMenu, MenuItem } from "react-contextmenu";
|
||||
import { Menu, Item as CtxMenuItem } from "react-contexify";
|
||||
import "react-contexify/dist/ReactContexify.min.css";
|
||||
import { useBeforeunload } from "react-beforeunload";
|
||||
import {
|
||||
FaBookOpen,
|
||||
|
@ -379,13 +380,6 @@ 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.
|
||||
useEffect(() => {
|
||||
|
@ -440,14 +434,24 @@ const Showplanner: React.FC<{ timeslotId: number }> = function({ timeslotId }) {
|
|||
</div>
|
||||
</DragDropContext>
|
||||
</div>
|
||||
<ContextMenu id={TS_ITEM_MENU_ID}>
|
||||
<MenuItem onClick={onCtxRemoveClick}>
|
||||
<Menu id={TS_ITEM_MENU_ID}>
|
||||
<CtxMenuItem
|
||||
onClick={(args) =>
|
||||
dispatch(removeItem(timeslotId, (args.props as any).id))
|
||||
}
|
||||
>
|
||||
<FaTrash /> Remove
|
||||
</MenuItem>
|
||||
<MenuItem onClick={onCtxUnPlayedClick}>
|
||||
</CtxMenuItem>
|
||||
<CtxMenuItem
|
||||
onClick={(args) =>
|
||||
dispatch(
|
||||
setItemPlayed({ itemId: (args.props as any).id, played: false })
|
||||
)
|
||||
}
|
||||
>
|
||||
<FaCircleNotch /> Mark Unplayed
|
||||
</MenuItem>
|
||||
</ContextMenu>
|
||||
</CtxMenuItem>
|
||||
</Menu>
|
||||
<OptionsMenu />
|
||||
<WelcomeModal
|
||||
isOpen={showWelcomeModal}
|
||||
|
|
|
@ -47,6 +47,16 @@ export function itemId(
|
|||
throw new Error("Can't get id of unknown item.");
|
||||
}
|
||||
|
||||
export function isTrack(
|
||||
item: PlanItem | Track | AuxItem
|
||||
): item is (api.TimeslotItemBase & api.TimeslotItemCentral) | Track {
|
||||
return "trackid" in item;
|
||||
}
|
||||
|
||||
export function isAux(item: PlanItem | Track | AuxItem): item is AuxItem {
|
||||
return "auxid" in item;
|
||||
}
|
||||
|
||||
interface ShowplanState {
|
||||
planLoading: boolean;
|
||||
planLoadError: string | null;
|
||||
|
|
14
yarn.lock
14
yarn.lock
|
@ -3299,7 +3299,7 @@ class-utils@^0.3.5:
|
|||
isobject "^3.0.0"
|
||||
static-extend "^0.1.1"
|
||||
|
||||
classnames@^2.2.3, classnames@^2.2.5:
|
||||
classnames@^2.2.3, classnames@^2.2.6:
|
||||
version "2.2.6"
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
|
||||
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
|
||||
|
@ -10100,13 +10100,13 @@ react-beforeunload@^2.1.0:
|
|||
dependencies:
|
||||
prop-types "^15.7.2"
|
||||
|
||||
react-contextmenu@^2.13.0:
|
||||
version "2.13.0"
|
||||
resolved "https://registry.yarnpkg.com/react-contextmenu/-/react-contextmenu-2.13.0.tgz#dabaea63124e30c85f1b4245c095b7045d013459"
|
||||
integrity sha512-hhFuJX4di0zGV7H7pXPn42U70OZbGpQD+PxcdmKStNT5mebSjI+inhOuFESDmDbqVsN/f99hI5/nw95oXTVRXQ==
|
||||
react-contexify@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/react-contexify/-/react-contexify-4.1.1.tgz#f5eba1ad82a923c033c91d0abcea1da0a71ebaa1"
|
||||
integrity sha512-WJeRI4ohHEOmNiH0xb62a/eV+5ae168FB7H6pfbeEVJkf0UN7D5H99l6b89poc2LHKN1gOimFjREyY8quGVsXA==
|
||||
dependencies:
|
||||
classnames "^2.2.5"
|
||||
object-assign "^4.1.0"
|
||||
classnames "^2.2.6"
|
||||
prop-types "^15.6.2"
|
||||
|
||||
react-dev-utils@^10.2.1:
|
||||
version "10.2.1"
|
||||
|
|
Loading…
Reference in a new issue