fix: enable mobile swipe through playback layer and sound control
This commit is contained in:
+3
-3
@@ -1,6 +1,6 @@
|
||||
import Head from 'next/head';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { Heart, MessageCircle, Bookmark, Share2, Plus, Play, Pause, Volume2, VolumeX, ChevronUp, ChevronDown, Search, Home, Compass, Users, Music2, Maximize, X, Check, MapPin, Send, ArrowUpRight, TvMinimal, Ellipsis, UserRound } from 'lucide-react';
|
||||
import { Heart, MessageCircle, Bookmark, Share2, Plus, Play, Pause, Volume2, VolumeX, ChevronUp, ChevronDown, Search, Home, Compass, Users, Music2, Maximize, X, Check, MapPin, Send, ArrowUpRight, UserRound } from 'lucide-react';
|
||||
import { videos, compact } from '../lib/videos';
|
||||
type Reaction = { liked?:boolean; saved?:boolean; followed?:boolean };
|
||||
type Comment = {name:string; text:string};
|
||||
@@ -26,10 +26,10 @@ export default function Feed(){
|
||||
<div className="app-shell">
|
||||
<aside className="sidebar"><a className="brand" href="/" aria-label="瞬间首页"><span className="brand-mark"><Music2 size={28}/></span>瞬间<span className="brand-en">FLOW</span></a><button className="search-box" onClick={()=>setPanel('search')}><Search size={19}/><span>搜索感兴趣的内容</span><kbd>/</kbd></button><nav>{[{name:'推荐',icon:Home},{name:'发现',icon:Compass},{name:'关注',icon:Users}].map(({name,icon:Icon})=><button key={name} className={`nav-item ${tab===name?'active':''}`} onClick={()=>{setTab(name);if(name==='发现')setPanel('search');if(name==='关注')notify('关注作者后,关注标记会保存在此设备');}}><Icon size={23}/>{name}{name==='推荐'&&<span className="active-dot"/>}</button>)}</nav><div className="sidebar-line"/><p className="sidebar-label">精选频道</p>{['生活的浪漫','自然放映厅','城市漫游'].map((label,i)=><button key={label} className="channel" onClick={()=>{setIndex(i);setProgress(0);setPlaying(true);setError(false);}}><span className={`channel-dot dot-${i}`}/>{label}<ArrowUpRight size={14}/></button>)}<div className="sidebar-bottom"><div className="mini-brand">每一刻,都值得被看见<span>MAKE EVERY MOMENT COUNT.</span></div><p>关于瞬间 · 使用指南 · 联系我们</p><p>© 2026 瞬间 FLOW</p><span className="demo-pill"><span/>本地演示 · 无需登录</span></div></aside>
|
||||
<main className="main"><header className="desktop-header"><div><span className="eyebrow">FOR YOU</span><h1>发现生活的另一面<span>精选推荐</span></h1></div><span className="header-note"><span/> 偶遇一个好瞬间</span></header>
|
||||
<section ref={stage} className={`stage scene-${item.id}`} aria-label="短视频播放器" onTouchStart={e=>{touch.current={x:e.touches[0].clientX,y:e.touches[0].clientY};}} onTouchEnd={e=>{if(panel||(e.target as HTMLElement).closest('button,input'))return;const dy=e.changedTouches[0].clientY-touch.current.y,dx=e.changedTouches[0].clientX-touch.current.x;if(Math.abs(dy)>55&&Math.abs(dy)>Math.abs(dx))next(dy<0?1:-1);}}>
|
||||
<section ref={stage} className={`stage scene-${item.id}`} aria-label="短视频播放器" onTouchStart={e=>{touch.current={x:e.touches[0].clientX,y:e.touches[0].clientY};}} onTouchEnd={e=>{if(panel||(e.target as HTMLElement).closest('button:not(.video-hit),input'))return;const dy=e.changedTouches[0].clientY-touch.current.y,dx=e.changedTouches[0].clientX-touch.current.x;if(Math.abs(dy)>55&&Math.abs(dy)>Math.abs(dx)){e.preventDefault();next(dy<0?1:-1);}}}>
|
||||
<video key={item.id} ref={video} className="video" src={item.src} poster={item.poster} loop playsInline muted={muted} autoPlay preload="auto" onTimeUpdate={e=>setProgress(e.currentTarget.currentTime)} onLoadedMetadata={e=>setDuration(e.currentTarget.duration)} onPlay={()=>setPlaying(true)} onPause={()=>setPlaying(false)} onError={()=>{setError(true);setPlaying(false);}}/>
|
||||
<div className="scrim"/><button className="video-hit" aria-label={playing?'暂停视频':'播放视频'} onClick={()=>{if(clickTimer.current)clearTimeout(clickTimer.current);clickTimer.current=setTimeout(()=>setPlaying(p=>!p),220);}} onDoubleClick={()=>{if(clickTimer.current)clearTimeout(clickTimer.current);like();}}/>
|
||||
<div className="mobile-top"><TvMinimal size={23}/><div><button onClick={()=>notify('点击作者头像即可关注')}>关注</button><button className="selected" onClick={()=>setTab('推荐')}>推荐</button></div><button aria-label="搜索视频" onClick={()=>setPanel('search')}><Search size={24}/></button></div>
|
||||
<div className="mobile-top"><button aria-label={muted?'开启声音':'静音'} onClick={()=>setMuted(m=>!m)}>{muted?<VolumeX size={23}/>:<Volume2 size={23}/>}</button><div><button onClick={()=>notify('点击作者头像即可关注')}>关注</button><button className="selected" onClick={()=>setTab('推荐')}>推荐</button></div><button aria-label="搜索视频" onClick={()=>setPanel('search')}><Search size={24}/></button></div>
|
||||
<div className="stage-top"><span className="curated"><span/> 今日精选</span><span className="location"><MapPin size={14}/>{item.location}</span><button aria-label={muted?'开启声音':'静音'} className="sound-top" onClick={()=>setMuted(m=>!m)}>{muted?<VolumeX size={19}/>:<Volume2 size={19}/>}</button></div>
|
||||
<div className="scene-copy" aria-hidden="true"><span>{item.label}</span><strong>{item.subtitle}</strong><i>THE LITTLE THINGS. THE BIG FEELINGS.</i></div>
|
||||
{!playing&&!error&&<span className="paused"><Play size={54} fill="currentColor"/></span>}{burst&&<span className="heart-burst"><Heart size={110} fill="currentColor"/></span>}{error&&<div className="video-error">视频暂时无法加载<button onClick={()=>{setError(false);video.current?.load();setPlaying(true);}}>重新加载</button></div>}
|
||||
|
||||
Reference in New Issue
Block a user