add rightclick context menu events on tags

This commit is contained in:
lukas 2021-01-30 21:54:20 +01:00
parent 4e52688ff9
commit d59980460f
6 changed files with 102 additions and 19 deletions

View File

@ -70,7 +70,7 @@ class PopupBase extends React.Component<props> {
} }
/** /**
* Alert if clicked on outside of element * handle click on outside of element
*/ */
handleClickOutside(event: MouseEvent): void { handleClickOutside(event: MouseEvent): void {
if (this.wrapperRef && this.wrapperRef.current && !this.wrapperRef.current.contains(event.target as Node)) { if (this.wrapperRef && this.wrapperRef.current && !this.wrapperRef.current.contains(event.target as Node)) {

View File

@ -72,7 +72,7 @@ class Preview extends React.Component<PreviewProps, PreviewState> {
popupvisible(): JSX.Element { popupvisible(): JSX.Element {
if (this.state.optionsvisible) if (this.state.optionsvisible)
return (<QuickActionPop>heeyyho</QuickActionPop>); return (<QuickActionPop position={{x: 50, y: 50}} onHide={(): void => this.setState({optionsvisible: false})}>heeyyho</QuickActionPop>);
else else
return <></>; return <></>;
} }

View File

@ -1,24 +1,50 @@
import React from 'react'; import React, {RefObject} from 'react';
import style from './QuickActionPopup.module.css' import style from './QuickActionPopup.module.css';
interface props { interface props {
position: {
x: number,
y: number
},
onHide: () => void
} }
class QuickActionPop extends React.Component<props> { class QuickActionPop extends React.Component<props> {
private readonly wrapperRef: RefObject<HTMLDivElement>;
constructor(props: props) { constructor(props: props) {
super(props); super(props);
this.state = {}; this.wrapperRef = React.createRef();
this.handleClickOutside = this.handleClickOutside.bind(this);
}
componentDidMount(): void {
document.addEventListener('mousedown', this.handleClickOutside);
}
componentWillUnmount(): void {
document.removeEventListener('mousedown', this.handleClickOutside);
} }
render(): JSX.Element { render(): JSX.Element {
return ( return (
<div className={style.quickaction}> <div ref={this.wrapperRef} className={style.quickaction} style={{top: this.props.position.y, left: this.props.position.x}}>
<div onClick={():void => {console.log('clicked');}}>testi</div>testi {this.props.children}
</div> </div>
); );
} }
/**
* trigger hide if we click outside the div
*/
handleClickOutside(event: MouseEvent): void {
if (this.wrapperRef && this.wrapperRef.current && !this.wrapperRef.current.contains(event.target as Node)) {
this.props.onHide();
}
}
} }
export default QuickActionPop; export default QuickActionPop;

View File

@ -4,5 +4,4 @@
height: 120px; height: 120px;
z-index: 2; z-index: 2;
position: absolute; position: absolute;
} }

View File

@ -1,18 +1,33 @@
import React from 'react'; import React, {SyntheticEvent} from 'react';
import styles from './Tag.module.css'; import styles from './Tag.module.css';
import {Link} from 'react-router-dom'; import {Link} from 'react-router-dom';
import {TagType} from '../../types/VideoTypes'; import {TagType} from '../../types/VideoTypes';
interface props { interface props {
onclick?: (_: string) => void onclick?: (_: string) => void;
tagInfo: TagType tagInfo: TagType;
onContextMenu?: (pos: {x: number, y: number}) => void
}
interface state {
contextVisible: boolean
} }
/** /**
* A Component representing a single Category tag * A Component representing a single Category tag
*/ */
class Tag extends React.Component<props> { class Tag extends React.Component<props, state> {
constructor(props: Readonly<props> | props) {
super(props);
this.state = {
contextVisible: false
};
this.contextmenu = this.contextmenu.bind(this);
}
render(): JSX.Element { render(): JSX.Element {
if (this.props.onclick) { if (this.props.onclick) {
return this.renderButton(); return this.renderButton();
@ -27,7 +42,9 @@ class Tag extends React.Component<props> {
renderButton(): JSX.Element { renderButton(): JSX.Element {
return ( return (
<button className={styles.tagbtn} onClick={(): void => this.TagClick()} <button className={styles.tagbtn}
onClick={(): void => this.TagClick()}
onContextMenu={this.contextmenu}
data-testid='Test-Tag'>{this.props.tagInfo.tag_name}</button> data-testid='Test-Tag'>{this.props.tagInfo.tag_name}</button>
); );
} }
@ -42,6 +59,20 @@ class Tag extends React.Component<props> {
return; return;
} }
} }
/**
* handle a custom contextmenu for this item
* @param e
* @private
*/
private contextmenu(e: SyntheticEvent): void {
if (!this.props.onContextMenu) return;
const event = e as unknown as PointerEvent;
event.preventDefault();
this.props.onContextMenu({x: event.clientX, y: event.clientY});
// this.setState({contextVisible: true});
}
} }
export default Tag; export default Tag;

View File

@ -12,7 +12,7 @@ import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {faPlusCircle} from '@fortawesome/free-solid-svg-icons'; import {faPlusCircle} from '@fortawesome/free-solid-svg-icons';
import AddActorPopup from '../../elements/Popups/AddActorPopup/AddActorPopup'; import AddActorPopup from '../../elements/Popups/AddActorPopup/AddActorPopup';
import ActorTile from '../../elements/ActorTile/ActorTile'; import ActorTile from '../../elements/ActorTile/ActorTile';
import {withRouter} from 'react-router-dom'; import {Link, withRouter} from 'react-router-dom';
import {callAPI, getBackendDomain} from '../../utils/Api'; import {callAPI, getBackendDomain} from '../../utils/Api';
import {RouteComponentProps} from 'react-router'; import {RouteComponentProps} from 'react-router';
import {GeneralSuccess} from '../../types/GeneralTypes'; import {GeneralSuccess} from '../../types/GeneralTypes';
@ -20,6 +20,7 @@ import {ActorType, TagType} from '../../types/VideoTypes';
import PlyrJS from 'plyr'; import PlyrJS from 'plyr';
import {Button} from '../../elements/GPElements/Button'; import {Button} from '../../elements/GPElements/Button';
import {VideoTypes} from '../../types/ApiTypes'; import {VideoTypes} from '../../types/ApiTypes';
import QuickActionPop from '../../elements/QuickActionPop/QuickActionPop';
interface myprops extends RouteComponentProps<{ id: string }> {} interface myprops extends RouteComponentProps<{ id: string }> {}
@ -34,7 +35,8 @@ interface mystate {
suggesttag: TagType[], suggesttag: TagType[],
popupvisible: boolean, popupvisible: boolean,
actorpopupvisible: boolean, actorpopupvisible: boolean,
actors: ActorType[] actors: ActorType[],
tagContextMenu: boolean
} }
/** /**
@ -42,7 +44,7 @@ interface mystate {
* and actions such as tag adding and liking * and actions such as tag adding and liking
*/ */
export class Player extends React.Component<myprops, mystate> { export class Player extends React.Component<myprops, mystate> {
options: PlyrJS.Options = { private options: PlyrJS.Options = {
controls: [ controls: [
'play-large', // The large play button in the center 'play-large', // The large play button in the center
'play', // Play/pause playback 'play', // Play/pause playback
@ -59,10 +61,13 @@ export class Player extends React.Component<myprops, mystate> {
] ]
}; };
private contextpos = {x: 0, y: 0};
constructor(props: myprops) { constructor(props: myprops) {
super(props); super(props);
this.state = { this.state = {
tagContextMenu: false,
movie_id: -1, movie_id: -1,
movie_name: '', movie_name: '',
likes: 0, likes: 0,
@ -148,7 +153,10 @@ export class Player extends React.Component<myprops, mystate> {
<Line/> <Line/>
<SideBarTitle>Tags:</SideBarTitle> <SideBarTitle>Tags:</SideBarTitle>
{this.state.tags.map((m: TagType) => ( {this.state.tags.map((m: TagType) => (
<Tag tagInfo={m}/> <Tag tagInfo={m} onContextMenu={(pos): void => {
this.setState({tagContextMenu: true});
this.contextpos = pos;
}}/>
))} ))}
<Line/> <Line/>
<SideBarTitle>Tag Quickadd:</SideBarTitle> <SideBarTitle>Tag Quickadd:</SideBarTitle>
@ -232,6 +240,8 @@ export class Player extends React.Component<myprops, mystate> {
this.setState({actorpopupvisible: false}); this.setState({actorpopupvisible: false});
}} movie_id={this.state.movie_id}/> : null }} movie_id={this.state.movie_id}/> : null
} }
{this.renderContextMenu()}
</> </>
); );
} }
@ -319,6 +329,23 @@ export class Player extends React.Component<myprops, mystate> {
this.setState({actors: result}); this.setState({actors: result});
}); });
} }
/**
* render the Tag context menu
*/
private renderContextMenu(): JSX.Element {
if (this.state.tagContextMenu) {
return (
<QuickActionPop onHide={(): void => this.setState({tagContextMenu: false})}
position={this.contextpos}>
<Button title='Delete'
color={{backgroundColor: 'red'}}
onClick={(): void => {}}/>
</QuickActionPop>);
} else {
return <></>;
}
}
} }
export default withRouter(Player); export default withRouter(Player);