Skip to content

Commit

Permalink
Feat/navigate (#81)
Browse files Browse the repository at this point in the history
* feat/navigate upgrade react router
* feat/navigate migrate to react router 6
* feat/navigate style modal
* feat/navigate create endpoints for app settings
* feat/navigate protect editor with pin
* feat/navigate apply dynamic routing draft
* feat/navigate upgrade relevant packages
* feat/navigate restructure directory and add tests
* feat/navigate test aliases validation
* feat/navigate validate aliases before sending
* feat/navigate create data endpoint
* feat/navigate config: prettier
* feat/navigate invalidate empty strings
* feat/navigate create endpoints
* feat/navigate parse on import
* feat/navigate navigate to alias
* feat/navigate user help and sample data
* feat/navigate refact aliases modal
* feat/navigate refact settings style
* feat/navigate update sample db
* feat/navigate link is relative to hostname
* feat/navigate navigate to first match
* feat/navigate update readme and version bump
* feat/navigate config: create shared module
* feat/navigate config: cheat module install
* feat/navigate fix tests
* feat/navigate run tests in pull request
* Update ontime_cy.yml
  • Loading branch information
cpvalente authored Jan 4, 2022
1 parent dd43d5e commit 2fa3975
Show file tree
Hide file tree
Showing 74 changed files with 2,577 additions and 1,413 deletions.
64 changes: 64 additions & 0 deletions .github/workflows/ontime_cy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions

name: ontime_test_CI

on: [push, pull_request]

jobs:
build:

runs-on: ubuntu-latest
env:
CI: ''

steps:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v2
with:
node-version: '14.x'

# Utils server
- name: Utils - Install dependencies
run: yarn install
working-directory: ./server/utils

- name: Utils - run link command
run: yarn link
working-directory: ./server/utils

# React
- name: React - Link to utils
run: yarn link ontime-utils
working-directory: ./client

- name: React - Install dependencies
run: yarn install
working-directory: ./client

- name: React - Run tests
run: yarn test:pipeline
working-directory: ./client

- name: React - Build project
run: yarn build
working-directory: ./client

# Node server
- name: React - Link to utils
run: yarn link ontime-utils
working-directory: ./server/src

- name: Server - Install dependencies
run: yarn install
working-directory: ./server/src

# App
- name: Electron - Install dependencies
run: yarn install
working-directory: ./server

- name: Electron - Run tests
run: yarn test
working-directory: ./server
7 changes: 7 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"jsxSingleQuote": true
}
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,23 @@ From here, any device in the same network with a browser is able to render the v
You can then use the ontime logo in the top right corner to select the desired view (event in the lower thirds view, where it is hidden).

In case of unattended machines or automations, it is possible to use different URL to recall individual views
and extend with using the URL aliases feature

```
For the presentation views...
-------------------------------------------------------------
IP.ADDRESS:4001 > Web server default to presenter timer view
IP.ADDRESS:4001/preseter > Presenter / Stage timer view
IP.ADDRESS:4001/sm > Stage Manager / Backstage view
IP.ADDRESS:4001/public > Public / Foyer view
IP.ADDRESS:4001/pip > Picture in Picture view
IP.ADDRESS:4001/lower > Lower Thirds
IP.ADDRESS:4001/studio > Studio Clock
...and for the editor (the control interface, same as the app)
-------------------------------------------------------------
IP.ADDRESS:4001/studio > Studio Clock
```

