mirror of
https://github.com/lencx/ChatGPT.git
synced 2024-10-01 01:06:13 -04:00
feat: chatgpt prompts
This commit is contained in:
parent
3318bfb23f
commit
47c9072f40
@ -1,5 +1,5 @@
|
||||
use crate::{conf::ChatConfJson, utils};
|
||||
use std::fs;
|
||||
use std::{fs, path::PathBuf};
|
||||
use tauri::{api, command, AppHandle, Manager};
|
||||
|
||||
#[command]
|
||||
@ -59,3 +59,8 @@ pub fn form_msg(app: AppHandle, label: &str, title: &str, msg: &str) {
|
||||
let win = app.app_handle().get_window(label);
|
||||
tauri::api::dialog::message(win.as_ref(), title, msg);
|
||||
}
|
||||
|
||||
#[command]
|
||||
pub fn open_file(path: PathBuf) {
|
||||
utils::open_file(path);
|
||||
}
|
@ -26,6 +26,7 @@ fn main() {
|
||||
cmd::form_cancel,
|
||||
cmd::form_confirm,
|
||||
cmd::form_msg,
|
||||
cmd::open_file,
|
||||
])
|
||||
.setup(setup::init)
|
||||
.plugin(tauri_plugin_positioner::init())
|
||||
|
4
src/components/Tags/index.tsx
vendored
4
src/components/Tags/index.tsx
vendored
@ -16,6 +16,10 @@ const Tags: FC<TagsProps> = ({ value = [], onChange }) => {
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
const inputRef = useRef<InputRef>(null);
|
||||
|
||||
useEffect(() => {
|
||||
setTags(value);
|
||||
}, [value])
|
||||
|
||||
useEffect(() => {
|
||||
if (inputVisible) {
|
||||
inputRef.current?.focus();
|
||||
|
1
src/layout/index.scss
vendored
1
src/layout/index.scss
vendored
@ -10,6 +10,7 @@
|
||||
|
||||
.chat-container {
|
||||
padding: 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ant-menu {
|
||||
|
1
src/layout/index.tsx
vendored
1
src/layout/index.tsx
vendored
@ -3,7 +3,6 @@ import { Layout, Menu } from 'antd';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
|
||||
import Routes, { menuItems } from '@/routes';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const { Content, Footer, Sider } = Layout;
|
||||
|
6
src/utils.ts
vendored
6
src/utils.ts
vendored
@ -8,10 +8,14 @@ export const DISABLE_AUTO_COMPLETE = {
|
||||
spellCheck: false
|
||||
};
|
||||
|
||||
const chatRoot = async () => {
|
||||
export const chatRoot = async () => {
|
||||
return join(await homeDir(), '.chatgpt')
|
||||
}
|
||||
|
||||
export const chatModelPath = async () => {
|
||||
return join(await chatRoot(), CHAT_MODEL_JSON);
|
||||
}
|
||||
|
||||
export const readJSON = async (path: string, defaultVal = {}) => {
|
||||
const root = await chatRoot();
|
||||
const file = await join(root, path);
|
||||
|
2
src/view/LanguageModel/Form.tsx
vendored
2
src/view/LanguageModel/Form.tsx
vendored
@ -47,7 +47,7 @@ const LanguageModel: ForwardRefRenderFunction<FormProps, LanguageModelProps> = (
|
||||
<Input placeholder="Please input act" {...DISABLE_AUTO_COMPLETE} />
|
||||
</Form.Item>
|
||||
<Form.Item label="Tags" name="tags">
|
||||
<Tags />
|
||||
<Tags value={record?.tags} />
|
||||
</Form.Item>
|
||||
<Form.Item label="Enable" name="enable" valuePropName="checked">
|
||||
<Switch />
|
||||
|
12
src/view/LanguageModel/config.tsx
vendored
12
src/view/LanguageModel/config.tsx
vendored
@ -5,7 +5,7 @@ export const modelColumns = () => [
|
||||
title: '/{cmd}',
|
||||
dataIndex: 'cmd',
|
||||
fixed: 'left',
|
||||
width: 40,
|
||||
width: 120,
|
||||
key: 'cmd',
|
||||
render: (v: string) => <Tag color="#2a2a2a">/{v}</Tag>
|
||||
},
|
||||
@ -13,23 +13,29 @@ export const modelColumns = () => [
|
||||
title: 'Act',
|
||||
dataIndex: 'act',
|
||||
key: 'act',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: 'Tags',
|
||||
dataIndex: 'tags',
|
||||
key: 'tags',
|
||||
render: (v: string[]) => v?.map(i => <Tag key={i}>{i}</Tag>),
|
||||
width: 150,
|
||||
render: (v: string[]) => (
|
||||
<span className="chat-prompts-tags">{v?.map(i => <Tag key={i}>{i}</Tag>)}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Enable',
|
||||
dataIndex: 'enable',
|
||||
key: 'enable',
|
||||
width: 80,
|
||||
render: (v: boolean = false) => <Switch checked={v} disabled />,
|
||||
},
|
||||
{
|
||||
title: 'Prompt',
|
||||
dataIndex: 'prompt',
|
||||
key: 'prompt',
|
||||
width: 300,
|
||||
render: (v: string) => (
|
||||
<Tooltip overlayInnerStyle={{ width: 350 }} title={v}><span className="chat-prompts-val">{v}</span></Tooltip>
|
||||
),
|
||||
@ -37,6 +43,8 @@ export const modelColumns = () => [
|
||||
{
|
||||
title: 'Action',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
width: 120,
|
||||
render: (_: any, row: any, actions: any) => (
|
||||
<Space size="middle">
|
||||
<a onClick={() => actions.setRecord(row, 'edit')}>Edit</a>
|
||||
|
31
src/view/LanguageModel/index.scss
vendored
31
src/view/LanguageModel/index.scss
vendored
@ -3,10 +3,37 @@
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.chat-prompts-tags {
|
||||
.ant-tag {
|
||||
margin: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.chat-model-path {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #888;
|
||||
margin-bottom: 5px;
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
// background-color: #d8d8d8;
|
||||
color: #4096ff;
|
||||
padding: 0 8px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
33
src/view/LanguageModel/index.tsx
vendored
33
src/view/LanguageModel/index.tsx
vendored
@ -1,20 +1,35 @@
|
||||
import { useState, useRef, useEffect } from 'react';
|
||||
import { Table, Button, Modal } from 'antd';
|
||||
import { invoke } from '@tauri-apps/api';
|
||||
|
||||
import useChatModel from '@/hooks/useChatModel';
|
||||
import useColumns from '@/hooks/useColumns';
|
||||
import useData from '@/hooks/useData';
|
||||
import { chatModelPath } from '@/utils';
|
||||
import { modelColumns } from './config';
|
||||
import LanguageModelForm from './Form';
|
||||
import './index.scss';
|
||||
|
||||
export default function LanguageModel() {
|
||||
const [isVisible, setVisible] = useState(false);
|
||||
const [modelPath, setChatModelPath] = useState('');
|
||||
const { modelData, modelSet } = useChatModel();
|
||||
const { opData, opAdd, opRemove, opReplace, opSafeKey } = useData(modelData);
|
||||
const { columns, ...opInfo } = useColumns(modelColumns());
|
||||
const formRef = useRef<any>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!opInfo.opType) return;
|
||||
if (['edit', 'new'].includes(opInfo.opType)) {
|
||||
setVisible(true);
|
||||
}
|
||||
if (['delete'].includes(opInfo.opType)) {
|
||||
const data = opRemove(opInfo?.opRecord?.[opSafeKey]);
|
||||
modelSet(data);
|
||||
opInfo.resetRecord();
|
||||
}
|
||||
}, [opInfo.opType, formRef]);
|
||||
|
||||
const hide = () => {
|
||||
setVisible(false);
|
||||
opInfo.resetRecord();
|
||||
@ -34,27 +49,23 @@ export default function LanguageModel() {
|
||||
})
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!opInfo.opType) return;
|
||||
if (['edit', 'new'].includes(opInfo.opType)) {
|
||||
setVisible(true);
|
||||
}
|
||||
if (['delete'].includes(opInfo.opType)) {
|
||||
const data = opRemove(opInfo?.opRecord?.[opSafeKey]);
|
||||
modelSet(data);
|
||||
opInfo.resetRecord();
|
||||
}
|
||||
}, [opInfo.opType, formRef]);
|
||||
const handleOpenFile = async () => {
|
||||
const path = await chatModelPath();
|
||||
setChatModelPath(path);
|
||||
invoke('open_file', { path });
|
||||
};
|
||||
|
||||
const modalTitle = `${({ new: 'Create', edit: 'Edit' })[opInfo.opType]} Language Model`;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button className="add-btn" type="primary" onClick={opInfo.opNew}>Add Model</Button>
|
||||
<div className="chat-model-path">PATH: <span onClick={handleOpenFile}>{modelPath}</span></div>
|
||||
<Table
|
||||
key={opInfo.opTime}
|
||||
rowKey="cmd"
|
||||
columns={columns}
|
||||
scroll={{ x: 'auto' }}
|
||||
dataSource={opData}
|
||||
pagination={{
|
||||
hideOnSinglePage: true,
|
||||
|
Loading…
Reference in New Issue
Block a user