Skip to content

Commit

Permalink
Merge branch 'develop' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
nytamin committed Sep 19, 2022
2 parents 892840f + 1393569 commit 50d9c1b
Show file tree
Hide file tree
Showing 20 changed files with 485 additions and 309 deletions.
2 changes: 1 addition & 1 deletion apps/app/src/electron/IPCServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ export class IPCServer
}
async handleClientError(error: string, stack?: string): Promise<void> {
// Handle an error thrown in the client
this.callbacks.handleError(error, stack)
this.callbacks.handleError('Client error: ' + error, stack)
}
async debugThrowError(type: 'sync' | 'async' | 'setTimeout'): Promise<void> {
// This method is used for development-purposes only, to check how error reporting works.
Expand Down
18 changes: 13 additions & 5 deletions apps/app/src/electron/rundown.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import { Resolver } from 'superfly-timeline'
import { ResolvedTimeline, Resolver } from 'superfly-timeline'
import { getPartLabel, getResolvedTimelineTotalDuration } from '../lib/util'
import { Part } from '../models/rundown/Part'
import { TimelineObjResolvedInstance } from '../models/rundown/TimelineObj'

export function postProcessPart(part: Part, noModify?: boolean): void {
const resolvedTimeline = Resolver.resolveTimeline(
part.timeline.map((o) => o.obj),
{ time: 0 }
)
let resolvedTimeline: ResolvedTimeline

const partTimeline = part.timeline.map((o) => o.obj)
try {
resolvedTimeline = Resolver.resolveTimeline(partTimeline, { time: 0 })
} catch (err) {
if (err && (err as Error).stack) {
// Also add the timeline, this is useful when troubleshooting:
;(err as Error).stack += '\n ' + JSON.stringify(partTimeline)
}
throw err
}
let modified = false

for (const o of part.timeline) {
Expand Down
2 changes: 1 addition & 1 deletion apps/app/src/lib/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export function TSRTimelineObjFromResource(resource: ResourceAny): TSRTimelineOb
templateType: 'html',
name: resource.name,
data: JSON.stringify(resource.data ?? {}),
useStopCommand: true,
useStopCommand: resource.useStopCommand ?? true,
},
}

Expand Down
153 changes: 77 additions & 76 deletions apps/app/src/react/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,15 @@ import { ClientSideLogger } from './api/logger'
import { useMemoComputedValue } from './mobx/lib'
import { Action, getAllActionsInParts } from '../lib/triggers/action'
import { PartWithRef } from '../lib/util'
import { assertNever } from '@shared/lib'
import { assertNever, stringifyErrorInner } from '@shared/lib'
import { setupClipboard } from './api/clipboard/clipboard'
import { ClipBoardContext } from './api/clipboard/lib'
import { UserAgreementScreen } from './components/UserAgreementScreen'
import { USER_AGREEMENT_VERSION } from '../lib/userAgreement'
import { DebugTestErrors } from './components/util/Debug'
import { ErrorBoundary } from './components/util/ErrorBoundary'
import { Spinner } from './components/util/Spinner'
import { CB } from './lib/errorHandling'

/**
* Used to remove unnecessary cruft from error messages.
Expand Down Expand Up @@ -108,41 +109,22 @@ export const App = observer(function App() {
}, [triggers, logger])

const handleError = useCallback(
(error: any) => {
logger.error(error)

let message: string
let stack = undefined
if (typeof error === 'string') {
message = error
} else if (error === null) {
message = ''
} else if (typeof error === 'object' && 'message' in error) {
message = error.message ?? ''
} else if (typeof error === 'object' && typeof error.reason === 'object' && error.reason.message) {
message = error.reason.message
stack = error.reason.stack || error.reason.reason
} else if (typeof error === 'object' && typeof error.error === 'object' && error.error.message) {
message = error.error.message
stack = error.error.stack
} else if (typeof error === 'object' && error.message) {
message = 'error message: ' + error.message
} else if (typeof error === 'object') {
message = 'error object: ' + error.toString()
} else {
message = `Unknown error, see console for details. (${error})`
}

if (message) {
enqueueSnackbar(message.replace(ErrorCruftRegex, ''), { variant: 'error' })

// Don't send sever-errors back to server:
if (!message.match(ErrorCruftRegex)) {
// eslint-disable-next-line no-console
serverAPI.handleClientError(message, stack).catch(console.error)
(...args: any[]) => {
for (const error of args) {
logger.error(args)
const { message, stack } = stringifyErrorInner(error)

if (message) {
enqueueSnackbar(message.replace(ErrorCruftRegex, ''), { variant: 'error' })

// Don't send sever-errors back to server:
if (!message.match(ErrorCruftRegex)) {
// eslint-disable-next-line no-console
serverAPI.handleClientError(message, stack).catch(console.error)
}
}
}
// }
return true
},
[enqueueSnackbar, logger, serverAPI]
)
Expand Down Expand Up @@ -255,8 +237,14 @@ export const App = observer(function App() {
serverAPI.setKeyboardKeys({ activeKeys }).catch(handleError)
}
}
document.addEventListener('keydown', (e) => handleKey(e))
document.addEventListener('keyup', (e) => handleKey(e))
document.addEventListener(
'keydown',
CB((e) => handleKey(e))
)
document.addEventListener(
'keyup',
CB((e) => handleKey(e))
)
}, [handleError, triggers, serverAPI])

const gui = store.guiStore
Expand Down Expand Up @@ -556,57 +544,70 @@ export const App = observer(function App() {
<ProjectContext.Provider value={project}>
<ErrorHandlerContext.Provider value={errorHandlerContextValue}>
<div className="app" onClick={handleClickAnywhere}>
<HeaderBar />

{
// Splash screens:
splashScreenOpen ? (
<SplashScreen
seenVersion={appStore.version?.seenVersion}
currentVersion={appStore.version?.currentVersion}
onClose={onSplashScreenClose}
/>
) : userAgreementScreenOpen ? (
<UserAgreementScreen
onAgree={(agreementVersion: string) => {
onUserAgreement(agreementVersion)
}}
onDisagree={() => {
window.close()
}}
/>
) : null
}
<ErrorBoundary>
<HeaderBar />
</ErrorBoundary>

<ErrorBoundary>
{
// Splash screens:
splashScreenOpen ? (
<SplashScreen
seenVersion={appStore.version?.seenVersion}
currentVersion={appStore.version?.currentVersion}
onClose={onSplashScreenClose}
/>
) : userAgreementScreenOpen ? (
<UserAgreementScreen
onAgree={(agreementVersion: string) => {
onUserAgreement(agreementVersion)
}}
onDisagree={() => {
window.close()
}}
/>
) : null
}
</ErrorBoundary>

{store.guiStore.isNewRundownSelected() ? (
<NewRundownPage />
<ErrorBoundary>
<NewRundownPage />
</ErrorBoundary>
) : store.guiStore.isHomeSelected() ? (
<HomePage project={project} />
<ErrorBoundary>
<HomePage project={project} />
</ErrorBoundary>
) : (
<>
<div className="main-area">
<RundownView mappings={project.mappings} />
<ErrorBoundary>
<RundownView mappings={project.mappings} />
</ErrorBoundary>
</div>
<div className="side-bar">
<Sidebar mappings={project.mappings} />
<ErrorBoundary>
<Sidebar mappings={project.mappings} />
</ErrorBoundary>
</div>
</>
)}

<ConfirmationDialog
open={!!showDeleteConfirmationDialog}
title="Delete"
acceptLabel="Delete"
onDiscarded={() => {
setShowDeleteConfirmationDialog(undefined)
}}
onAccepted={() => {
deleteSelectedTimelineObjs()
setShowDeleteConfirmationDialog(undefined)
}}
>
<p>Do you want to delete {showDeleteConfirmationDialog}?</p>
</ConfirmationDialog>
<ErrorBoundary>
<ConfirmationDialog
open={!!showDeleteConfirmationDialog}
title="Delete"
acceptLabel="Delete"
onDiscarded={() => {
setShowDeleteConfirmationDialog(undefined)
}}
onAccepted={() => {
deleteSelectedTimelineObjs()
setShowDeleteConfirmationDialog(undefined)
}}
>
<p>Do you want to delete {showDeleteConfirmationDialog}?</p>
</ConfirmationDialog>
</ErrorBoundary>

<ErrorBoundary>{debugMode && <DebugTestErrors />}</ErrorBoundary>
</div>
Expand Down
72 changes: 4 additions & 68 deletions apps/app/src/react/api/clipboard/casparCGClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { assertNever, literal } from '@shared/lib'
import { CasparCGMedia, CasparCGTemplate, ResourceAny, ResourceType } from '@shared/models'
import { DeviceType } from 'timeline-state-resolver-types'
import { getDefaultGroup, getDefaultPart } from '../../../electron/defaults'
import { findDeviceOfType, MoveTarget, shortID } from '../../../lib/util'
import { findDeviceOfType, shortID } from '../../../lib/util'
import { Group } from '../../../models/rundown/Group'
import { Part } from '../../../models/rundown/Part'
import { store } from '../../mobx/store'
import { ClipBoardContext } from './lib'
import { ClipBoardContext, insertGroups, insertParts } from './lib'

const parser = new DOMParser()

Expand All @@ -16,8 +16,6 @@ const parser = new DOMParser()
*/
export async function handleCasparCGClient(context: ClipBoardContext, str: string): Promise<boolean> {
if (!str.startsWith('<?xml version="1.0"?><items><item><type>')) return false
const currentRundownId = store.rundownsStore.currentRundownId
if (!currentRundownId) return false

let xml: Document
try {
Expand Down Expand Up @@ -53,72 +51,10 @@ export async function handleCasparCGClient(context: ClipBoardContext, str: strin
}

if (groups.length) {
let target: MoveTarget
const selected = store.guiStore.mainSelected
if (selected) {
target = {
type: 'after',
id: selected.groupId,
}
} else {
target = {
type: 'last',
}
}
const insertedGroups = await context.serverAPI.insertGroups({
rundownId: currentRundownId,
groups,
target,
})
if (insertedGroups.length) {
store.guiStore.clearSelected()
for (const insert of insertedGroups) {
store.guiStore.addSelected({
type: 'group',
groupId: insert.groupId,
})
}
}
await insertGroups(context, groups)
}
if (parts.length) {
let target: MoveTarget
let insertGroupId: string | null
const selected = store.guiStore.mainSelected
if (selected) {
insertGroupId = selected.groupId
if (selected.type === 'part' || selected.type === 'timelineObj') {
target = {
type: 'after',
id: selected.partId,
}
} else {
target = {
type: 'last',
}
}
} else {
insertGroupId = null
target = {
type: 'last',
}
}

const insertedParts = await context.serverAPI.insertParts({
rundownId: currentRundownId,
groupId: insertGroupId,
parts: parts,
target,
})
if (insertedParts.length) {
store.guiStore.clearSelected()
for (const insert of insertedParts) {
store.guiStore.addSelected({
type: 'part',
groupId: insert.groupId,
partId: insert.partId,
})
}
}
await insertParts(context, parts)
}
return true
}
Expand Down
Loading

0 comments on commit 50d9c1b

Please sign in to comment.