1
1
<script setup lang="ts">
2
2
import type { CustomInspectorState , TimelineEventOptions } from ' @vue/devtools-kit'
3
- import { DevToolsMessagingEvents , rpc } from ' @vue/devtools-core'
3
+ import { DevToolsMessagingEvents , rpc , useDevToolsState } from ' @vue/devtools-core'
4
4
import { parse } from ' @vue/devtools-kit'
5
+ import { vTooltip , VueIcIcon } from ' @vue/devtools-ui'
5
6
6
7
import { Pane , Splitpanes } from ' splitpanes'
7
8
import { computed , onUnmounted , ref } from ' vue'
@@ -14,6 +15,7 @@ import EventList from './EventList.vue'
14
15
15
16
const props = withDefaults (defineProps <{
16
17
layerIds: string []
18
+ pluginId: string
17
19
docLink: string
18
20
githubRepoLink? : string
19
21
headerVisible? : boolean
@@ -29,7 +31,10 @@ expandedStateNodes.value = ['0', '1']
29
31
const eventList = ref <TimelineEventOptions [' event' ][]>([])
30
32
const groupList = ref <Map <string | number | undefined , TimelineEventOptions [' event' ][]>>(new Map ())
31
33
const selectedEventIndex = ref (0 )
34
+ const devtoolsState = useDevToolsState ()
35
+ const recordingState = computed (() => devtoolsState .timelineLayersState .value ?.[props .pluginId ])
32
36
const selectedEventInfo = computed (() => eventList .value [selectedEventIndex .value ] ?? null )
37
+ const recordingTooltip = computed (() => recordingState .value ? ' Stop recording' : ' Start recording' )
33
38
// event info
34
39
const normalizedEventInfo = computed (() => {
35
40
const info: CustomInspectorState [] = []
@@ -96,19 +101,28 @@ onUnmounted(() => {
96
101
rpc .functions .off (DevToolsMessagingEvents .TIMELINE_EVENT_UPDATED , onTimelineEventUpdated )
97
102
})
98
103
104
+ function clear() {
105
+ eventList .value = []
106
+ groupList .value .clear ()
107
+ }
108
+
99
109
defineExpose ({
100
- clear() {
101
- eventList .value = []
102
- groupList .value .clear ()
103
- },
110
+ clear ,
104
111
})
112
+
113
+ function toggleRecordingState() {
114
+ rpc .value .updateTimelineLayersState ({
115
+ [props .pluginId ]: ! recordingState .value ,
116
+ })
117
+ }
105
118
</script >
106
119
107
120
<template >
108
- <div class =" h-full flex flex-col" >
121
+ <div class =" relative h-full flex flex-col" >
109
122
<DevToolsHeader v-if =" headerVisible" :doc-link =" docLink" :github-repo-link =" githubRepoLink" >
110
123
<Navbar />
111
124
</DevToolsHeader >
125
+
112
126
<template v-if =" eventList .length " >
113
127
<div class =" flex-1 overflow-hidden" >
114
128
<Splitpanes class =" h-full" >
@@ -128,5 +142,36 @@ defineExpose({
128
142
<Empty v-else class =" flex-1" >
129
143
No events
130
144
</Empty >
145
+
146
+ <div class =" absolute right-3 top-12 flex items-center justify-end b-1 border-base rounded-1 b-solid px2 py1" >
147
+ <div class =" flex items-center gap-2 px-1" >
148
+ <div v-tooltip.bottom-end =" { content: recordingTooltip }" class =" flex items-center gap1" @click =" toggleRecordingState" >
149
+ <span v-if =" recordingState" class =" recording recording-btn bg-[#ef4444]" />
150
+ <span v-else class =" recording-btn bg-black op70 dark:(bg-white) hover:op100" />
151
+ </div >
152
+ <div v-tooltip.bottom-end =" { content: 'Clear all timelines' }" class =" flex items-center gap1" @click =" clear" >
153
+ <VueIcIcon name =" baseline-delete" cursor-pointer text-xl op70 hover:op100 />
154
+ </div >
155
+ <div v-tooltip.bottom-end =" { content: '<p style=\'width: 285px\'>Timeline events can cause significant performance overhead in large applications, so we recommend enabling it only when needed and on-demand. </p>', html: true }" class =" flex items-center gap1" >
156
+ <VueIcIcon name =" baseline-tips-and-updates" cursor-pointer text-xl op70 hover:op100 />
157
+ </div >
158
+ </div >
159
+ </div >
131
160
</div >
132
161
</template >
162
+
163
+ <style scoped>
164
+ @keyframes pulse {
165
+ 50% {
166
+ opacity : 0.5 ;
167
+ }
168
+ }
169
+ .recording-btn {
170
+ --at-apply : w-3.5 h-3.5 inline-flex cursor-pointer rounded-50%;
171
+ }
172
+ .recording {
173
+ animation : pulse 2s cubic-bezier (0.4 , 0 , 0.6 , 1 ) infinite ;
174
+ transition-duration : 1s ;
175
+ box-shadow : #ef4444 0 0 8px ;
176
+ }
177
+ </style >
0 commit comments