Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor/ts sockets #210

Merged
merged 9 commits into from
Oct 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"@testing-library/react": "^13.1.1",
"@testing-library/react-hooks": "^8.0.0",
"@testing-library/user-event": "^14.1.1",
"@types/color": "^3.0.3",
"@types/node": "^18.7.16",
"@types/react": "^18.0.19",
"@types/react-dom": "^18.0.6",
Expand Down
42 changes: 42 additions & 0 deletions client/src/common/application-types/event.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
export interface OntimeBaseEvent {
type: 'block' | 'event' | 'delay';
id: string;
}

export interface OntimeDelay extends OntimeBaseEvent {
type: 'delay';
duration: number;
revision: number;
}

export interface OntimeBlock extends OntimeBaseEvent {
type: 'block';
}

export interface OntimeEvent extends OntimeBaseEvent {
type: 'event';
title: string,
subtitle: string,
presenter: string,
note: string,
timeStart: number,
timeEnd: number,
timeType?: string,
duration: number,
isPublic: boolean,
skip: boolean,
colour: string,
user0: string,
user1: string,
user2: string,
user3: string,
user4: string,
user5: string,
user6: string,
user7: string,
user8: string,
user9: string,
revision: number,
}

export type OntimeEventEntry = OntimeDelay | OntimeBlock | OntimeEvent;
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@ import { Tooltip } from '@chakra-ui/tooltip';
import { FiClock } from '@react-icons/all-files/fi/FiClock';
import { FiMinusCircle } from '@react-icons/all-files/fi/FiMinusCircle';
import { FiPlus } from '@react-icons/all-files/fi/FiPlus';
import PropTypes from 'prop-types';

import { tooltipDelayMid } from '../../../ontimeConfig';

