fix: #1183 Reveal in finder does not work on windows (#1239)

* fix(OpenFile): #1183 reveal in finder does not work on windows

Signed-off-by: James <james@jan.ai>
---------

Signed-off-by: James <james@jan.ai>
This commit is contained in:
NamH 2023-12-28 13:00:20 +07:00 committed by GitHub
parent c580b4c848
commit cbc63da831
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 39 additions and 19 deletions

View File

@ -10,6 +10,7 @@ export enum AppRoute {
openAppDirectory = 'openAppDirectory', openAppDirectory = 'openAppDirectory',
openFileExplore = 'openFileExplorer', openFileExplore = 'openFileExplorer',
relaunch = 'relaunch', relaunch = 'relaunch',
joinPath = 'joinPath'
} }
export enum AppEvent { export enum AppEvent {

View File

@ -44,6 +44,13 @@ const getUserSpace = (): Promise<string> => global.core.api?.getUserSpace()
const openFileExplorer: (path: string) => Promise<any> = (path) => const openFileExplorer: (path: string) => Promise<any> = (path) =>
global.core.api?.openFileExplorer(path) global.core.api?.openFileExplorer(path)
/**
* Joins multiple paths together.
* @param paths - The paths to join.
* @returns {Promise<string>} A promise that resolves with the joined path.
*/
const joinPath: (paths: string[]) => Promise<string> = (paths) => global.core.api?.joinPath(paths)
const getResourcePath: () => Promise<string> = () => global.core.api?.getResourcePath() const getResourcePath: () => Promise<string> = () => global.core.api?.getResourcePath()
/** /**
@ -66,4 +73,5 @@ export {
getUserSpace, getUserSpace,
openFileExplorer, openFileExplorer,
getResourcePath, getResourcePath,
joinPath,
} }

View File

@ -48,6 +48,13 @@ export function handleAppIPCs() {
shell.openPath(url) shell.openPath(url)
}) })
/**
* Joins multiple paths together, respect to the current OS.
*/
ipcMain.handle(AppRoute.joinPath, async (_event, paths: string[]) =>
join(...paths)
)
/** /**
* Relaunches the app in production - reload window in development. * Relaunches the app in production - reload window in development.
* @param _event - The IPC event object. * @param _event - The IPC event object.

View File

@ -29,6 +29,13 @@ export default function CardSidebar({
useClickOutside(() => setMore(false), null, [menu, toggle]) useClickOutside(() => setMore(false), null, [menu, toggle])
let openFolderTitle: string = 'Open Containing Folder'
if (isMac) {
openFolderTitle = 'Reveal in Finder'
} else if (isWindows) {
openFolderTitle = 'Reveal in File Explorer'
}
return ( return (
<div <div
className={twMerge( className={twMerge(
@ -74,7 +81,7 @@ export default function CardSidebar({
> >
<FolderOpenIcon size={16} className="text-muted-foreground" /> <FolderOpenIcon size={16} className="text-muted-foreground" />
<span className="text-bold text-black dark:text-muted-foreground"> <span className="text-bold text-black dark:text-muted-foreground">
Reveal in Finder {openFolderTitle}
</span> </span>
</div> </div>
<div <div

View File

@ -32,6 +32,9 @@ const nextConfig = {
JSON.stringify(process.env.ANALYTICS_ID) ?? JSON.stringify('xxx'), JSON.stringify(process.env.ANALYTICS_ID) ?? JSON.stringify('xxx'),
ANALYTICS_HOST: ANALYTICS_HOST:
JSON.stringify(process.env.ANALYTICS_HOST) ?? JSON.stringify('xxx'), JSON.stringify(process.env.ANALYTICS_HOST) ?? JSON.stringify('xxx'),
isMac: process.platform === 'darwin',
isWindows: process.platform === 'win32',
isLinux: process.platform === 'linux',
}), }),
] ]
return config return config

View File

@ -1,8 +1,6 @@
import { join } from 'path'
import React from 'react' import React from 'react'
import { getUserSpace, openFileExplorer } from '@janhq/core' import { getUserSpace, openFileExplorer, joinPath } from '@janhq/core'
import { Input, Textarea } from '@janhq/uikit' import { Input, Textarea } from '@janhq/uikit'
@ -54,23 +52,22 @@ const Sidebar: React.FC = () => {
const assistantId = activeThread.assistants[0]?.assistant_id const assistantId = activeThread.assistants[0]?.assistant_id
switch (type) { switch (type) {
case 'Thread': case 'Thread':
filePath = join('threads', activeThread.id) filePath = await joinPath(['threads', activeThread.id])
break break
case 'Model': case 'Model':
if (!selectedModel) return if (!selectedModel) return
filePath = join('models', selectedModel.id) filePath = await joinPath(['models', selectedModel.id])
break break
case 'Assistant': case 'Assistant':
if (!assistantId) return if (!assistantId) return
filePath = join('assistants', assistantId) filePath = await joinPath(['assistants', assistantId])
break break
default: default:
break break
} }
if (!filePath) return if (!filePath) return
const fullPath = await joinPath([userSpace, filePath])
const fullPath = join(userSpace, filePath)
openFileExplorer(fullPath) openFileExplorer(fullPath)
} }
@ -87,23 +84,22 @@ const Sidebar: React.FC = () => {
const assistantId = activeThread.assistants[0]?.assistant_id const assistantId = activeThread.assistants[0]?.assistant_id
switch (type) { switch (type) {
case 'Thread': case 'Thread':
filePath = join('threads', activeThread.id, 'thread.json') filePath = await joinPath(['threads', activeThread.id, 'thread.json'])
break break
case 'Model': case 'Model':
if (!selectedModel) return if (!selectedModel) return
filePath = join('models', selectedModel.id, 'model.json') filePath = await joinPath(['models', selectedModel.id, 'model.json'])
break break
case 'Assistant': case 'Assistant':
if (!assistantId) return if (!assistantId) return
filePath = join('assistants', assistantId, 'assistant.json') filePath = await joinPath(['assistants', assistantId, 'assistant.json'])
break break
default: default:
break break
} }
if (!filePath) return if (!filePath) return
const fullPath = await joinPath([userSpace, filePath])
const fullPath = join(userSpace, filePath)
openFileExplorer(fullPath) openFileExplorer(fullPath)
} }

View File

@ -5,8 +5,6 @@ import React, { useState, useEffect, useRef, useContext } from 'react'
import { Button } from '@janhq/uikit' import { Button } from '@janhq/uikit'
import Loader from '@/containers/Loader'
import { FeatureToggleContext } from '@/context/FeatureToggle' import { FeatureToggleContext } from '@/context/FeatureToggle'
import { useGetAppVersion } from '@/hooks/useGetAppVersion' import { useGetAppVersion } from '@/hooks/useGetAppVersion'
@ -18,7 +16,6 @@ import { extensionManager } from '@/extension'
const ExtensionCatalog = () => { const ExtensionCatalog = () => {
const [activeExtensions, setActiveExtensions] = useState<any[]>([]) const [activeExtensions, setActiveExtensions] = useState<any[]>([])
const [extensionCatalog, setExtensionCatalog] = useState<any[]>([]) const [extensionCatalog, setExtensionCatalog] = useState<any[]>([])
const [isLoading, setIsLoading] = useState<boolean>(false)
const fileInputRef = useRef<HTMLInputElement | null>(null) const fileInputRef = useRef<HTMLInputElement | null>(null)
const { version } = useGetAppVersion() const { version } = useGetAppVersion()
const { experimentalFeatureEnabed } = useContext(FeatureToggleContext) const { experimentalFeatureEnabed } = useContext(FeatureToggleContext)
@ -95,8 +92,6 @@ const ExtensionCatalog = () => {
} }
} }
if (isLoading) return <Loader description="Installing ..." />
return ( return (
<div className="block w-full"> <div className="block w-full">
{extensionCatalog {extensionCatalog

View File

@ -8,6 +8,9 @@ declare global {
declare const VERSION: string declare const VERSION: string
declare const ANALYTICS_ID: string declare const ANALYTICS_ID: string
declare const ANALYTICS_HOST: string declare const ANALYTICS_HOST: string
declare const isMac: boolean
declare const isWindows: boolean
declare const isLinux: boolean
interface Core { interface Core {
api: APIFunctions api: APIFunctions
events: EventEmitter events: EventEmitter