Complete 3.4.1: Tablet Layouts - Implement tablet-specific UI with adaptive sizing and gesture support

This commit is contained in:
VinnyNC 2025-09-29 21:36:38 -04:00
parent ac7aade762
commit c05c3a63cc
4 changed files with 93 additions and 8 deletions

View file

@ -361,10 +361,16 @@ Always come back and update UI_UPDATE.MD once complete with task and task item.
### Sub-task 3.4: Tablet and Desktop Optimizations ### Sub-task 3.4: Tablet and Desktop Optimizations
#### 3.4.1: Tablet Layouts #### 3.4.1: Tablet Layouts - COMPLETED 9/29/2025
- [ ] Design tablet-specific fullscreen layouts - [x] Design tablet-specific fullscreen layouts
- [ ] Implement adaptive component sizing - [x] Implement adaptive component sizing
- [ ] Create tablet gesture support - [x] Create tablet gesture support
**Notes:** Implemented comprehensive tablet-specific UI with:
- Tablet-specific CSS layout (768px-1023px) with side-by-side layout and optimized 320px chat panel width
- Adaptive component sizing with tablet-specific header padding, logo sizing, and chat header adjustments
- Tablet gesture support with swipe-to-seek functionality (swipe left/right on video seeks forward/backward 10 seconds)
- Device detection and responsive gesture handling that differs from mobile (chat toggle) and desktop (no gestures)
#### 3.4.2: Desktop Enhancements #### 3.4.2: Desktop Enhancements
- [ ] Optimize for large screen viewing - [ ] Optimize for large screen viewing

View file

@ -185,9 +185,18 @@
} }
} }
// Mobile responsive behavior // Determine device type for responsive behavior
function getDeviceType() {
const width = window.innerWidth;
if (width <= AppConfig.ui.mobileBreakpoint) return 'mobile';
if (width >= 768 && width < 1024) return 'tablet'; // Tablet: 768px-1023px
return 'desktop'; // Desktop: 1024px+
}
// Responsive behavior based on device type
function handleWindowResize() { function handleWindowResize() {
const isMobile = window.innerWidth <= AppConfig.ui.mobileBreakpoint; const deviceType = getDeviceType();
const isMobile = deviceType === 'mobile';
if (isMobile && !AppState.chatCollapsed) { if (isMobile && !AppState.chatCollapsed) {
// Auto-collapse chat on mobile for better viewing // Auto-collapse chat on mobile for better viewing
@ -234,9 +243,9 @@
const minSwipeDistance = 75; // Minimum swipe distance in pixels const minSwipeDistance = 75; // Minimum swipe distance in pixels
if (Math.abs(deltaX) > minSwipeDistance) { if (Math.abs(deltaX) > minSwipeDistance) {
const isMobile = window.innerWidth <= AppConfig.ui.mobileBreakpoint; const deviceType = getDeviceType();
if (isMobile) { if (deviceType === 'mobile') {
// On mobile, swipe left to hide chat, right to show chat // On mobile, swipe left to hide chat, right to show chat
if (deltaX < 0) { if (deltaX < 0) {
// Swipe left - hide chat // Swipe left - hide chat
@ -249,6 +258,23 @@
toggleChat(); toggleChat();
} }
} }
} else if (deviceType === 'tablet') {
// On tablet, swipe gestures control video playback
if (deltaX < 0) {
// Swipe left - seek forward
if (AppState.player && typeof AppState.player.currentTime === 'function') {
const currentTime = AppState.player.currentTime();
AppState.player.currentTime(currentTime + 10); // Skip forward 10 seconds
showToast('Skipped forward 10s', 1000);
}
} else {
// Swipe right - seek backward
if (AppState.player && typeof AppState.player.currentTime === 'function') {
const currentTime = AppState.player.currentTime();
AppState.player.currentTime(Math.max(0, currentTime - 10)); // Skip back 10 seconds
showToast('Skipped back 10s', 1000);
}
}
} }
} }
} }

View file

@ -826,6 +826,21 @@
gap: var(--spacing-5); gap: var(--spacing-5);
} }
/* Tablet-specific video header adjustments */
@media (min-width: calc(var(--breakpoint-md))) and (max-width: calc(var(--breakpoint-lg) - 1px)) {
.video-player__header:not(.video-responsive-preserve) {
padding: var(--spacing-4) var(--spacing-6);
}
.video-player__header-left:not(.video-responsive-preserve) {
gap: var(--spacing-6);
}
.stream-logo {
font-size: var(--font-size-2xl);
}
}
.stream-logo { .stream-logo {
font-size: var(--font-size-xl); font-size: var(--font-size-xl);
font-weight: var(--font-weight-bold); font-weight: var(--font-weight-bold);
@ -982,6 +997,23 @@
justify-content: space-between; justify-content: space-between;
} }
/* Tablet-specific chat header adjustments */
@media (min-width: calc(var(--breakpoint-md))) and (max-width: calc(var(--breakpoint-lg) - 1px)) {
.chat__header:not(.chat-responsive-preserve) {
padding: var(--spacing-5) var(--spacing-6);
font-size: var(--font-size-lg);
}
.chat__header-title {
gap: var(--spacing-3);
}
.chat__header-title::before {
width: 1.5em;
height: 1.5em;
}
}
.chat__header-title { .chat__header-title {
display: flex; display: flex;
align-items: center; align-items: center;

View file

@ -11,6 +11,14 @@
transition: all var(--transition-slow); transition: all var(--transition-slow);
} }
/* Tablet-specific theater layout */
@media (min-width: var(--breakpoint-md)) and (max-width: calc(var(--breakpoint-lg) - 1px)) {
.theater {
flex-direction: row;
/* Optimized for tablet: more balanced split */
}
}
/* Mobile-first responsive layout */ /* Mobile-first responsive layout */
@media (max-width: calc(var(--breakpoint-md) - 1px)) { @media (max-width: calc(var(--breakpoint-md) - 1px)) {
.theater { .theater {
@ -60,6 +68,19 @@
width: 100%; width: 100%;
} }
/* Tablet-specific video section adjustments */
@media (min-width: var(--breakpoint-md)) and (max-width: calc(var(--breakpoint-lg) - 1px)) {
.theater__video-section {
flex-basis: 0; /* Allow flex-grow to control sizing */
flex-grow: 1;
min-width: 0; /* Prevent flex item from exceeding container */
}
.theater__video-section.expanded {
flex-grow: 2; /* When chat is collapsed, video takes more space */
}
}
/* ================================================================= /* =================================================================
VIDEO WRAPPER - Contains the video element VIDEO WRAPPER - Contains the video element
================================================================= */ ================================================================= */