mirror of
https://github.com/lencx/ChatGPT.git
synced 2024-10-01 01:06:13 -04:00
chore: path
This commit is contained in:
parent
f38d683f4e
commit
a7d12bafc0
@ -34,13 +34,16 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^4.8.0",
|
||||
"@monaco-editor/react": "^4.4.6",
|
||||
"@tauri-apps/api": "^1.2.0",
|
||||
"antd": "^5.1.0",
|
||||
"clsx": "^1.2.1",
|
||||
"dayjs": "^1.11.7",
|
||||
"lodash": "^4.17.21",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-markdown": "^8.0.4",
|
||||
"react-resizable-panels": "^0.0.33",
|
||||
"react-router-dom": "^6.4.5",
|
||||
"react-syntax-highlighter": "^15.5.0",
|
||||
"uuid": "^9.0.0"
|
||||
|
36
src/components/FilePath/index.tsx
vendored
Normal file
36
src/components/FilePath/index.tsx
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import { path, shell } from '@tauri-apps/api';
|
||||
|
||||
import { chatRoot } from '@/utils';
|
||||
|
||||
interface FilePathProps {
|
||||
paths?: string;
|
||||
label?: string;
|
||||
className?: string;
|
||||
content?: string;
|
||||
url?: string;
|
||||
}
|
||||
|
||||
const FilePath: FC<FilePathProps> = ({ className, label = 'PATH', paths = '', url, content }) => {
|
||||
const [filePath, setPath] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
if (!path && !url) return;
|
||||
(async () => {
|
||||
if (url) {
|
||||
setPath(url);
|
||||
return;
|
||||
}
|
||||
setPath(await path.join(await chatRoot(), ...paths.split('/').filter(i => !!i)));
|
||||
})()
|
||||
}, [url, paths])
|
||||
|
||||
return (
|
||||
<div className={clsx(className, 'chat-file-path')}>
|
||||
<div>{label}: <a onClick={() => shell.open(filePath)} title={filePath}>{content ? content : filePath}</a></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default FilePath;
|
25
src/components/Markdown/Editor.tsx
vendored
Normal file
25
src/components/Markdown/Editor.tsx
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
import Editor from "@monaco-editor/react";
|
||||
import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const MarkdownEditor = () => {
|
||||
return (
|
||||
<div>
|
||||
<PanelGroup direction="horizontal">
|
||||
<Panel>
|
||||
<Editor
|
||||
height="calc(100vh - 120px)"
|
||||
language="markdown"
|
||||
/>
|
||||
</Panel>
|
||||
<PanelResizeHandle className="resize-handle" />
|
||||
<Panel collapsible={true}>
|
||||
<div>1284</div>
|
||||
</Panel>
|
||||
</PanelGroup>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
export default MarkdownEditor;
|
12
src/components/Markdown/index.scss
vendored
12
src/components/Markdown/index.scss
vendored
@ -5,3 +5,15 @@
|
||||
font-family: monospace, monospace;
|
||||
}
|
||||
}
|
||||
|
||||
.resize-handle {
|
||||
width: 0.25rem;
|
||||
transition: 250ms linear background-color;
|
||||
background-color: #7f8082;
|
||||
outline: none;
|
||||
|
||||
&:hover,
|
||||
&[data-resize-handle-active] {
|
||||
background-color: #5194eb;
|
||||
}
|
||||
}
|
||||
|
1
src/main.scss
vendored
1
src/main.scss
vendored
@ -19,6 +19,7 @@ html, body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.ant-table-selection-col,
|
||||
.ant-table-selection-column {
|
||||
width: 50px !important;
|
||||
min-width: 50px !important;
|
||||
|
6
src/routes.tsx
vendored
6
src/routes.tsx
vendored
@ -17,6 +17,7 @@ import SyncCustom from '@/view/model/SyncCustom';
|
||||
import SyncRecord from '@/view/model/SyncRecord';
|
||||
import Download from '@/view/download';
|
||||
import Notes from '@/view/notes';
|
||||
import Markdown from '@/view/markdown';
|
||||
|
||||
export type ChatRouteMetaObject = {
|
||||
label: string;
|
||||
@ -48,6 +49,11 @@ export const routes: Array<ChatRouteObject> = [
|
||||
icon: <FormOutlined />,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/md/:id',
|
||||
element: <Markdown />,
|
||||
hideMenu: true,
|
||||
},
|
||||
{
|
||||
path: '/model',
|
||||
meta: {
|
||||
|
1
src/utils.ts
vendored
1
src/utils.ts
vendored
@ -2,6 +2,7 @@ import { readTextFile, writeTextFile, exists, createDir } from '@tauri-apps/api/
|
||||
import { homeDir, join, dirname } from '@tauri-apps/api/path';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
export const CHAT_CONF_JSON = 'chat.conf.json';
|
||||
export const CHAT_MODEL_JSON = 'chat.model.json';
|
||||
export const CHAT_MODEL_CMD_JSON = 'chat.model.cmd.json';
|
||||
export const CHAT_DOWNLOAD_JSON = 'chat.download.json';
|
||||
|
14
src/view/General.tsx
vendored
14
src/view/General.tsx
vendored
@ -1,14 +1,15 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Form, Radio, Switch, Input, Button, Space, message, Tooltip } from 'antd';
|
||||
import { QuestionCircleOutlined } from '@ant-design/icons';
|
||||
import { invoke, shell, path } from '@tauri-apps/api';
|
||||
import { invoke } from '@tauri-apps/api';
|
||||
import { platform } from '@tauri-apps/api/os';
|
||||
import { ask } from '@tauri-apps/api/dialog';
|
||||
import { relaunch } from '@tauri-apps/api/process';
|
||||
import { clone, omit, isEqual } from 'lodash';
|
||||
|
||||
import useInit from '@/hooks/useInit';
|
||||
import { DISABLE_AUTO_COMPLETE, chatRoot } from '@/utils';
|
||||
import FilePath from '@/components/FilePath';
|
||||
import { DISABLE_AUTO_COMPLETE, CHAT_CONF_JSON } from '@/utils';
|
||||
|
||||
const AutoUpdateLabel = () => {
|
||||
return (
|
||||
@ -68,13 +69,10 @@ const GlobalShortcutLabel = () => {
|
||||
|
||||
export default function General() {
|
||||
const [form] = Form.useForm();
|
||||
const [jsonPath, setJsonPath] = useState('');
|
||||
const [platformInfo, setPlatform] = useState<string>('');
|
||||
const [chatConf, setChatConf] = useState<any>(null);
|
||||
|
||||
useInit(async () => {
|
||||
setJsonPath(await path.join(await chatRoot(), 'chat.conf.json'));
|
||||
|
||||
setPlatform(await platform());
|
||||
const chatData = await invoke('get_chat_conf');
|
||||
setChatConf(chatData);
|
||||
@ -117,11 +115,7 @@ export default function General() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="chat-table-tip">
|
||||
<div className="chat-sync-path">
|
||||
<div>PATH: <a onClick={() => shell.open(jsonPath)} title={jsonPath}>{jsonPath}</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<FilePath paths={CHAT_CONF_JSON} />
|
||||
<Form
|
||||
form={form}
|
||||
style={{ maxWidth: 500 }}
|
||||
|
16
src/view/download/index.tsx
vendored
16
src/view/download/index.tsx
vendored
@ -1,11 +1,11 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Table, Modal, Popconfirm, Button, message } from 'antd';
|
||||
import { invoke, path, shell, fs } from '@tauri-apps/api';
|
||||
import { invoke, path, fs } from '@tauri-apps/api';
|
||||
|
||||
import useInit from '@/hooks/useInit';
|
||||
import useJson from '@/hooks/useJson';
|
||||
import useData from '@/hooks/useData';
|
||||
import useColumns from '@/hooks/useColumns';
|
||||
import FilePath from '@/components/FilePath';
|
||||
import { useTableRowSelection, TABLE_PAGINATION } from '@/hooks/useTable';
|
||||
import { chatRoot, CHAT_DOWNLOAD_JSON } from '@/utils';
|
||||
import { downloadColumns } from './config';
|
||||
@ -19,7 +19,6 @@ function renderFile(buff: Uint8Array, type: string) {
|
||||
}
|
||||
|
||||
export default function Download() {
|
||||
const [downloadPath, setDownloadPath] = useState('');
|
||||
const [source, setSource] = useState('');
|
||||
const [isVisible, setVisible] = useState(false);
|
||||
const { opData, opInit, opReplace, opSafeKey } = useData([]);
|
||||
@ -28,11 +27,6 @@ export default function Download() {
|
||||
const { json, refreshJson, updateJson } = useJson<any[]>(CHAT_DOWNLOAD_JSON);
|
||||
const selectedItems = rowSelection.selectedRowKeys || [];
|
||||
|
||||
useInit(async () => {
|
||||
const file = await path.join(await chatRoot(), CHAT_DOWNLOAD_JSON);
|
||||
setDownloadPath(file);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!json || json.length <= 0) return;
|
||||
opInit(json);
|
||||
@ -118,11 +112,7 @@ export default function Download() {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="chat-table-tip">
|
||||
<div className="chat-file-path">
|
||||
<div>PATH: <a onClick={() => shell.open(downloadPath)} title={downloadPath}>{downloadPath}</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<FilePath paths={CHAT_DOWNLOAD_JSON} />
|
||||
<Table
|
||||
rowKey="id"
|
||||
columns={columns}
|
||||
|
32
src/view/markdown/index.tsx
vendored
Normal file
32
src/view/markdown/index.tsx
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
import { useState } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { Breadcrumb } from 'antd';
|
||||
import { ArrowLeftOutlined } from '@ant-design/icons';
|
||||
import MarkdownEditor from '@/components/Markdown/Editor';
|
||||
|
||||
import useInit from '@/hooks/useInit';
|
||||
import { getPath } from '@/view/notes/config';
|
||||
|
||||
export default function Markdown() {
|
||||
const [filePath, setFilePath] = useState('');
|
||||
const location = useLocation();
|
||||
const state = location?.state;
|
||||
|
||||
useInit(async () => {
|
||||
setFilePath(await getPath(state));
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<Breadcrumb separator=" ">
|
||||
<Breadcrumb.Item href="">
|
||||
<ArrowLeftOutlined />
|
||||
</Breadcrumb.Item>
|
||||
<Breadcrumb.Item href="">
|
||||
{filePath}
|
||||
</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
<MarkdownEditor />
|
||||
</>
|
||||
);
|
||||
}
|
2
src/view/model/SyncCustom/index.tsx
vendored
2
src/view/model/SyncCustom/index.tsx
vendored
@ -3,9 +3,9 @@ import { Table, Modal, Button, message } from 'antd';
|
||||
import { invoke, path, fs } from '@tauri-apps/api';
|
||||
|
||||
import useData from '@/hooks/useData';
|
||||
import useChatModel, { useCacheModel } from '@/hooks/useChatModel';
|
||||
import useColumns from '@/hooks/useColumns';
|
||||
import { TABLE_PAGINATION } from '@/hooks/useTable';
|
||||
import useChatModel, { useCacheModel } from '@/hooks/useChatModel';
|
||||
import { CHAT_MODEL_JSON, chatRoot, readJSON, genCmd } from '@/utils';
|
||||
import { syncColumns, getPath } from './config';
|
||||
import SyncForm from './Form';
|
||||
|
7
src/view/model/SyncPrompts/index.tsx
vendored
7
src/view/model/SyncPrompts/index.tsx
vendored
@ -1,10 +1,11 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Table, Button, Popconfirm } from 'antd';
|
||||
import { invoke, path, shell } from '@tauri-apps/api';
|
||||
import { invoke, path } from '@tauri-apps/api';
|
||||
|
||||
import useInit from '@/hooks/useInit';
|
||||
import useData from '@/hooks/useData';
|
||||
import useColumns from '@/hooks/useColumns';
|
||||
import FilePath from '@/components/FilePath';
|
||||
import useChatModel, { useCacheModel } from '@/hooks/useChatModel';
|
||||
import { useTableRowSelection, TABLE_PAGINATION } from '@/hooks/useTable';
|
||||
import { fmtDate, chatRoot } from '@/utils';
|
||||
@ -80,8 +81,8 @@ export default function SyncPrompts() {
|
||||
</div>
|
||||
<div className="chat-table-tip">
|
||||
<div className="chat-sync-path">
|
||||
<div>PATH: <a onClick={() => shell.open(promptsURL)} target="_blank" title={promptsURL}>f/awesome-chatgpt-prompts/prompts.csv</a></div>
|
||||
<div>CACHE: <a onClick={() => shell.open(jsonPath)} target="_blank" title={jsonPath}>{jsonPath}</a></div>
|
||||
<FilePath url={promptsURL} content="f/awesome-chatgpt-prompts/prompts.csv" />
|
||||
<FilePath label="CACHE" paths="cache_model/chatgpt_prompts.json" />
|
||||
</div>
|
||||
{lastUpdated && <span style={{ marginLeft: 10, color: '#888', fontSize: 12 }}>Last updated on {fmtDate(lastUpdated)}</span>}
|
||||
</div>
|
||||
|
11
src/view/model/SyncRecord/index.tsx
vendored
11
src/view/model/SyncRecord/index.tsx
vendored
@ -2,14 +2,15 @@ import { useEffect, useState } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { ArrowLeftOutlined } from '@ant-design/icons';
|
||||
import { Table, Button } from 'antd';
|
||||
import { shell, path } from '@tauri-apps/api';
|
||||
import { path } from '@tauri-apps/api';
|
||||
|
||||
import useColumns from '@/hooks/useColumns';
|
||||
import useData from '@/hooks/useData';
|
||||
import useColumns from '@/hooks/useColumns';
|
||||
import FilePath from '@/components/FilePath';
|
||||
import { useCacheModel } from '@/hooks/useChatModel';
|
||||
import { useTableRowSelection, TABLE_PAGINATION } from '@/hooks/useTable';
|
||||
import { fmtDate, chatRoot } from '@/utils';
|
||||
import { getPath } from '@/view/model/SyncCustom/config';
|
||||
import { fmtDate, chatRoot } from '@/utils';
|
||||
import { syncColumns } from './config';
|
||||
import useInit from '@/hooks/useInit';
|
||||
|
||||
@ -66,8 +67,8 @@ export default function SyncRecord() {
|
||||
</div>
|
||||
<div className="chat-table-tip">
|
||||
<div className="chat-sync-path">
|
||||
<div>PATH: <a onClick={() => shell.open(filePath)} target="_blank" title={filePath}>{filePath}</a></div>
|
||||
<div>CACHE: <a onClick={() => shell.open(jsonPath)} target="_blank" title={jsonPath}>{jsonPath}</a></div>
|
||||
<FilePath url={filePath} />
|
||||
<FilePath label="CACHE" paths={`cache_model/${state?.id}.json`} />
|
||||
</div>
|
||||
{state?.last_updated && <span style={{ marginLeft: 10, color: '#888', fontSize: 12 }}>Last updated on {fmtDate(state?.last_updated)}</span>}
|
||||
</div>
|
||||
|
10
src/view/model/UserCustom/index.tsx
vendored
10
src/view/model/UserCustom/index.tsx
vendored
@ -1,11 +1,12 @@
|
||||
import { useState, useRef, useEffect } from 'react';
|
||||
import { Table, Button, Modal, message } from 'antd';
|
||||
import { shell, path } from '@tauri-apps/api';
|
||||
import { path } from '@tauri-apps/api';
|
||||
|
||||
import useInit from '@/hooks/useInit';
|
||||
import useData from '@/hooks/useData';
|
||||
import useChatModel, { useCacheModel } from '@/hooks/useChatModel';
|
||||
import useColumns from '@/hooks/useColumns';
|
||||
import FilePath from '@/components/FilePath';
|
||||
import useChatModel, { useCacheModel } from '@/hooks/useChatModel';
|
||||
import { useTableRowSelection, TABLE_PAGINATION } from '@/hooks/useTable';
|
||||
import { chatRoot, fmtDate } from '@/utils';
|
||||
import { modelColumns } from './config';
|
||||
@ -108,11 +109,8 @@ export default function LanguageModel() {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{/* <div className="chat-model-path">PATH: <span onClick={handleOpenFile}>{modelPath}</span></div> */}
|
||||
<div className="chat-table-tip">
|
||||
<div className="chat-sync-path">
|
||||
<div>CACHE: <a onClick={() => shell.open(jsonPath)} title={jsonPath}>{jsonPath}</a></div>
|
||||
</div>
|
||||
<FilePath label="CACHE" paths="cache_model/user_custom.json" />
|
||||
{lastUpdated && <span style={{ marginLeft: 10, color: '#888', fontSize: 12 }}>Last updated on {fmtDate(lastUpdated)}</span>}
|
||||
</div>
|
||||
<Table
|
||||
|
3
src/view/notes/config.tsx
vendored
3
src/view/notes/config.tsx
vendored
@ -1,4 +1,5 @@
|
||||
import { useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Space, Popconfirm } from 'antd';
|
||||
import { path, shell } from '@tauri-apps/api';
|
||||
|
||||
@ -40,7 +41,7 @@ export const notesColumns = () => [
|
||||
return (
|
||||
<Space>
|
||||
<a onClick={() => actions.setRecord(row, 'preview')}>Preview</a>
|
||||
<a onClick={() => actions.setRecord(row, 'edit')}>Edit</a>
|
||||
<Link to={`/md/${row.id}`} state={row}>Edit</Link>
|
||||
<Popconfirm
|
||||
title="Are you sure to delete this file?"
|
||||
onConfirm={() => actions.setRecord(row, 'delete')}
|
||||
|
19
src/view/notes/index.tsx
vendored
19
src/view/notes/index.tsx
vendored
@ -1,18 +1,17 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Table, Modal, Popconfirm, Button, message } from 'antd';
|
||||
import { invoke, path, shell, fs } from '@tauri-apps/api';
|
||||
import { invoke, path, fs } from '@tauri-apps/api';
|
||||
|
||||
import useInit from '@/hooks/useInit';
|
||||
import useJson from '@/hooks/useJson';
|
||||
import useData from '@/hooks/useData';
|
||||
import useColumns from '@/hooks/useColumns';
|
||||
import Markdown from '@/components/Markdown';
|
||||
import FilePath from '@/components/FilePath';
|
||||
import { useTableRowSelection, TABLE_PAGINATION } from '@/hooks/useTable';
|
||||
import { chatRoot, CHAT_NOTES_JSON } from '@/utils';
|
||||
import { notesColumns } from './config';
|
||||
|
||||
export default function Notes() {
|
||||
const [notesPath, setNotesPath] = useState('');
|
||||
const [source, setSource] = useState('');
|
||||
const [isVisible, setVisible] = useState(false);
|
||||
const { opData, opInit, opReplace, opSafeKey } = useData([]);
|
||||
@ -21,11 +20,6 @@ export default function Notes() {
|
||||
const { json, refreshJson, updateJson } = useJson<any[]>(CHAT_NOTES_JSON);
|
||||
const selectedItems = rowSelection.selectedRowKeys || [];
|
||||
|
||||
useInit(async () => {
|
||||
const file = await path.join(await chatRoot(), CHAT_NOTES_JSON);
|
||||
setNotesPath(file);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!json || json.length <= 0) return;
|
||||
opInit(json);
|
||||
@ -42,9 +36,6 @@ export default function Notes() {
|
||||
setVisible(true);
|
||||
return;
|
||||
}
|
||||
if (opInfo.opType === 'edit') {
|
||||
alert('TODO');
|
||||
}
|
||||
if (opInfo.opType === 'delete') {
|
||||
await fs.removeFile(file);
|
||||
await handleRefresh();
|
||||
@ -111,11 +102,7 @@ export default function Notes() {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="chat-table-tip">
|
||||
<div className="chat-file-path">
|
||||
<div>PATH: <a onClick={() => shell.open(notesPath)} title={notesPath}>{notesPath}</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<FilePath paths={CHAT_NOTES_JSON} />
|
||||
<Table
|
||||
rowKey="id"
|
||||
columns={columns}
|
||||
|
Loading…
Reference in New Issue
Block a user