export default function ActionButtons(props) {
interface ActionButtonProps {
showAdd?: boolean;
showDelay?: boolean;
showBlock?: boolean;
actionHandler: (action: string) => void;
}

export default function ActionButtons(props: ActionButtonProps) {
const { showAdd, showDelay, showBlock, actionHandler } = props;

const menuStyle = {
Expand All @@ -18,7 +24,7 @@ export default function ActionButtons(props) {

return (
<Menu isLazy lazyBehavior='unmount'>
<Tooltip label='Add ...' delay={tooltipDelayMid}>
<Tooltip label='Add ...' openDelay={tooltipDelayMid}>
<MenuButton
as={IconButton}
aria-label='Options'
Expand Down Expand Up @@ -49,10 +55,3 @@ export default function ActionButtons(props) {
</Menu>
);
}

ActionButtons.propTypes = {
showAdd: PropTypes.bool,
showDelay: PropTypes.bool,
showBlock: PropTypes.bool,
actionHandler: PropTypes.func,
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
import { IconButton } from '@chakra-ui/button';
import { Tooltip } from '@chakra-ui/tooltip';
import { IoPause } from '@react-icons/all-files/io5/IoPause';
import PropTypes from 'prop-types';

import { tooltipDelayMid } from '../../../ontimeConfig';

export default function PauseIconBtn(props) {
interface PauseIconBtnProps {
clickhandler: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
active: boolean;
disabled: boolean;
}

export default function PauseIconBtn(props: PauseIconBtnProps) {
const { clickhandler, active, disabled, ...rest } = props;
return (
<Tooltip label='Pause timer' openDelay={tooltipDelayMid} shouldWrapChildren={disabled}>
<IconButton
icon={<IoPause size='24px' />}
colorScheme='orange'
_hover={!disabled && { bg: 'orange.400' }}
variant={active ? 'solid' : 'outline'}
onClick={clickhandler}
width={120}
disabled={disabled}
aria-label='Pause playback'
{...rest}
/>
</Tooltip>
);
}

PauseIconBtn.propTypes = {
clickhandler: PropTypes.func,
active: PropTypes.bool,
disabled: PropTypes.bool
}
39 changes: 0 additions & 39 deletions client/src/common/components/paginator/TodayItem.jsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
import { useEffect, useState } from 'react';
import { useInterval } from 'common/hooks/useInterval';
import PropTypes from 'prop-types';

import { OntimeEvent } from '../../application-types/event';
import Empty from '../state/Empty';

import TodayItem from './TodayItem';

import './Paginator.scss';
import style from './Paginator.module.scss';

export default function Paginator(props) {
interface PaginatorProps {
events: OntimeEvent[];
selectedId: string;
limit?: number;
time?: number;
isBackstage: boolean;
setPageNumber: (page: number) => void;
setCurrentPage: (selectedPage: number) => void;
}

export default function Paginator(props: PaginatorProps) {
const {
events,
selectedId,
Expand All @@ -21,9 +31,9 @@ export default function Paginator(props) {
const LIMIT_PER_PAGE = limit;
const SCROLL_TIME = time * 1000;
const [numEvents, setNumEvents] = useState(0);
const [page, setPage] = useState([]);
const [pages, setPages] = useState(0);
const [selPage, setSelPage] = useState(0);
const [page, setPage] = useState<OntimeEvent[]>([]);
const [pages, setPages] = useState<number>(0);
const [selPage, setSelPage] = useState<number>(0);

// keep parent up to date
useEffect(() => {
Expand Down Expand Up @@ -70,7 +80,7 @@ export default function Paginator(props) {
}

return (
<div className='paginator entries'>
<div className={style.entries}>
{page.map((e) => {
if (e.id === selectedId) selectedState = 1;
else if (selectedState === 1) selectedState = 2;
Expand All @@ -83,19 +93,10 @@ export default function Paginator(props) {
title={e.title}
colour={isBackstage ? e.colour : ''}
backstageEvent={!e.isPublic}
skip={e.skip}
/>
);
})}
</div>
);
}

Paginator.propTypes = {
events: PropTypes.array,
selectedId: PropTypes.string,
limit: PropTypes.number,
time: PropTypes.number,
isBackstage: PropTypes.bool,
setPageNumber: PropTypes.func,
setCurrentPage: PropTypes.func,
};
51 changes: 51 additions & 0 deletions client/src/common/components/views/TodayItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import PropTypes from 'prop-types';

import { formatTime } from '../../utils/time';

import style from './Paginator.module.scss';

interface TodayItemProps {
selected: number;
timeStart: number;
timeEnd: number;
title: string;
backstageEvent: boolean;
colour: string;
skip: boolean;
}

// Todo: apply skip CSS and selector
export default function TodayItem(props: TodayItemProps) {
// @ts-ignore
const { selected, timeStart, timeEnd, title, backstageEvent, colour, skip } = props;

// Format timers
const start = formatTime(timeStart, { format: 'hh:mm' });
const end = formatTime(timeEnd, { format: 'hh:mm' });

// user colours
const userColour = colour !== '' ? colour : 'transparent';

// select styling
let selectStyle = style.entryPast;
if (selected === 1) selectStyle = style.entryNow;
else if (selected === 2) selectStyle = style.entryFuture;
return (
<div className={selectStyle} style={{ borderLeft: `4px solid ${userColour}` }}>
<div className={`${style.entryTimes} ${backstageEvent ? style.backstage : ''}`}>
{`${start} · ${end}`}
</div>
<div className={style.entryTitle}>{title}</div>
{backstageEvent && <div className={style.backstageInd} />}
</div>
);
}

TodayItem.propTypes = {
selected: PropTypes.number,
timeStart: PropTypes.number,
timeEnd: PropTypes.number,
title: PropTypes.string,
backstageEvent: PropTypes.bool,
colour: PropTypes.string,
};
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
import { createContext, useCallback, useMemo, useState } from 'react';
import { createContext, ReactNode, useCallback, useMemo, useState } from 'react';

import { useLocalStorage } from '../hooks/useLocalStorage';

export const CursorContext = createContext({
interface CursorContextState {
cursor: number;
isCursorLocked: boolean;
toggleCursorLocked: (newValue?: boolean) => void;
setCursor: (index: number) => void;
moveCursorUp: () => void;
moveCursorDown: () => void;
moveCursorTo: (index: number) => void;
}

export const CursorContext = createContext<CursorContextState>({
cursor: 0,
isCursorLocked: false,

toggleCursorLocked: () => undefined,
setCursor: () => undefined,
moveCursorUp: () => undefined,
moveCursorDown: () => undefined,
moveCursorTo: () => undefined,
});

export const CursorProvider = ({ children }) => {
interface CursorProviderProps {
children: ReactNode
}

export const CursorProvider = ({ children }: CursorProviderProps) => {
const [cursor, setCursor] = useState(0);
const [_cursorLocked, _setCursorLocked] = useLocalStorage('isCursorLocked', 'locked');
const isCursorLocked = useMemo(() => _cursorLocked === 'locked', [_cursorLocked]);
Expand All @@ -31,7 +46,7 @@ export const CursorProvider = ({ children }) => {
* @param {boolean | undefined} newValue
*/
const toggleCursorLocked = useCallback(
(newValue = undefined) => {
(newValue?: boolean) => {
if (typeof newValue === 'undefined') {
if (isCursorLocked) {
cursorLockedOff();
Expand All @@ -46,6 +61,11 @@ export const CursorProvider = ({ children }) => {
},
[cursorLockedOff, cursorLockedOn, isCursorLocked]
);

// moves cursor to given index
const moveCursorTo = useCallback((index: number) => {
setCursor(index);
}, []);

return (
<CursorContext.Provider
Expand All @@ -56,6 +76,7 @@ export const CursorProvider = ({ children }) => {
setCursor,
moveCursorUp,
moveCursorDown,
moveCursorTo,
}}
>
{children}
Expand Down
Loading