Skip to content

Commit

Permalink
Reordering apps is now possible
Browse files Browse the repository at this point in the history
  • Loading branch information
ItsRiprod committed Sep 18, 2024
1 parent 5ff0e05 commit 33d089d
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 105 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Icon } from '.'

function IconArrowLeft(props): JSX.Element {
return (
<Icon {...props}>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="m15 18-6-6 6-6" />
</svg>
</Icon>
)
}

export default IconArrowLeft
13 changes: 13 additions & 0 deletions DeskThingServer/src/renderer/src/assets/icons/icon/IconArrowUp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Icon } from '.'

function IconArrowUp(props): JSX.Element {
return (
<Icon {...props}>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="m18 15-6-6-6 6" />
</svg>
</Icon>
)
}

export default IconArrowUp
2 changes: 2 additions & 0 deletions DeskThingServer/src/renderer/src/assets/icons/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export { default as IconArrowRight } from './icon/IconArrowRight'
export { default as IconArrowLeft } from './icon/IconArrowLeft'
export { default as IconArrowUp } from './icon/IconArrowUp'
export { default as IconArrowDown } from './icon/IconArrowDown'
export { default as IconBell } from './icon/IconBell'
export { default as IconRefresh } from './icon/IconRefresh'
Expand Down
63 changes: 55 additions & 8 deletions DeskThingServer/src/renderer/src/components/AppComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { useEffect, useState } from 'react'
import { App as AppType } from '../store/appStore'
import { IconX, IconPause, IconPlay, IconDetails, IconPulsing, IconLogoGear } from '../assets/icons'
import { appStoreInstance, App as AppType } from '../store/appStore'
import {
IconX,
IconPause,
IconPlay,
IconDetails,
IconPulsing,
IconLogoGear,
IconArrowUp,
IconArrowDown
} from '../assets/icons'
import RequestStoreInstance, { Request } from '../store/requestStore'
import AppRequestOverlay from '../overlays/AppRequest'

Expand All @@ -9,9 +18,9 @@ export type View = 'apps' | 'local' | 'web'
interface AppProps {
app: AppType
appIndex: number
setEnabled: (boolean) => void
setSEnabled: (boolean) => void
setAppIndex: (number) => void
setEnabled: (val: boolean) => void
setSEnabled: (val: boolean) => void
setAppIndex: (index: number) => void
}

