mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-26 15:07:39 +00:00
add view transition for terminal open
This commit is contained in:
parent
8b64f2088d
commit
d8dae14bde
6 changed files with 132 additions and 3 deletions
|
|
@ -171,6 +171,71 @@ export class VibeTunnelApp extends LitElement {
|
|||
this.showCreateModal = false;
|
||||
}
|
||||
|
||||
private async handleNavigateToSession(e: CustomEvent): Promise<void> {
|
||||
const { sessionId } = e.detail;
|
||||
|
||||
// Check if View Transitions API is supported
|
||||
if ('startViewTransition' in document && typeof document.startViewTransition === 'function') {
|
||||
// Debug: Check what elements have view-transition-name before transition
|
||||
console.log('Before transition - elements with view-transition-name:');
|
||||
document.querySelectorAll('[style*="view-transition-name"]').forEach((el) => {
|
||||
console.log('Element:', el, 'Style:', el.getAttribute('style'));
|
||||
});
|
||||
|
||||
// Use View Transitions API for smooth animation
|
||||
const transition = document.startViewTransition(async () => {
|
||||
// Update state which will trigger a re-render
|
||||
this.selectedSessionId = sessionId;
|
||||
this.currentView = 'session';
|
||||
this.updateUrl(sessionId);
|
||||
|
||||
// Wait for LitElement to complete its update
|
||||
await this.updateComplete;
|
||||
|
||||
// Debug: Check what elements have view-transition-name after transition
|
||||
console.log('After transition - elements with view-transition-name:');
|
||||
document.querySelectorAll('[style*="view-transition-name"]').forEach((el) => {
|
||||
console.log('Element:', el, 'Style:', el.getAttribute('style'));
|
||||
});
|
||||
});
|
||||
|
||||
// Log if transition is ready
|
||||
transition.ready
|
||||
.then(() => {
|
||||
console.log('View transition ready');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('View transition failed:', err);
|
||||
});
|
||||
} else {
|
||||
// Fallback for browsers without View Transitions support
|
||||
this.selectedSessionId = sessionId;
|
||||
this.currentView = 'session';
|
||||
this.updateUrl(sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
private handleNavigateToList(): void {
|
||||
// Check if View Transitions API is supported
|
||||
if ('startViewTransition' in document && typeof document.startViewTransition === 'function') {
|
||||
// Use View Transitions API for smooth animation
|
||||
document.startViewTransition(() => {
|
||||
// Update state which will trigger a re-render
|
||||
this.selectedSessionId = null;
|
||||
this.currentView = 'list';
|
||||
this.updateUrl();
|
||||
|
||||
// Force update to ensure DOM changes happen within the transition
|
||||
return this.updateComplete;
|
||||
});
|
||||
} else {
|
||||
// Fallback for browsers without View Transitions support
|
||||
this.selectedSessionId = null;
|
||||
this.currentView = 'list';
|
||||
this.updateUrl();
|
||||
}
|
||||
}
|
||||
|
||||
private async handleKillAll() {
|
||||
// Find all session cards and trigger their kill buttons
|
||||
const sessionCards = this.querySelectorAll<SessionCard>('session-card');
|
||||
|
|
|
|||
|
|
@ -40,7 +40,15 @@ export class SessionList extends LitElement {
|
|||
|
||||
private handleSessionSelect(e: CustomEvent) {
|
||||
const session = e.detail as Session;
|
||||
window.location.search = `?session=${session.id}`;
|
||||
|
||||
// Dispatch a custom event that the app can handle with view transitions
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('navigate-to-session', {
|
||||
detail: { sessionId: session.id },
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private handleSessionKilled(e: CustomEvent) {
|
||||
|
|
|
|||
|
|
@ -446,7 +446,13 @@ export class SessionView extends LitElement {
|
|||
}
|
||||
|
||||
private handleBack() {
|
||||
window.location.search = '';
|
||||
// Dispatch a custom event that the app can handle with view transitions
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('navigate-to-list', {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private handleSessionExit(e: Event) {
|
||||
|
|
|
|||
|
|
@ -1195,6 +1195,7 @@ export class Terminal extends LitElement {
|
|||
class="terminal-container w-full h-full overflow-hidden"
|
||||
tabindex="0"
|
||||
contenteditable="false"
|
||||
style="view-transition-name: terminal-${this.sessionId}"
|
||||
@paste=${this.handlePaste}
|
||||
@click=${this.handleClick}
|
||||
></div>
|
||||
|
|
|
|||
|
|
@ -191,7 +191,10 @@ export class VibeTerminalBuffer extends LitElement {
|
|||
line-height: ${lineHeight}px;
|
||||
}
|
||||
</style>
|
||||
<div class="relative w-full h-full overflow-hidden bg-black">
|
||||
<div
|
||||
class="relative w-full h-full overflow-hidden bg-black"
|
||||
style="view-transition-name: terminal-${this.sessionId}"
|
||||
>
|
||||
${this.error
|
||||
? html`
|
||||
<div class="absolute inset-0 flex items-center justify-center">
|
||||
|
|
|
|||
|
|
@ -701,3 +701,49 @@ body {
|
|||
color: #00ff88;
|
||||
box-shadow: 0 0 10px rgba(0, 255, 136, 0.3);
|
||||
}
|
||||
|
||||
/* View Transitions */
|
||||
@supports (view-transition-name: none) {
|
||||
::view-transition {
|
||||
/* Set the transition duration to 0.1s as requested */
|
||||
--transition-duration: 100ms;
|
||||
}
|
||||
|
||||
::view-transition-group(*) {
|
||||
animation-duration: var(--transition-duration);
|
||||
animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
::view-transition-old(*),
|
||||
::view-transition-new(*) {
|
||||
animation-duration: var(--transition-duration);
|
||||
mix-blend-mode: normal;
|
||||
}
|
||||
|
||||
/* Specific styling for terminal transitions */
|
||||
::view-transition-old(terminal-*) {
|
||||
animation: view-transition-fade-out var(--transition-duration) cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
::view-transition-new(terminal-*) {
|
||||
animation: view-transition-fade-in var(--transition-duration) cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
@keyframes view-transition-fade-out {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes view-transition-fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue