Skip to content

Commit

Permalink
FileDropper: scenePlaylist & virtualOrder
Browse files Browse the repository at this point in the history
  • Loading branch information
YeonV committed Dec 16, 2024
1 parent 15db493 commit d7cd462
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 7 deletions.
10 changes: 4 additions & 6 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEffect, useMemo } from 'react'
import { createTheme, ThemeProvider } from '@mui/material/styles'
import { SnackbarProvider } from 'notistack'
import isElectron from 'is-electron'
import { Box, CssBaseline } from '@mui/material'
import { CssBaseline } from '@mui/material'
import Cookies from 'universal-cookie'
import ws, { WsContext, HandleWs } from './utils/Websocket'
import useStore from './store/useStore'
Expand All @@ -16,6 +16,7 @@ import { ledfxThemes, ledfxTheme, common } from './themes/AppThemes'
import xmas from './assets/xmas.png'
import newyear from './assets/fireworks.jpg'
import login from './utils/login'
import FiledropProvider from './utils/FiledropProvider'

export default function App() {
const { height, width } = useWindowDimensions()
Expand Down Expand Up @@ -220,13 +221,10 @@ export default function App() {
<SnackbarProvider maxSnack={15}>
<WsContext.Provider value={ws}>
<SpotifyProvider>
<Box
sx={{ display: 'flex' }}
style={{ paddingTop: isElectron() ? '30px' : 0 }}
>
<FiledropProvider>
<CssBaseline />
<Pages handleWs={<HandleWs />} />
</Box>
</FiledropProvider>
</SpotifyProvider>
</WsContext.Provider>
{features.waves && (
Expand Down
2 changes: 1 addition & 1 deletion src/components/DnD/OrderListDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const OrderListDialog: FC<OrderListDialogProps> = ({
onOpen()
}
}
console.log('virtualOrder', virtualOrder)

const handleClose = () => {
setOpen(false)
}
Expand Down
15 changes: 15 additions & 0 deletions src/store/ui/storeDialogs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ const storeDialogs = (set: any) => ({
effectType: {
open: false,
edit: false
},
filedrop: {
open: false,
edit: false
}
},
assistant: {
Expand Down Expand Up @@ -88,6 +92,17 @@ const storeDialogs = (set: any) => ({
false,
'api/dialog/nohost'
),
setDialogOpenFileDrop: (open: boolean, edit?: boolean) =>
set(
produce((state: IStore) => {
state.dialogs.filedrop = {
open,
edit: edit || false
}
}),
false,
'api/dialog/FileDrop'
),
setDialogOpenAddScene: (
open: boolean,
edit?: boolean,
Expand Down
125 changes: 125 additions & 0 deletions src/utils/FiledropProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import {
Box,
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle
} from '@mui/material'
import { useCallback, useState } from 'react'
import isElectron from 'is-electron'
import useStore from '../store/useStore'

const FiledropProvider = ({ children }: { children: React.ReactNode }) => {
const [title, setTitle] = useState('LedFx JSON detected')
const [newData, setNewData] = useState<any>(null)
const showSnackbar = useStore((state) => state.ui.showSnackbar)
const open = useStore((state) => state.dialogs.filedrop.open)
const virtualOrder = useStore((state) => state.virtualOrder)
const setVirtualOrder = useStore((state) => state.setVirtualOrder)
const setDialogOpenFileDrop = useStore((state) => state.setDialogOpenFileDrop)
const setScenePL = useStore((state) => state.setScenePL)
const setScenePLintervals = useStore((state) => state.setScenePLintervals)

const handleJsonFile = useCallback(
async (e: any) => {
const fileReader = new FileReader()
fileReader.readAsText(e.target.files[0], 'UTF-8')
fileReader.onload = (ev: any) => {
const data = JSON.parse(ev.target.result)
if (!data) {
showSnackbar('error', 'Invalid file')
return
}
if (data.virtualOrder) {
const newOrder = data.virtualOrder
const oldVirtIds = virtualOrder.map((o: any) => o.virtId)
const newVirtIds = newOrder.map((o: any) => o.virtId)
if (
newOrder.length === virtualOrder.length &&
oldVirtIds.sort().join(',') === newVirtIds.sort().join(',')
) {
setTitle('New Device Order detected')
setNewData({ type: 'virtualOrder', data: newOrder })
setDialogOpenFileDrop(true)
} else {
showSnackbar('warning', 'Order file does not match')
}
} else if (data.scenePL || data.scenePLintervals) {
setTitle('New Scene Playlist detected')
setNewData({ type: 'scenePlaylist', data })
setDialogOpenFileDrop(true)
} else {
showSnackbar('error', 'Invalid file')
}
}
},
[setDialogOpenFileDrop, showSnackbar, virtualOrder]
)

const handleDrop = useCallback(
(e: React.DragEvent) => {
e.preventDefault()
const file = e.dataTransfer.files[0]
if (file && file.type === 'application/json') {
console.log('file', file)
handleJsonFile({ target: { files: [file] } })
} else {
showSnackbar('error', 'Please drop a valid JSON file')
}
},
[handleJsonFile, showSnackbar]
)

const handleDragOver = (e: React.DragEvent) => {
e.preventDefault()
}

const handleClose = () => {
setDialogOpenFileDrop(false)
}

const handleSave = () => {
showSnackbar('info', 'saving...')
if (newData) {
switch (newData.type) {
case 'virtualOrder':
setVirtualOrder(newData.data)
showSnackbar('success', 'Order updated')
break
case 'scenePlaylist':
if (newData.data.scenePL) setScenePL(newData.data.scenePL)
if (newData.data.scenePLintervals)
setScenePLintervals(newData.data.scenePLintervals)
showSnackbar('success', 'Scene Playlist updated')
break
default:
showSnackbar('error', 'Unknown data type')
}
}
setDialogOpenFileDrop(false)
}

return (
<Box
sx={{ display: 'flex' }}
style={{ paddingTop: isElectron() ? '30px' : 0 }}
onDrop={handleDrop}
onDragOver={handleDragOver}
>
{children}
<Dialog open={open}>
<DialogTitle>{title}</DialogTitle>
<DialogContent>
Would you like to import it and overwrite current?
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>No</Button>
<Button onClick={handleSave}>Yes</Button>
</DialogActions>
</Dialog>
</Box>
)
}

export default FiledropProvider

0 comments on commit d7cd462

Please sign in to comment.