3434 @mousedown =" focusedId = s.id" >
3535 <Terminal :ref =" el => setTermRef(s.id, el)" :cwd =" rootPath"
3636 :active =" s.id === activeId || s.id === splitId"
37- :focused =" s.id === focusedId" />
37+ :focused =" s.id === focusedId"
38+ :shareTerminalId =" s.shareTerminalId"
39+ @shareCreated =" terminalId => onShareCreated(s.id, terminalId)" />
3840 </div >
3941 </div >
4042 <div v-if =" !isMobile" class =" terminal-sidebar" >
5759</template >
5860
5961<script setup lang="ts">
62+ const { isSharing, sharedTerminals } = useShare ();
63+
6064const props = defineProps <{
6165 rootPath: string ;
6266 isMobile: boolean ;
@@ -76,6 +80,7 @@ const emit = defineEmits<{
7680interface TerminalSession {
7781 id: string ;
7882 name: string ;
83+ shareTerminalId? : string ; // server's terminal ID (for subscribed sessions)
7984}
8085
8186let nextId = 1 ;
@@ -91,6 +96,10 @@ function createSessions(count: number): TerminalSession[] {
9196}
9297
9398const sessions = ref <TerminalSession []>(createSessions (1 ));
99+
100+ // Track server terminal IDs we've already registered (to avoid duplicates on terminal-added)
101+ const knownShareIds = new Set <string >();
102+
94103// activeId = left terminal in split (or the single visible terminal)
95104const activeId = ref (sessions .value [0 ]! .id );
96105const splitId = ref <string | null >(null );
@@ -104,6 +113,51 @@ const contentRef = ref<HTMLElement | null>(null);
104113
105114const panelHeight = ref (props .initialTerminalHeight ?? 261 );
106115
116+ // --- Share mode: sync sessions from server's sharedTerminals ---
117+ watch (isSharing , (sharing ) => {
118+ if (sharing ) {
119+ knownShareIds .clear ();
120+ sessions .value = [];
121+ splitId .value = null ;
122+ savedPairsMap .clear ();
123+ }
124+ });
125+
126+ watch (sharedTerminals , (list ) => {
127+ if (! isSharing .value ) return ;
128+ // Add new terminals
129+ for (const t of list ) {
130+ if (! knownShareIds .has (t .id )) {
131+ knownShareIds .add (t .id );
132+ sessions .value = [... sessions .value , { id: t .id , name: t .name , shareTerminalId: t .id }];
133+ // Select first terminal automatically
134+ if (sessions .value .length === 1 ) {
135+ activeId .value = t .id ;
136+ focusedId .value = t .id ;
137+ }
138+ }
139+ }
140+ // Remove gone terminals
141+ const activeIds = new Set (list .map ((t : any ) => t .id ));
142+ const before = sessions .value .length ;
143+ sessions .value = sessions .value .filter (s => {
144+ if (s .shareTerminalId && ! activeIds .has (s .shareTerminalId )) {
145+ knownShareIds .delete (s .shareTerminalId );
146+ return false ;
147+ }
148+ return true ;
149+ });
150+ if (sessions .value .length !== before ) {
151+ // Re-select if active was removed
152+ if (! sessions .value .find (s => s .id === activeId .value ) && sessions .value .length > 0 ) {
153+ activeId .value = sessions .value [0 ]! .id ;
154+ focusedId .value = activeId .value ;
155+ } else if (sessions .value .length === 0 ) {
156+ emit (" close" );
157+ }
158+ }
159+ }, { deep: true });
160+
107161watch (() => props .initialTerminalHeight , (val ) => {
108162 if (val !== undefined ) panelHeight .value = val ;
109163});
@@ -120,6 +174,14 @@ function focusTerminal(id: string) {
120174 nextTick (() => termRefs [id ]?.focus ());
121175}
122176
177+ function onShareCreated(localId : string , serverTerminalId : string ) {
178+ const s = sessions .value .find (s => s .id === localId );
179+ if (s ) {
180+ s .shareTerminalId = serverTerminalId ;
181+ knownShareIds .add (serverTerminalId );
182+ }
183+ }
184+
123185function termSlotClass(id : string ) {
124186 if (! splitId .value ) {
125187 return { hidden: id !== activeId .value };
@@ -296,6 +358,11 @@ function addSession() {
296358}
297359
298360function removeSession() {
361+ const removedId = focusedId .value ;
362+ // In share mode, tell server to close the terminal
363+ if (isSharing .value ) {
364+ termRefs [removedId ]?.closeShared ?.();
365+ }
299366 if (sessions .value .length <= 1 ) {
300367 sessions .value = [];
301368 splitId .value = null ;
@@ -305,7 +372,6 @@ function removeSession() {
305372 emit (" close" );
306373 return ;
307374 }
308- const removedId = focusedId .value ;
309375 const idx = sessions .value .findIndex (s => s .id === removedId );
310376 sessions .value = sessions .value .filter (s => s .id !== removedId );
311377
0 commit comments