Skip to content

Commit

Permalink
work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
jbilcke-hf committed Jul 29, 2024
1 parent fd46ec1 commit 58cb97c
Show file tree
Hide file tree
Showing 41 changed files with 7,964 additions and 4,907 deletions.
11,770 changes: 6,958 additions & 4,812 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "clapper",
"version": "0.0.6",
"version": "0.0.7",
"private": true,
"description": "🎬 Clapper",
"license": "GPL-3.0-only",
Expand Down Expand Up @@ -38,9 +38,9 @@
"dependencies": {
"@aitube/broadway": "0.1.2",
"@aitube/clap": "0.1.2",
"@aitube/clapper-services": "0.1.2-8",
"@aitube/clapper-services": "0.1.2-14",
"@aitube/engine": "0.1.2",
"@aitube/timeline": "0.1.2-2",
"@aitube/timeline": "0.1.2-3",
"@fal-ai/serverless-client": "^0.13.0",
"@ffmpeg/ffmpeg": "^0.12.10",
"@ffmpeg/util": "^0.12.1",
Expand Down
49 changes: 31 additions & 18 deletions src/app/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { ScriptEditor } from '@/components/editors/ScriptEditor'
import { SegmentEditor } from '@/components/editors/SegmentEditor'
import { EntityEditor } from '@/components/editors/EntityEditor'
import { WorkflowEditor } from '@/components/editors/WorkflowEditor'
import { FilterEditor } from '@/components/editors/FilterEditor'

type DroppableThing = { files: File[] }

Expand Down Expand Up @@ -117,7 +118,7 @@ function MainContent() {
<FruityDesktop>
<FruityWindow
id="ScriptEditor"
title="Script editor"
title="Screenplay"
defaultWidth={375}
minWidth={200}
defaultHeight={370}
Expand All @@ -131,7 +132,7 @@ function MainContent() {

<FruityWindow
id="SegmentEditor"
title="segment editor"
title="Segments"
defaultWidth={342}
minWidth={200}
defaultHeight={395}
Expand All @@ -145,7 +146,7 @@ function MainContent() {

<FruityWindow
id="EntityEditor"
title="Entity editor"
title="Entities"
defaultWidth={544}
minWidth={200}
defaultHeight={318}
Expand All @@ -157,21 +158,33 @@ function MainContent() {
<EntityEditor />
</FruityWindow>

{hasBetaAccess && (
<FruityWindow
id="WorkflowEditor"
title="Workflow editor"
defaultWidth={459}
minWidth={200}
defaultHeight={351}
minHeight={100}
defaultX={536}
defaultY={3}
canBeClosed={false}
>
<WorkflowEditor />
</FruityWindow>
)}
<FruityWindow
id="WorkflowEditor"
title="Workflows"
defaultWidth={459}
minWidth={200}
defaultHeight={351}
minHeight={100}
defaultX={536}
defaultY={3}
canBeClosed={false}
>
<WorkflowEditor />
</FruityWindow>

<FruityWindow
id="FilterEditor"
title="Filters"
defaultWidth={459}
minWidth={200}
defaultHeight={351}
minHeight={100}
defaultX={936}
defaultY={400}
canBeClosed={false}
>
<FilterEditor />
</FruityWindow>

<FruityWindow
id="Monitor"
Expand Down
74 changes: 74 additions & 0 deletions src/components/editors/FilterEditor/FilterTree/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
'use client'

import { useEffect } from 'react'

import { cn } from '@/lib/utils'
import { isClapEntity } from '@/components/tree-browsers/utils/isSomething'
import { TreeNodeItem, LibraryNodeType } from '@/components/tree-browsers/types'
import { Tree } from '@/components/core/tree'

import { useFilterTree } from './useFilterTree'
import { useFilterEditor } from '@/services/editors/filter-editor/useFilterEditor'

export function FilterTree({
className = '',
}: {
className?: string
} = {}) {
const libraryTreeRoot = useFilterTree((s) => s.libraryTreeRoot)
const selectTreeNode = useFilterTree((s) => s.selectTreeNode)
const selectedTreeNodeId = useFilterTree((s) => s.selectedTreeNodeId)
const setAvailableFilters = useFilterTree((s) => s.setAvailableFilters)

const availableFilters = useFilterEditor((s) => s.availableFilters)
const activeFilters = useFilterEditor((s) => s.activeFilters)
const current = useFilterEditor((s) => s.current)

useEffect(() => {
console.log('TODO: populate the filter tree')
}, [availableFilters.map((f) => f.id).join(',')])
/**
* handle click on tree node
* yes, this is where the magic happens!
*
* @param id
* @param nodeType
* @param node
* @returns
*/
const handleOnChange = async (
id: string | null,
nodeType?: LibraryNodeType,
nodeItem?: TreeNodeItem
) => {
console.log(`calling selectTreeNodeById(id)`)
selectTreeNode(id, nodeType, nodeItem)

if (!nodeType || !nodeItem) {
console.log('tree-browser: clicked on an undefined node')
return
}
if (isClapEntity(nodeType, nodeItem)) {
// ClapEntity
} else {
console.log(
`tree-browser: no action attached to ${nodeType}, so skipping`
)
return
}
console.log(`tree-browser: clicked on a ${nodeType}`, nodeItem)
}

return (
<Tree.Root<LibraryNodeType, TreeNodeItem>
value={selectedTreeNodeId}
onChange={handleOnChange}
className={cn(`not-prose h-full w-full px-2 pt-2`, className)}
label="Filters"
>
{libraryTreeRoot.map((node) => (
<Tree.Node node={node} key={node.id} />
))}
</Tree.Root>
)
}
147 changes: 147 additions & 0 deletions src/components/editors/FilterEditor/FilterTree/useFilterTree.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
'use client'

import { create } from 'zustand'
import { ClapEntity, UUID } from '@aitube/clap'
import { Filter } from '@aitube/clapper-services'

import {
LibraryTreeNode,
TreeNodeItem,
LibraryNodeType,
} from '@/components/tree-browsers/types'
import { icons } from '@/components/icons'
import {
collectionClassName,
libraryClassName,
} from '@/components/tree-browsers/style/treeNodeStyles'

export const useFilterTree = create<{
availableFiltersLibraryTreeNodeId: string

// activeFiltersLibraryTreeNodeId: string

libraryTreeRoot: LibraryTreeNode[]
init: () => void

/**
* Load available filters into the tree
*
* @param collections
* @returns
*/
setAvailableFilters: (filters: Filter[]) => void

// we support those all selection modes for convenience - please keep them!
selectedNodeItem?: TreeNodeItem
selectedNodeType?: LibraryNodeType
selectTreeNode: (
treeNodeId?: string | null,
nodeType?: LibraryNodeType,
nodeItem?: TreeNodeItem
) => void
selectedTreeNodeId: string | null
}>((set, get) => ({
availableFiltersLibraryTreeNodeId: '',

// activeFiltersLibraryTreeNodeId: '',

libraryTreeRoot: [],
init: () => {
const availableFilterLibrary: LibraryTreeNode = {
id: UUID(),
nodeType: 'TREE_ROOT_PROJECT',
label: 'Available filters',
icon: icons.project,
className: libraryClassName,
isExpanded: true,
children: [
{
id: UUID(),
nodeType: 'DEFAULT_TREE_NODE_EMPTY',
label: 'Empty',
icon: icons.project,
className: collectionClassName,
},
],
}

const libraryTreeRoot = [availableFilterLibrary]

set({
availableFiltersLibraryTreeNodeId: availableFilterLibrary.id,
libraryTreeRoot,
selectedNodeItem: undefined,
selectedTreeNodeId: null,
})
},

setAvailableFilters: (filters: Filter[]) => {
const availableFilterLibrary: LibraryTreeNode = {
id: UUID(),
nodeType: 'TREE_ROOT_PROJECT',
label: 'Filters',
icon: icons.project,
className: libraryClassName,
isExpanded: true,
children: [
{
id: UUID(),
nodeType: 'DEFAULT_TREE_NODE_EMPTY',
label: 'Empty',
icon: icons.project,
className: collectionClassName,
},
],
}

const libraryTreeRoot = [availableFilterLibrary]

set({
availableFiltersLibraryTreeNodeId: availableFilterLibrary.id,
libraryTreeRoot,
selectedNodeItem: undefined,
selectedTreeNodeId: null,
})
},

/*
setCommunityCollections: (collections: CommunityEntityCollection[]) => {
// TODO: implement this
},
*/

selectedNodeItem: undefined,
selectEntity: (entity?: ClapEntity) => {
if (entity) {
console.log(
'TODO julian: change this code to search in the entity collections'
)
const selectedTreeNode = get().libraryTreeRoot.find(
(node) => node.data?.id === entity.id
)

// set({ selectedTreeNode })
set({ selectedTreeNodeId: selectedTreeNode?.id || null })
set({ selectedNodeItem: entity })
} else {
// set({ selectedTreeNode: undefined })
set({ selectedTreeNodeId: null })
set({ selectedNodeItem: undefined })
}
},

// selectedTreeNode: undefined,
selectedTreeNodeId: null,
selectTreeNode: (
treeNodeId?: string | null,
nodeType?: LibraryNodeType,
nodeItem?: TreeNodeItem
) => {
set({ selectedTreeNodeId: treeNodeId ? treeNodeId : undefined })
set({ selectedNodeType: nodeType ? nodeType : undefined })
set({ selectedNodeItem: nodeItem ? nodeItem : undefined })
},
}))

useFilterTree.getState().init()
33 changes: 33 additions & 0 deletions src/components/editors/FilterEditor/FilterViewer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { FormSection } from '@/components/forms'
import { useFilterEditor, useUI } from '@/services'

export function FilterViewer() {
const current = useFilterEditor((s) => s.current)
const setCurrent = useFilterEditor((s) => s.setCurrent)
const undo = useFilterEditor((s) => s.undo)
const redo = useFilterEditor((s) => s.redo)

const hasBetaAccess = useUI((s) => s.hasBetaAccess)

if (!hasBetaAccess) {
return (
<FormSection label={'Filter Editor'} className="p-4">
Storyboard filters are WIP and not available yet.
</FormSection>
)
}

if (!current) {
return (
<FormSection label={'Filter Editor'} className="p-4">
No filter selected.
</FormSection>
)
}

return (
<FormSection label={'Filter Editor'} className="p-4">
<p>Put filter parameters</p>
</FormSection>
)
}
17 changes: 17 additions & 0 deletions src/components/editors/FilterEditor/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ReflexContainer, ReflexElement, ReflexSplitter } from 'react-reflex'
import { FilterTree } from './FilterTree'
import { FilterViewer } from './FilterViewer'

export function FilterEditor() {
return (
<ReflexContainer orientation="vertical">
<ReflexElement minSize={70} size={200}>
<FilterTree />
</ReflexElement>
<ReflexSplitter />
<ReflexElement minSize={70}>
<FilterViewer />
</ReflexElement>
</ReflexContainer>
)
}
1 change: 0 additions & 1 deletion src/components/editors/ProjectEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export function ProjectEditor() {

const current = useProjectEditor((s) => s.current)
const setCurrent = useProjectEditor((s) => s.setCurrent)
const history = useProjectEditor((s) => s.history)
const undo = useProjectEditor((s) => s.undo)
const redo = useProjectEditor((s) => s.redo)

Expand Down
1 change: 0 additions & 1 deletion src/components/editors/SegmentEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export function SegmentEditor() {
)
const current = useSegmentEditor((s) => s.current)
const setCurrent = useSegmentEditor((s) => s.setCurrent)
const history = useSegmentEditor((s) => s.history)
const undo = useSegmentEditor((s) => s.undo)
const redo = useSegmentEditor((s) => s.redo)

Expand Down
Loading

0 comments on commit 58cb97c

Please sign in to comment.