Skip to content

Commit

Permalink
[CastIt.Server.ClientApp] Do not load the pages until we are connecte…
Browse files Browse the repository at this point in the history
…d to the hub.

Bug fixes and improvements
  • Loading branch information
Wolfteam committed Aug 22, 2021
1 parent bf1475e commit 1c83ac3
Show file tree
Hide file tree
Showing 26 changed files with 360 additions and 176 deletions.
1 change: 0 additions & 1 deletion CastIt.Server/ClientApp/.env.development
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
REACT_APP_BASE_HUB_URL=http://localhost:62003/castithub
1 change: 0 additions & 1 deletion CastIt.Server/ClientApp/.env.production
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
REACT_APP_BASE_HUB_URL=http://192.168.1.104:9696/castithub
15 changes: 4 additions & 11 deletions CastIt.Server/ClientApp/src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CircularProgress, Container, createTheme, Grid, ThemeProvider } from '@material-ui/core';
import { createTheme, ThemeProvider } from '@material-ui/core';
import { green, purple } from '@material-ui/core/colors';
import CssBaseline from '@material-ui/core/CssBaseline';
import { BrowserRouter } from 'react-router-dom';
Expand All @@ -8,6 +8,8 @@ import { Suspense } from 'react';
import ServerMessage from './components/server_message';
import { TranslationContextProvider } from './context/translations.context';
import { CastItHubContextProvider } from './context/castit_hub.context';
import Loading from './components/loading';
import translations from './services/translations';

