Faisal Amir faa09bd2bf
feat: Dekstop Revamp (#2877)
* feat: desktop revamp

* feat: refactor system monitor

* fix linter CI

* remove unused import component

* added responsive and resizeable component

* responsive and resizeable local server page

* finalize responsive and resizeable component

* fix scroll custom ui

* remove react scroll to bottom from modal troubleshoot

* fix modal troubleshoot ui

* fix setting gpu list

* text area custom scroll bar

* fix padding message input

* cleanup classname

* update inference engine model dropdown

* update loader style

* update quick ask ui

* prepare theme provider

* update dark theme

* remove update hotkey list model and navigation

* fix: cleanup hardcode classname

* fix: update feedback

* Set native theme electron

* update destop ui revamp from feedback

* update button icon component insider icon chat input message

* update model dropdown ui

* update tranaparent baclground

* update logo model provider

* fix: set background material acrylic support to blur background windows

* fix: update tranparent left and right panel

* fix: linter CI

* update app using frameless window

* styling custom style minimize, maximize and close app

* temporary hidden maximize window

* fix: responsive left and right panel

* fix: enable click outside when leftpanel responsive

* fix: remove unused import

* update transparent variable css windows

* fix: ui import model

* feat: Support Theme system (#2946)

* feat: update support theme system

* update select component

* feat: add theme folder in root project

* fix: padding left and right center panel

* fix: update padding left and right

* chore: migrate themes

* fix: rmdirsync error

* chore: update gitignore

* fix: cp recursive

* fix: files electron package json

* fix: migration

* fix: update fgit ignore

---------

Co-authored-by: Louis <louis@jan.ai>

* fix: update feedback missing state when refrash app

* fix: error test CI

* chore: refactor useLoadThemes

* chore: cleanup unused vars

* fix: revert back menubar windows

* fix minor ui

* fix: minor ui

---------

Co-authored-by: Louis <louis@jan.ai>
2024-05-29 13:37:18 +07:00

121 lines
4.0 KiB
TypeScript

import { Tooltip, useMediaQuery } from '@janhq/joi'
import { motion as m } from 'framer-motion'
import { useAtom, useAtomValue, useSetAtom } from 'jotai'
import {
MessageCircleIcon,
SettingsIcon,
LayoutGridIcon,
SquareCodeIcon,
} from 'lucide-react'
import { twMerge } from 'tailwind-merge'
import { MainViewState } from '@/constants/screens'
import { mainViewStateAtom, showLeftPanelAtom } from '@/helpers/atoms/App.atom'
import { editMessageAtom } from '@/helpers/atoms/ChatMessage.atom'
import { serverEnabledAtom } from '@/helpers/atoms/LocalServer.atom'
import {
reduceTransparentAtom,
selectedSettingAtom,
} from '@/helpers/atoms/Setting.atom'
export default function RibbonPanel() {
const [mainViewState, setMainViewState] = useAtom(mainViewStateAtom)
const [serverEnabled] = useAtom(serverEnabledAtom)
const setEditMessage = useSetAtom(editMessageAtom)
const showLeftPanel = useAtomValue(showLeftPanelAtom)
const matches = useMediaQuery('(max-width: 880px)')
const reduceTransparent = useAtomValue(reduceTransparentAtom)
const setSelectedSetting = useSetAtom(selectedSettingAtom)
const onMenuClick = (state: MainViewState) => {
if (mainViewState === state) return
if (serverEnabled && state === MainViewState.Thread) return
if (state === MainViewState.Settings) setSelectedSetting('My Models')
setMainViewState(state)
setEditMessage('')
}
const RibbonNavMenus = [
{
name: 'Thread',
icon: <MessageCircleIcon size={18} className="flex-shrink-0" />,
state: MainViewState.Thread,
},
{
name: 'Hub',
icon: <LayoutGridIcon size={18} className="flex-shrink-0" />,
state: MainViewState.Hub,
},
{
name: 'Local API Server',
icon: <SquareCodeIcon size={18} className="flex-shrink-0" />,
state: MainViewState.LocalServer,
},
{
name: 'Settings',
icon: <SettingsIcon size={18} className="flex-shrink-0" />,
state: MainViewState.Settings,
},
]
return (
<div
className={twMerge(
'relative top-0 flex h-full w-12 flex-shrink-0 flex-col items-center border-r border-[hsla(var(--app-border))] py-2',
mainViewState === MainViewState.Hub &&
!reduceTransparent &&
'border-none',
!showLeftPanel && !reduceTransparent && 'border-none',
matches && !reduceTransparent && 'border-none',
reduceTransparent && ' bg-[hsla(var(--ribbon-panel-bg))]'
)}
>
{RibbonNavMenus.filter((menu) => !!menu).map((menu, i) => {
const isActive = mainViewState === menu.state
return (
<div
className={twMerge(
'relative my-0.5 flex h-8 w-8 items-center justify-center rounded-md hover:bg-[hsla(var(--ribbon-panel-icon-hover))]',
i === 1 && 'mb-auto'
)}
key={i}
>
<Tooltip
side="right"
disabled={mainViewState === menu.state}
trigger={
<div>
<div
data-testid={menu.name}
className={twMerge(
'relative flex w-full flex-shrink-0 cursor-pointer items-center justify-center text-[hsla(var(--ribbon-panel-icon))] ',
isActive &&
'z-10 text-[hsla(var(--ribbon-panel-icon-active))]'
)}
onClick={() => onMenuClick(menu.state)}
>
{menu.icon}
</div>
{isActive && (
<m.div
className="absolute inset-0 left-0 h-full w-full rounded-md bg-[hsla(var(--ribbon-panel-icon-active-bg))]"
layoutId="active-state-menu"
/>
)}
</div>
}
content={
serverEnabled && menu.state === MainViewState.Thread
? 'Threads are disabled while the server is running'
: menu.name
}
/>
</div>
)
})}
</div>
)
}