feat: MinApp added to the sidebar does not support direct hiding.
This commit is contained in:
parent
ad9fb9aa6d
commit
7633d70435
@ -1,10 +1,11 @@
|
||||
import { Center } from '@renderer/components/Layout'
|
||||
import { getAllMinApps } from '@renderer/config/minapps'
|
||||
import { useSettings } from '@renderer/hooks/useSettings'
|
||||
import App from '@renderer/pages/apps/App'
|
||||
import { Popover } from 'antd'
|
||||
import { Empty } from 'antd'
|
||||
import { isEmpty } from 'lodash'
|
||||
import { FC, useState } from 'react'
|
||||
import { FC, useMemo, useState } from 'react'
|
||||
import { useHotkeys } from 'react-hotkeys-hook'
|
||||
import styled from 'styled-components'
|
||||
|
||||
@ -16,7 +17,14 @@ interface Props {
|
||||
|
||||
const AppStorePopover: FC<Props> = ({ children }) => {
|
||||
const [open, setOpen] = useState(false)
|
||||
const apps = getAllMinApps()
|
||||
const { miniAppIcons } = useSettings()
|
||||
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', () => {
|
||||
setOpen(false)
|
||||
@ -29,10 +37,10 @@ const AppStorePopover: FC<Props> = ({ children }) => {
|
||||
const content = (
|
||||
<PopoverContent>
|
||||
<AppsContainer>
|
||||
{apps.map((app) => (
|
||||
{visibleApps.map((app) => (
|
||||
<App key={app.id} app={app} onClick={handleClose} size={50} />
|
||||
))}
|
||||
{isEmpty(apps) && (
|
||||
{isEmpty(visibleApps) && (
|
||||
<Center>
|
||||
<Empty />
|
||||
</Center>
|
||||
|
||||
@ -411,6 +411,7 @@
|
||||
"display.minApp.visible": "Visible MinApp",
|
||||
"display.minApp.disabled": "Hidden MinApp",
|
||||
"display.minApp.empty": "Drag minApp from the left to hide them here",
|
||||
"display.minApp.pinnedError": "MinApp that have been added to the sidebar do not support hiding. If you want to hide them, please remove them from the sidebar first.",
|
||||
"display.topic.title": "Topic Settings",
|
||||
"display.custom.css": "Custom CSS",
|
||||
"display.custom.css.placeholder": "/* Put custom CSS here */",
|
||||
|
||||
@ -412,6 +412,7 @@
|
||||
"display.minApp.visible": "表示中ミニプログラム",
|
||||
"display.minApp.disabled": "非表示ミニプログラム",
|
||||
"display.minApp.empty": "非表示にしたいアプレットを左からここまでドラッグします",
|
||||
"display.minApp.pinnedError": "サイドバーに追加されたミニ プログラムは非表示をサポートしていません。非表示にしたい場合は、まずサイドバーから削除してください",
|
||||
"input.auto_translate_with_space": "スペースを3回押して翻訳",
|
||||
"messages.divider": "メッセージ間に区切り線を表示",
|
||||
"messages.input.paste_long_text_as_file": "長いテキストをファイルとして貼り付け",
|
||||
|
||||
@ -411,6 +411,7 @@
|
||||
"display.minApp.visible": "Отображаемый апплет",
|
||||
"display.minApp.disabled": "скрытый апплет",
|
||||
"display.minApp.empty": "Перетащите апплет, который хотите скрыть, слева сюда",
|
||||
"display.minApp.pinnedError": "Мини-программы, добавленные на боковую панель, не поддерживают скрытие. Если вы хотите скрыть их, сначала удалите их с боковой панели",
|
||||
"display.topic.title": "Настройки топиков",
|
||||
"display.custom.css": "Пользовательский CSS",
|
||||
"display.custom.css.placeholder": "/* Здесь введите пользовательский CSS */",
|
||||
|
||||
@ -412,6 +412,7 @@
|
||||
"display.minApp.visible": "显示的小程序",
|
||||
"display.minApp.disabled": "隐藏的小程序",
|
||||
"display.minApp.empty": "把要隐藏的小程序从左侧拖拽到这里",
|
||||
"display.minApp.pinnedError": "已经添加到侧边栏的小程序,不支持隐藏,如需隐藏请先从侧边栏移除",
|
||||
"display.topic.title": "话题设置",
|
||||
"display.custom.css": "自定义 CSS",
|
||||
"display.custom.css.placeholder": "/* 这里写自定义CSS */",
|
||||
|
||||
@ -408,17 +408,14 @@
|
||||
"display.sidebar.empty": "把要隱藏的功能從左側拖拽到這裡",
|
||||
"display.sidebar.visible": "顯示我的側邊欄圖標",
|
||||
"display.sidebar.disabled": "隱藏我的側邊欄圖標",
|
||||
"display.minApp.title": "小程序顯示設定",
|
||||
"display.minApp.visible": "顯示的小程序",
|
||||
"display.minApp.disabled": "隱藏的小程序",
|
||||
"display.minApp.empty": "把要隱藏的小程序從左側拖拽到這裡",
|
||||
"display.minApp.pinnedError": "已新增至側邊欄的小程序,不支援隱藏,如需隱藏請先從側邊欄移除",
|
||||
"display.custom.css": "自定義 CSS",
|
||||
"display.custom.css.placeholder": "/* 這裡寫自定義 CSS */",
|
||||
"input.auto_translate_with_space": "快速敲擊3次空格翻譯",
|
||||
"display": {
|
||||
"minApp": {
|
||||
"title": "小程序顯示設定",
|
||||
"visible": "顯示的小程序",
|
||||
"disabled": "隱藏的小程序",
|
||||
"empty": "把要隱藏的小程序從左側拖拽到這裡"
|
||||
}
|
||||
},
|
||||
"messages.divider": "訊息間顯示分隔線",
|
||||
"messages.input.paste_long_text_as_file": "將長文本貼上為檔案",
|
||||
"messages.input.send_shortcuts": "發送快捷鍵",
|
||||
|
||||
@ -8,7 +8,6 @@ import { FC } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
|
||||
|
||||
interface Props {
|
||||
app: MinAppType
|
||||
onClick?: () => void
|
||||
@ -20,6 +19,7 @@ const App: FC<Props> = ({ app, onClick, size = 60 }) => {
|
||||
const dispatch = useAppDispatch()
|
||||
const { miniAppIcons } = useAppSelector((state) => state.settings)
|
||||
const isPinned = miniAppIcons?.pinned.includes(app.id)
|
||||
const isVisible = miniAppIcons?.visible.includes(app.id)
|
||||
|
||||
const handleClick = () => {
|
||||
MinApp.start(app)
|
||||
@ -38,13 +38,16 @@ const App: FC<Props> = ({ app, onClick, size = 60 }) => {
|
||||
dispatch(
|
||||
setMiniAppIcons({
|
||||
...miniAppIcons,
|
||||
pinned: newPinned
|
||||
pinned: newPinned,
|
||||
visible: isPinned ? miniAppIcons.visible : [...new Set([...miniAppIcons.visible, app.id])]
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
if (!isVisible) return null
|
||||
|
||||
return (
|
||||
<Dropdown menu={{ items: menuItems }} trigger={['contextMenu']}>
|
||||
<Container onClick={handleClick}>
|
||||
|
||||
@ -17,11 +17,15 @@ const AppsPage: FC = () => {
|
||||
const { miniAppIcons } = useSettings()
|
||||
const allApps = useMemo(() => getAllMinApps(), [])
|
||||
|
||||
// 只显示可见的小程序
|
||||
// 只显示可见的小程序,但包括所有固定的小程序
|
||||
const visibleApps = useMemo(() => {
|
||||
if (!miniAppIcons?.visible) return allApps
|
||||
return allApps.filter((app) => miniAppIcons.visible.includes(app.id))
|
||||
}, [allApps, miniAppIcons?.visible])
|
||||
const visibleIds = new Set([
|
||||
...miniAppIcons.visible,
|
||||
...(miniAppIcons.pinned || []) // 确保固定的小程序总是可见
|
||||
])
|
||||
return allApps.filter((app) => visibleIds.has(app.id))
|
||||
}, [allApps, miniAppIcons?.visible, miniAppIcons?.pinned])
|
||||
|
||||
const filteredApps = search
|
||||
? visibleApps.filter(
|
||||
|
||||
@ -8,13 +8,13 @@ import {
|
||||
DropResult
|
||||
} from '@hello-pangea/dnd'
|
||||
import { getAllMinApps } from '@renderer/config/minapps'
|
||||
import { useSettings } from '@renderer/hooks/useSettings'
|
||||
import { useAppDispatch } from '@renderer/store'
|
||||
import { MinAppIcon, setMiniAppIcons } from '@renderer/store/settings'
|
||||
import { FC, useCallback, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import { MinAppIcon, setMiniAppIcons } from '../../../store/settings'
|
||||
|
||||
interface MiniAppManagerProps {
|
||||
visibleMiniApps: MinAppIcon[]
|
||||
disabledMiniApps: MinAppIcon[]
|
||||
@ -29,6 +29,50 @@ interface AppInfo {
|
||||
logo?: string
|
||||
}
|
||||
|
||||
// 添加 reorderLists 函数的接口定义
|
||||
interface ReorderListsParams {
|
||||
sourceList: MinAppIcon[]
|
||||
destList: MinAppIcon[]
|
||||
sourceIndex: number
|
||||
destIndex: number
|
||||
isSameList: boolean
|
||||
}
|
||||
|
||||
interface ReorderListsResult {
|
||||
sourceList: MinAppIcon[]
|
||||
destList: MinAppIcon[]
|
||||
}
|
||||
|
||||
// 添加 reorderLists 函数
|
||||
const reorderLists = ({
|
||||
sourceList,
|
||||
destList,
|
||||
sourceIndex,
|
||||
destIndex,
|
||||
isSameList
|
||||
}: ReorderListsParams): ReorderListsResult => {
|
||||
if (isSameList) {
|
||||
// 在同一列表内重新排序
|
||||
const newList = [...sourceList]
|
||||
const [removed] = newList.splice(sourceIndex, 1)
|
||||
newList.splice(destIndex, 0, removed)
|
||||
return {
|
||||
sourceList: newList,
|
||||
destList: destList
|
||||
}
|
||||
} else {
|
||||
// 在不同列表间移动
|
||||
const newSourceList = [...sourceList]
|
||||
const [removed] = newSourceList.splice(sourceIndex, 1)
|
||||
const newDestList = [...destList]
|
||||
newDestList.splice(destIndex, 0, removed)
|
||||
return {
|
||||
sourceList: newSourceList,
|
||||
destList: newDestList
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const MiniAppIconsManager: FC<MiniAppManagerProps> = ({
|
||||
visibleMiniApps,
|
||||
disabledMiniApps,
|
||||
@ -37,6 +81,7 @@ const MiniAppIconsManager: FC<MiniAppManagerProps> = ({
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const dispatch = useAppDispatch()
|
||||
const { miniAppIcons } = useSettings()
|
||||
const allApps = useMemo(() => getAllMinApps(), [])
|
||||
|
||||
// 创建 app 信息的 Map 缓存
|
||||
@ -58,48 +103,64 @@ const MiniAppIconsManager: FC<MiniAppManagerProps> = ({
|
||||
)
|
||||
|
||||
const handleListUpdate = useCallback(
|
||||
(visible: MinAppIcon[], disabled: MinAppIcon[]) => {
|
||||
setVisibleMiniApps(visible)
|
||||
setDisabledMiniApps(disabled)
|
||||
dispatch(setMiniAppIcons({ visible, disabled, pinned: [] }))
|
||||
(newVisible: MinAppIcon[], newDisabled: MinAppIcon[]) => {
|
||||
setVisibleMiniApps(newVisible)
|
||||
setDisabledMiniApps(newDisabled)
|
||||
|
||||
// 保持 pinned 状态不变
|
||||
dispatch(
|
||||
setMiniAppIcons({
|
||||
visible: newVisible,
|
||||
disabled: newDisabled,
|
||||
pinned: miniAppIcons.pinned // 保持原有的 pinned 状态
|
||||
})
|
||||
)
|
||||
},
|
||||
[dispatch, setVisibleMiniApps, setDisabledMiniApps]
|
||||
[dispatch, setVisibleMiniApps, setDisabledMiniApps, miniAppIcons.pinned]
|
||||
)
|
||||
|
||||
const onDragEnd = useCallback(
|
||||
(result: DropResult) => {
|
||||
if (!result.destination) return
|
||||
|
||||
const { source, destination } = result
|
||||
if (!destination) return
|
||||
const sourceList = source.droppableId as ListType
|
||||
const destList = destination.droppableId as ListType
|
||||
|
||||
const sourceList = source.droppableId === 'visible' ? visibleMiniApps : disabledMiniApps
|
||||
const destList = destination.droppableId === 'visible' ? visibleMiniApps : disabledMiniApps
|
||||
// 如果是 pinned 的小程序,不允许拖到 disabled
|
||||
if (destList === 'disabled') {
|
||||
const draggedApp = sourceList === 'visible' ? visibleMiniApps[source.index] : disabledMiniApps[source.index]
|
||||
|
||||
if (source.droppableId === destination.droppableId) {
|
||||
const newList = [...sourceList]
|
||||
const [removed] = newList.splice(source.index, 1)
|
||||
newList.splice(destination.index, 0, removed)
|
||||
|
||||
handleListUpdate(
|
||||
source.droppableId === 'visible' ? newList : visibleMiniApps,
|
||||
source.droppableId === 'disabled' ? newList : disabledMiniApps
|
||||
)
|
||||
} else {
|
||||
const sourceNewList = [...sourceList]
|
||||
const [removed] = sourceNewList.splice(source.index, 1)
|
||||
const destNewList = [...destList]
|
||||
destNewList.splice(destination.index, 0, removed)
|
||||
|
||||
handleListUpdate(
|
||||
destination.droppableId === 'visible' ? destNewList : sourceNewList,
|
||||
destination.droppableId === 'disabled' ? destNewList : sourceNewList
|
||||
)
|
||||
if (miniAppIcons.pinned.includes(draggedApp)) {
|
||||
window.message.error(t('settings.display.minApp.pinnedError'))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const newLists = reorderLists({
|
||||
sourceList: sourceList === 'visible' ? visibleMiniApps : disabledMiniApps,
|
||||
destList: destList === 'visible' ? visibleMiniApps : disabledMiniApps,
|
||||
sourceIndex: source.index,
|
||||
destIndex: destination.index,
|
||||
isSameList: sourceList === destList
|
||||
})
|
||||
|
||||
handleListUpdate(
|
||||
sourceList === 'visible' ? newLists.sourceList : newLists.destList,
|
||||
sourceList === 'visible' ? newLists.destList : newLists.sourceList
|
||||
)
|
||||
},
|
||||
[visibleMiniApps, disabledMiniApps, handleListUpdate]
|
||||
[visibleMiniApps, disabledMiniApps, handleListUpdate, miniAppIcons.pinned, t]
|
||||
)
|
||||
|
||||
const onMoveMiniApp = useCallback(
|
||||
(program: MinAppIcon, fromList: ListType) => {
|
||||
// 如果是从可见列表移动到隐藏列表,且程序是 pinned 状态,则阻止移动
|
||||
if (fromList === 'visible' && miniAppIcons.pinned.includes(program)) {
|
||||
window.message.error(t('settings.display.minApp.pinnedError'))
|
||||
return
|
||||
}
|
||||
|
||||
const isMovingToVisible = fromList === 'disabled'
|
||||
const newVisible = isMovingToVisible
|
||||
? [...visibleMiniApps, program]
|
||||
@ -110,7 +171,7 @@ const MiniAppIconsManager: FC<MiniAppManagerProps> = ({
|
||||
|
||||
handleListUpdate(newVisible, newDisabled)
|
||||
},
|
||||
[visibleMiniApps, disabledMiniApps, handleListUpdate]
|
||||
[visibleMiniApps, disabledMiniApps, handleListUpdate, miniAppIcons.pinned, t]
|
||||
)
|
||||
|
||||
const renderProgramItem = (program: MinAppIcon, provided: DraggableProvided, listType: ListType) => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user