Skip to content

Commit

Permalink
[CastIt.Server] Added missing logic to the file item component
Browse files Browse the repository at this point in the history
  • Loading branch information
Wolfteam committed Aug 15, 2021
1 parent 904778b commit d8ec563
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 33 deletions.
111 changes: 111 additions & 0 deletions CastIt.Server/ClientApp/src/components/dialogs/add_files_dialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import {
Dialog,
DialogContent,
DialogTitle,
Grid,
DialogActions,
Button,
TextField,
FormGroup,
Switch,
FormControlLabel,
} from '@material-ui/core';
import React, { useState } from 'react';
import translations from '../../services/translations';

interface Props {
isOpen: boolean;
onClose(path: string | null, includeSubFolder: boolean, onlyVideo: boolean): void;
}

interface State {
path: string;
isPathValid: boolean;
isPathDirty: boolean;
includeSubFolder: boolean;
onlyVideo: boolean;
}

const initialState: State = {
path: '',
isPathValid: false,
isPathDirty: false,
includeSubFolder: true,
onlyVideo: true,
};

function AddFilesDialog(props: Props) {
const [state, setState] = useState(initialState);

const handlePathChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
const newVal = event.target.value;
const newState = { ...state };
newState.path = newVal;
newState.isPathDirty = true;
newState.isPathValid = newVal !== '' && newVal !== null && newVal.length > 1;

setState(newState);
};

const handleClose = (saveChanges: boolean): void => {
const path = saveChanges ? state.path : null;
props.onClose(path, state.includeSubFolder, state.onlyVideo);
setState(initialState);
};

const showError = !state.isPathValid && state.isPathDirty;

return (
<Dialog open={props.isOpen} onClose={() => handleClose(false)}>
<DialogTitle id="form-dialog-title">{translations.addFiles}</DialogTitle>
<DialogContent>
<Grid container alignItems="flex-start" justifyContent="space-between">
<FormGroup row>
<TextField
required
autoFocus
margin="dense"
label={'Path'}
type="text"
fullWidth
onChange={handlePathChange}
value={state.path}
error={showError}
helperText={showError ? translations.fieldIsNotValid : ''}
/>
<FormControlLabel
control={
<Switch
checked={state.includeSubFolder}
onChange={(_, checked) => setState((s) => ({ ...s, includeSubFolder: checked }))}
color="primary"
/>
}
label={translations.includeSubFolders}
/>
<FormControlLabel
control={
<Switch
checked={state.onlyVideo}
onChange={(_, checked) => setState((s) => ({ ...s, onlyVideo: checked }))}
color="primary"
/>
}
label={translations.onlyVideo}
/>
</FormGroup>
</Grid>
</DialogContent>
<DialogActions>
<Button onClick={() => handleClose(false)} color="primary">
{translations.cancel}
</Button>
<Button variant="contained" onClick={() => handleClose(true)} color="primary" disabled={!state.isPathValid}>
{translations.ok}
</Button>
</DialogActions>
</Dialog>
);
}