const AppComponent = ({
Expand All @@ -25,6 +34,7 @@ const AppComponent = ({
const [appsWithActiveRequests, setAppsWithActiveRequests] = useState<string[]>([])
const [currentRequest, setCurrentRequest] = useState<[string, Request | null]>(['', null])
const [displayRequest, setDisplayRequest] = useState(false)
const [swapping, setSwapping] = useState(0)

const handleAddAndRunApp = (appName: string): void => {
window.electron.ipcRenderer.send('add-app', appName)
Expand All @@ -46,7 +56,7 @@ const AppComponent = ({
setAppIndex(appIndex)
setSEnabled(true)
}
const requestAppsList = (): void => window.electron.ipcRenderer.send('get-apps')
const requestAppsList = (): void => appStoreInstance.requestApps()

useEffect(() => {
// Subscribe to changes in request status
Expand Down Expand Up @@ -77,8 +87,31 @@ const AppComponent = ({
}
}

const handleMove = (val: number): void => {
setSwapping(val)
setTimeout(() => {
const order = appStoreInstance.getOrder()
const newOrder = [...order]
const temp = newOrder[appIndex]
newOrder[appIndex] = newOrder[appIndex + val]
newOrder[appIndex + val] = temp
appStoreInstance.setOrder(newOrder)
setSwapping(0)
}, 200) // Adjust this timing to match the CSS animation duration
}

const handleMoveUp = (): void => {
handleMove(-1)
}

const handleMoveDown = (): void => {
handleMove(1)
}

return (
<div className="h-vh w-[100%] flex flex-col justify-between items-center">
<div
className={`h-vh w-[100%] flex flex-col justify-between items-center transition-transform duration-200 ${swapping != 0 && (swapping == -1 ? '-translate-y-full' : 'translate-y-full')}`}
>
<div className="pt-5 w-full flex justify-center">
{displayRequest && currentRequest[1] && currentRequest[0] && (
<AppRequestOverlay
Expand All @@ -87,8 +120,22 @@ const AppComponent = ({
onClose={() => setDisplayRequest(false)}
/>
)}
<div className="border-2 border-zinc-400 p-5 w-11/12 md:w-11/12 xl:w-fit xl:gap-5 h-fit flex justify-between rounded-3xl shadow-lg px-5 items-center">
<div
className={`border-2 border-zinc-400 p-5 w-11/12 md:w-11/12 xl:w-fit xl:gap-5 h-fit flex justify-between rounded-3xl shadow-lg px-5 items-center`}
>
<div className="flex flex-wrap sm:flex-nowrap gap-2 xl:mr-2">
<div className="flex flex-col">
<button
className="text-sm"
onClick={handleMoveUp}
disabled={appIndex === 0 || swapping != 0}
>
<IconArrowUp />
</button>
<button className="text-sm" onClick={handleMoveDown} disabled={swapping != 0}>
<IconArrowDown />
</button>
</div>
<button
className="group h-fit flex gap-2 border-2 border-gray-500 hover:bg-gray-500 text-gray-400 hover:text-gray-200 p-2 rounded-lg"
onClick={() => handleSettings(appIndex)}
Expand Down
62 changes: 20 additions & 42 deletions DeskThingServer/src/renderer/src/pages/Apps/Apps.tsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,30 @@
import { useEffect, useRef, useState } from 'react'
import { useAppStore, App } from '../../store/appStore'
import { useEffect, useState } from 'react'
import { App, appStoreInstance } from '../../store/appStore'
import DisplayAppData from '../../overlays/DisplayAppData'
import AppSettingsOverlay from '../../overlays/AppSettingsOverlay'
import AppComponent from '../../components/AppComponent'
export type View = 'apps' | 'local' | 'web'

const Apps = (): JSX.Element => {
const { appsList, setAppList } = useAppStore()
const [appsList, setAppList] = useState<App[]>(appStoreInstance.getAppsList())
const [enabled, setEnabled] = useState(false)
const [sEnabled, setSEnabled] = useState(false)
const [appIndex, setAppIndex] = useState(1)
const dragItem = useRef<number | null>(null)
const dragOverItem = useRef<number | null>(null)

const requestAppsList = (): void => window.electron.ipcRenderer.send('get-apps')
const requestAppsList = (): void => appStoreInstance.requestApps()

useEffect(() => {
requestAppsList()
}, [])

const handleDragStart = (index: number) => {
dragItem.current = index
}
const onAppStoreUpdate = (apps: App[]): void => {
setAppList(apps)
}

const handleDragEnter = (index: number) => {
dragOverItem.current = index
}
const removeAppListener = appStoreInstance.on('update', onAppStoreUpdate)
requestAppsList()

const handleDragEnd = () => {
if (dragItem.current !== null && dragOverItem.current !== null) {
const copyListItems = [...appsList]
const dragItemContent = copyListItems[dragItem.current]
copyListItems.splice(dragItem.current, 1)
copyListItems.splice(dragOverItem.current, 0, dragItemContent)
dragItem.current = null
dragOverItem.current = null
setAppList(copyListItems)
return () => {
removeAppListener()
}
}
}, [])

return (
<div className="h-vh w-[100%] flex flex-col justify-between items-center">
Expand All @@ -47,25 +34,16 @@ const Apps = (): JSX.Element => {
<AppSettingsOverlay appIndex={appIndex} setEnabled={setSEnabled} data={appsList} />
)}
{appsList?.length > 0 && Object.keys(appsList).length > 0 ? (
<div className="pt-5 w-full flex xl:flex-row xl:flex-wrap xl:gap-5 xl:px-5 flex-col items-center gap-2">
<div className="pt-5 w-full flex xl:flex-row xl:flex-wrap xl:gap-5 xl:px-5 flex-col items-center">
{(appsList as App[]).map((app, index) => (
<div
<AppComponent
key={index}
draggable
onDragStart={() => handleDragStart(index)}
onDragEnter={() => handleDragEnter(index)}
onDragEnd={handleDragEnd}
onDragOver={(e) => e.preventDefault()}
className="w-full"
>
<AppComponent
appIndex={index}
app={app}
setSEnabled={setSEnabled}
setEnabled={setEnabled}
setAppIndex={setAppIndex}
/>
</div>
appIndex={index}
app={app}
setSEnabled={setSEnabled}
setEnabled={setEnabled}
setAppIndex={setAppIndex}
/>
))}
</div>
) : (
Expand Down
11 changes: 9 additions & 2 deletions DeskThingServer/src/renderer/src/pages/Dev/Apps.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react'
import { useAppStore, App } from '../../store/appStore'
import { App, appStoreInstance } from '../../store/appStore'
import { IconX, IconPause, IconPlay, IconDetails, IconPulsing } from '../../assets/icons'
import DisplayAppData from '../../overlays/DisplayAppData'
import RequestStoreInstance, { Request } from '../../store/requestStore'
Expand All @@ -8,7 +8,7 @@ import AppRequestOverlay from '../../overlays/AppRequest'
export type View = 'apps' | 'local' | 'web'

const Apps = (): JSX.Element => {
const { appsList } = useAppStore()
const [appsList, setAppsList] = useState<App[]>(appStoreInstance.getAppsList())
const [app, setApp] = useState<App>()
const [tooltips, setTooltips] = useState<string[]>([])
const [enabled, setEnabled] = useState(false)
Expand Down Expand Up @@ -51,13 +51,20 @@ const Apps = (): JSX.Element => {
setAppsWithActiveRequests(appsWithActiveRequests)
}

const onAppStoreUpdate = (apps: App[]): void => {
setAppsList(apps)
}

const removeAppListener = appStoreInstance.on('update', onAppStoreUpdate)

onRequestUpdate(RequestStoreInstance.getQueue()) // Get initial queue of requests

RequestStoreInstance.on('request', onRequestUpdate)

return () => {
// Clean up the subscription on unmount
RequestStoreInstance.off('request', onRequestUpdate)
removeAppListener()
}
}, [appsList])

Expand Down
Loading

0 comments on commit 33d089d

Please sign in to comment.