mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-09 11:55:53 +00:00
Fix 1-2 second animation delay when reopening session sidebar
- Remove animate-fade-in class from compact mode session list items - Prevent sessions-showing/hiding animation classes when in session detail view - Disable View Transitions API for navigating back from session detail view - Add body.in-session-view class to disable all animations in session view - Remove transition-all duration-200 from compact session list items - Disable grid transitions when in session view This eliminates all staggered animations and transitions that were causing the perceived 1-2 second delay when toggling the sidebar in session detail view. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
35e523f051
commit
d7a8b565d2
3 changed files with 72 additions and 85 deletions
|
|
@ -127,6 +127,15 @@ export class VibeTunnelApp extends LitElement {
|
|||
if (changedProperties.has('sessions') || changedProperties.has('currentView')) {
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
// Add/remove body class based on current view to control animations
|
||||
if (changedProperties.has('currentView')) {
|
||||
if (this.currentView === 'session') {
|
||||
document.body.classList.add('in-session-view');
|
||||
} else {
|
||||
document.body.classList.remove('in-session-view');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
|
|
@ -557,8 +566,21 @@ export class VibeTunnelApp extends LitElement {
|
|||
logger.log('handleHideExitedChange', {
|
||||
currentHideExited: this.hideExited,
|
||||
newHideExited: e.detail,
|
||||
currentView: this.currentView,
|
||||
});
|
||||
|
||||
// Skip animations entirely when in session detail view
|
||||
const isInSessionDetailView = this.currentView === 'session';
|
||||
|
||||
if (isInSessionDetailView) {
|
||||
// Just update state without any animations
|
||||
this.hideExited = e.detail;
|
||||
this.saveHideExitedState(this.hideExited);
|
||||
await this.updateComplete;
|
||||
logger.log('Skipped animations in session detail view');
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't use View Transitions for hide/show exited toggle
|
||||
// as it causes the entire UI to fade. Use CSS animations instead.
|
||||
const wasHidingExited = this.hideExited;
|
||||
|
|
@ -729,88 +751,33 @@ export class VibeTunnelApp extends LitElement {
|
|||
mediaStateIsMobile: this.mediaState.isMobile,
|
||||
});
|
||||
|
||||
// Check if View Transitions API is supported - DISABLED for session navigation
|
||||
// if ('startViewTransition' in document && typeof document.startViewTransition === 'function') {
|
||||
if (false) {
|
||||
// Debug: Check what elements have view-transition-name before transition
|
||||
logger.debug('before transition - elements with view-transition-name:');
|
||||
document.querySelectorAll('[style*="view-transition-name"]').forEach((el) => {
|
||||
logger.debug('element:', el, 'style:', el.getAttribute('style'));
|
||||
});
|
||||
// View Transitions disabled for session navigation to prevent animations
|
||||
// Direct state update for instant navigation
|
||||
this.selectedSessionId = sessionId;
|
||||
this.sessionLoadingState = 'idle'; // Reset loading state for new session
|
||||
this.currentView = 'session';
|
||||
this.updateUrl(sessionId);
|
||||
|
||||
// Use View Transitions API for smooth animation
|
||||
const transition = document.startViewTransition(async () => {
|
||||
// Update state which will trigger a re-render
|
||||
this.selectedSessionId = sessionId;
|
||||
this.sessionLoadingState = 'idle'; // Reset loading state for new session
|
||||
this.currentView = 'session';
|
||||
this.updateUrl(sessionId);
|
||||
|
||||
// Update page title with session name
|
||||
const session = this.sessions.find((s) => s.id === sessionId);
|
||||
if (session) {
|
||||
const sessionName = session.name || session.command.join(' ');
|
||||
console.log('[App] Setting title from view transition:', sessionName);
|
||||
document.title = `${sessionName} - VibeTunnel`;
|
||||
} else {
|
||||
console.log('[App] No session found for view transition:', sessionId);
|
||||
}
|
||||
|
||||
// Collapse sidebar on mobile after selecting a session
|
||||
if (this.mediaState.isMobile) {
|
||||
this.sidebarCollapsed = true;
|
||||
this.saveSidebarState(true);
|
||||
}
|
||||
|
||||
// Wait for LitElement to complete its update
|
||||
await this.updateComplete;
|
||||
|
||||
// Trigger terminal resize after session switch to ensure proper dimensions
|
||||
triggerTerminalResize(sessionId, this);
|
||||
|
||||
// Debug: Check what elements have view-transition-name after transition
|
||||
logger.debug('after transition - elements with view-transition-name:');
|
||||
document.querySelectorAll('[style*="view-transition-name"]').forEach((el) => {
|
||||
logger.debug('element:', el, 'style:', el.getAttribute('style'));
|
||||
});
|
||||
});
|
||||
|
||||
// Log if transition is ready
|
||||
transition.ready
|
||||
.then(() => {
|
||||
logger.debug('view transition ready');
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error('view transition failed:', err);
|
||||
});
|
||||
// Update page title with session name
|
||||
const session = this.sessions.find((s) => s.id === sessionId);
|
||||
if (session) {
|
||||
const sessionName = session.name || session.command.join(' ');
|
||||
console.log('[App] Setting title:', sessionName);
|
||||
document.title = `${sessionName} - VibeTunnel`;
|
||||
} else {
|
||||
// Fallback for browsers without View Transitions support
|
||||
this.selectedSessionId = sessionId;
|
||||
this.sessionLoadingState = 'idle'; // Reset loading state for new session
|
||||
this.currentView = 'session';
|
||||
this.updateUrl(sessionId);
|
||||
|
||||
// Update page title with session name
|
||||
const session = this.sessions.find((s) => s.id === sessionId);
|
||||
if (session) {
|
||||
const sessionName = session.name || session.command.join(' ');
|
||||
console.log('[App] Setting title from fallback:', sessionName);
|
||||
document.title = `${sessionName} - VibeTunnel`;
|
||||
} else {
|
||||
console.log('[App] No session found for fallback:', sessionId);
|
||||
}
|
||||
|
||||
// Collapse sidebar on mobile after selecting a session
|
||||
if (this.mediaState.isMobile) {
|
||||
this.sidebarCollapsed = true;
|
||||
this.saveSidebarState(true);
|
||||
}
|
||||
|
||||
// Trigger terminal resize after session switch to ensure proper dimensions
|
||||
this.updateComplete.then(() => {
|
||||
triggerTerminalResize(sessionId, this);
|
||||
});
|
||||
console.log('[App] No session found:', sessionId);
|
||||
}
|
||||
|
||||
// Collapse sidebar on mobile after selecting a session
|
||||
if (this.mediaState.isMobile) {
|
||||
this.sidebarCollapsed = true;
|
||||
this.saveSidebarState(true);
|
||||
}
|
||||
|
||||
// Trigger terminal resize after session switch to ensure proper dimensions
|
||||
this.updateComplete.then(() => {
|
||||
triggerTerminalResize(sessionId, this);
|
||||
});
|
||||
}
|
||||
|
||||
private handleNavigateToList(): void {
|
||||
|
|
@ -821,8 +788,16 @@ export class VibeTunnelApp extends LitElement {
|
|||
const sessionCount = this.sessions.length;
|
||||
document.title = `VibeTunnel - ${sessionCount} Session${sessionCount !== 1 ? 's' : ''}`;
|
||||
|
||||
// Check if View Transitions API is supported
|
||||
if ('startViewTransition' in document && typeof document.startViewTransition === 'function') {
|
||||
// Disable View Transitions when navigating from session detail view
|
||||
// to prevent animations when sidebar is involved
|
||||
const skipViewTransition = this.currentView === 'session';
|
||||
|
||||
// Check if View Transitions API is supported and should be used
|
||||
if (
|
||||
!skipViewTransition &&
|
||||
'startViewTransition' in document &&
|
||||
typeof document.startViewTransition === 'function'
|
||||
) {
|
||||
// Use View Transitions API for smooth animation
|
||||
document.startViewTransition(() => {
|
||||
// Update state which will trigger a re-render
|
||||
|
|
@ -834,7 +809,7 @@ export class VibeTunnelApp extends LitElement {
|
|||
return this.updateComplete;
|
||||
});
|
||||
} else {
|
||||
// Fallback for browsers without View Transitions support
|
||||
// Fallback for browsers without View Transitions support or when skipping
|
||||
this.selectedSessionId = null;
|
||||
this.currentView = 'list';
|
||||
this.updateUrl();
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ export class SessionList extends LitElement {
|
|||
? html`
|
||||
<!-- Enhanced compact list item for sidebar -->
|
||||
<div
|
||||
class="group flex items-center gap-3 p-3 rounded-lg cursor-pointer transition-all duration-200 animate-fade-in ${
|
||||
class="group flex items-center gap-3 p-3 rounded-lg cursor-pointer ${
|
||||
session.id === this.selectedSessionId
|
||||
? 'bg-dark-bg-elevated border border-accent-primary shadow-card-hover'
|
||||
: 'bg-dark-bg-secondary border border-dark-border hover:bg-dark-bg-tertiary hover:border-dark-border-light hover:shadow-card'
|
||||
|
|
@ -558,7 +558,7 @@ export class SessionList extends LitElement {
|
|||
? html`
|
||||
<!-- Enhanced compact list item for sidebar -->
|
||||
<div
|
||||
class="group flex items-center gap-3 p-3 rounded-lg cursor-pointer transition-all duration-200 animate-fade-in ${
|
||||
class="group flex items-center gap-3 p-3 rounded-lg cursor-pointer ${
|
||||
session.id === this.selectedSessionId
|
||||
? 'bg-dark-bg-elevated border border-accent-primary shadow-card-hover'
|
||||
: 'bg-dark-bg-secondary border border-dark-border hover:bg-dark-bg-tertiary hover:border-dark-border-light hover:shadow-card opacity-75'
|
||||
|
|
|
|||
|
|
@ -219,9 +219,14 @@
|
|||
grid-auto-rows: 400px;
|
||||
gap: 1.25rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
/* Enable smooth grid transitions */
|
||||
/* Enable smooth grid transitions - disabled in session view */
|
||||
transition: grid-template-columns 0.3s ease-out;
|
||||
}
|
||||
|
||||
/* Disable grid transitions in session view */
|
||||
body.in-session-view .session-flex-responsive {
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
.session-flex-responsive > * {
|
||||
height: 100%;
|
||||
|
|
@ -529,6 +534,13 @@ body.sessions-showing .session-flex-responsive > session-card {
|
|||
animation: sessionFlow 0.2s ease-out backwards;
|
||||
}
|
||||
|
||||
/* Disable ALL animations when in session view */
|
||||
body.in-session-view .session-flex-responsive > session-card,
|
||||
body.in-session-view .space-y-2 > div {
|
||||
animation: none !important;
|
||||
animation-delay: 0s !important;
|
||||
}
|
||||
|
||||
/* Stagger animation when showing exited sessions */
|
||||
body.sessions-showing .session-flex-responsive > session-card:nth-child(1) {
|
||||
animation-delay: 0s;
|
||||
|
|
|
|||
Loading…
Reference in a new issue