diff --git a/client/packages/rtc-web/.eslintrc.cjs b/client/packages/rtc-web/.eslintrc.cjs
index 574cae5..503f1af 100644
--- a/client/packages/rtc-web/.eslintrc.cjs
+++ b/client/packages/rtc-web/.eslintrc.cjs
@@ -20,5 +20,6 @@ module.exports = {
rules: {
indent: ['error', 2],
semi: ['error', 'always'],
+ 'vue/attribute-hyphenation': 'off',
},
};
diff --git a/client/packages/rtc-web/index.html b/client/packages/rtc-web/index.html
index 143557b..c92fabd 100644
--- a/client/packages/rtc-web/index.html
+++ b/client/packages/rtc-web/index.html
@@ -4,7 +4,7 @@
-
Vite + Vue + TS
+ Rtc
diff --git a/client/packages/rtc-web/package.json b/client/packages/rtc-web/package.json
index e67e947..05138df 100644
--- a/client/packages/rtc-web/package.json
+++ b/client/packages/rtc-web/package.json
@@ -9,7 +9,10 @@
},
"dependencies": {
"@vitejs/plugin-vue-jsx": "^3.0.1",
- "vue": "^3.3.4"
+ "@vueuse/core": "^10.2.0",
+ "theme-change": "^2.5.0",
+ "vue": "^3.3.4",
+ "vue-router": "4"
},
"devDependencies": {
"@types/node": "^20.3.1",
diff --git a/client/packages/rtc-web/src/App.vue b/client/packages/rtc-web/src/App.vue
index a7d8731..8853cc7 100644
--- a/client/packages/rtc-web/src/App.vue
+++ b/client/packages/rtc-web/src/App.vue
@@ -2,6 +2,7 @@
import Layout from '@/layout/index.vue';
+
diff --git a/client/packages/rtc-web/src/assets/svg-icon/github.svg b/client/packages/rtc-web/src/assets/svg-icon/github.svg
new file mode 100644
index 0000000..83901c3
--- /dev/null
+++ b/client/packages/rtc-web/src/assets/svg-icon/github.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/client/packages/rtc-web/src/assets/svg-icon/moon.svg b/client/packages/rtc-web/src/assets/svg-icon/moon.svg
new file mode 100644
index 0000000..17e0c9a
--- /dev/null
+++ b/client/packages/rtc-web/src/assets/svg-icon/moon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/client/packages/rtc-web/src/assets/svg-icon/sun.svg b/client/packages/rtc-web/src/assets/svg-icon/sun.svg
new file mode 100644
index 0000000..476d5b2
--- /dev/null
+++ b/client/packages/rtc-web/src/assets/svg-icon/sun.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/client/packages/rtc-web/src/components/base/index.ts b/client/packages/rtc-web/src/components/base/index.ts
index 707bf95..bfc3e31 100644
--- a/client/packages/rtc-web/src/components/base/index.ts
+++ b/client/packages/rtc-web/src/components/base/index.ts
@@ -1,2 +1,3 @@
export { default as SvgIcon } from './svg-icon.vue';
export { default as MenuSide } from './menu-side.vue';
+export { default as NavIcons } from './nav-icons.vue';
diff --git a/client/packages/rtc-web/src/components/base/nav-icons.vue b/client/packages/rtc-web/src/components/base/nav-icons.vue
new file mode 100644
index 0000000..e849f7d
--- /dev/null
+++ b/client/packages/rtc-web/src/components/base/nav-icons.vue
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
diff --git a/client/packages/rtc-web/src/components/base/svg-icon.vue b/client/packages/rtc-web/src/components/base/svg-icon.vue
index d655b53..e540b3d 100644
--- a/client/packages/rtc-web/src/components/base/svg-icon.vue
+++ b/client/packages/rtc-web/src/components/base/svg-icon.vue
@@ -1,10 +1,11 @@
-
+
+
diff --git a/client/packages/rtc-web/src/components/lib.tsx b/client/packages/rtc-web/src/components/lib.tsx
index ea36580..efb1082 100644
--- a/client/packages/rtc-web/src/components/lib.tsx
+++ b/client/packages/rtc-web/src/components/lib.tsx
@@ -1,13 +1,7 @@
import { SetupContext } from 'vue';
-import { MenuSide, SvgIcon } from './base';
+import { MenuSide, SvgIcon, NavIcons } from './base';
-;
-
-export function NavHeader() {
+export const NavHeader = () => {
return (
@@ -24,6 +18,7 @@ export function NavHeader() {
Web-Rtc
+
@@ -32,20 +27,27 @@ export function NavHeader() {
);
-}
+};
-export function FullScreenBox(
- props: { dire: 'col' | 'row' },
+export type FullHeightFlexBoxProps = Partial<{
+ dire: 'col' | 'row';
+ type: 'full' | 'screen';
+}>;
+
+export const FullHeightFlexBox = (
+ props: FullHeightFlexBoxProps,
ctx: SetupContext
-) {
- const { dire } = props;
+) => {
+ const { dire = 'row', type = 'screen' } = props;
+
+ const height: Record<'full' | 'screen', string> = {
+ full: 'h-full',
+ screen: 'h-screen',
+ };
+
return (
-
+
{ctx.slots.default?.()}
);
-}
-
-export function NavContent(_: unknown, ctx: SetupContext) {
- return
{ctx.slots.default?.()}
;
-}
+};
diff --git a/client/packages/rtc-web/src/hooks/index.ts b/client/packages/rtc-web/src/hooks/index.ts
new file mode 100644
index 0000000..7baad7d
--- /dev/null
+++ b/client/packages/rtc-web/src/hooks/index.ts
@@ -0,0 +1 @@
+export * from './useTheme';
diff --git a/client/packages/rtc-web/src/hooks/useTheme.ts b/client/packages/rtc-web/src/hooks/useTheme.ts
new file mode 100644
index 0000000..b645835
--- /dev/null
+++ b/client/packages/rtc-web/src/hooks/useTheme.ts
@@ -0,0 +1,42 @@
+import { themeChange } from 'theme-change';
+import { useLocalStorage, usePreferredDark } from '@vueuse/core';
+import { onMounted, watch } from 'vue';
+
+export enum ThemeEnum {
+ DARK = 'dark',
+ LIGHT = 'light',
+}
+
+export const useTheme = () => {
+ const isPreferredDark = usePreferredDark();
+
+ const themeInfo = useLocalStorage
(
+ 'rtc-theme',
+ isPreferredDark ? ThemeEnum.DARK : ThemeEnum.LIGHT
+ );
+
+ const setTheme = (theme: ThemeEnum) => {
+ themeInfo.value = theme;
+ };
+
+ return {
+ themeInfo,
+ setTheme,
+ };
+};
+
+export const useSwitchTheme = () => {
+ const { themeInfo, setTheme } = useTheme();
+
+ watch(
+ () => themeInfo.value,
+ (v) => {
+ document.documentElement.setAttribute('data-theme', v);
+ },
+ {
+ immediate: true,
+ }
+ );
+
+ return { themeInfo, setTheme };
+};
diff --git a/client/packages/rtc-web/src/layout/index.vue b/client/packages/rtc-web/src/layout/index.vue
index f3cab89..601db61 100644
--- a/client/packages/rtc-web/src/layout/index.vue
+++ b/client/packages/rtc-web/src/layout/index.vue
@@ -1,6 +1,6 @@
-
+
-
+
- content
-
-
+
+
+
diff --git a/client/packages/rtc-web/src/main.ts b/client/packages/rtc-web/src/main.ts
index 51f4b5e..f8ccbe9 100644
--- a/client/packages/rtc-web/src/main.ts
+++ b/client/packages/rtc-web/src/main.ts
@@ -1,12 +1,15 @@
import { createApp } from 'vue';
import './assets/styles/index.css';
-import App from './App.vue';
+
+import router from './routes';
import 'virtual:svg-icons-register';
import SvgIcon from '@/components/base/svg-icon.vue';
+import App from './App.vue';
+
function setup() {
- return createApp(App).component('svg-icon', SvgIcon);
+ return createApp(App).use(router).component('svg-icon', SvgIcon);
}
setup().mount('#app');
diff --git a/client/packages/rtc-web/src/routes/index.ts b/client/packages/rtc-web/src/routes/index.ts
new file mode 100644
index 0000000..3502572
--- /dev/null
+++ b/client/packages/rtc-web/src/routes/index.ts
@@ -0,0 +1,8 @@
+import { createWebHistory, createRouter } from 'vue-router';
+
+import { routes } from './router';
+
+export default createRouter({
+ history: createWebHistory(),
+ routes,
+});
diff --git a/client/packages/rtc-web/src/routes/router.ts b/client/packages/rtc-web/src/routes/router.ts
new file mode 100644
index 0000000..b713658
--- /dev/null
+++ b/client/packages/rtc-web/src/routes/router.ts
@@ -0,0 +1,4 @@
+export const routes = [
+ { path: '/', component: () => import('@/views/welcome.vue') },
+ { path: '/chat', component: () => import('@/views/chat/chat.vue') },
+];
diff --git a/client/packages/rtc-web/src/views/chat/chat.vue b/client/packages/rtc-web/src/views/chat/chat.vue
new file mode 100644
index 0000000..bdb53c7
--- /dev/null
+++ b/client/packages/rtc-web/src/views/chat/chat.vue
@@ -0,0 +1,11 @@
+
+
+
+ 我是chat
+
+
+
diff --git a/client/packages/rtc-web/src/views/file/file.vue b/client/packages/rtc-web/src/views/file/file.vue
new file mode 100644
index 0000000..13d7b1e
--- /dev/null
+++ b/client/packages/rtc-web/src/views/file/file.vue
@@ -0,0 +1,11 @@
+
+
+
+ 发送文件
+
+
+
diff --git a/client/packages/rtc-web/src/views/welcome.vue b/client/packages/rtc-web/src/views/welcome.vue
new file mode 100644
index 0000000..184e808
--- /dev/null
+++ b/client/packages/rtc-web/src/views/welcome.vue
@@ -0,0 +1,11 @@
+
+
+
+ Welcome
+
+
+
diff --git a/client/packages/rtc-web/tailwind.config.js b/client/packages/rtc-web/tailwind.config.js
index 1de13d1..61c865e 100644
--- a/client/packages/rtc-web/tailwind.config.js
+++ b/client/packages/rtc-web/tailwind.config.js
@@ -1,6 +1,10 @@
/** @type {import('tailwindcss').Config} */
export default {
+ darkMode: 'class',
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
+ daisyui: {
+ themes: ['light', 'dark'],
+ },
theme: {
extend: {},
},
diff --git a/client/pnpm-lock.yaml b/client/pnpm-lock.yaml
index d8a6fc9..4c605c7 100644
--- a/client/pnpm-lock.yaml
+++ b/client/pnpm-lock.yaml
@@ -12,6 +12,7 @@ importers:
'@typescript-eslint/parser': ^5.60.0
'@vitejs/plugin-vue': ^4.2.3
'@vitejs/plugin-vue-jsx': ^3.0.1
+ '@vueuse/core': ^10.2.0
autoprefixer: ^10.4.14
daisyui: ^3.1.6
eslint: ^8.43.0
@@ -23,16 +24,21 @@ importers:
prettier: ^2.8.8
prettier-plugin-tailwindcss: ^0.3.0
tailwindcss: ^3.3.2
+ theme-change: ^2.5.0
typescript: ^5.1.3
vite: ^4.3.9
vite-plugin-eslint: ^1.8.1
vite-plugin-svg-icons: ^2.0.1
vue: ^3.3.4
vue-eslint-parser: ^9.3.1
+ vue-router: '4'
vue-tsc: ^1.8.1
dependencies:
'@vitejs/plugin-vue-jsx': 3.0.1_vite@4.3.9+vue@3.3.4
+ '@vueuse/core': 10.2.0_vue@3.3.4
+ theme-change: 2.5.0
vue: 3.3.4
+ vue-router: 4.2.2_vue@3.3.4
devDependencies:
'@types/node': 20.3.2
'@typescript-eslint/eslint-plugin': 5.60.1_emhilanx7rvvqwlixwztbx5x2m
@@ -687,6 +693,10 @@ packages:
'@types/node': 20.3.2
dev: true
+ /@types/web-bluetooth/0.0.17:
+ resolution: {integrity: sha512-4p9vcSmxAayx72yn70joFoL44c9MO/0+iVEBIQXe3v2h2SiAsEIo/G5v6ObFWvNKRFjbrVadNf9LqEEZeQPzdA==}
+ dev: false
+
/@typescript-eslint/eslint-plugin/5.60.1_emhilanx7rvvqwlixwztbx5x2m:
resolution: {integrity: sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -919,6 +929,10 @@ packages:
'@vue/compiler-dom': 3.3.4
'@vue/shared': 3.3.4
+ /@vue/devtools-api/6.5.0:
+ resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==}
+ dev: false
+
/@vue/language-core/1.8.2_typescript@5.1.3:
resolution: {integrity: sha512-QJujhmp89TRoWwzjn2sPMezG97+mNyaCTfznGHWNCE3LBsillZCBqAO7M7cxO8ee1V3r+qHjWytkoh3M4YkRJw==}
peerDependencies:
@@ -986,6 +1000,31 @@ packages:
- typescript
dev: true
+ /@vueuse/core/10.2.0_vue@3.3.4:
+ resolution: {integrity: sha512-aHBnoCteIS3hFu7ZZkVB93SanVDY6t4TIb7XDLxJT/HQdAZz+2RdIEJ8rj5LUoEJr7Damb5+sJmtpCwGez5ozQ==}
+ dependencies:
+ '@types/web-bluetooth': 0.0.17
+ '@vueuse/metadata': 10.2.0
+ '@vueuse/shared': 10.2.0_vue@3.3.4
+ vue-demi: 0.14.5_vue@3.3.4
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+ dev: false
+
+ /@vueuse/metadata/10.2.0:
+ resolution: {integrity: sha512-IR7Mkq6QSgZ38q/2ZzOt+Zz1OpcEsnwE64WBumDQ+RGKrosFCtUA2zgRrOqDEzPBXrVB+4HhFkwDjQMu0fDBKw==}
+ dev: false
+
+ /@vueuse/shared/10.2.0_vue@3.3.4:
+ resolution: {integrity: sha512-dIeA8+g9Av3H5iF4NXR/sft4V6vys76CpZ6hxwj8eMXybXk2WRl3scSsOVi+kQ9SX38COR7AH7WwY83UcuxbSg==}
+ dependencies:
+ vue-demi: 0.14.5_vue@3.3.4
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+ dev: false
+
/acorn-jsx/5.3.2_acorn@8.9.0:
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies:
@@ -3283,6 +3322,10 @@ packages:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
dev: true
+ /theme-change/2.5.0:
+ resolution: {integrity: sha512-B/UdsgdHAGhSKHTAQnxg/etN0RaMDpehuJmZIjLMDVJ6DGIliRHGD6pODi1CXLQAN9GV0GSyB3G6yCuK05PkPQ==}
+ dev: false
+
/thenify-all/1.6.0:
resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
engines: {node: '>=0.8'}
@@ -3493,6 +3536,21 @@ packages:
optionalDependencies:
fsevents: 2.3.2
+ /vue-demi/0.14.5_vue@3.3.4:
+ resolution: {integrity: sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==}
+ engines: {node: '>=12'}
+ hasBin: true
+ requiresBuild: true
+ peerDependencies:
+ '@vue/composition-api': ^1.0.0-rc.1
+ vue: ^3.0.0-0 || ^2.6.0
+ peerDependenciesMeta:
+ '@vue/composition-api':
+ optional: true
+ dependencies:
+ vue: 3.3.4
+ dev: false
+
/vue-eslint-parser/9.3.1_eslint@8.43.0:
resolution: {integrity: sha512-Clr85iD2XFZ3lJ52/ppmUDG/spxQu6+MAeHXjjyI4I1NUYZ9xmenQp4N0oaHJhrA8OOxltCVxMRfANGa70vU0g==}
engines: {node: ^14.17.0 || >=16.0.0}
@@ -3511,6 +3569,15 @@ packages:
- supports-color
dev: true
+ /vue-router/4.2.2_vue@3.3.4:
+ resolution: {integrity: sha512-cChBPPmAflgBGmy3tBsjeoe3f3VOSG6naKyY5pjtrqLGbNEXdzCigFUHgBvp9e3ysAtFtEx7OLqcSDh/1Cq2TQ==}
+ peerDependencies:
+ vue: ^3.2.0
+ dependencies:
+ '@vue/devtools-api': 6.5.0
+ vue: 3.3.4
+ dev: false
+
/vue-template-compiler/2.7.14:
resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==}
dependencies: