Skip to content

Commit 025167f

Browse files
committed
feat: add custom navs
1 parent c2cb445 commit 025167f

File tree

8 files changed

+234
-731
lines changed

8 files changed

+234
-731
lines changed

electron/main/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ app.whenReady().then(() => {
128128
// electron-vite-vue#298
129129
winAbout.webContents.loadURL(`${url}#/about`);
130130
} else {
131-
winAbout.webContents.loadFile(`${indexHtml}#/about`);
131+
winAbout.webContents.loadFile(`${indexHtml}`, {
132+
hash: "/about"
133+
});
132134
}
133135
}
134136
},

package.json

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vocechat-desktop",
3-
"version": "0.7.4",
3+
"version": "0.7.5",
44
"main": "dist-electron/main/index.js",
55
"description": "vocechat desktop version",
66
"author": "Tristan <yanggc888@163.com>",
@@ -25,6 +25,7 @@
2525
"@tippyjs/react": "^4.2.6",
2626
"clsx": "^2.0.0",
2727
"electron-updater": "^6.1.1",
28+
"framer-motion": "^10.13.1",
2829
"react-redux": "^8.1.1",
2930
"react-router-dom": "^6.14.2",
3031
"redux-state-sync": "^3.1.4",
@@ -33,15 +34,15 @@
3334
},
3435
"devDependencies": {
3536
"@ianvs/prettier-plugin-sort-imports": "^4.1.0",
36-
"@types/react": "^18.2.15",
37+
"@types/react": "^18.2.16",
3738
"@types/react-dom": "^18.2.7",
3839
"@types/redux-state-sync": "^3.1.5",
39-
"@typescript-eslint/eslint-plugin": "^6.1.0",
40-
"@typescript-eslint/parser": "^6.1.0",
40+
"@typescript-eslint/eslint-plugin": "^6.2.0",
41+
"@typescript-eslint/parser": "^6.2.0",
4142
"@vitejs/plugin-react": "^4.0.3",
4243
"autoprefixer": "^10.4.14",
4344
"electron": "^25.3.1",
44-
"electron-builder": "^24.4.0",
45+
"electron-builder": "^24.6.3",
4546
"electron-builder-notarize": "^1.5.1",
4647
"eslint": "^8.45.0",
4748
"eslint-config-prettier": "^8.8.0",
@@ -56,7 +57,7 @@
5657
"react-dom": "^18.2.0",
5758
"tailwindcss": "^3.3.3",
5859
"typescript": "^5.1.6",
59-
"vite": "^4.4.6",
60+
"vite": "^4.4.7",
6061
"vite-plugin-electron": "^0.12.0",
6162
"vite-plugin-electron-renderer": "^0.14.5",
6263
"vite-plugin-svgr": "^3.2.0",

src/assets/icons/arrow.left.svg

Lines changed: 3 additions & 0 deletions
Loading

src/assets/icons/arrow.right.svg

Lines changed: 3 additions & 0 deletions
Loading

src/assets/icons/drag.svg

Lines changed: 3 additions & 0 deletions
Loading

src/assets/icons/refresh.svg

Lines changed: 3 additions & 0 deletions
Loading

src/components/layout.tsx

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
import { MouseEvent, useEffect, useState } from "react";
1+
import { MouseEvent, useEffect, useRef, useState } from "react";
22
import { useDispatch } from "react-redux";
33
import clsx from "clsx";
4-
4+
import { motion } from "framer-motion";
55
import { switchServer, updateAddModalVisible } from "@/app/slices/data";
66
import { useAppSelector } from "@/app/store";
77
import { ReactComponent as IconAdd } from "@/assets/icons/add.svg";
8+
// import { ReactComponent as IconDrag } from "@/assets/icons/drag.svg";
9+
import { ReactComponent as IconRefresh } from "@/assets/icons/refresh.svg";
10+
import { ReactComponent as IconLeft } from "@/assets/icons/arrow.left.svg";
11+
import { ReactComponent as IconRight } from "@/assets/icons/arrow.right.svg";
812
// import { isDarkMode } from "@/utils";
913
import ServerTip from "./server-tip";
1014
import AddServerModal from "./modal-add-server";
@@ -15,17 +19,21 @@ import { hideAll } from "tippy.js";
1519
import ContextMenu, { MenuItem } from "./context-menu";
1620

1721
const Layout = () => {
22+
const webviewContainerRef = useRef(null);
1823
const [removeServer, setRemoveServer] = useState<undefined | string>();
1924
const [reloadVisible, setReloadVisible] = useState(false);
2025
const [menuVisibleMap, setMenuVisibleMap] = useState<Record<string, boolean>>({});
2126
const { servers, active, addModalVisible } = useAppSelector((store) => store.data);
2227
const dispatch = useDispatch();
28+
// const dragControls = useDragControls();
2329
useEffect(() => {
2430
if (servers.length == 0) {
2531
handleAddServer();
2632
}
2733
}, [servers]);
28-
34+
// const startDrag = (event: any) => {
35+
// dragControls.start(event, { snapToCursor: true });
36+
// };
2937
const handleSwitch = (evt: MouseEvent<HTMLLIElement>) => {
3038
console.log("switch");
3139
const { url } = evt.currentTarget.dataset;
@@ -34,6 +42,25 @@ const Layout = () => {
3442
dispatch(switchServer(url));
3543
}
3644
};
45+
const handleWebviewNav = (cmd: "back" | "forward" | "refresh") => {
46+
const wv = document.querySelector("webview[data-visible='true']") as WebviewTag;
47+
if (wv) {
48+
switch (cmd) {
49+
case "back":
50+
wv.goBack();
51+
break;
52+
case "forward":
53+
wv.goForward();
54+
break;
55+
case "refresh":
56+
wv.reload();
57+
break;
58+
59+
default:
60+
break;
61+
}
62+
}
63+
};
3764
const handleAddServer = () => {
3865
dispatch(updateAddModalVisible(true));
3966
};
@@ -106,6 +133,7 @@ const Layout = () => {
106133
}
107134
return (
108135
<Tippy
136+
key={web_url}
109137
appendTo={document.body}
110138
offset={[-20, 34]}
111139
onClickOutside={hideContextMenu.bind(null, web_url)}
@@ -164,7 +192,10 @@ const Layout = () => {
164192
</div>
165193
</ServerTip>
166194
</aside>
167-
<main className="relative flex h-full flex-1 items-center justify-center">
195+
<motion.main
196+
ref={webviewContainerRef}
197+
className="relative flex h-full flex-1 items-center justify-center"
198+
>
168199
{servers.map((server) => {
169200
const { web_url } = server;
170201

@@ -176,18 +207,51 @@ const Layout = () => {
176207
//@ts-ignore
177208
//eslint-disable-next-line react/no-unknown-property
178209
disablewebsecurity="true"
179-
useragent={`${navigator.userAgent} ${process.platform}`}
210+
key={web_url}
180211
className={clsx(
181212
"absolute left-0 top-0 h-full w-full",
182213
active == web_url ? "visible" : "invisible"
183214
)}
215+
useragent={`${navigator.userAgent} ${process.platform}`}
184216
data-visible={active == web_url}
185-
key={web_url}
186217
src={web_url}
187218
></webview>
188219
);
189220
})}
190-
</main>
221+
<motion.div
222+
drag
223+
// dragControls={dragControls}
224+
dragListener={false}
225+
dragConstraints={webviewContainerRef}
226+
dragElastic={false}
227+
dragMomentum={false}
228+
className="group absolute bottom-1 left-1/2 flex -translate-x-1/2 flex-col items-center opacity-50 hover:opacity-100"
229+
>
230+
{/* <button onPointerDown={startDrag} className="invisible cursor-move group-hover:visible">
231+
<IconDrag className="h-4 w-4 dark:stroke-gray-200" />
232+
</button> */}
233+
<div className="flex overflow-hidden rounded-lg border border-gray-500">
234+
<button
235+
onClick={handleWebviewNav.bind(null, "back")}
236+
className=" px-2 py-1 hover:bg-gray-500"
237+
>
238+
<IconLeft className="dark:stroke-gray-200" />
239+
</button>
240+
<button
241+
onClick={handleWebviewNav.bind(null, "refresh")}
242+
className=" px-2 py-1 hover:bg-gray-500"
243+
>
244+
<IconRefresh className="dark:stroke-gray-200" />
245+
</button>
246+
<button
247+
onClick={handleWebviewNav.bind(null, "forward")}
248+
className=" px-2 py-1 hover:bg-gray-500"
249+
>
250+
<IconRight className="dark:stroke-gray-200" />
251+
</button>
252+
</div>
253+
</motion.div>
254+
</motion.main>
191255

192256
{contextMenuVisible ? (
193257
<div className="menu-mask fixed left-0 top-0 z-10 h-full w-full"></div>

0 commit comments

Comments
 (0)