More documentation available [here](https://cpvalente.gitbook.io/ontime/)
Expand All @@ -47,6 +55,9 @@ More documentation available [here](https://cpvalente.gitbook.io/ontime/)
- [x] Open Sound Control (OSC) Control and Feedback
- [x] Roll mode: run independently using the system clock
- [x] Import event list from Excel
- [x] URL Aliases (define configurable aliases to ease onsite setup)
- [x] Logging view
- [x] Edit anywhere: run ontime in your local network and use any machine to reach the editor page (same as app)

## Unopinionated
We are not interested in forcing workflows and have made ontime, so it is flexible to whichever way you would like to work.
Expand Down Expand Up @@ -77,8 +88,6 @@ These will be implemented in a development friendly order unless there is user d
- [ ] Companion module
- [ ] Lower Third Manager
- [ ] Note only event
- [ ] URL Aliases (define configurable aliases to ease onsite setup)
- [ ] Logging view
- [ ] Reach Schedule: way to speedup timer to meet a deadline
- [ ] vMix integration

Expand Down
15 changes: 8 additions & 7 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,26 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@chakra-ui/react": "^1.7.1",
"@emotion/react": "^11.5.0",
"@emotion/styled": "^11.3.0",
"@chakra-ui/react": "^1.7.3",
"@emotion/react": "^11.7.1",
"@emotion/styled": "^11.6.0",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"axios": "^0.24.0",
"framer-motion": "^4.1.6",
"jotai": "^0.16.5",
"ontime-utils": "link: ../server/utils/",
"react": "17.0.2",
"react-beautiful-dnd": "^13.1.0",
"react-dom": "^17.0.1",
"react-fast-compare": "^3.2.0",
"react-icons": "^4.3.1",
"react-qr-code": "^2.0.2",
"react-qr-code": "2.0.3",
"react-query": "^3.34.5",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-router-dom": "^6.2.1",
"react-scripts": "5.0.0",
"socket.io-client": "^4.3.2",
"socket.io-client": "4.4.0",
"typeface-open-sans": "^1.1.13",
"use-fit-text": "^2.4.0",
"web-vitals": "^1.0.1"
Expand All @@ -31,6 +31,7 @@
"start": "set BROWSER=none&&react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"test:pipeline": "react-scripts test --watchAll=false --runInBand --detectOpenHandles --forceExit ",
"eject": "react-scripts eject"
},
"browserslist": {
Expand Down
90 changes: 49 additions & 41 deletions client/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { lazy, Suspense, useCallback, useEffect } from 'react';
import { Route, Switch } from 'react-router-dom';
import { Route, Routes, useLocation, useNavigate } from 'react-router-dom';
import './App.scss';
import { QueryClient, QueryClientProvider } from 'react-query';
import SocketProvider from 'app/context/socketContext';
import withSocket from 'features/viewers/ViewWrapper';
import ErrorBoundary from 'common/components/errorBoundary/ErrorBoundary';
import ProtectRoute from './common/components/protectRoute/ProtectRoute';
import { useFetch } from './app/hooks/useFetch';
import { ALIASES } from './app/api/apiConstants';
import { getAliases } from './app/api/ontimeApi';

const Editor = lazy(() => import('features/editors/Editor'));
const PresenterView = lazy(() =>
import('features/viewers/presenter/PresenterView')
);
const PresenterSimple = lazy(() =>
import('features/viewers/presenter/PresenterSimple')
);
const StageManager = lazy(() =>
import('features/viewers/backstage/StageManager')
);
Expand All @@ -21,25 +20,20 @@ const Lower = lazy(() =>
import('features/viewers/production/lower/LowerWrapper')
);
const Pip = lazy(() => import('features/viewers/production/Pip'));

const StudioClock = lazy(() => import('features/viewers/studio/StudioClock'));

const queryClient = new QueryClient();
// Seemed to cause issues
// broadcastQueryClient({
// queryClient,
// broadcastChannel: 'ontime',
// });

const SPresenter = withSocket(PresenterView);
const SPresenterSimple = withSocket(PresenterSimple);
const SStageManager = withSocket(StageManager);
const SPublic = withSocket(Public);
const SLowerThird = withSocket(Lower);
const SPip = withSocket(Pip);
const SStudio = withSocket(StudioClock);

function App() {
const { data } = useFetch(ALIASES, getAliases);
const location = useLocation();
const navigate = useNavigate();

// Handle keyboard shortcuts
const handleKeyPress = useCallback((e) => {
// check if the alt key is pressed
Expand All @@ -65,33 +59,47 @@ function App() {
};
}, [handleKeyPress]);

// navigate if is alias route
useEffect(() => {
if (data == null) return;
for (const d of data) {
if (`/${d.alias}` === location.pathname && d.enabled) {
navigate(`/${d.pathAndParams}`);
break;
}
}
}, [data, location, navigate]);

return (
<SocketProvider>
<QueryClientProvider client={queryClient}>
<div className='App'>
<ErrorBoundary>
<Suspense fallback={null}>
<Switch>
<Route exact path='/' component={SPresenter} />
<Route exact path='/sm' component={SStageManager} />
<Route exact path='/speaker' component={SPresenter} />
<Route exact path='/presenter' component={SPresenter} />
<Route exact path='/stage' component={SPresenter} />
<Route exact path='/presentersimple' component={SPresenterSimple} />
<Route exact path='/editor' component={Editor} />
<Route exact path='/public' component={SPublic} />
<Route exact path='/pip' component={SPip} />
<Route exact path='/studio' component={SStudio} />
{/* Lower cannot have fallback */}
<Route exact path='/lower' component={SLowerThird} />
{/* Send to default if nothing found */}
<Route component={SPresenter} />
</Switch>
</Suspense>
</ErrorBoundary>
</div>
</QueryClientProvider>
</SocketProvider>
<div className='App'>
<ErrorBoundary>
<Suspense fallback={null}>
<Routes>
<Route path='/' element={<SPresenter />} />
<Route path='/sm' element={<SStageManager />} />
<Route path='/speaker' element={<SPresenter />} />
<Route path='/presenter' element={<SPresenter />} />
<Route path='/stage' element={<SPresenter />} />
<Route path='/public' element={<SPublic />} />
<Route path='/pip' element={<SPip />} />
<Route path='/studio' element={<SStudio />} />
{/*/!* Lower cannot have fallback *!/*/}
<Route path='/lower' element={<SLowerThird />} />
{/*/!* Protected Routes *!/*/}
<Route
path='/editor'
element={
<ProtectRoute>
<Editor />
</ProtectRoute>
}
/>
{/* Send to default if nothing found */}
<Route path='*' element={<SPresenter />} />
</Routes>
</Suspense>
</ErrorBoundary>
</div>
);
}

Expand Down
15 changes: 0 additions & 15 deletions client/src/_main.scss

This file was deleted.

2 changes: 2 additions & 0 deletions client/src/app/api/apiConstants.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
export const NODE_PORT = 4001;
export const EVENT_TABLE = 'event';
export const ALIASES = 'aliases';
export const EVENTS_TABLE = 'events';
export const APP_TABLE = 'appinfo';
export const OSC_SETTINGS = 'oscSettings';
export const APP_SETTINGS = 'appSettings';

const calculateServer = () => {
return window.location.origin.replace(window.location.port, `${NODE_PORT}/`);
Expand Down
30 changes: 30 additions & 0 deletions client/src/app/api/ontimeApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,18 @@ export const ontimePlaceholderInfo = {
},
};

export const ontimePlaceholderSettings = {
pinCode: null,
};

export const eventPlaceholderSettings = {
title: '',
url: '',
publicInfo: '',
backstageInfo: '',
endMessage: '',
};

export const oscPlaceholderSettings = {
port: '',
portOut: '',
Expand Down Expand Up @@ -74,6 +86,15 @@ export const ontimeVars = [
},
];

export const getSettings = async () => {
const res = await axios.get(`${ontimeURL}/settings`);
return res.data;
};

export const postSettings = async (data) => {
return await axios.post(`${ontimeURL}/settings`, data);
};

export const getInfo = async () => {
const res = await axios.get(`${ontimeURL}/info`);
return res.data;
Expand All @@ -83,6 +104,15 @@ export const postInfo = async (data) => {
return await axios.post(`${ontimeURL}/info`, data);
};

export const getAliases = async () => {
const res = await axios.get(`${ontimeURL}/aliases`);
return res.data;
};

export const postAliases = async (data) => {
return await axios.post(`${ontimeURL}/aliases`, data);
};

export const getOSC = async () => {
const res = await axios.get(`${ontimeURL}/osc`);
return res.data;
Expand Down
14 changes: 14 additions & 0 deletions client/src/app/appConstants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Exported viewer links
const speakerLink = 'http://localhost:4001/speaker';
const smLink = 'http://localhost:4001/sm';
const publicLink = 'http://localhost:4001/public';
const pipLink = 'http://localhost:4001/pip';
const studioLink = 'http://localhost:4001/studio';

export const viewerLinks = [
{ link: speakerLink, label: 'Speaker Screen' },
{ link: smLink, label: 'Backstage Screen' },
{ link: publicLink, label: 'Public Screen' },
{ link: pipLink, label: 'Picture in Picture' },
{ link: studioLink, label: 'Studio Clock' }
];
Loading

0 comments on commit 2fa3975

Please sign in to comment.