feat: add qwenlm minapp

This commit is contained in:
kangfenmao 2025-01-13 13:52:45 +08:00
parent 49a5bc7900
commit 3998ad08de
11 changed files with 71 additions and 59 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,39 @@
import { DEFAULT_MIN_APPS } from '@renderer/config/minapps'
import { MinAppType } from '@renderer/types'
import { FC } from 'react'
import styled from 'styled-components'
interface Props {
app: MinAppType
size?: number
style?: React.CSSProperties
}
const MinAppIcon: FC<Props> = ({ app, size = 48, style }) => {
const _app = DEFAULT_MIN_APPS.find((item) => item.id === app.id)
if (!_app) {
return null
}
return (
<Container
src={_app.logo}
style={{
border: _app.bodered ? '0.5px solid var(--color-border)' : 'none',
width: `${size}px`,
height: `${size}px`,
backgroundColor: _app.background,
...style
}}
/>
)
}
const Container = styled.img`
border-radius: 16px;
user-select: none;
-webkit-user-drag: none;
`
export default MinAppIcon

View File

@ -1,11 +1,10 @@
import { Center } from '@renderer/components/Layout' import { Center } from '@renderer/components/Layout'
import { getAllMinApps } from '@renderer/config/minapps' import { useMinapps } from '@renderer/hooks/useMinapps'
import { useSettings } from '@renderer/hooks/useSettings'
import App from '@renderer/pages/apps/App' import App from '@renderer/pages/apps/App'
import { Popover } from 'antd' import { Popover } from 'antd'
import { Empty } from 'antd' import { Empty } from 'antd'
import { isEmpty } from 'lodash' import { isEmpty } from 'lodash'
import { FC, useMemo, useState } from 'react' import { FC, useState } from 'react'
import { useHotkeys } from 'react-hotkeys-hook' import { useHotkeys } from 'react-hotkeys-hook'
import styled from 'styled-components' import styled from 'styled-components'
@ -15,16 +14,9 @@ interface Props {
children: React.ReactNode children: React.ReactNode
} }
const AppStorePopover: FC<Props> = ({ children }) => { const MinAppsPopover: FC<Props> = ({ children }) => {
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const { miniAppIcons } = useSettings() const { minapps } = useMinapps()
const allApps = useMemo(() => getAllMinApps(), [])
// 只显示可见的小程序
const visibleApps = useMemo(() => {
if (!miniAppIcons?.visible) return allApps
return allApps.filter((app) => miniAppIcons.visible.includes(app.id))
}, [allApps, miniAppIcons?.visible])
useHotkeys('esc', () => { useHotkeys('esc', () => {
setOpen(false) setOpen(false)
@ -37,10 +29,10 @@ const AppStorePopover: FC<Props> = ({ children }) => {
const content = ( const content = (
<PopoverContent> <PopoverContent>
<AppsContainer> <AppsContainer>
{visibleApps.map((app) => ( {minapps.map((app) => (
<App key={app.id} app={app} onClick={handleClose} size={50} /> <App key={app.id} app={app} onClick={handleClose} size={50} />
))} ))}
{isEmpty(visibleApps) && ( {isEmpty(minapps) && (
<Center> <Center>
<Empty /> <Empty />
</Center> </Center>
@ -70,4 +62,4 @@ const AppsContainer = styled.div`
gap: 18px; gap: 18px;
` `
export default AppStorePopover export default MinAppsPopover

View File

@ -16,6 +16,7 @@ import { useLocation, useNavigate } from 'react-router-dom'
import styled from 'styled-components' import styled from 'styled-components'
import DragableList from '../DragableList' import DragableList from '../DragableList'
import MinAppIcon from '../Icons/MinAppIcon'
import MinApp from '../MinApp' import MinApp from '../MinApp'
import UserPopup from '../Popups/UserPopup' import UserPopup from '../Popups/UserPopup'
@ -149,14 +150,7 @@ const PinnedApps: FC = () => {
<StyledLink> <StyledLink>
<Dropdown menu={{ items: menuItems }} trigger={['contextMenu']}> <Dropdown menu={{ items: menuItems }} trigger={['contextMenu']}>
<Icon onClick={() => MinApp.start(app)}> <Icon onClick={() => MinApp.start(app)}>
<AppIcon <MinAppIcon size={20} app={app} style={{ borderRadius: 6 }} />
src={app.logo}
style={{
width: '20px',
height: '20px',
border: app.bodered ? '0.5px solid var(--color-border)' : 'none'
}}
/>
</Icon> </Icon>
</Dropdown> </Dropdown>
</StyledLink> </StyledLink>
@ -246,10 +240,6 @@ const StyledLink = styled.div`
} }
` `
const AppIcon = styled.img`
border-radius: 6px;
`
const AppsContainer = styled.div` const AppsContainer = styled.div`
display: flex; display: flex;
flex: 1; flex: 1;

View File

@ -17,6 +17,7 @@ import NamiAiSearchLogo from '@renderer/assets/images/apps/nm.webp'
import PerplexityAppLogo from '@renderer/assets/images/apps/perplexity.webp' import PerplexityAppLogo from '@renderer/assets/images/apps/perplexity.webp'
import PoeAppLogo from '@renderer/assets/images/apps/poe.webp' import PoeAppLogo from '@renderer/assets/images/apps/poe.webp'
import ZhipuProviderLogo from '@renderer/assets/images/apps/qingyan.png' import ZhipuProviderLogo from '@renderer/assets/images/apps/qingyan.png'
import QwenlmAppLogo from '@renderer/assets/images/apps/qwenlm.webp'
import SensetimeAppLogo from '@renderer/assets/images/apps/sensetime.png' import SensetimeAppLogo from '@renderer/assets/images/apps/sensetime.png'
import SparkDeskAppLogo from '@renderer/assets/images/apps/sparkdesk.png' import SparkDeskAppLogo from '@renderer/assets/images/apps/sparkdesk.png'
import ThinkAnyLogo from '@renderer/assets/images/apps/thinkany.webp' import ThinkAnyLogo from '@renderer/assets/images/apps/thinkany.webp'
@ -35,7 +36,7 @@ import SiliconFlowProviderLogo from '@renderer/assets/images/providers/silicon.p
import MinApp from '@renderer/components/MinApp' import MinApp from '@renderer/components/MinApp'
import { MinAppType } from '@renderer/types' import { MinAppType } from '@renderer/types'
const _apps: MinAppType[] = [ export const DEFAULT_MIN_APPS: MinAppType[] = [
{ {
id: 'openai', id: 'openai',
name: 'ChatGPT', name: 'ChatGPT',
@ -253,14 +254,16 @@ const _apps: MinAppType[] = [
logo: GrokAppLogo, logo: GrokAppLogo,
url: 'https://x.com/i/grok', url: 'https://x.com/i/grok',
bodered: true bodered: true
},
{
id: 'qwenlm',
name: 'QwenLM',
logo: QwenlmAppLogo,
url: 'https://qwenlm.ai/'
} }
] ]
export function getAllMinApps() {
return _apps as MinAppType[]
}
export function startMinAppById(id: string) { export function startMinAppById(id: string) {
const app = getAllMinApps().find((app) => app?.id === id) const app = DEFAULT_MIN_APPS.find((app) => app?.id === id)
app && MinApp.start(app) app && MinApp.start(app)
} }

View File

@ -1,3 +1,4 @@
import MinAppIcon from '@renderer/components/Icons/MinAppIcon'
import MinApp from '@renderer/components/MinApp' import MinApp from '@renderer/components/MinApp'
import { useMinapps } from '@renderer/hooks/useMinapps' import { useMinapps } from '@renderer/hooks/useMinapps'
import { MinAppType } from '@renderer/types' import { MinAppType } from '@renderer/types'
@ -40,14 +41,7 @@ const App: FC<Props> = ({ app, onClick, size = 60 }) => {
return ( return (
<Dropdown menu={{ items: menuItems }} trigger={['contextMenu']}> <Dropdown menu={{ items: menuItems }} trigger={['contextMenu']}>
<Container onClick={handleClick}> <Container onClick={handleClick}>
<AppIcon <MinAppIcon size={size} app={app} />
src={app.logo}
style={{
border: app.bodered ? '0.5px solid var(--color-border)' : 'none',
width: `${size}px`,
height: `${size}px`
}}
/>
<AppTitle>{app.name}</AppTitle> <AppTitle>{app.name}</AppTitle>
</Container> </Container>
</Dropdown> </Dropdown>
@ -63,12 +57,6 @@ const Container = styled.div`
overflow: hidden; overflow: hidden;
` `
const AppIcon = styled.img`
border-radius: 16px;
user-select: none;
-webkit-user-drag: none;
`
const AppTitle = styled.div` const AppTitle = styled.div`
font-size: 12px; font-size: 12px;
margin-top: 5px; margin-top: 5px;

View File

@ -1,7 +1,7 @@
import { FormOutlined, SearchOutlined } from '@ant-design/icons' import { FormOutlined, SearchOutlined } from '@ant-design/icons'
import { Navbar, NavbarLeft, NavbarRight } from '@renderer/components/app/Navbar' import { Navbar, NavbarLeft, NavbarRight } from '@renderer/components/app/Navbar'
import { HStack } from '@renderer/components/Layout' import { HStack } from '@renderer/components/Layout'
import AppStorePopover from '@renderer/components/Popups/AppStorePopover' import MinAppsPopover from '@renderer/components/Popups/MinAppsPopover'
import SearchPopup from '@renderer/components/Popups/SearchPopup' import SearchPopup from '@renderer/components/Popups/SearchPopup'
import { isMac, isWindows } from '@renderer/config/constant' import { isMac, isWindows } from '@renderer/config/constant'
import { useAssistant } from '@renderer/hooks/useAssistant' import { useAssistant } from '@renderer/hooks/useAssistant'
@ -84,11 +84,11 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant }) => {
<i className="iconfont icon-icon-adaptive-width"></i> <i className="iconfont icon-icon-adaptive-width"></i>
</NarrowIcon> </NarrowIcon>
{sidebarIcons.visible.includes('minapp') && ( {sidebarIcons.visible.includes('minapp') && (
<AppStorePopover> <MinAppsPopover>
<NarrowIcon> <NarrowIcon>
<i className="iconfont icon-appstore" /> <i className="iconfont icon-appstore" />
</NarrowIcon> </NarrowIcon>
</AppStorePopover> </MinAppsPopover>
)} )}
{topicPosition === 'right' && ( {topicPosition === 'right' && (
<NarrowIcon onClick={toggleShowTopics}> <NarrowIcon onClick={toggleShowTopics}>

View File

@ -1,5 +1,5 @@
import { isMac } from '@renderer/config/constant' import { isMac } from '@renderer/config/constant'
import { getAllMinApps } from '@renderer/config/minapps' import { DEFAULT_MIN_APPS } from '@renderer/config/minapps'
import { useTheme } from '@renderer/context/ThemeProvider' import { useTheme } from '@renderer/context/ThemeProvider'
import { useMinapps } from '@renderer/hooks/useMinapps' import { useMinapps } from '@renderer/hooks/useMinapps'
import { useSettings } from '@renderer/hooks/useSettings' import { useSettings } from '@renderer/hooks/useSettings'
@ -59,9 +59,9 @@ const DisplaySettings: FC = () => {
}, [dispatch]) }, [dispatch])
const handleResetMinApps = useCallback(() => { const handleResetMinApps = useCallback(() => {
setVisibleMiniApps(getAllMinApps()) setVisibleMiniApps(DEFAULT_MIN_APPS)
setDisabledMiniApps([]) setDisabledMiniApps([])
updateMinapps(getAllMinApps()) updateMinapps(DEFAULT_MIN_APPS)
updateDisabledMinapps([]) updateDisabledMinapps([])
}, [updateDisabledMinapps, updateMinapps]) }, [updateDisabledMinapps, updateMinapps])

View File

@ -7,10 +7,10 @@ import {
DroppableProvided, DroppableProvided,
DropResult DropResult
} from '@hello-pangea/dnd' } from '@hello-pangea/dnd'
import { getAllMinApps } from '@renderer/config/minapps' import { DEFAULT_MIN_APPS } from '@renderer/config/minapps'
import { useMinapps } from '@renderer/hooks/useMinapps' import { useMinapps } from '@renderer/hooks/useMinapps'
import { MinAppType } from '@renderer/types' import { MinAppType } from '@renderer/types'
import { FC, useCallback, useMemo } from 'react' import { FC, useCallback } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import styled from 'styled-components' import styled from 'styled-components'
@ -74,7 +74,6 @@ const MiniAppIconsManager: FC<MiniAppManagerProps> = ({
setDisabledMiniApps setDisabledMiniApps
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
const allApps = useMemo(() => getAllMinApps(), [])
const { pinned, updateMinapps, updateDisabledMinapps, updatePinnedMinapps } = useMinapps() const { pinned, updateMinapps, updateDisabledMinapps, updatePinnedMinapps } = useMinapps()
const handleListUpdate = useCallback( const handleListUpdate = useCallback(
@ -130,7 +129,7 @@ const MiniAppIconsManager: FC<MiniAppManagerProps> = ({
) )
const renderProgramItem = (program: MinAppType, provided: DraggableProvided, listType: ListType) => { const renderProgramItem = (program: MinAppType, provided: DraggableProvided, listType: ListType) => {
const { name, logo } = allApps.find((app) => app.id === program.id) || { name: program.name, logo: '' } const { name, logo } = DEFAULT_MIN_APPS.find((app) => app.id === program.id) || { name: program.name, logo: '' }
return ( return (
<ProgramItem ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}> <ProgramItem ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>

View File

@ -1,5 +1,5 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit' import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import { getAllMinApps } from '@renderer/config/minapps' import { DEFAULT_MIN_APPS } from '@renderer/config/minapps'
import { MinAppType, SidebarIcon } from '@renderer/types' import { MinAppType, SidebarIcon } from '@renderer/types'
export const DEFAULT_SIDEBAR_ICONS: SidebarIcon[] = [ export const DEFAULT_SIDEBAR_ICONS: SidebarIcon[] = [
@ -19,7 +19,7 @@ export interface MinAppsState {
} }
const initialState: MinAppsState = { const initialState: MinAppsState = {
enabled: getAllMinApps(), enabled: DEFAULT_MIN_APPS,
disabled: [], disabled: [],
pinned: [] pinned: []
} }

View File

@ -134,6 +134,7 @@ export type MinAppType = {
logo: string logo: string
url: string url: string
bodered?: boolean bodered?: boolean
background?: string
} }
export interface FileType { export interface FileType {