export default AddFilesDialog;
81 changes: 50 additions & 31 deletions CastIt.Server/ClientApp/src/components/file/file_item.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Fragment, useEffect, useState } from 'react';
import React, { Fragment, useEffect, useState } from 'react';
import {
Typography,
Slider,
Expand All @@ -16,9 +16,19 @@ import {
Grid,
} from '@material-ui/core';
import { IFileItemResponseDto } from '../../models';
import { onFileChanged, onFileEndReached, onPlayerStatusChanged, play, loopFile } from '../../services/castithub.service';
import { Add, ClearAll, Delete, Folder, InsertLink, Loop, PlayArrow, Refresh, Repeat, RepeatOne } from '@material-ui/icons';
import {
onFileChanged,
onFileEndReached,
onPlayerStatusChanged,
play,
loopFile,
deleteFile,
removeAllMissingFiles,
addFolderOrFileOrUrl,
} from '../../services/castithub.service';
import { Add, ClearAll, Delete, Loop, PlayArrow, Refresh, Repeat, RepeatOne } from '@material-ui/icons';
import translations from '../../services/translations';
import AddFilesDialog from '../dialogs/add_files_dialog';

const useStyles = makeStyles((theme) =>
createStyles({
Expand Down Expand Up @@ -53,7 +63,7 @@ interface Props {
interface State {
playListId: number;
id: number;
name: string;
filename: string;
subTitle: string;
path: string;
playedPercentage: number;
Expand All @@ -71,7 +81,7 @@ interface ContextMenuState {
const initialState: State = {
playListId: 0,
id: 0,
name: '',
filename: '',
subTitle: '',
path: '',
playedPercentage: 0,
Expand All @@ -90,12 +100,13 @@ function FileItem(props: Props) {
const classes = useStyles();
const [state, setState] = useState<State>(initialState);
const [contextMenu, setContextMenu] = useState(initialContextMenuState);
const [showAddFilesDialog, setShowAddFilesDialog] = useState(false);

useEffect(() => {
setState({
playListId: props.file.playListId,
id: props.file.id,
name: props.file.name,
filename: props.file.filename,
subTitle: props.file.subTitle,
path: props.file.path,
playedPercentage: props.file.playedPercentage,
Expand Down Expand Up @@ -169,14 +180,6 @@ function FileItem(props: Props) {
};
}, [props.file.id, state.isBeingPlayed]);

const handleClick = async (): Promise<void> => {
if (state.isBeingPlayed) {
return;
}

await play(props.file.playListId, state.id, false, false);
};

const handleOpenContextMenu = (event: React.MouseEvent<HTMLDivElement>) => {
event.preventDefault();
setContextMenu({
Expand All @@ -185,7 +188,12 @@ function FileItem(props: Props) {
});
};

const handleCloseContextMenu = () => {
const handlePlay = async (force: boolean = false): Promise<void> => {
handleCloseContextMenu();
await play(props.file.playListId, state.id, force, false);
};

const handleCloseContextMenu = (): void => {
setContextMenu(initialContextMenuState);
};

Expand All @@ -194,9 +202,27 @@ function FileItem(props: Props) {
await loopFile(state.playListId, state.id, !state.loop);
};

const handleAddFiles = async (path: string | null, includeSubFolder: boolean, onlyVideo: boolean): Promise<void> => {
handleCloseContextMenu();
setShowAddFilesDialog(false);
if (path) {
await addFolderOrFileOrUrl(state.playListId, path, includeSubFolder, onlyVideo);
}
};

const handleDelete = async (): Promise<void> => {
handleCloseContextMenu();
await deleteFile(props.file.playListId, props.file.id);
};

const handleRemoveAllMissing = async (): Promise<void> => {
handleCloseContextMenu();
await removeAllMissingFiles(props.file.playListId);
};

const title = (
<Tooltip title={state.name}>
<Typography className={classes.text}>{state.name}</Typography>
<Tooltip title={state.filename}>
<Typography className={classes.text}>{state.filename}</Typography>
</Tooltip>
);

Expand Down Expand Up @@ -226,7 +252,7 @@ function FileItem(props: Props) {

return (
<div data-played-file={state.isBeingPlayed} onContextMenu={handleOpenContextMenu} style={{ cursor: 'context-menu' }}>
<ListItem button onClick={handleClick} className={state.isBeingPlayed ? classes.beingPlayed : ''}>
<ListItem button onClick={() => handlePlay()} className={state.isBeingPlayed ? classes.beingPlayed : ''}>
<ListItemAvatar>
<Avatar className={classes.position}>{state.position}</Avatar>
</ListItemAvatar>
Expand All @@ -249,38 +275,31 @@ function FileItem(props: Props) {
: undefined
}
>
<MenuItem onClick={handleCloseContextMenu}>
<MenuItem onClick={() => handlePlay()}>
<PlayArrow fontSize="small" />
<ListItemText className={classes.menuItemText} primary={translations.play} />
</MenuItem>
<MenuItem onClick={handleCloseContextMenu}>
<MenuItem onClick={() => handlePlay(true)}>
<Refresh fontSize="small" />
<ListItemText className={classes.menuItemText} primary={translations.playFromTheStart} />
</MenuItem>
{toggleLoopMenuItem}
<MenuItem onClick={handleCloseContextMenu}>
<Folder fontSize="small" />
<ListItemText className={classes.menuItemText} primary={translations.addFolder} />
</MenuItem>
<MenuItem onClick={handleCloseContextMenu}>
<MenuItem onClick={() => setShowAddFilesDialog(true)}>
<Add fontSize="small" />
<ListItemText className={classes.menuItemText} primary={translations.addFiles} />
</MenuItem>
<MenuItem onClick={handleCloseContextMenu}>
<InsertLink fontSize="small" />
<ListItemText className={classes.menuItemText} primary={translations.addUrl} />
</MenuItem>
{/* TODO: REMOVE ALL SELECTED AND SELECT ALL */}
<MenuItem onClick={handleCloseContextMenu}>
<MenuItem onClick={handleDelete}>
<Delete fontSize="small" />
<ListItemText className={classes.menuItemText} primary={translations.remove} />
</MenuItem>
<MenuItem onClick={handleCloseContextMenu}>
<MenuItem onClick={handleRemoveAllMissing}>
<ClearAll fontSize="small" />
<ListItemText className={classes.menuItemText} primary={translations.removeAllMissing} />
</MenuItem>
</Menu>
<Divider variant="middle" />
<AddFilesDialog isOpen={showAddFilesDialog} onClose={handleAddFiles} />
</div>
);
}
Expand Down
4 changes: 2 additions & 2 deletions CastIt.Server/ClientApp/src/components/player/player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import PlayerVolume from './player_volume';
import PlayerSettings from './player_settings';
import PlayerDevices from './player_devices';
import PlayerCurrentFile from './player_current_file';
import { ArrowDownward, ExpandLess, ExpandMore } from '@material-ui/icons';
import { Fragment, useState } from 'react';
import { ExpandLess, ExpandMore } from '@material-ui/icons';
import { useState } from 'react';

const useStyles = makeStyles((theme) =>
createStyles({
Expand Down

0 comments on commit d8ec563

Please sign in to comment.