# VO UI pre-tasks This fully plans out the prerequisite VO UI tasks that Collin and I can get started on right now: making the editor login-protected and splitting the audio panel into two to lay the foundation for future work without changing any functionality yet. Coming next: tasks for the rest! ## TASK: Make the editor login-protected ### SUBTASK: Centralize our React Router components (estimate: 0.5 days) - Create a new `app/routes/` directory - Move `app/components/AppRoutes.js` -> `app/routes/index.tsx` - Move `app/components/AccountRouter.js` -> `app/routes/AccountRouter.tsx` - Move `app/components/ShopRouter.js` -> `app/routes/ShopRouter.tsx` - Move `app/components/VideosRouter.js` -> `app/routes/VideosRouter.tsx` - Move `app/components/RootRouter.js` -> `app/routes/RootRouter.tsx` - Update imports for all of the old components as needed ### SUBTASK: Refactor `EnsureLoggedInContainer` component and wrap the editor's routes with it (estimate: 0.5 days) - Replace `app/components/EnsureLoggedInContainer.js` with `app/routes/components/EnsureLoggedInRedirect.tsx` - `EnsureLoggedInRedirectProps`: - children: React.ReactNode - `EnsureLoggedInRedirect` component - isLoggedIn = useSelectors(selectors.isLoggedIn) - useEffect - if !isLoggedIn - dispatch(loginActionActions.addLoginAction(...)) so we will navigate back to whatever the current url pathname is after the user successfully logs in - goToInternalURL(appURLs.login) - If isLoggedIn, return children, otherwise return null - Wrap the route for the editor pages in `app/routes/index.tsx` with `<EnsureLoggedInRedirect>` ### SUBTASK: Update template browser editor links to be login-protected (estimate: 0.5 days) - Update the `TemplateBrowserVariantListItem` component in `app/components/TemplateBrowserVariantListItem.js` - attemptLoginProtectedAction = useAttemptLoginProtectedAction() - Change the `<InternalLink>` component -> `<WaymarkButton>` - onClick = `attemptLoginProtectedAction(() => goToInternalURL(appURLs.editVariant(...)))` ## TASK: Split the audio control panel in two ### SUBTASK: Update the main editor control panel's buttons to match new styles (estimate: 0.5 days) - Update `editor/components/EditorMainControlPanel.tsx` - Remove `FootageCompositionPanelButton`, `FontPanelButton`, `AudioPanelButton`, and `ColorPanelButton` components - Make editor panel keys - Convert `editor/constants/Editor.js` to TS and make editor panel keys type safe - `export const editorPanelKeys = { ... } as const` - `export type EditorPanelKey = typeof editorPanelKeys[keyof typeof editorPanelKeys]` - Update imports to reflect the new TS extension - Add new `ControlPanelButton` component - `ControlPanelButtonProps` - panelKey: EditorPanelKey - Key for the editor panel which this button should open when clicked - icon: React.ReactNode - SVG icon to display in the button - buttonText: string - Text to display under the icon - Update `PanelButtons` component - panelButtonProps: `Array<ControlPanelButtonProps>` = useMemo() - Make an array and push a ControlPanelButtonProps object onto the array for each field that we need to include a button for - Return a div which wraps the buttons - data-hasoddchildcount = panelButtonProps length is odd - Styled with CSS grid - grid-template-columns: repeat(2, 1fr) - `[data-hasoddchildcount="true"] { grid-template-columns: repeat(3, 1fr) }` - `panelButtonProps.map(({ panelKey, icon, buttonText }) => <ControlPanelButton key={panelKey} ... />)` ### SUBTASK: Break EditorAudioControlPanel into MusicControlPanel and VoiceOverControlPanel (estimate: 1-2 days) - Update `editor/providers/EditorFormDescriptionProvider.js` - We need to split the behavior in the `useResetToDefaultConfigurationValue` hook from `getRichAudioField` since it currently touches both the background AND VO tracks at the same time - Add 2 new hooks: - `useResetBackgroundAudioToDefault` - Don't touch auxiliary audio or volume, just reset the backgroundAudio to default - `useResetAuxiliaryAudioToDefault` - Remove auxiliary audio track and reset volume - `editor/constants/Editor.ts` - Remove "audio", and "restoreRemovedAudio" from `editorPanelKeys` - Add "music", "voiceOverUpload", and "restoreRemovedVoiceOver" to `editorPanelKeys` - `editor/components/panels/Music/` - `index.tsx` - export default makeEditorControlPanel(MusicPanelHeader, MusicPanelControls); - `PanelHeader.tsx` - Copy `EditorAudioHeader` from `editor/components/EditorAudioControlPanel.js` file as a starting point - `EditorAudioHeader` -> `PanelHeader` - Remove everything related to `EditorPanelTabButtons` - `useResetBackgroundAudioToDefault` - `PanelControls.tsx` - Copy `EditorAudioControls` from `editor/components/EditorAudioControlPanel.js` file as a starting point - `EditorAudioControls` -> `PanelControls` - Remove everything tab-related - Copy the contents of `EditorBackgroundAudioTab` and inline them in this `PanelControls` component; adjust as needed, but probably doesn't need much more work - `editor/components/panels/VoiceOverUpload/` - `index.tsx` - export default makeEditorControlPanel(VoiceOverUploadPanelHeader, VoiceOverUploadPanelControls); - `PanelHeader.tsx` - Copy `EditorAudioHeader` from `editor/components/EditorAudioControlPanel.js` file as a starting point - `EditorAudioHeader` -> `PanelHeader` - Remove everything related to `EditorPanelTabButtons` - `useResetAuxiliaryAudioToDefault` - `PanelControls.tsx` - Copy `EditorAudioControls` from `editor/components/EditorAudioControlPanel.js` file as a starting point - `EditorAudioControls` -> `PanelControls` - Remove everything tab-related - Copy the contents of `EditorVoiceOverAudioTab` and inline them in this `PanelControls` component; adjust as needed - Update the `EditorModeButton` at the bottom of the panel - Remove onClick in favor of `targetMode={editorPanelKeys.restoreRemovedVoiceOver}` - The analytics action on this button is wrong so let's fix that too - Update `editor/constants/EditorControlPanels.js` to register these new panels for their panel keys - Update `EditorMainControlPanel.tsx` to remove the old audio panel button in favor of our two new split panels - Make sure the VO button is only rendered if the user has VO permissions