feat: implement library.rs, types.ts, api.ts, and extract CSS
- library.rs: full video library management (1948 lines, 10 tests) folder scanning, progress tracking, playlists, subtitle integration, background duration scanning - types.ts: all TypeScript interfaces for Tauri command responses - api.ts: typed wrappers for all 26 Tauri invoke commands - 6 CSS files extracted from Python HTML into src/styles/
This commit is contained in:
278
src/styles/player.css
Normal file
278
src/styles/player.css
Normal file
@@ -0,0 +1,278 @@
|
||||
.videoWrap{position:relative; background:#000; flex:0 0 auto;}
|
||||
video{width:100%; height:auto; display:block; background:#000; aspect-ratio:16/9; outline:none; cursor:pointer;}
|
||||
video::cue{
|
||||
background:transparent;
|
||||
color:#fff;
|
||||
font-family:var(--sans);
|
||||
font-size:1.1em;
|
||||
font-weight:600;
|
||||
text-shadow:
|
||||
-1px -1px 0 #000,
|
||||
1px -1px 0 #000,
|
||||
-1px 1px 0 #000,
|
||||
1px 1px 0 #000,
|
||||
-2px 0 0 #000,
|
||||
2px 0 0 #000,
|
||||
0 -2px 0 #000,
|
||||
0 2px 0 #000;
|
||||
}
|
||||
|
||||
.videoOverlay{
|
||||
position:absolute;
|
||||
inset:0;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
pointer-events:none;
|
||||
z-index:5;
|
||||
}
|
||||
.overlayIcon{
|
||||
position:relative;
|
||||
width:100px;
|
||||
height:100px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
opacity:0;
|
||||
transition:opacity 0.8s ease;
|
||||
border-radius:50%;
|
||||
background:rgba(20,25,35,.5);
|
||||
backdrop-filter:blur(8px) saturate(1.3);
|
||||
-webkit-backdrop-filter:blur(8px) saturate(1.3);
|
||||
border:1.5px solid rgba(255,255,255,.15);
|
||||
box-shadow:
|
||||
0 8px 32px rgba(0,0,0,.5),
|
||||
0 0 0 1px rgba(0,0,0,.3);
|
||||
}
|
||||
.overlayIcon.show{
|
||||
opacity:1;
|
||||
}
|
||||
.overlayIcon.pulse{
|
||||
animation:overlayPulse 0.4s ease-out;
|
||||
}
|
||||
@keyframes overlayPulse{
|
||||
0%{transform:scale(1);}
|
||||
50%{transform:scale(1.15);}
|
||||
100%{transform:scale(1);}
|
||||
}
|
||||
.overlayIcon::before{
|
||||
content:"";
|
||||
position:absolute;
|
||||
inset:0;
|
||||
border-radius:50%;
|
||||
background:
|
||||
radial-gradient(circle at 30% 30%, rgba(255,255,255,.1), transparent 50%),
|
||||
radial-gradient(circle at 70% 70%, rgba(95,175,255,.08), transparent 50%);
|
||||
pointer-events:none;
|
||||
}
|
||||
.overlayIcon.show:hover{
|
||||
border-color:rgba(255,255,255,.22);
|
||||
box-shadow:
|
||||
0 12px 40px rgba(0,0,0,.6),
|
||||
0 0 0 1px rgba(0,0,0,.4),
|
||||
0 0 40px rgba(95,175,255,.1);
|
||||
}
|
||||
.overlayIcon i{
|
||||
font-size:36px;
|
||||
color:rgba(255,255,255,.92)!important;
|
||||
filter:drop-shadow(0 2px 10px rgba(0,0,0,.6));
|
||||
position:relative;
|
||||
z-index:2;
|
||||
transition:transform 0.3s ease, color 0.3s ease;
|
||||
margin-left:4px; /* center play icon visually */
|
||||
}
|
||||
.overlayIcon.pause i{
|
||||
margin-left:0;
|
||||
}
|
||||
.overlayIcon.show:hover i{
|
||||
transform:scale(1.1);
|
||||
color:rgba(255,255,255,1)!important;
|
||||
}
|
||||
|
||||
.controls{display:flex; flex-direction:column; gap:10px; padding:12px; border-top:1px solid var(--stroke); flex:0 0 auto; background:linear-gradient(180deg, rgba(0,0,0,.06), rgba(0,0,0,.0));}
|
||||
.controlsRow{display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap;}
|
||||
.group{display:flex; align-items:center; gap:10px; flex-wrap:wrap;}
|
||||
|
||||
.iconBtn{
|
||||
width:40px; height:36px;
|
||||
border-radius:8px;
|
||||
border:1px solid rgba(255,255,255,.08);
|
||||
background:linear-gradient(180deg, rgba(255,255,255,.05), rgba(255,255,255,.02));
|
||||
box-shadow:
|
||||
0 2px 6px rgba(0,0,0,.12),
|
||||
inset 0 1px 0 rgba(255,255,255,.06);
|
||||
display:inline-flex; align-items:center; justify-content:center;
|
||||
cursor:pointer; user-select:none;
|
||||
transition:all .2s cubic-bezier(.4,0,.2,1);
|
||||
position:relative;
|
||||
overflow:hidden;
|
||||
}
|
||||
.iconBtn::before{
|
||||
content:"";
|
||||
position:absolute;
|
||||
inset:0;
|
||||
background:radial-gradient(circle at 50% 0%, rgba(255,255,255,.15), transparent 70%);
|
||||
opacity:0;
|
||||
transition:opacity .2s ease;
|
||||
}
|
||||
.iconBtn:hover{
|
||||
border-color:rgba(255,255,255,.15);
|
||||
background:linear-gradient(180deg, rgba(255,255,255,.08), rgba(255,255,255,.03));
|
||||
transform:translateY(-1px);
|
||||
box-shadow:
|
||||
0 4px 12px rgba(0,0,0,.2),
|
||||
inset 0 1px 0 rgba(255,255,255,.1);
|
||||
}
|
||||
.iconBtn:hover::before{opacity:1;}
|
||||
.iconBtn:active{
|
||||
transform:translateY(0);
|
||||
box-shadow:0 1px 4px rgba(0,0,0,.15);
|
||||
}
|
||||
.iconBtn.primary{
|
||||
border-color:rgba(95,175,255,.25);
|
||||
background:linear-gradient(180deg, rgba(95,175,255,.15), rgba(95,175,255,.05));
|
||||
box-shadow:
|
||||
0 2px 8px rgba(0,0,0,.15),
|
||||
0 4px 16px rgba(95,175,255,.08),
|
||||
inset 0 1px 0 rgba(255,255,255,.1);
|
||||
}
|
||||
.iconBtn.primary::before{
|
||||
background:radial-gradient(circle at 50% 0%, rgba(255,255,255,.2), transparent 70%);
|
||||
}
|
||||
.iconBtn.primary:hover{
|
||||
border-color:rgba(95,175,255,.4);
|
||||
background:linear-gradient(180deg, rgba(95,175,255,.22), rgba(95,175,255,.08));
|
||||
box-shadow:
|
||||
0 4px 12px rgba(0,0,0,.2),
|
||||
0 8px 24px rgba(95,175,255,.12),
|
||||
inset 0 1px 0 rgba(255,255,255,.15);
|
||||
}
|
||||
.iconBtn .fa{font-size:15px; color:var(--iconStrong)!important; opacity:.9; transition:transform .2s ease; position:relative; z-index:1;}
|
||||
.iconBtn:hover .fa{transform:scale(1.1);}
|
||||
|
||||
.timeChip{display:inline-flex; align-items:center; gap:10px; padding:8px 10px; border-radius:999px; border:1px solid var(--strokeMed); background:var(--surface); box-shadow:var(--shadow2); font-family:var(--mono); font-size:12px; color:var(--text); letter-spacing:.15px; font-variant-numeric:tabular-nums; transition:border-color .15s ease;}
|
||||
.timeDot{width:8px; height:8px; border-radius:999px; background:radial-gradient(circle at 35% 35%, rgba(255,255,255,.90), rgba(130,230,180,.55)); box-shadow:0 0 0 3px rgba(130,230,180,.10); opacity:.95; transition:transform .3s ease; animation:pulse 2s ease-in-out infinite;}
|
||||
@keyframes pulse{0%,100%{transform:scale(1);opacity:.95;} 50%{transform:scale(1.15);opacity:1;}}
|
||||
|
||||
.seekWrap{display:flex; align-items:center; gap:10px; width:100%; position:relative;}
|
||||
.seekTrack{
|
||||
position:absolute;
|
||||
left:0; right:0; top:50%;
|
||||
height:10px;
|
||||
transform:translateY(-50%);
|
||||
border-radius:999px;
|
||||
background:rgba(255,255,255,.06);
|
||||
border:1px solid rgba(255,255,255,.10);
|
||||
box-shadow:0 8px 18px rgba(0,0,0,.28);
|
||||
overflow:hidden;
|
||||
pointer-events:none;
|
||||
}
|
||||
.seekFill{
|
||||
height:100%;
|
||||
width:0%;
|
||||
background:linear-gradient(90deg, rgba(95,175,255,.7), rgba(130,200,255,.5) 60%, rgba(180,230,200,.4));
|
||||
border-radius:999px 0 0 999px;
|
||||
box-shadow:0 0 12px rgba(95,175,255,.3);
|
||||
transition:width .1s linear;
|
||||
}
|
||||
.seek{-webkit-appearance:none; appearance:none; width:100%; height:18px; border-radius:999px; background:transparent; border:none; box-shadow:none; outline:none; position:relative; z-index:2; cursor:pointer; margin:0;}
|
||||
.seek::-webkit-slider-runnable-track{background:transparent; height:18px;}
|
||||
.seek::-webkit-slider-thumb{-webkit-appearance:none; appearance:none; width:18px; height:18px; border-radius:999px; border:2px solid rgba(255,255,255,.25); background:linear-gradient(180deg, rgba(255,255,255,.95), rgba(200,220,255,.8)); box-shadow:0 4px 12px rgba(0,0,0,.4), 0 0 0 4px rgba(95,175,255,.15); cursor:pointer; transition:transform .15s ease, box-shadow .15s ease; margin-top:0;}
|
||||
.seek:hover::-webkit-slider-thumb{transform:scale(1.15); box-shadow:0 6px 16px rgba(0,0,0,.5), 0 0 0 6px rgba(95,175,255,.2);}
|
||||
.seek:active::-webkit-slider-thumb{transform:scale(1.05); box-shadow:0 2px 8px rgba(0,0,0,.4), 0 0 0 8px rgba(95,175,255,.25);}
|
||||
.seek::-moz-range-track{background:transparent; height:18px;}
|
||||
.seek::-moz-range-thumb{width:18px; height:18px; border-radius:999px; border:2px solid rgba(255,255,255,.25); background:linear-gradient(180deg, rgba(255,255,255,.95), rgba(200,220,255,.8)); box-shadow:0 4px 12px rgba(0,0,0,.4); cursor:pointer;}
|
||||
|
||||
.miniCtl{display:flex; align-items:center; gap:10px; padding:8px 10px; border-radius:999px; border:1px solid var(--strokeMed); background:var(--surface); box-shadow:var(--shadow2); position:relative; transition:border-color .15s ease;}
|
||||
.miniCtl:hover{border-color:rgba(255,255,255,.16);}
|
||||
.miniCtl .fa{font-size:14px; color:var(--iconStrong)!important; opacity:.95; flex:0 0 auto;}
|
||||
|
||||
.volWrap{position:relative; width:120px; height:14px; display:flex; align-items:center;}
|
||||
.volTrack{
|
||||
position:absolute;
|
||||
left:0; right:0; top:50%;
|
||||
height:6px;
|
||||
transform:translateY(-50%);
|
||||
border-radius:999px;
|
||||
background:rgba(255,255,255,.06);
|
||||
border:1px solid rgba(255,255,255,.10);
|
||||
overflow:hidden;
|
||||
pointer-events:none;
|
||||
}
|
||||
.volFill{
|
||||
height:100%;
|
||||
width:100%;
|
||||
background:linear-gradient(90deg, rgba(95,175,255,.6), rgba(130,200,255,.4));
|
||||
border-radius:999px 0 0 999px;
|
||||
box-shadow:0 0 8px rgba(95,175,255,.2);
|
||||
transition:width .05s linear;
|
||||
}
|
||||
.vol{-webkit-appearance:none; appearance:none; width:100%; height:14px; border-radius:999px; background:transparent; border:none; outline:none; position:relative; z-index:2; cursor:pointer; margin:0;}
|
||||
.vol::-webkit-slider-runnable-track{background:transparent; height:14px;}
|
||||
.vol::-webkit-slider-thumb{-webkit-appearance:none; appearance:none; width:14px; height:14px; border-radius:999px; border:2px solid rgba(255,255,255,.25); background:linear-gradient(180deg, rgba(255,255,255,.95), rgba(200,220,255,.8)); box-shadow:0 2px 8px rgba(0,0,0,.35), 0 0 0 3px rgba(95,175,255,.12); cursor:pointer; transition:transform .15s ease, box-shadow .15s ease;}
|
||||
.vol:hover::-webkit-slider-thumb{transform:scale(1.15); box-shadow:0 3px 10px rgba(0,0,0,.4), 0 0 0 4px rgba(95,175,255,.18);}
|
||||
.vol::-moz-range-track{background:transparent; height:14px;}
|
||||
.vol::-moz-range-thumb{width:14px; height:14px; border-radius:999px; border:2px solid rgba(255,255,255,.25); background:linear-gradient(180deg, rgba(255,255,255,.95), rgba(200,220,255,.8)); box-shadow:0 2px 8px rgba(0,0,0,.35); cursor:pointer;}
|
||||
|
||||
.volTooltip{
|
||||
position:absolute;
|
||||
bottom:calc(100% + 12px);
|
||||
left:0;
|
||||
padding:8px 12px;
|
||||
border-radius:var(--r2);
|
||||
background:
|
||||
radial-gradient(ellipse 120% 100% at 20% 0%, rgba(95,175,255,.12), transparent 50%),
|
||||
linear-gradient(175deg, rgba(28,34,48,.97), rgba(16,20,30,.98));
|
||||
border:1px solid rgba(255,255,255,.12);
|
||||
color:#fff;
|
||||
font-family:var(--mono);
|
||||
font-size:13px;
|
||||
font-weight:600;
|
||||
letter-spacing:.03em;
|
||||
white-space:nowrap;
|
||||
pointer-events:none;
|
||||
opacity:0;
|
||||
transform:translateX(-50%) translateY(4px);
|
||||
transition:opacity .15s ease, transform .15s ease, left .05s linear;
|
||||
box-shadow:
|
||||
0 0 0 1px rgba(0,0,0,.3),
|
||||
0 4px 8px rgba(0,0,0,.2),
|
||||
0 12px 24px rgba(0,0,0,.25),
|
||||
inset 0 1px 0 rgba(255,255,255,.08);
|
||||
backdrop-filter:blur(16px);
|
||||
z-index:100;
|
||||
}
|
||||
.volTooltip::before{
|
||||
content:"";
|
||||
position:absolute;
|
||||
top:0; left:0; right:0;
|
||||
height:1px;
|
||||
background:linear-gradient(90deg, transparent, rgba(95,175,255,.4) 50%, transparent);
|
||||
border-radius:var(--r2) var(--r2) 0 0;
|
||||
}
|
||||
.volTooltip::after{
|
||||
content:"";
|
||||
position:absolute;
|
||||
top:100%;
|
||||
left:50%;
|
||||
transform:translateX(-50%);
|
||||
border:6px solid transparent;
|
||||
border-top-color:rgba(20,26,36,.95);
|
||||
}
|
||||
.volTooltip.show{
|
||||
opacity:1;
|
||||
transform:translateX(-50%) translateY(0);
|
||||
}
|
||||
|
||||
.speedBox{display:flex; align-items:center; gap:10px; position:relative;}
|
||||
.speedBtn{border:none; outline:none; background:transparent; color:rgba(246,248,255,.92); font-family:var(--mono); font-size:12px; letter-spacing:.10px; padding:0 2px; cursor:pointer; line-height:1; display:inline-flex; align-items:center; gap:8px; transition:color .15s ease;}
|
||||
.speedBtn span:first-child{min-width:3.5ch; text-align:right;}
|
||||
.speedBtn:hover{color:rgba(255,255,255,1);}
|
||||
.speedCaret .fa{font-size:12px; opacity:.85; color:var(--icon)!important; transition:transform .2s ease;}
|
||||
.speedBtn:hover .speedCaret .fa{transform:translateY(2px);}
|
||||
|
||||
.progressPill{flex:0 0 auto; display:flex; align-items:center; gap:10px; padding:8px 10px; border-radius:999px; border:1px solid var(--strokeMed); background:radial-gradient(400px 100px at 20% 0%, var(--accentGlow), transparent 60%), var(--surface); box-shadow:var(--shadow2); min-width:220px;}
|
||||
.progressLabel{font-size:11.2px; font-weight:820; letter-spacing:.12px; text-transform:uppercase; color:rgba(190,198,220,.78); margin-right:2px;}
|
||||
.progressBar{width:120px; height:8px; border-radius:999px; border:1px solid rgba(255,255,255,.09); background:rgba(255,255,255,.05); overflow:hidden;}
|
||||
.progressBar>div{height:100%; width:0%; background:linear-gradient(90deg, rgba(100,180,255,.95), rgba(130,230,180,.88));}
|
||||
.progressPct{font-family:var(--mono); font-size:11.6px; color:rgba(230,235,255,.92); font-variant-numeric:tabular-nums; letter-spacing:.10px; min-width:58px; text-align:right;}
|
||||
Reference in New Issue
Block a user