const theme = createTheme({
palette: {
Expand All @@ -22,15 +24,6 @@ const theme = createTheme({
});

function App() {
const loading = (
<Container>
<Grid container justifyContent="center" alignItems="center" direction="column" style={{ minHeight: '100vh' }}>
<Grid item xs={12}>
<CircularProgress />
</Grid>
</Grid>
</Container>
);
return (
<SnackbarProvider
autoHideDuration={3000}
Expand All @@ -45,7 +38,7 @@ function App() {
<TranslationContextProvider>
<CastItHubContextProvider>
<ServerMessage>
<Suspense fallback={loading}>
<Suspense fallback={<Loading message={translations.loading + '...'} />}>
<AppRoutes />
<PlayerRoutes />
</Suspense>
Expand Down
5 changes: 2 additions & 3 deletions CastIt.Server/ClientApp/src/components/device/device_item.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Grid, IconButton, Typography } from '@material-ui/core';
import { Tv, CastConnected, Cast } from '@material-ui/icons';
import { useContext } from 'react';
import { CastItHubContext } from '../../context/castit_hub.context';
import { useCastItHub } from '../../context/castit_hub.context';

interface Props {
id: string;
Expand All @@ -11,7 +10,7 @@ interface Props {
}

function DeviceItem(props: Props) {
const [castItHub] = useContext(CastItHubContext);
const castItHub = useCastItHub();
const connectedIcon = props.isConnected ? <CastConnected /> : <Cast />;

const handleToggleConnect = async (): Promise<void> => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ function AddFilesDialog(props: Props) {
};

const showError = !state.isPathValid && state.isPathDirty;
if (!props.isOpen) {
return null;
}

return (
<Dialog open={props.isOpen} onClose={() => handleClose(false)}>
Expand All @@ -65,7 +68,7 @@ function AddFilesDialog(props: Props) {
required
autoFocus
margin="dense"
label={'Path'}
label={translations.path}
type="text"
fullWidth
onChange={handlePathChange}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React, { useState } from 'react';
import { Dialog, DialogContent, DialogTitle, Grid, DialogActions, Button, TextField, FormGroup } from '@material-ui/core';
import translations from '../../services/translations';

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

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

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

function AddSubtitlesDialog(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);
setState(initialState);
};

const showError = !state.isPathValid && state.isPathDirty;
if (!props.isOpen) {
return null;
}
return (
<Dialog open={props.isOpen} onClose={() => handleClose(false)} maxWidth="sm" fullWidth>
<DialogTitle>{translations.subtitles}</DialogTitle>
<DialogContent>
<Grid container alignItems="stretch" justifyContent="center" >
<FormGroup row style={{ width: '100%' }}>
<TextField
required
autoFocus
margin="dense"
label={translations.path}
type="text"
fullWidth
onChange={handlePathChange}
value={state.path}
error={showError}
helperText={showError ? translations.fieldIsNotValid : ''}
/>
</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 AddSubtitlesDialog;
76 changes: 39 additions & 37 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 React, { useContext, useEffect, useState } from 'react';
import React, { useEffect, useState } from 'react';
import {
Typography,
Divider,
Expand All @@ -21,7 +21,7 @@ import AddFilesDialog from '../dialogs/add_files_dialog';
import { Draggable } from 'react-beautiful-dnd';
import FileItemSubtitle from './file_item_subtitle';
import FileItemDuration from './file_item_duration';
import { CastItHubContext } from '../../context/castit_hub.context';
import { useCastItHub } from '../../context/castit_hub.context';

const useStyles = makeStyles((theme) =>
createStyles({
Expand Down Expand Up @@ -89,7 +89,7 @@ function FileItem(props: Props) {
const [state, setState] = useState<State>(initialState);
const [contextMenu, setContextMenu] = useState(initialContextMenuState);
const [showAddFilesDialog, setShowAddFilesDialog] = useState(false);
const [castItHub] = useContext(CastItHubContext);
const castItHub = useCastItHub();

useEffect(() => {
setState({
Expand Down Expand Up @@ -266,40 +266,42 @@ function FileItem(props: Props) {
/>
<FileItemDuration fullTotalDuration={state.fullTotalDuration} loop={state.loop} />
</ListItem>
<Menu
keepMounted
open={contextMenu.mouseY !== null}
onClose={handleCloseContextMenu}
anchorReference="anchorPosition"
anchorPosition={
contextMenu.mouseY !== null && contextMenu.mouseX !== null
? { top: contextMenu.mouseY, left: contextMenu.mouseX }
: undefined
}
>
<MenuItem onClick={() => handlePlay()}>
<PlayArrow fontSize="small" />
<ListItemText className={classes.menuItemText} primary={translations.play} />
</MenuItem>
<MenuItem onClick={() => handlePlay(true)}>
<Refresh fontSize="small" />
<ListItemText className={classes.menuItemText} primary={translations.playFromTheStart} />
</MenuItem>
{toggleLoopMenuItem}
<MenuItem onClick={() => setShowAddFilesDialog(true)}>
<Add fontSize="small" />
<ListItemText className={classes.menuItemText} primary={translations.addFiles} />
</MenuItem>
{/* TODO: REMOVE ALL SELECTED AND SELECT ALL */}
<MenuItem onClick={handleDelete}>
<Delete fontSize="small" />
<ListItemText className={classes.menuItemText} primary={translations.remove} />
</MenuItem>
<MenuItem onClick={handleRemoveAllMissing}>
<ClearAll fontSize="small" />
<ListItemText className={classes.menuItemText} primary={translations.removeAllMissing} />
</MenuItem>
</Menu>
{contextMenu.mouseY === null ? null : (
<Menu
keepMounted
open={contextMenu.mouseY !== null}
onClose={handleCloseContextMenu}
anchorReference="anchorPosition"
anchorPosition={
contextMenu.mouseY !== null && contextMenu.mouseX !== null
? { top: contextMenu.mouseY, left: contextMenu.mouseX }
: undefined
}
>
<MenuItem onClick={() => handlePlay()}>
<PlayArrow fontSize="small" />
<ListItemText className={classes.menuItemText} primary={translations.play} />
</MenuItem>
<MenuItem onClick={() => handlePlay(true)}>
<Refresh fontSize="small" />
<ListItemText className={classes.menuItemText} primary={translations.playFromTheStart} />
</MenuItem>
{toggleLoopMenuItem}
<MenuItem onClick={() => setShowAddFilesDialog(true)}>
<Add fontSize="small" />
<ListItemText className={classes.menuItemText} primary={translations.addFiles} />
</MenuItem>
{/* TODO: REMOVE ALL SELECTED AND SELECT ALL */}
<MenuItem onClick={handleDelete}>
<Delete fontSize="small" />
<ListItemText className={classes.menuItemText} primary={translations.remove} />
</MenuItem>
<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
26 changes: 26 additions & 0 deletions CastIt.Server/ClientApp/src/components/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Container, Grid, CircularProgress, Typography } from '@material-ui/core';

interface Props {
message?: string;
}

function Loading(props: Props) {
return (
<Container>
<Grid
container
justifyContent="center"
alignItems="center"
direction="column"
style={{ minHeight: '100vh', textAlign: 'center' }}
>
<Grid item xs={12}>
<CircularProgress />
{props.message ? <Typography>{props.message}</Typography> : null}
</Grid>
</Grid>
</Container>
);
}

export default Loading;
39 changes: 39 additions & 0 deletions CastIt.Server/ClientApp/src/components/nothing_found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { makeStyles, createStyles, Container, Grid, Typography } from '@material-ui/core';
import { Info } from '@material-ui/icons';
import translations from '../services/translations';

const useStyles = makeStyles((theme) =>
createStyles({
root: {
flex: 'auto',
height: '100%',
},
nothingFound: {
textAlign: 'center',
height: '100%',
},
})
);

interface Props {
icon?: JSX.Element;
text?: string;
children?: JSX.Element | JSX.Element[];
}

function NothingFound(props: Props) {
const classes = useStyles();
return (
<Container className={classes.root}>
<Grid container className={classes.nothingFound} justifyContent="center" alignItems="center">
<Grid item xs={12}>
{props.icon ?? <Info fontSize="large" />}
<Typography>{props.text ?? translations.nothingFound}</Typography>
{props.children}
</Grid>
</Grid>
</Container>
);
}

export default NothingFound;
22 changes: 9 additions & 13 deletions CastIt.Server/ClientApp/src/components/player/player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,11 @@ function Player() {
</IconButton>
);

const playerControls = (
<Grid container direction="column">
<Grid item>
<PlayerControls />
</Grid>
<Grid item>
<PlayerProgressIndicator />
</Grid>
</Grid>
);

if (!state.isExpanded) {
return (
<Grid container className={classes.root} justifyContent="center" alignItems="center">
<Grid item xs={10} md={11}>
{playerControls}
<PlayerProgressIndicator />
</Grid>
<Grid item xs={1} style={{ textAlign: 'center' }}>
{toggleExpandButton}
Expand All @@ -75,7 +64,14 @@ function Player() {
<PlayerCurrentFile />
</Grid>
<Grid item xs={12} md={6}>
{playerControls}
<Grid container direction="column">
<Grid item>
<PlayerControls />
</Grid>
<Grid item>
<PlayerProgressIndicator />
</Grid>
</Grid>
</Grid>
<Grid item xs={12} md={3}>
<Grid container alignItems="center" justifyContent="center">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Grid, IconButton } from '@material-ui/core';
import { useContext, useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import { SkipPrevious, SkipNext, FastForward, FastRewind, PlayArrow, Stop, Pause } from '@material-ui/icons';
import { onPlayerStatusChanged } from '../../services/castithub.service';
import { CastItHubContext } from '../../context/castit_hub.context';
import { useCastItHub } from '../../context/castit_hub.context';

interface State {
isPlayingOrPaused: boolean;
Expand All @@ -18,7 +18,7 @@ const initialState: State = {

function PlayerControls() {
const [state, setState] = useState(initialState);
const [castItHub] = useContext(CastItHubContext);
const castItHub = useCastItHub();

useEffect(() => {
const onPlayerStatusChangedSubscription = onPlayerStatusChanged.subscribe((status) => {
Expand Down
Loading

0 comments on commit 1c83ac3

Please sign in to comment.