From 035d805c5a4b54b84bed4ae78d30e24ba511ef86 Mon Sep 17 00:00:00 2001
From: alexzhang1030 <1642114555@qq.com>
Date: Mon, 11 Dec 2023 13:51:43 +0800
Subject: [PATCH 1/2] feat: add states of split screen
---
packages/client/src/App.vue | 19 ++++++++++++++++++-
packages/client/src/assets/styles/main.css | 18 +++++++-----------
.../src/components/common/DockingPanel.vue | 12 ++++++++++++
packages/client/src/composables/state.ts | 14 ++++++++++++++
4 files changed, 51 insertions(+), 12 deletions(-)
diff --git a/packages/client/src/App.vue b/packages/client/src/App.vue
index 1305a549..a0153f53 100644
--- a/packages/client/src/App.vue
+++ b/packages/client/src/App.vue
@@ -2,6 +2,7 @@
import type { Ref } from 'vue'
import { useDevToolsBridge, useDevToolsState } from '@vue-devtools-next/core'
import { isInChromePanel } from '@vue-devtools-next/shared'
+import { Pane, Splitpanes } from 'splitpanes'
// @TODO: fix browser extension cross-origin localStorage issue
useColorMode()
@@ -36,6 +37,13 @@ useEventListener('keydown', (e) => {
if (e.code === 'KeyD' && e.altKey && e.shiftKey)
bridge.value.emit('toggle-panel')
})
+
+const splitScreenEnabled = computed(() => clientState.value.splitScreen.enabled)
+const isSplitScreenAvailable = splitScreenAvailable
+const splitScreenSize = computed({
+ get: () => clientState.value.splitScreen.size,
+ set: v => clientState.value.splitScreen.size = v,
+})
@@ -49,7 +57,16 @@ useEventListener('keydown', (e) => {
h-full h-screen of-hidden font-sans bg-base
>
-
+ v.size)"
+ >
+
+
+
+
+ hello world
+
+
diff --git a/packages/client/src/assets/styles/main.css b/packages/client/src/assets/styles/main.css
index a22c0c05..427bc954 100644
--- a/packages/client/src/assets/styles/main.css
+++ b/packages/client/src/assets/styles/main.css
@@ -25,39 +25,35 @@ body::-webkit-scrollbar {
.splitpanes__splitter {
position: relative;
}
-
.splitpanes__splitter:before {
position: absolute;
left: 0;
top: 0;
- transition: .2s ease;
+ transition: 0.2s ease;
content: '';
transition: opacity 0.4s;
z-index: 1;
}
-
.splitpanes__splitter:hover:before {
background: #8881;
opacity: 1;
}
-
-.splitpanes--vertical>.splitpanes__splitter {
+.splitpanes--vertical > .splitpanes__splitter {
min-width: 0 !important;
width: 0 !important;
+ @apply border-r border-base;
}
-
-.splitpanes--horizontal>.splitpanes__splitter {
+.splitpanes--horizontal > .splitpanes__splitter {
min-height: 0 !important;
height: 0 !important;
+ --uno: border-t border-base;
}
-
-.splitpanes--vertical>.splitpanes__splitter:before {
+.splitpanes--vertical > .splitpanes__splitter:before {
left: -5px;
right: -4px;
height: 100%;
}
-
-.splitpanes--horizontal>.splitpanes__splitter:before {
+.splitpanes--horizontal > .splitpanes__splitter:before {
top: -5px;
bottom: -4px;
width: 100%;
diff --git a/packages/client/src/components/common/DockingPanel.vue b/packages/client/src/components/common/DockingPanel.vue
index 3e140bcc..e7c44493 100644
--- a/packages/client/src/components/common/DockingPanel.vue
+++ b/packages/client/src/components/common/DockingPanel.vue
@@ -13,6 +13,12 @@ const expandSidebar = computed({
set: v => (devtoolsClientState.value.expandSidebar = v),
})
+const splitScreenEnabled = computed({
+ get: () => devtoolsClientState.value.splitScreen.enabled,
+ set: v => (devtoolsClientState.value.splitScreen.enabled = v),
+})
+const isSplitScreenAvailable = splitScreenAvailable
+
function refreshPage() {
location.reload()
}
@@ -36,6 +42,12 @@ function refreshPage() {
Settings
+
+
+
+ {{ splitScreenEnabled ? 'Close Split Screen' : 'Split Screen' }}
+
+
Refresh Page
diff --git a/packages/client/src/composables/state.ts b/packages/client/src/composables/state.ts
index 2bea1121..2fb05994 100644
--- a/packages/client/src/composables/state.ts
+++ b/packages/client/src/composables/state.ts
@@ -8,6 +8,11 @@ export const devtoolsClientState: RemovableRef<{
graphSettings: GraphSettings
tabSettings: TabSettings
expandSidebar: boolean
+ splitScreen: {
+ enabled: boolean
+ view: string
+ size: [number, number]
+ }
}> = useLocalStorage('__VUE_DEVTOOLS_CLIENT_STATE__', {
isFirstVisit: true,
route: '/',
@@ -21,9 +26,18 @@ export const devtoolsClientState: RemovableRef<{
hiddenTabs: [],
pinnedTabs: [],
},
+ splitScreen: {
+ enabled: false,
+ view: 'overview',
+ size: [50, 50],
+ },
expandSidebar: false,
}, { mergeDefaults: true })
export function clearDevtoolsClientState() {
devtoolsClientState.value = undefined
}
+
+const windowSize = useWindowSize()
+
+export const splitScreenAvailable = computed(() => windowSize.width.value > 1080)
From 73e85a6153a74046fed01ab24760e2e2561f6f4f Mon Sep 17 00:00:00 2001
From: alexzhang1030 <1642114555@qq.com>
Date: Mon, 11 Dec 2023 15:22:10 +0800
Subject: [PATCH 2/2] feat: implement split screen
---
packages/client/src/App.vue | 2 +-
.../client/src/components/common/SideNav.vue | 4 +-
.../src/components/common/SideNavItem.vue | 2 +
.../src/components/common/SplitScreen.vue | 98 +++++++++++++++++++
.../client/src/components/common/TabsGrid.vue | 26 +++++
.../src/components/graph/GraphDrawer.vue | 2 +-
packages/client/src/composables/state-tab.ts | 17 +++-
packages/client/src/composables/state.ts | 9 ++
packages/client/src/constants/tab.ts | 6 +-
packages/client/src/pages/assets.vue | 4 +-
10 files changed, 160 insertions(+), 10 deletions(-)
create mode 100644 packages/client/src/components/common/SplitScreen.vue
create mode 100644 packages/client/src/components/common/TabsGrid.vue
diff --git a/packages/client/src/App.vue b/packages/client/src/App.vue
index a0153f53..3c1446a6 100644
--- a/packages/client/src/App.vue
+++ b/packages/client/src/App.vue
@@ -64,7 +64,7 @@ const splitScreenSize = computed({
- hello world
+
diff --git a/packages/client/src/components/common/SideNav.vue b/packages/client/src/components/common/SideNav.vue
index 5d4f0749..7c45bef9 100644
--- a/packages/client/src/components/common/SideNav.vue
+++ b/packages/client/src/components/common/SideNav.vue
@@ -9,7 +9,7 @@ const buttonMoreTabs = ref()
const sidebarExpanded = computed(() => devtoolsClientState.value.expandSidebar)
const sidebarScrollable = ref(false)
-const { categorizedTabs: displayedTabs } = useAllTabs()
+const { enabledTabs } = useAllTabs()
@@ -50,7 +50,7 @@ const { categorizedTabs: displayedTabs } = useAllTabs()
flex="~ auto col gap-0.5 items-center" w-full p1 class="no-scrollbar"
:class="sidebarExpanded ? '' : 'of-x-hidden of-y-auto'"
>
-
+
route.path.startsWith(tabPath.value))
function onClick() {
if ('onClick' in props.tab && props.tab.onClick)
props.tab.onClick()
+ else if (props.target === 'side')
+ devtoolsClientState.value.splitScreen.view = props.tab.name
}
diff --git a/packages/client/src/components/common/SplitScreen.vue b/packages/client/src/components/common/SplitScreen.vue
new file mode 100644
index 00000000..c19cce9c
--- /dev/null
+++ b/packages/client/src/components/common/SplitScreen.vue
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ currentTab?.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Select a tab to start
+
+
+
+
+
+ Close Split Screen
+
+
+
+
diff --git a/packages/client/src/components/common/TabsGrid.vue b/packages/client/src/components/common/TabsGrid.vue
new file mode 100644
index 00000000..c210f955
--- /dev/null
+++ b/packages/client/src/components/common/TabsGrid.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
diff --git a/packages/client/src/components/graph/GraphDrawer.vue b/packages/client/src/components/graph/GraphDrawer.vue
index d7daa24f..2f09a9cc 100644
--- a/packages/client/src/components/graph/GraphDrawer.vue
+++ b/packages/client/src/components/graph/GraphDrawer.vue
@@ -31,7 +31,7 @@ const keys = [
-
+
diff --git a/packages/client/src/composables/state-tab.ts b/packages/client/src/composables/state-tab.ts
index 7da547a0..c91ea485 100644
--- a/packages/client/src/composables/state-tab.ts
+++ b/packages/client/src/composables/state-tab.ts
@@ -17,6 +17,8 @@ export interface CategorizedCategory {
hidden: boolean
}
+export type CategorizedTabs = [CategorizedCategory, CategorizedTab[]][]
+
export function useAllTabs() {
const state = useDevToolsState()
const customTabs = ref(state.tabs.value || [])
@@ -49,7 +51,7 @@ export function useAllTabs() {
const categorizedTabs = computed(() => {
const { hiddenTabCategories, hiddenTabs, pinnedTabs } = devtoolsClientState.value.tabSettings
// TODO: custom tabs
- const tabs = allTabs.value.reduce<[CategorizedCategory, CategorizedTab[]][]>((prev, [category, tabs]) => {
+ const tabs = allTabs.value.reduce((prev, [category, tabs]) => {
const data: [CategorizedCategory, CategorizedTab[]] = [{ hidden: false, name: category }, []]
let hiddenCount = 0
tabs.forEach((tab) => {
@@ -75,6 +77,17 @@ export function useAllTabs() {
tabs[0][1].sort((a, b) => pinnedTabs.indexOf(a.name) - pinnedTabs.indexOf(b.name))
return tabs
})
+ const enabledTabs = computed(() => {
+ return categorizedTabs.value.reduce((prev, [meta, tabs]) => {
+ if (meta.hidden)
+ return prev
+ const filtered = tabs.filter(t => !t.hidden)
+ if (filtered.length)
+ prev.push([meta, filtered])
+ return prev
+ }, [])
+ })
+
const bridgeRpc = useDevToolsBridgeRpc()
onDevToolsClientConnected(() => {
bridgeRpc.on.customTabsUpdated((data) => {
@@ -82,5 +95,5 @@ export function useAllTabs() {
})
})
- return { categorizedTabs, flattenedTabs }
+ return { categorizedTabs, flattenedTabs, enabledTabs }
}
diff --git a/packages/client/src/composables/state.ts b/packages/client/src/composables/state.ts
index 2fb05994..f7ef4e9b 100644
--- a/packages/client/src/composables/state.ts
+++ b/packages/client/src/composables/state.ts
@@ -38,6 +38,15 @@ export function clearDevtoolsClientState() {
devtoolsClientState.value = undefined
}
+// #region split screen related
const windowSize = useWindowSize()
export const splitScreenAvailable = computed(() => windowSize.width.value > 1080)
+
+watch(() => devtoolsClientState.value.splitScreen.enabled, (enabled, o) => {
+ if (o && !enabled) {
+ // reset size
+ devtoolsClientState.value.splitScreen.size = [50, 50]
+ }
+})
+// #endregion
diff --git a/packages/client/src/constants/tab.ts b/packages/client/src/constants/tab.ts
index 604e8d6c..63316002 100644
--- a/packages/client/src/constants/tab.ts
+++ b/packages/client/src/constants/tab.ts
@@ -71,6 +71,8 @@ export const viteOnlyTabs = [
'graph',
'vite-inspect',
]
-export function getBuiltinTab(viteDetected: boolean) {
- return viteDetected ? builtinTab : JSON.parse(JSON.stringify(builtinTab)).map(([_, tabs]) => [_, tabs.filter(t => !viteOnlyTabs.includes(t.name))])
+export function getBuiltinTab(viteDetected: boolean): [string, ModuleBuiltinTab[]][] {
+ return viteDetected
+ ? builtinTab
+ : deepClone(builtinTab).map(([_, tabs]) => [_, tabs.filter(t => !viteOnlyTabs.includes(t.name))])
}
diff --git a/packages/client/src/pages/assets.vue b/packages/client/src/pages/assets.vue
index 99d4f527..064193d9 100644
--- a/packages/client/src/pages/assets.vue
+++ b/packages/client/src/pages/assets.vue
@@ -84,7 +84,7 @@ function toggleView() {
-
+
@@ -162,7 +162,7 @@ function toggleView() {
{
if (!v) selected = undefined
}"