import { useState, useEffect } from 'react'; import { Box, Flex, IconButton, Link, Spacer, Stack, Text, } from '@chakra-ui/react'; import { FiSettings, FiList, FiPause, FiPlay } from 'react-icons/fi'; import Channel from '~/utils/channel'; import { LocalData, LocalDataKey, RecorderStatus, ServiceName, RecordStartedMessage, RecordStoppedMessage, Session, EventName, } from '~/types'; import Browser from 'webextension-polyfill'; import { CircleButton } from '~/components/CircleButton'; import { Timer } from './Timer'; import { pauseRecording, resumeRecording } from '~/utils/recording'; import { saveSession } from '~/utils/storage'; const RECORD_BUTTON_SIZE = 3; const channel = new Channel(); export function App() { const [status, setStatus] = useState(RecorderStatus.IDLE); const [errorMessage, setErrorMessage] = useState(''); const [startTime, setStartTime] = useState(0); const [newSession, setNewSession] = useState(null); useEffect(() => { void Browser.storage.local.get(LocalDataKey.recorderStatus).then((data) => { const localData = data as LocalData; if (!localData || !localData[LocalDataKey.recorderStatus]) return; const { status, startTimestamp, pausedTimestamp } = localData[ LocalDataKey.recorderStatus ]; setStatus(status); if (startTimestamp && pausedTimestamp) setStartTime(Date.now() - pausedTimestamp + startTimestamp || 0); else if (startTimestamp) setStartTime(startTimestamp); }); }, []); return ( RRWeb Recorder { void Browser.tabs.create({ url: '/pages/index.html#/' }); }} size="xs" icon={} aria-label={'Session List'} title="Session List" > { void Browser.runtime.openOptionsPage(); }} size="xs" icon={} aria-label={'Settings button'} title="Settings" > {status !== RecorderStatus.IDLE && startTime && ( )} {[RecorderStatus.IDLE, RecorderStatus.RECORDING].includes(status) && ( { if (status === RecorderStatus.RECORDING) { // stop recording setErrorMessage(''); void channel.getCurrentTabId().then((tabId) => { if (tabId === -1) return; void channel .requestToTab(tabId, ServiceName.StopRecord, {}) .then(async (res: RecordStoppedMessage) => { if (!res) return; setStatus(RecorderStatus.IDLE); const status: LocalData[LocalDataKey.recorderStatus] = { status: RecorderStatus.IDLE, activeTabId: tabId, }; await Browser.storage.local.set({ [LocalDataKey.recorderStatus]: status, }); if (res.session) { setNewSession(res.session); await saveSession(res.session, res.events).catch( (e) => { setErrorMessage((e as { message: string }).message); }, ); channel.emit(EventName.SessionUpdated, {}); } }) .catch((error: Error) => { setErrorMessage(error.message); }); }); } else { // start recording void channel.getCurrentTabId().then((tabId) => { if (tabId === -1) return; void channel .requestToTab(tabId, ServiceName.StartRecord, {}) .then(async (res: RecordStartedMessage | undefined) => { if (res) { setStatus(RecorderStatus.RECORDING); setStartTime(res.startTimestamp); const status: LocalData[LocalDataKey.recorderStatus] = { status: RecorderStatus.RECORDING, activeTabId: tabId, startTimestamp: res.startTimestamp, }; await Browser.storage.local.set({ [LocalDataKey.recorderStatus]: status, }); } }) .catch((error: Error) => { setErrorMessage(error.message); }); }); } }} > )} {status !== RecorderStatus.IDLE && ( { if (status === RecorderStatus.RECORDING) { void pauseRecording(channel, RecorderStatus.PAUSED).then( (result) => { if (!result) return; setStatus(result?.status.status); }, ); } else { void channel.getCurrentTabId().then((tabId) => { if (tabId === -1) return; resumeRecording(channel, tabId) .then((statusData) => { if (!statusData) return; setStatus(statusData.status); if (statusData.startTimestamp) setStartTime(statusData.startTimestamp); }) .catch((error: Error) => { setErrorMessage(error.message); }); }); } }} > {[RecorderStatus.PAUSED, RecorderStatus.PausedSwitch].includes( status, ) && ( )} {status === RecorderStatus.RECORDING && ( )} )} {newSession && ( New Session: {newSession.name} )} {errorMessage !== '' && ( {errorMessage}
Maybe refresh your current tab.
)}
); }