mirror of
https://github.com/FranP-code/ChatGPT.git
synced 2025-10-13 00:13:25 +00:00
chore: dashboard
This commit is contained in:
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1,3 +1,3 @@
|
|||||||
*.js linguist-vendored
|
*.js linguist-vendored
|
||||||
*.tsx linguist-vendored
|
*.tsx linguist-vendored
|
||||||
*.css linguist-vendored
|
*.scss linguist-vendored
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<img width="180" src="./logo.png" alt="ChatGPT">
|
<img width="180" src="./public/logo.png" alt="ChatGPT">
|
||||||
<h1 align="center">ChatGPT</h1>
|
<h1 align="center">ChatGPT</h1>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|||||||
12
package.json
12
package.json
@@ -30,18 +30,22 @@
|
|||||||
"url": "https://github.com/lencx/ChatGPT"
|
"url": "https://github.com/lencx/ChatGPT"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@tauri-apps/api": "^1.2.0",
|
||||||
|
"antd": "^5.0.6",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"@tauri-apps/api": "^1.2.0"
|
"react-router-dom": "^6.4.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@tauri-apps/cli": "^1.2.2",
|
||||||
|
"@tauri-release/cli": "^0.2.3",
|
||||||
"@types/node": "^18.7.10",
|
"@types/node": "^18.7.10",
|
||||||
"@types/react": "^18.0.15",
|
"@types/react": "^18.0.15",
|
||||||
"@types/react-dom": "^18.0.6",
|
"@types/react-dom": "^18.0.6",
|
||||||
"@vitejs/plugin-react": "^3.0.0",
|
"@vitejs/plugin-react": "^3.0.0",
|
||||||
"typescript": "^4.6.4",
|
"sass": "^1.56.2",
|
||||||
|
"typescript": "^4.9.4",
|
||||||
"vite": "^4.0.0",
|
"vite": "^4.0.0",
|
||||||
"@tauri-apps/cli": "^1.2.2",
|
"vite-tsconfig-paths": "^4.0.2"
|
||||||
"@tauri-release/cli": "^0.2.3"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
@@ -48,6 +48,10 @@ pub fn init(context: &Context<EmbeddedAssets>) -> Menu {
|
|||||||
let preferences_menu = Submenu::new(
|
let preferences_menu = Submenu::new(
|
||||||
"Preferences",
|
"Preferences",
|
||||||
Menu::with_items([
|
Menu::with_items([
|
||||||
|
CustomMenuItem::new("dashboard".to_string(), "Dashboard")
|
||||||
|
.accelerator("CmdOrCtrl+D")
|
||||||
|
.into(),
|
||||||
|
MenuItem::Separator.into(),
|
||||||
Submenu::new(
|
Submenu::new(
|
||||||
"Theme",
|
"Theme",
|
||||||
Menu::new()
|
Menu::new()
|
||||||
@@ -165,6 +169,7 @@ pub fn menu_handler(event: WindowMenuEvent<tauri::Wry>) {
|
|||||||
|
|
||||||
match menu_id {
|
match menu_id {
|
||||||
// Preferences
|
// Preferences
|
||||||
|
"dashboard" => app.get_window("main").unwrap().show().unwrap(),
|
||||||
"restart" => tauri::api::process::restart(&app.env()),
|
"restart" => tauri::api::process::restart(&app.env()),
|
||||||
"inject_script" => open(&app, script_path),
|
"inject_script" => open(&app, script_path),
|
||||||
"go_conf" => utils::open_file(utils::chat_root()),
|
"go_conf" => utils::open_file(utils::chat_root()),
|
||||||
|
|||||||
@@ -36,10 +36,15 @@ fn main() {
|
|||||||
.on_window_event(|event| {
|
.on_window_event(|event| {
|
||||||
// https://github.com/tauri-apps/tauri/discussions/2684
|
// https://github.com/tauri-apps/tauri/discussions/2684
|
||||||
if let tauri::WindowEvent::CloseRequested { api, .. } = event.event() {
|
if let tauri::WindowEvent::CloseRequested { api, .. } = event.event() {
|
||||||
// TODO: https://github.com/tauri-apps/tauri/issues/3084
|
let win = event.window();
|
||||||
// event.window().hide().unwrap();
|
if win.label() == "main" {
|
||||||
// https://github.com/tauri-apps/tao/pull/517
|
win.hide().unwrap();
|
||||||
event.window().minimize().unwrap();
|
} else {
|
||||||
|
// TODO: https://github.com/tauri-apps/tauri/issues/3084
|
||||||
|
// event.window().hide().unwrap();
|
||||||
|
// https://github.com/tauri-apps/tao/pull/517
|
||||||
|
event.window().minimize().unwrap();
|
||||||
|
}
|
||||||
api.prevent_close();
|
api.prevent_close();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "npm run dev:fe",
|
"beforeDevCommand": "npm run dev:fe",
|
||||||
"beforeBuildCommand": "npm run build:fe",
|
"beforeBuildCommand": "npm run build:fe",
|
||||||
"devPath": "http://localhost:1420/",
|
"devPath": "http://localhost:1420",
|
||||||
"distDir": "../dist"
|
"distDir": "../dist"
|
||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
@@ -68,6 +68,7 @@
|
|||||||
{
|
{
|
||||||
"label": "main",
|
"label": "main",
|
||||||
"url": "index.html",
|
"url": "index.html",
|
||||||
|
"title": "ChatGPT",
|
||||||
"visible": false
|
"visible": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
.logo.vite:hover {
|
|
||||||
filter: drop-shadow(0 0 2em #747bff);
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo.react:hover {
|
|
||||||
filter: drop-shadow(0 0 2em #61dafb);
|
|
||||||
}
|
|
||||||
11
src/App.tsx
vendored
11
src/App.tsx
vendored
@@ -1,11 +0,0 @@
|
|||||||
import "./App.css";
|
|
||||||
|
|
||||||
function App() {
|
|
||||||
return (
|
|
||||||
<div className="container">
|
|
||||||
ChatGPT
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default App;
|
|
||||||
13
src/layout/index.scss
vendored
Normal file
13
src/layout/index.scss
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
.chat-logo {
|
||||||
|
text-align: center;
|
||||||
|
padding: 5px 0;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
57
src/layout/index.tsx
vendored
Normal file
57
src/layout/index.tsx
vendored
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import { FC, useState } from 'react';
|
||||||
|
import {
|
||||||
|
DesktopOutlined,
|
||||||
|
BulbOutlined
|
||||||
|
} from '@ant-design/icons';
|
||||||
|
import type { MenuProps } from 'antd';
|
||||||
|
import { Layout, Menu } from 'antd';
|
||||||
|
import './index.scss';
|
||||||
|
|
||||||
|
const { Content, Footer, Sider } = Layout;
|
||||||
|
|
||||||
|
type MenuItem = Required<MenuProps>['items'][number];
|
||||||
|
|
||||||
|
function getItem(
|
||||||
|
label: React.ReactNode,
|
||||||
|
key: React.Key,
|
||||||
|
icon?: React.ReactNode,
|
||||||
|
children?: MenuItem[],
|
||||||
|
): MenuItem {
|
||||||
|
return {
|
||||||
|
key,
|
||||||
|
icon,
|
||||||
|
children,
|
||||||
|
label,
|
||||||
|
} as MenuItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
const items: MenuItem[] = [
|
||||||
|
getItem('General', 'general', <DesktopOutlined />),
|
||||||
|
getItem('ChatGPT Prompts', 'chatgpt-prompts', <BulbOutlined />),
|
||||||
|
];
|
||||||
|
|
||||||
|
interface ChatLayoutProps {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ChatLayout: FC<ChatLayoutProps> = ({ children }) => {
|
||||||
|
const [collapsed, setCollapsed] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Layout style={{ minHeight: '100vh' }}>
|
||||||
|
<Sider theme="light" collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)}>
|
||||||
|
<div className="chat-logo"><img src="/logo.png" /></div>
|
||||||
|
<Menu defaultSelectedKeys={['1']} mode="inline" items={items} />
|
||||||
|
</Sider>
|
||||||
|
<Layout className="chat-layout">
|
||||||
|
<Content className="chat-container">
|
||||||
|
{children}
|
||||||
|
</Content>
|
||||||
|
<Footer style={{ textAlign: 'center' }}>
|
||||||
|
<a href="https://github.com/lencx/chatgpt" target="_blank">ChatGPT Desktop Application</a> ©2022 Created by lencx</Footer>
|
||||||
|
</Layout>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ChatLayout;
|
||||||
20
src/main.scss
vendored
Normal file
20
src/main.scss
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
:root {
|
||||||
|
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 24px;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
color: #2a2a2a;
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
|
||||||
|
font-synthesis: none;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
21
src/main.tsx
vendored
21
src/main.tsx
vendored
@@ -1,11 +1,16 @@
|
|||||||
import React from "react";
|
import { StrictMode, Suspense } from 'react';
|
||||||
import ReactDOM from "react-dom/client";
|
import { BrowserRouter } from 'react-router-dom';
|
||||||
|
import ReactDOM from 'react-dom/client';
|
||||||
|
|
||||||
import App from "./App";
|
import Routes from './routes';
|
||||||
import "./style.css";
|
import './main.scss';
|
||||||
|
|
||||||
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
|
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
||||||
<React.StrictMode>
|
<StrictMode>
|
||||||
<App />
|
<Suspense fallback={null}>
|
||||||
</React.StrictMode>
|
<BrowserRouter>
|
||||||
|
<Routes />
|
||||||
|
</BrowserRouter>
|
||||||
|
</Suspense>
|
||||||
|
</StrictMode>
|
||||||
);
|
);
|
||||||
|
|||||||
22
src/routes.tsx
vendored
Normal file
22
src/routes.tsx
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { useLayoutEffect } from 'react';
|
||||||
|
import { useLocation, useRoutes } from 'react-router-dom';
|
||||||
|
import type { RouteObject } from 'react-router-dom';
|
||||||
|
|
||||||
|
import App from '@view/App';
|
||||||
|
|
||||||
|
const routes: RouteObject[] = [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
element: <App />
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const location = useLocation();
|
||||||
|
const pathname = location.pathname;
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
const name = pathname.substring(1).replace(/\//gi, '_');
|
||||||
|
document.body.className = `${name ? name : 'main'}_screen`
|
||||||
|
}, [pathname]);
|
||||||
|
return useRoutes(routes);
|
||||||
|
};
|
||||||
102
src/style.css
102
src/style.css
@@ -1,102 +0,0 @@
|
|||||||
:root {
|
|
||||||
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 24px;
|
|
||||||
font-weight: 400;
|
|
||||||
|
|
||||||
color: #0f0f0f;
|
|
||||||
background-color: #f6f6f6;
|
|
||||||
|
|
||||||
font-synthesis: none;
|
|
||||||
text-rendering: optimizeLegibility;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
-webkit-text-size-adjust: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
margin: 0;
|
|
||||||
padding-top: 10vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
height: 6em;
|
|
||||||
padding: 1.5em;
|
|
||||||
will-change: filter;
|
|
||||||
transition: 0.75s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo.tauri:hover {
|
|
||||||
filter: drop-shadow(0 0 2em #24c8db);
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
font-weight: 500;
|
|
||||||
color: #646cff;
|
|
||||||
text-decoration: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
color: #535bf2;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
input,
|
|
||||||
button {
|
|
||||||
border-radius: 8px;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
padding: 0.6em 1.2em;
|
|
||||||
font-size: 1em;
|
|
||||||
font-weight: 500;
|
|
||||||
font-family: inherit;
|
|
||||||
color: #0f0f0f;
|
|
||||||
background-color: #ffffff;
|
|
||||||
transition: border-color 0.25s;
|
|
||||||
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:hover {
|
|
||||||
border-color: #396cd8;
|
|
||||||
}
|
|
||||||
|
|
||||||
input,
|
|
||||||
button {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#greet-input {
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
:root {
|
|
||||||
color: #f6f6f6;
|
|
||||||
background-color: #2f2f2f;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
color: #24c8db;
|
|
||||||
}
|
|
||||||
|
|
||||||
input,
|
|
||||||
button {
|
|
||||||
color: #ffffff;
|
|
||||||
background-color: #0f0f0f98;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
9
src/view/App.tsx
vendored
Normal file
9
src/view/App.tsx
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import Layout from "@layout/index";
|
||||||
|
|
||||||
|
export default function Dashboard() {
|
||||||
|
return (
|
||||||
|
<Layout>
|
||||||
|
Hello
|
||||||
|
</Layout>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -14,7 +14,13 @@
|
|||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"jsx": "react-jsx"
|
"jsx": "react-jsx",
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@view/*": ["src/view/*"],
|
||||||
|
"@comps/*": ["src/components/*"],
|
||||||
|
"@layout/*": ["src/layout/*"],
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": ["src"],
|
||||||
"references": [{ "path": "./tsconfig.node.json" }]
|
"references": [{ "path": "./tsconfig.node.json" }]
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { defineConfig } from "vite";
|
import { defineConfig } from "vite";
|
||||||
import react from "@vitejs/plugin-react";
|
import react from "@vitejs/plugin-react";
|
||||||
|
import tsconfigPaths from "vite-tsconfig-paths";
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react()],
|
plugins: [tsconfigPaths(), react()],
|
||||||
|
|
||||||
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
|
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
|
||||||
// prevent vite from obscuring rust errors
|
// prevent vite from obscuring rust errors
|
||||||
|
|||||||
Reference in New Issue
Block a user