perryrperry commited on
Commit
7d85f2e
·
verified ·
1 Parent(s): 386ef1c

Delete index.html

Browse files
Files changed (1) hide show
  1. index.html +0 -1561
index.html DELETED
@@ -1,1561 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="zh-CN">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
6
- <title>VideoFlow - 沉浸式短视频</title>
7
- <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
8
- <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet">
9
- <style>
10
- :root {
11
- --primary-color: #FF2C55;
12
- --secondary-color: #00F2EA;
13
- --dark-color: #121212;
14
- --light-color: #ffffff;
15
- --gray-color: #888888;
16
- --overlay-color: rgba(0, 0, 0, 0.4);
17
- --gradient-overlay: linear-gradient(to top, rgba(0, 0, 0, 0.7) 0%, transparent 40%);
18
- --card-background: rgba(255, 255, 255, 0.08);
19
- --blur-effect: blur(10px);
20
- --transition-normal: all 0.3s cubic-bezier(0.19, 1, 0.22, 1);
21
- --transition-slow: all 0.5s cubic-bezier(0.19, 1, 0.22, 1);
22
- --shadow-normal: 0 4px 12px rgba(0, 0, 0, 0.15);
23
- --shadow-elevated: 0 8px 24px rgba(0, 0, 0, 0.2);
24
- }
25
-
26
- * {
27
- margin: 0;
28
- padding: 0;
29
- box-sizing: border-box;
30
- }
31
-
32
- body {
33
- font-family: 'Nunito', 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
34
- background-color: var(--dark-color);
35
- color: var(--light-color);
36
- overflow: hidden;
37
- touch-action: pan-y;
38
- position: fixed;
39
- width: 100%;
40
- height: 100%;
41
- }
42
-
43
- .app-container {
44
- width: 100%;
45
- height: 100vh;
46
- overflow: hidden;
47
- position: relative;
48
- }
49
-
50
- /* Main screens */
51
- .screen {
52
- width: 100%;
53
- height: calc(100vh - 60px);
54
- position: absolute;
55
- left: 0;
56
- top: 0;
57
- transition: var(--transition-normal);
58
- opacity: 0;
59
- visibility: hidden;
60
- overflow-y: auto;
61
- overflow-x: hidden;
62
- -webkit-overflow-scrolling: touch;
63
- }
64
-
65
- .screen.active {
66
- opacity: 1;
67
- visibility: visible;
68
- }
69
-
70
- /* Video Feed Screen */
71
- .video-feed {
72
- width: 100%;
73
- height: 100%;
74
- position: relative;
75
- overflow: hidden;
76
- background-color: black;
77
- }
78
-
79
- .video-card {
80
- width: 100%;
81
- height: 100%;
82
- position: absolute;
83
- left: 0;
84
- top: 0;
85
- display: flex;
86
- justify-content: center;
87
- align-items: center;
88
- transition: var(--transition-slow);
89
- }
90
-
91
- video {
92
- width: 100%;
93
- height: 100%;
94
- object-fit: cover;
95
- }
96
-
97
- .video-overlay {
98
- position: absolute;
99
- bottom: 0;
100
- left: 0;
101
- width: 100%;
102
- height: 40%;
103
- background: var(--gradient-overlay);
104
- z-index: 5;
105
- display: flex;
106
- flex-direction: column;
107
- justify-content: flex-end;
108
- padding: 20px;
109
- }
110
-
111
- .action-buttons {
112
- position: absolute;
113
- right: 16px;
114
- bottom: 120px;
115
- display: flex;
116
- flex-direction: column;
117
- align-items: center;
118
- z-index: 10;
119
- }
120
-
121
- .action-button {
122
- width: 44px;
123
- height: 44px;
124
- background-color: rgba(255, 255, 255, 0.15);
125
- border-radius: 50%;
126
- display: flex;
127
- justify-content: center;
128
- align-items: center;
129
- margin-bottom: 20px;
130
- cursor: pointer;
131
- backdrop-filter: var(--blur-effect);
132
- -webkit-backdrop-filter: var(--blur-effect);
133
- border: 1px solid rgba(255, 255, 255, 0.2);
134
- box-shadow: var(--shadow-normal);
135
- transition: var(--transition-normal);
136
- }
137
-
138
- .action-button:hover, .action-button:active {
139
- transform: scale(1.1);
140
- background-color: rgba(255, 255, 255, 0.25);
141
- }
142
-
143
- .action-button.like {
144
- background-color: rgba(255, 44, 85, 0.2);
145
- }
146
-
147
- .action-button.like.active {
148
- background-color: rgba(255, 44, 85, 0.4);
149
- }
150
-
151
- .action-button.favorite {
152
- background-color: rgba(255, 215, 0, 0.2);
153
- }
154
-
155
- .action-button.favorite.active {
156
- background-color: rgba(255, 215, 0, 0.4);
157
- }
158
-
159
- .action-label {
160
- font-size: 12px;
161
- margin-top: 5px;
162
- color: var(--light-color);
163
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
164
- }
165
-
166
- .loading-screen {
167
- position: fixed;
168
- top: 0;
169
- left: 0;
170
- width: 100%;
171
- height: 100%;
172
- background-color: var(--dark-color);
173
- display: flex;
174
- flex-direction: column;
175
- justify-content: center;
176
- align-items: center;
177
- z-index: 1000;
178
- }
179
-
180
- .loading-spinner {
181
- width: 50px;
182
- height: 50px;
183
- border: 3px solid transparent;
184
- border-top: 3px solid var(--primary-color);
185
- border-right: 3px solid var(--secondary-color);
186
- border-radius: 50%;
187
- animation: spin 1s linear infinite;
188
- margin-bottom: 20px;
189
- }
190
-
191
- @keyframes spin {
192
- 0% { transform: rotate(0deg); }
193
- 100% { transform: rotate(360deg); }
194
- }
195
-
196
- .swipe-indicator {
197
- position: absolute;
198
- bottom: 80px;
199
- left: 50%;
200
- transform: translateX(-50%);
201
- display: flex;
202
- flex-direction: column;
203
- align-items: center;
204
- opacity: 0.8;
205
- z-index: 10;
206
- animation: pulse 2s infinite;
207
- }
208
-
209
- @keyframes pulse {
210
- 0% { opacity: 0.4; transform: translateX(-50%) scale(0.95); }
211
- 50% { opacity: 0.8; transform: translateX(-50%) scale(1); }
212
- 100% { opacity: 0.4; transform: translateX(-50%) scale(0.95); }
213
- }
214
-
215
- .swipe-icon {
216
- width: 36px;
217
- height: 36px;
218
- margin-bottom: 8px;
219
- }
220
-
221
- .swipe-text {
222
- font-size: 14px;
223
- color: var(--light-color);
224
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
225
- font-weight: 600;
226
- }
227
-
228
- .header {
229
- position: absolute;
230
- top: 0;
231
- left: 0;
232
- width: 100%;
233
- height: 60px;
234
- display: flex;
235
- justify-content: space-between;
236
- align-items: center;
237
- padding: 0 16px;
238
- z-index: 100;
239
- background: linear-gradient(to bottom, rgba(0,0,0,0.4) 0%, transparent 100%);
240
- }
241
-
242
- .app-title {
243
- font-size: 22px;
244
- font-weight: 700;
245
- color: var(--light-color);
246
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
247
- }
248
-
249
- .app-title span {
250
- color: var(--primary-color);
251
- }
252
-
253
- .progress-bar {
254
- position: absolute;
255
- top: 60px;
256
- left: 0;
257
- width: 100%;
258
- height: 3px;
259
- background-color: rgba(255, 255, 255, 0.2);
260
- z-index: 100;
261
- }
262
-
263
- .progress-fill {
264
- height: 100%;
265
- width: 0;
266
- background-color: var(--primary-color);
267
- transition: width 0.1s linear;
268
- }
269
-
270
- .video-info {
271
- padding: 12px 16px;
272
- position: relative;
273
- z-index: 10;
274
- }
275
-
276
- .video-title {
277
- font-size: 18px;
278
- font-weight: 700;
279
- margin-bottom: 8px;
280
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
281
- }
282
-
283
- .video-desc {
284
- font-size: 14px;
285
- opacity: 0.9;
286
- margin-bottom: 12px;
287
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
288
- }
289
-
290
- .video-meta {
291
- display: flex;
292
- align-items: center;
293
- font-size: 12px;
294
- opacity: 0.7;
295
- }
296
-
297
- .video-meta-item {
298
- margin-right: 16px;
299
- display: flex;
300
- align-items: center;
301
- }
302
-
303
- .video-meta-item svg {
304
- margin-right: 4px;
305
- width: 14px;
306
- height: 14px;
307
- }
308
-
309
- .play-pause-overlay {
310
- position: absolute;
311
- top: 50%;
312
- left: 50%;
313
- transform: translate(-50%, -50%) scale(0);
314
- width: 80px;
315
- height: 80px;
316
- background-color: rgba(0, 0, 0, 0.5);
317
- border-radius: 50%;
318
- display: flex;
319
- justify-content: center;
320
- align-items: center;
321
- z-index: 15;
322
- opacity: 0;
323
- transition: var(--transition-normal);
324
- backdrop-filter: var(--blur-effect);
325
- -webkit-backdrop-filter: var(--blur-effect);
326
- }
327
-
328
- .play-pause-overlay.visible {
329
- transform: translate(-50%, -50%) scale(1);
330
- opacity: 1;
331
- }
332
-
333
- .volume-control {
334
- position: absolute;
335
- right: 16px;
336
- top: 80px;
337
- width: 40px;
338
- height: 40px;
339
- background-color: rgba(255, 255, 255, 0.15);
340
- border-radius: 50%;
341
- display: flex;
342
- justify-content: center;
343
- align-items: center;
344
- z-index: 10;
345
- cursor: pointer;
346
- backdrop-filter: var(--blur-effect);
347
- -webkit-backdrop-filter: var(--blur-effect);
348
- border: 1px solid rgba(255, 255, 255, 0.2);
349
- box-shadow: var(--shadow-normal);
350
- }
351
-
352
- /* Navigation Bar */
353
- .nav-bar {
354
- position: fixed;
355
- bottom: 0;
356
- left: 0;
357
- width: 100%;
358
- height: 60px;
359
- background-color: rgba(18, 18, 18, 0.95);
360
- backdrop-filter: var(--blur-effect);
361
- -webkit-backdrop-filter: var(--blur-effect);
362
- display: flex;
363
- justify-content: space-around;
364
- align-items: center;
365
- z-index: 1000;
366
- border-top: 1px solid rgba(255, 255, 255, 0.1);
367
- }
368
-
369
- .nav-item {
370
- display: flex;
371
- flex-direction: column;
372
- align-items: center;
373
- justify-content: center;
374
- padding: 8px 0;
375
- width: 25%;
376
- cursor: pointer;
377
- }
378
-
379
- .nav-icon {
380
- width: 24px;
381
- height: 24px;
382
- margin-bottom: 4px;
383
- transition: var(--transition-normal);
384
- }
385
-
386
- .nav-label {
387
- font-size: 12px;
388
- transition: var(--transition-normal);
389
- color: var(--gray-color);
390
- }
391
-
392
- .nav-item.active .nav-label {
393
- color: var(--primary-color);
394
- }
395
-
396
- .nav-item.active .nav-icon {
397
- color: var(--primary-color);
398
- }
399
-
400
- /* History Screen */
401
- .history-screen, .favorites-screen {
402
- background-color: var(--dark-color);
403
- padding: 16px;
404
- padding-top: 70px;
405
- }
406
-
407
- .section-title {
408
- font-size: 24px;
409
- font-weight: 700;
410
- margin-bottom: 20px;
411
- margin-top: 10px;
412
- padding-left: 16px;
413
- }
414
-
415
- .video-grid {
416
- display: grid;
417
- grid-template-columns: repeat(2, 1fr);
418
- gap: 16px;
419
- padding: 0 16px;
420
- }
421
-
422
- .video-item {
423
- background-color: var(--card-background);
424
- border-radius: 12px;
425
- overflow: hidden;
426
- box-shadow: var(--shadow-normal);
427
- transition: var(--transition-normal);
428
- border: 1px solid rgba(255, 255, 255, 0.1);
429
- }
430
-
431
- .video-item:hover, .video-item:active {
432
- transform: translateY(-5px);
433
- box-shadow: var(--shadow-elevated);
434
- }
435
-
436
- .video-thumbnail {
437
- position: relative;
438
- width: 100%;
439
- padding-top: 177.77%; /* 16:9 aspect ratio */
440
- overflow: hidden;
441
- background-color: #333;
442
- }
443
-
444
- .video-thumbnail img {
445
- position: absolute;
446
- top: 0;
447
- left: 0;
448
- width: 100%;
449
- height: 100%;
450
- object-fit: cover;
451
- }
452
-
453
- .video-duration {
454
- position: absolute;
455
- bottom: 8px;
456
- right: 8px;
457
- background-color: rgba(0, 0, 0, 0.7);
458
- color: white;
459
- padding: 2px 6px;
460
- border-radius: 4px;
461
- font-size: 12px;
462
- }
463
-
464
- .video-item-info {
465
- padding: 10px;
466
- }
467
-
468
- .video-item-title {
469
- font-size: 14px;
470
- font-weight: 600;
471
- margin-bottom: 6px;
472
- white-space: nowrap;
473
- overflow: hidden;
474
- text-overflow: ellipsis;
475
- }
476
-
477
- .video-item-meta {
478
- display: flex;
479
- justify-content: space-between;
480
- align-items: center;
481
- font-size: 12px;
482
- color: var(--gray-color);
483
- }
484
-
485
- .time-ago {
486
- display: flex;
487
- align-items: center;
488
- }
489
-
490
- .time-ago svg {
491
- width: 12px;
492
- height: 12px;
493
- margin-right: 4px;
494
- }
495
-
496
- /* Empty state */
497
- .empty-state {
498
- display: flex;
499
- flex-direction: column;
500
- align-items: center;
501
- justify-content: center;
502
- height: 50vh;
503
- text-align: center;
504
- padding: 20px;
505
- color: var(--gray-color);
506
- }
507
-
508
- .empty-icon {
509
- width: 80px;
510
- height: 80px;
511
- margin-bottom: 20px;
512
- opacity: 0.5;
513
- }
514
-
515
- .empty-title {
516
- font-size: 20px;
517
- font-weight: 600;
518
- margin-bottom: 10px;
519
- }
520
-
521
- .empty-desc {
522
- font-size: 14px;
523
- max-width: 280px;
524
- }
525
-
526
- /* Profile Screen */
527
- .profile-screen {
528
- background-color: var(--dark-color);
529
- padding-top: 0;
530
- }
531
-
532
- .profile-header {
533
- height: 200px;
534
- background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
535
- position: relative;
536
- display: flex;
537
- flex-direction: column;
538
- justify-content: flex-end;
539
- align-items: center;
540
- padding-bottom: 24px;
541
- }
542
-
543
- .profile-avatar {
544
- width: 100px;
545
- height: 100px;
546
- border-radius: 50%;
547
- border: 4px solid white;
548
- overflow: hidden;
549
- margin-bottom: 12px;
550
- box-shadow: var(--shadow-elevated);
551
- }
552
-
553
- .profile-avatar img {
554
- width: 100%;
555
- height: 100%;
556
- object-fit: cover;
557
- }
558
-
559
- .profile-name {
560
- font-size: 22px;
561
- font-weight: 700;
562
- margin-bottom: 4px;
563
- }
564
-
565
- .profile-stats {
566
- display: flex;
567
- justify-content: space-around;
568
- align-items: center;
569
- width: 100%;
570
- padding: 20px 16px;
571
- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
572
- }
573
-
574
- .stat-item {
575
- display: flex;
576
- flex-direction: column;
577
- align-items: center;
578
- }
579
-
580
- .stat-value {
581
- font-size: 18px;
582
- font-weight: 700;
583
- margin-bottom: 4px;
584
- }
585
-
586
- .stat-label {
587
- font-size: 12px;
588
- color: var(--gray-color);
589
- }
590
-
591
- .profile-actions {
592
- display: flex;
593
- flex-direction: column;
594
- padding: 20px 16px;
595
- }
596
-
597
- .action-row {
598
- display: flex;
599
- align-items: center;
600
- padding: 16px 0;
601
- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
602
- }
603
-
604
- .action-icon {
605
- width: 24px;
606
- height: 24px;
607
- margin-right: 16px;
608
- opacity: 0.8;
609
- }
610
-
611
- .action-text {
612
- flex: 1;
613
- font-size: 16px;
614
- }
615
-
616
- .action-arrow {
617
- width: 20px;
618
- height: 20px;
619
- opacity: 0.5;
620
- }
621
-
622
- /* Toast notification */
623
- .toast {
624
- position: fixed;
625
- top: 80px;
626
- left: 50%;
627
- transform: translateX(-50%);
628
- background-color: rgba(0, 0, 0, 0.8);
629
- color: white;
630
- padding: 10px 20px;
631
- border-radius: 30px;
632
- font-size: 14px;
633
- z-index: 2000;
634
- backdrop-filter: var(--blur-effect);
635
- -webkit-backdrop-filter: var(--blur-effect);
636
- opacity: 0;
637
- transition: var(--transition-normal);
638
- pointer-events: none;
639
- }
640
-
641
- .toast.show {
642
- opacity: 1;
643
- }
644
-
645
- /* Animation for card transition */
646
- @keyframes slideInUp {
647
- from {
648
- transform: translateY(100%);
649
- }
650
- to {
651
- transform: translateY(0);
652
- }
653
- }
654
-
655
- .slide-in {
656
- animation: slideInUp 0.5s cubic-bezier(0.19, 1, 0.22, 1);
657
- }
658
-
659
- /* Responsive adjustments */
660
- @media (min-width: 768px) {
661
- .video-grid {
662
- grid-template-columns: repeat(3, 1fr);
663
- }
664
- }
665
-
666
- @media (min-width: 1024px) {
667
- .video-grid {
668
- grid-template-columns: repeat(4, 1fr);
669
- }
670
- }
671
- </style>
672
- </head>
673
- <body>
674
- <div class="app-container">
675
- <div class="loading-screen" id="loadingScreen">
676
- <div class="loading-spinner"></div>
677
- <div class="loading-text">加载精彩内容中...</div>
678
- </div>
679
-
680
- <div class="toast" id="toast"></div>
681
-
682
- <!-- Home/Feed Screen -->
683
- <div class="screen active" id="homeScreen">
684
- <div class="header">
685
- <div class="app-title">Video<span>Flow</span></div>
686
- </div>
687
-
688
- <div class="progress-bar">
689
- <div class="progress-fill" id="progressFill"></div>
690
- </div>
691
-
692
- <div class="video-feed" id="videoFeed"></div>
693
-
694
- <div class="play-pause-overlay" id="playPauseOverlay">
695
- <svg width="36" height="36" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" id="playPauseIcon">
696
- <path d="M8 5V19L19 12L8 5Z" fill="white" id="playIcon"/>
697
- <path d="M6 19H10V5H6V19ZM14 5V19H18V5H14Z" fill="white" id="pauseIcon" style="display: none;"/>
698
- </svg>
699
- </div>
700
-
701
- <div class="volume-control" id="volumeControl">
702
- <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
703
- <path d="M3 9V15H7L12 20V4L7 9H3Z" fill="white" id="volumeOffIcon" style="display: none;"/>
704
- <path d="M3 9V15H7L12 20V4L7 9H3ZM16.5 12C16.5 10.23 15.48 8.71 14 7.97V16.02C15.48 15.29 16.5 13.77 16.5 12ZM14 3.23V5.29C16.89 6.15 19 8.83 19 12C19 15.17 16.89 17.85 14 18.71V20.77C17.95 19.86 21 16.28 21 12C21 7.72 17.95 4.14 14 3.23Z" fill="white" id="volumeOnIcon"/>
705
- </svg>
706
- </div>
707
-
708
- <div class="action-buttons">
709
- <div class="action-button like" id="likeButton">
710
- <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
711
- <path d="M12 21.35L10.55 20.03C5.4 15.36 2 12.28 2 8.5C2 5.42 4.42 3 7.5 3C9.24 3 10.91 3.81 12 5.09C13.09 3.81 14.76 3 16.5 3C19.58 3 22 5.42 22 8.5C22 12.28 18.6 15.36 13.45 20.04L12 21.35Z" fill="#FF2C55"/>
712
- </svg>
713
- </div>
714
- <div class="action-button favorite" id="favoriteButton">
715
- <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
716
- <path d="M12 17.27L18.18 21L16.54 13.97L22 9.24L14.81 8.63L12 2L9.19 8.63L2 9.24L7.46 13.97L5.82 21L12 17.27Z" fill="#FFD700"/>
717
- </svg>
718
- </div>
719
- <div class="action-button" id="commentButton">
720
- <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
721
- <path d="M21 6H19V15H6V17C6 17.55 6.45 18 7 18H18L22 22V7C22 6.45 21.55 6 21 6ZM17 12V3C17 2.45 16.55 2 16 2H3C2.45 2 2 2.45 2 3V17L6 13H16C16.55 13 17 12.55 17 12Z" fill="white"/>
722
- </svg>
723
- </div>
724
- <div class="action-button" id="shareButton">
725
- <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
726
- <path d="M18 16.08C17.24 16.08 16.56 16.38 16.04 16.85L8.91 12.7C8.96 12.47 9 12.24 9 12C9 11.76 8.96 11.53 8.91 11.3L15.96 7.19C16.5 7.69 17.21 8 18 8C19.66 8 21 6.66 21 5C21 3.34 19.66 2 18 2C16.34 2 15 3.34 15 5C15 5.24 15.04 5.47 15.09 5.7L8.04 9.81C7.5 9.31 6.79 9 6 9C4.34 9 3 10.34 3 12C3 13.66 4.34 15 6 15C6.79 15 7.5 14.69 8.04 14.19L15.16 18.35C15.11 18.56 15.08 18.78 15.08 19C15.08 20.61 16.39 21.92 18 21.92C19.61 21.92 20.92 20.61 20.92 19C20.92 17.39 19.61 16.08 18 16.08Z" fill="white"/>
727
- </svg>
728
- </div>
729
- </div>
730
-
731
- <div class="swipe-indicator" id="swipeIndicator">
732
- <svg class="swipe-icon" width="36" height="36" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
733
- <path d="M7.41 15.41L12 10.83L16.59 15.41L18 14L12 8L6 14L7.41 15.41Z" fill="white"/>
734
- </svg>
735
- <div class="swipe-text">上滑查看下一个</div>
736
- </div>
737
- </div>
738
-
739
- <!-- History Screen -->
740
- <div class="screen" id="historyScreen">
741
- <div class="section-title">观看历史</div>
742
- <div id="historyList" class="video-grid">
743
- <!-- History videos will be loaded here -->
744
- </div>
745
- <div class="empty-state" id="emptyHistory" style="display: none;">
746
- <svg class="empty-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
747
- <path d="M13 3C8.03 3 4 7.03 4 12H1L4.89 15.89L4.96 16.03L9 12H6C6 8.13 9.13 5 13 5C16.87 5 20 8.13 20 12C20 15.87 16.87 19 13 19C11.07 19 9.32 18.21 8.06 16.94L6.64 18.36C8.27 19.99 10.51 21 13 21C17.97 21 22 16.97 22 12C22 7.03 17.97 3 13 3ZM12 8V13L16.28 15.54L17 14.33L13.5 12.25V8H12Z" fill="currentColor"/>
748
- </svg>
749
- <div class="empty-title">暂无观看历史</div>
750
- <div class="empty-desc">您浏览过的视频将会显示在这里</div>
751
- </div>
752
- </div>
753
-
754
- <!-- Favorites Screen -->
755
- <div class="screen" id="favoritesScreen">
756
- <div class="section-title">我的收藏</div>
757
- <div id="favoritesList" class="video-grid">
758
- <!-- Favorite videos will be loaded here -->
759
- </div>
760
- <div class="empty-state" id="emptyFavorites" style="display: none;">
761
- <svg class="empty-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
762
- <path d="M12 17.27L18.18 21L16.54 13.97L22 9.24L14.81 8.63L12 2L9.19 8.63L2 9.24L7.46 13.97L5.82 21L12 17.27Z" fill="currentColor"/>
763
- </svg>
764
- <div class="empty-title">暂无收藏内容</div>
765
- <div class="empty-desc">点击视频右侧的星标图标将视频添加到收藏夹</div>
766
- </div>
767
- </div>
768
-
769
- <!-- Profile Screen -->
770
- <div class="screen" id="profileScreen">
771
- <div class="profile-header">
772
- <div class="profile-avatar">
773
- <img src="https://randomuser.me/api/portraits/women/44.jpg" alt="Profile">
774
- </div>
775
- <div class="profile-name">用户123456</div>
776
- </div>
777
-
778
- <div class="profile-stats">
779
- <div class="stat-item">
780
- <div class="stat-value">42</div>
781
- <div class="stat-label">收藏</div>
782
- </div>
783
- <div class="stat-item">
784
- <div class="stat-value">128</div>
785
- <div class="stat-label">点赞</div>
786
- </div>
787
- <div class="stat-item">
788
- <div class="stat-value">256</div>
789
- <div class="stat-label">观看</div>
790
- </div>
791
- </div>
792
-
793
- <div class="profile-actions">
794
- <div class="action-row">
795
- <svg class="action-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
796
- <path d="M12 12C14.21 12 16 10.21 16 8C16 5.79 14.21 4 12 4C9.79 4 8 5.79 8 8C8 10.21 9.79 12 12 12ZM12 14C9.33 14 4 15.34 4 18V20H20V18C20 15.34 14.67 14 12 14Z" fill="white"/>
797
- </svg>
798
- <div class="action-text">账号设置</div>
799
- <svg class="action-arrow" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
800
- <path d="M8.59 16.59L13.17 12L8.59 7.41L10 6L16 12L10 18L8.59 16.59Z" fill="white"/>
801
- </svg>
802
- </div>
803
- <div class="action-row">
804
- <svg class="action-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
805
- <path d="M19.14 12.94C19.18 12.64 19.2 12.33 19.2 12C19.2 11.68 19.18 11.36 19.13 11.06L21.16 9.48C21.34 9.34 21.39 9.07 21.28 8.87L19.36 5.55C19.24 5.33 18.99 5.26 18.77 5.33L16.38 6.29C15.88 5.91 15.35 5.59 14.76 5.35L14.4 2.81C14.36 2.57 14.16 2.4 13.92 2.4H10.08C9.84 2.4 9.65 2.57 9.61 2.81L9.25 5.35C8.66 5.59 8.12 5.92 7.63 6.29L5.24 5.33C5.02 5.25 4.77 5.33 4.65 5.55L2.74 8.87C2.62 9.08 2.66 9.34 2.86 9.48L4.89 11.06C4.84 11.36 4.8 11.69 4.8 12C4.8 12.31 4.82 12.64 4.87 12.94L2.84 14.52C2.66 14.66 2.61 14.93 2.72 15.13L4.64 18.45C4.76 18.67 5.01 18.74 5.23 18.67L7.62 17.71C8.12 18.09 8.65 18.41 9.24 18.65L9.6 21.19C9.65 21.43 9.84 21.6 10.08 21.6H13.92C14.16 21.6 14.36 21.43 14.39 21.19L14.75 18.65C15.34 18.41 15.88 18.09 16.37 17.71L18.76 18.67C18.98 18.75 19.23 18.67 19.35 18.45L21.27 15.13C21.39 14.91 21.34 14.66 21.15 14.52L19.14 12.94ZM12 15.6C10.02 15.6 8.4 13.98 8.4 12C8.4 10.02 10.02 8.4 12 8.4C13.98 8.4 15.6 10.02 15.6 12C15.6 13.98 13.98 15.6 12 15.6Z" fill="white"/>
806
- </svg>
807
- <div class="action-text">偏好设置</div>
808
- <svg class="action-arrow" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
809
- <path d="M8.59 16.59L13.17 12L8.59 7.41L10 6L16 12L10 18L8.59 16.59Z" fill="white"/>
810
- </svg>
811
- </div>
812
- <div class="action-row">
813
- <svg class="action-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
814
- <path d="M11.99 2C6.47 2 2 6.48 2 12C2 17.52 6.47 22 11.99 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 11.99 2ZM12 20C7.58 20 4 16.42 4 12C4 7.58 7.58 4 12 4C16.42 4 20 7.58 20 12C20 16.42 16.42 20 12 20ZM11 15H13V17H11V15ZM11 7H13V13H11V7Z" fill="white"/>
815
- </svg>
816
- <div class="action-text">关于我们</div>
817
- <svg class="action-arrow" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
818
- <path d="M8.59 16.59L13.17 12L8.59 7.41L10 6L16 12L10 18L8.59 16.59Z" fill="white"/>
819
- </svg>
820
- </div>
821
- <div class="action-row">
822
- <svg class="action-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="color: #FF4D4F;">
823
- <path d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41Z" fill="currentColor"/>
824
- </svg>
825
- <div class="action-text" style="color: #FF4D4F;">退出登录</div>
826
- <svg class="action-arrow" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
827
- <path d="M8.59 16.59L13.17 12L8.59 7.41L10 6L16 12L10 18L8.59 16.59Z" fill="white"/>
828
- </svg>
829
- </div>
830
- </div>
831
- </div>
832
-
833
- <!-- Navigation Bar -->
834
- <div class="nav-bar">
835
- <div class="nav-item active" data-screen="homeScreen">
836
- <svg class="nav-icon" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
837
- <path d="M10 20V14H14V20H19V12H22L12 3L2 12H5V20H10Z"/>
838
- </svg>
839
- <div class="nav-label">首页</div>
840
- </div>
841
- <div class="nav-item" data-screen="historyScreen">
842
- <svg class="nav-icon" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
843
- <path d="M13 3C8.03 3 4 7.03 4 12H1L4.89 15.89L4.96 16.03L9 12H6C6 8.13 9.13 5 13 5C16.87 5 20 8.13 20 12C20 15.87 16.87 19 13 19C11.07 19 9.32 18.21 8.06 16.94L6.64 18.36C8.27 19.99 10.51 21 13 21C17.97 21 22 16.97 22 12C22 7.03 17.97 3 13 3ZM12 8V13L16.28 15.54L17 14.33L13.5 12.25V8H12Z"/>
844
- </svg>
845
- <div class="nav-label">历史</div>
846
- </div>
847
- <div class="nav-item" data-screen="favoritesScreen">
848
- <svg class="nav-icon" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
849
- <path d="M12 17.27L18.18 21L16.54 13.97L22 9.24L14.81 8.63L12 2L9.19 8.63L2 9.24L7.46 13.97L5.82 21L12 17.27Z"/>
850
- </svg>
851
- <div class="nav-label">收藏</div>
852
- </div>
853
- <div class="nav-item" data-screen="profileScreen">
854
- <svg class="nav-icon" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
855
- <path d="M12 12C14.21 12 16 10.21 16 8C16 5.79 14.21 4 12 4C9.79 4 8 5.79 8 8C8 10.21 9.79 12 12 12ZM12 14C9.33 14 4 15.34 4 18V20H20V18C20 15.34 14.67 14 12 14Z"/>
856
- </svg>
857
- <div class="nav-label">我的</div>
858
- </div>
859
- </div>
860
- </div>
861
-
862
- <script>
863
- document.addEventListener('DOMContentLoaded', function() {
864
- const videoFeed = document.getElementById('videoFeed');
865
- const loadingScreen = document.getElementById('loadingScreen');
866
- const refreshButton = document.getElementById('refreshButton');
867
- const likeButton = document.getElementById('likeButton');
868
- const favoriteButton = document.getElementById('favoriteButton');
869
- const commentButton = document.getElementById('commentButton');
870
- const shareButton = document.getElementById('shareButton');
871
- const swipeIndicator = document.getElementById('swipeIndicator');
872
- const progressFill = document.getElementById('progressFill');
873
- const playPauseOverlay = document.getElementById('playPauseOverlay');
874
- const playIcon = document.getElementById('playIcon');
875
- const pauseIcon = document.getElementById('pauseIcon');
876
- const volumeControl = document.getElementById('volumeControl');
877
- const volumeOnIcon = document.getElementById('volumeOnIcon');
878
- const volumeOffIcon = document.getElementById('volumeOffIcon');
879
- const toast = document.getElementById('toast');
880
- const navItems = document.querySelectorAll('.nav-item');
881
- const screens = document.querySelectorAll('.screen');
882
- const historyList = document.getElementById('historyList');
883
- const favoritesList = document.getElementById('favoritesList');
884
- const emptyHistory = document.getElementById('emptyHistory');
885
- const emptyFavorites = document.getElementById('emptyFavorites');
886
-
887
- let currentIndex = 0;
888
- let videos = [];
889
- let touchStartY = 0;
890
- let touchEndY = 0;
891
- let isLoading = false;
892
- let isMuted = false;
893
-
894
- // 本地存储键名
895
- const STORAGE_KEYS = {
896
- HISTORY: 'videoflow_history',
897
- FAVORITES: 'videoflow_favorites'
898
- };
899
-
900
- // 初始化本地存储
901
- initLocalStorage();
902
-
903
- // 预加载三个视频
904
- loadVideos(3);
905
-
906
- // 载入历史记录和收藏列表
907
- loadHistoryList();
908
- loadFavoritesList();
909
-
910
- // 初始化本地存储
911
- function initLocalStorage() {
912
- if (!localStorage.getItem(STORAGE_KEYS.HISTORY)) {
913
- localStorage.setItem(STORAGE_KEYS.HISTORY, JSON.stringify([]));
914
- }
915
- if (!localStorage.getItem(STORAGE_KEYS.FAVORITES)) {
916
- localStorage.setItem(STORAGE_KEYS.FAVORITES, JSON.stringify([]));
917
- }
918
- }
919
-
920
- // 加载视频函数
921
- async function loadVideos(count) {
922
- loadingScreen.style.display = 'flex';
923
- isLoading = true;
924
-
925
- for (let i = 0; i < count; i++) {
926
- try {
927
- const response = await axios.get('https://v2.xxapi.cn/api/meinv');
928
- if (response.data && response.data.code === 200) {
929
- const videoUrl = response.data.data;
930
- createVideoElement(videoUrl);
931
- }
932
- } catch (error) {
933
- console.error('获取视频失败:', error);
934
- showToast('获取视频失败,请检查网络连接');
935
- }
936
- }
937
-
938
- loadingScreen.style.display = 'none';
939
- isLoading = false;
940
-
941
- // 第一次加载完成后显示引导
942
- if (videos.length > 0 && currentIndex === 0) {
943
- setTimeout(() => {
944
- swipeIndicator.style.display = 'flex';
945
- setTimeout(() => {
946
- swipeIndicator.style.opacity = '0';
947
- setTimeout(() => {
948
- swipeIndicator.style.display = 'none';
949
- }, 500);
950
- }, 5000);
951
- }, 1000);
952
- }
953
- }
954
-
955
- // 创建视频元素
956
- function createVideoElement(videoUrl) {
957
- const videoCard = document.createElement('div');
958
- videoCard.className = 'video-card';
959
- videoCard.style.transform = `translateY(${100 * videos.length}%)`;
960
-
961
- const video = document.createElement('video');
962
- video.src = videoUrl;
963
- video.loop = true;
964
- video.muted = false;
965
- video.autoplay = videos.length === 0; // 只有第一个视频自动播放
966
- video.setAttribute('playsinline', '');
967
- video.setAttribute('webkit-playsinline', '');
968
-
969
- // 创建随机视频标题和描述
970
- const videoTitle = `精选视频 #${videos.length + 1}`;
971
- const videoDesc = getRandomDescription();
972
-
973
- // 创建视频对象
974
- const videoObj = {
975
- id: generateId(),
976
- url: videoUrl,
977
- title: videoTitle,
978
- desc: videoDesc,
979
- timestamp: new Date().getTime(),
980
- duration: Math.floor(Math.random() * 60) + 10, // 10-70秒的随机时长
981
- element: videoCard,
982
- video: video,
983
- liked: false,
984
- favorited: false
985
- };
986
-
987
- // 添加视频信息覆盖层
988
- const overlay = document.createElement('div');
989
- overlay.className = 'video-overlay';
990
-
991
- const videoInfo = document.createElement('div');
992
- videoInfo.className = 'video-info';
993
-
994
- const titleEl = document.createElement('div');
995
- titleEl.className = 'video-title';
996
- titleEl.textContent = videoObj.title;
997
-
998
- const descEl = document.createElement('div');
999
- descEl.className = 'video-desc';
1000
- descEl.textContent = videoObj.desc;
1001
-
1002
- const metaEl = document.createElement('div');
1003
- metaEl.className = 'video-meta';
1004
-
1005
- const timeEl = document.createElement('div');
1006
- timeEl.className = 'video-meta-item';
1007
- timeEl.innerHTML = `
1008
- <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
1009
- <path d="M12 2C6.5 2 2 6.5 2 12C2 17.5 6.5 22 12 22C17.5 22 22 17.5 22 12C22 6.5 17.5 2 12 2ZM12 20C7.59 20 4 16.41 4 12C4 7.59 7.59 4 12 4C16.41 4 20 7.59 20 12C20 16.41 16.41 20 12 20ZM12.5 7H11V13L16.2 16.2L17 14.9L12.5 12.2V7Z"/>
1010
- </svg>
1011
- ${formatDuration(videoObj.duration)}
1012
- `;
1013
-
1014
- const viewsEl = document.createElement('div');
1015
- viewsEl.className = 'video-meta-item';
1016
- viewsEl.innerHTML = `
1017
- <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
1018
- <path d="M12 4.5C7 4.5 2.73 7.61 1 12C2.73 16.39 7 19.5 12 19.5C17 19.5 21.27 16.39 23 12C21.27 7.61 17 4.5 12 4.5ZM12 17C9.24 17 7 14.76 7 12C7 9.24 9.24 7 12 7C14.76 7 17 9.24 17 12C17 14.76 14.76 17 12 17ZM12 9C10.34 9 9 10.34 9 12C9 13.66 10.34 15 12 15C13.66 15 15 13.66 15 12C15 10.34 13.66 9 12 9Z"/>
1019
- </svg>
1020
- ${Math.floor(Math.random() * 100000)}
1021
- `;
1022
-
1023
- metaEl.appendChild(timeEl);
1024
- metaEl.appendChild(viewsEl);
1025
-
1026
- videoInfo.appendChild(titleEl);
1027
- videoInfo.appendChild(descEl);
1028
- videoInfo.appendChild(metaEl);
1029
- overlay.appendChild(videoInfo);
1030
-
1031
- videoCard.appendChild(video);
1032
- videoCard.appendChild(overlay);
1033
- videoFeed.appendChild(videoCard);
1034
-
1035
- videos.push(videoObj);
1036
-
1037
- // 添加进度条更新
1038
- video.addEventListener('timeupdate', function() {
1039
- if (videos.indexOf(videos.find(v => v.video === video)) === currentIndex) {
1040
- const progress = (video.currentTime / video.duration) * 100;
1041
- progressFill.style.width = `${progress}%`;
1042
- }
1043
- });
1044
-
1045
- // 第一个视频加载完成后播放
1046
- if (videos.length === 1) {
1047
- video.addEventListener('canplay', function onCanPlay() {
1048
- this.play();
1049
- video.removeEventListener('canplay', onCanPlay);
1050
- addToHistory(videoObj);
1051
- });
1052
- }
1053
-
1054
- // 添加视频加载事件
1055
- video.addEventListener('loadedmetadata', function() {
1056
- videoObj.duration = Math.round(video.duration);
1057
- timeEl.innerHTML = `
1058
- <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
1059
- <path d="M12 2C6.5 2 2 6.5 2 12C2 17.5 6.5 22 12 22C17.5 22 22 17.5 22 12C22 6.5 17.5 2 12 2ZM12 20C7.59 20 4 16.41 4 12C4 7.59 7.59 4 12 4C16.41 4 20 7.59 20 12C20 16.41 16.41 20 12 20ZM12.5 7H11V13L16.2 16.2L17 14.9L12.5 12.2V7Z"/>
1060
- </svg>
1061
- ${formatDuration(videoObj.duration)}
1062
- `;
1063
- });
1064
-
1065
- // 视频错误处理
1066
- video.addEventListener('error', function() {
1067
- console.error('视频加载失败:', videoUrl);
1068
- showToast('视频加载失败,正在尝试下一个');
1069
- switchToVideo(currentIndex + 1);
1070
- });
1071
- }
1072
-
1073
- // 切换到指定索引的视频
1074
- function switchToVideo(index) {
1075
- if (index < 0 || index >= videos.length || isLoading) return;
1076
-
1077
- currentIndex = index;
1078
-
1079
- // 暂停所有视频
1080
- videos.forEach(item => {
1081
- item.video.pause();
1082
- });
1083
-
1084
- // 更新所有视频位置
1085
- videos.forEach((item, idx) => {
1086
- item.element.style.transform = `translateY(${(idx - currentIndex) * 100}%)`;
1087
- });
1088
-
1089
- // 播放当前视频
1090
- videos[currentIndex].video.play();
1091
-
1092
- // 重置进度条
1093
- progressFill.style.width = '0';
1094
-
1095
- // 更新喜欢和收藏按钮状态
1096
- updateActionButtons();
1097
-
1098
- // 添加到历史记录
1099
- addToHistory(videos[currentIndex]);
1100
-
1101
- // 如果当前视频是倒数第二个,加载更多视频
1102
- if (currentIndex >= videos.length - 2) {
1103
- loadVideos(2);
1104
- }
1105
- }
1106
-
1107
- // 更新操作按钮状态
1108
- function updateActionButtons() {
1109
- const currentVideo = videos[currentIndex];
1110
-
1111
- // 更新喜欢按钮
1112
- if (currentVideo.liked) {
1113
- likeButton.classList.add('active');
1114
- } else {
1115
- likeButton.classList.remove('active');
1116
- }
1117
-
1118
- // 更新收藏按钮
1119
- if (currentVideo.favorited) {
1120
- favoriteButton.classList.add('active');
1121
- } else {
1122
- favoriteButton.classList.remove('active');
1123
- }
1124
- }
1125
-
1126
- // 触摸事件处理
1127
- document.addEventListener('touchstart', function(e) {
1128
- touchStartY = e.touches[0].clientY;
1129
- });
1130
-
1131
- document.addEventListener('touchend', function(e) {
1132
- touchEndY = e.changedTouches[0].clientY;
1133
- handleSwipe();
1134
- });
1135
-
1136
- // 处理滑动
1137
- function handleSwipe() {
1138
- const deltaY = touchStartY - touchEndY;
1139
-
1140
- if (Math.abs(deltaY) > 50) { // 滑动距离超过50px才触发
1141
- if (deltaY > 0) {
1142
- // 上滑
1143
- switchToVideo(currentIndex + 1);
1144
- } else {
1145
- // 下滑
1146
- switchToVideo(currentIndex - 1);
1147
- }
1148
- }
1149
- }
1150
-
1151
- // 刷新按钮点击事件
1152
- refreshButton.addEventListener('click', function() {
1153
- if (!isLoading) {
1154
- switchToVideo(currentIndex + 1);
1155
- if (currentIndex >= videos.length - 1) {
1156
- loadVideos(1);
1157
- }
1158
- }
1159
- });
1160
-
1161
- // 喜欢按钮点击事件
1162
- likeButton.addEventListener('click', function() {
1163
- if (currentIndex < videos.length) {
1164
- videos[currentIndex].liked = !videos[currentIndex].liked;
1165
- updateActionButtons();
1166
-
1167
- if (videos[currentIndex].liked) {
1168
- showToast('已添加到喜欢');
1169
- } else {
1170
- showToast('已取消喜欢');
1171
- }
1172
- }
1173
- });
1174
-
1175
- // 收藏按钮点击事件
1176
- favoriteButton.addEventListener('click', function() {
1177
- if (currentIndex < videos.length) {
1178
- const currentVideo = videos[currentIndex];
1179
- currentVideo.favorited = !currentVideo.favorited;
1180
- updateActionButtons();
1181
-
1182
- if (currentVideo.favorited) {
1183
- addToFavorites(currentVideo);
1184
- showToast('已添加到收藏');
1185
- } else {
1186
- removeFromFavorites(currentVideo.id);
1187
- showToast('已取消收藏');
1188
- }
1189
- }
1190
- });
1191
-
1192
- // 评论按钮点击事件
1193
- commentButton.addEventListener('click', function() {
1194
- showToast('评论功能开发中,敬请期待!');
1195
- });
1196
-
1197
- // 分享按钮点击事件
1198
- shareButton.addEventListener('click', function() {
1199
- showToast('分享功能开发中,敬请期待!');
1200
- });
1201
-
1202
- // 点击视频切换播放/暂停
1203
- videoFeed.addEventListener('click', function(e) {
1204
- // 避免点击按钮时触发
1205
- if (e.target.closest('.action-button') ||
1206
- e.target.closest('.volume-control')) {
1207
- return;
1208
- }
1209
-
1210
- const currentVideo = videos[currentIndex].video;
1211
-
1212
- if (currentVideo.paused) {
1213
- currentVideo.play();
1214
- playIcon.style.display = 'block';
1215
- pauseIcon.style.display = 'none';
1216
- } else {
1217
- currentVideo.pause();
1218
- playIcon.style.display = 'none';
1219
- pauseIcon.style.display = 'block';
1220
- }
1221
-
1222
- // 显示播放/暂停覆盖层
1223
- playPauseOverlay.classList.add('visible');
1224
- setTimeout(() => {
1225
- playPauseOverlay.classList.remove('visible');
1226
- }, 800);
1227
- });
1228
-
1229
- // 音量控制
1230
- volumeControl.addEventListener('click', function() {
1231
- isMuted = !isMuted;
1232
- videos.forEach(item => {
1233
- item.video.muted = isMuted;
1234
- });
1235
-
1236
- if (isMuted) {
1237
- volumeOnIcon.style.display = 'none';
1238
- volumeOffIcon.style.display = 'block';
1239
- showToast('已静音');
1240
- } else {
1241
- volumeOnIcon.style.display = 'block';
1242
- volumeOffIcon.style.display = 'none';
1243
- showToast('已开启声音');
1244
- }
1245
- });
1246
-
1247
- // 导航栏切换
1248
- navItems.forEach(item => {
1249
- item.addEventListener('click', function() {
1250
- const targetScreen = this.getAttribute('data-screen');
1251
-
1252
- // 更新导航栏状态
1253
- navItems.forEach(navItem => {
1254
- navItem.classList.remove('active');
1255
- });
1256
- this.classList.add('active');
1257
-
1258
- // 更新屏幕显示
1259
- screens.forEach(screen => {
1260
- screen.classList.remove('active');
1261
- if (screen.id === targetScreen) {
1262
- screen.classList.add('active');
1263
- }
1264
- });
1265
-
1266
- // 如果切换到首页,继续播放当前视频
1267
- if (targetScreen === 'homeScreen' && videos.length > 0) {
1268
- videos[currentIndex].video.play();
1269
- } else if (videos.length > 0) {
1270
- // 其他页面暂停视频播放
1271
- videos[currentIndex].video.pause();
1272
- }
1273
-
1274
- // 如果切换到历史记录或���藏夹,刷新列表
1275
- if (targetScreen === 'historyScreen') {
1276
- loadHistoryList();
1277
- } else if (targetScreen === 'favoritesScreen') {
1278
- loadFavoritesList();
1279
- }
1280
- });
1281
- });
1282
-
1283
- // 添加到历史记录
1284
- function addToHistory(videoObj) {
1285
- if (!videoObj) return;
1286
-
1287
- let history = JSON.parse(localStorage.getItem(STORAGE_KEYS.HISTORY)) || [];
1288
-
1289
- // 检查是否已存在
1290
- const existingIndex = history.findIndex(item => item.id === videoObj.id);
1291
- if (existingIndex !== -1) {
1292
- // 已存在,更新时间戳
1293
- history[existingIndex].timestamp = new Date().getTime();
1294
- } else {
1295
- // 创建简化版视频对象用于存储
1296
- const historyItem = {
1297
- id: videoObj.id,
1298
- url: videoObj.url,
1299
- title: videoObj.title,
1300
- desc: videoObj.desc,
1301
- duration: videoObj.duration,
1302
- timestamp: new Date().getTime()
1303
- };
1304
-
1305
- // 添加到历史记录
1306
- history.unshift(historyItem);
1307
- }
1308
-
1309
- // 限制只保存7天内的历史记录
1310
- const oneWeekAgo = new Date().getTime() - (7 * 24 * 60 * 60 * 1000);
1311
- history = history.filter(item => item.timestamp >= oneWeekAgo);
1312
-
1313
- // 保存到本地存储
1314
- localStorage.setItem(STORAGE_KEYS.HISTORY, JSON.stringify(history));
1315
- }
1316
-
1317
- // 加载历史记录列表
1318
- function loadHistoryList() {
1319
- let history = JSON.parse(localStorage.getItem(STORAGE_KEYS.HISTORY)) || [];
1320
-
1321
- // 按时间戳排序,最新的在前
1322
- history.sort((a, b) => b.timestamp - a.timestamp);
1323
-
1324
- // 清空列表
1325
- historyList.innerHTML = '';
1326
-
1327
- if (history.length === 0) {
1328
- // 显示空状态
1329
- emptyHistory.style.display = 'flex';
1330
- historyList.style.display = 'none';
1331
- } else {
1332
- // 隐藏空状态
1333
- emptyHistory.style.display = 'none';
1334
- historyList.style.display = 'grid';
1335
-
1336
- // 添加历史记录项
1337
- history.forEach(item => {
1338
- const videoItem = createVideoListItem(item, 'history');
1339
- historyList.appendChild(videoItem);
1340
- });
1341
- }
1342
- }
1343
-
1344
- // 添加到收藏夹
1345
- function addToFavorites(videoObj) {
1346
- if (!videoObj) return;
1347
-
1348
- let favorites = JSON.parse(localStorage.getItem(STORAGE_KEYS.FAVORITES)) || [];
1349
-
1350
- // 检查是否已存在
1351
- const existingIndex = favorites.findIndex(item => item.id === videoObj.id);
1352
- if (existingIndex === -1) {
1353
- // 创建简化版视频对象用于存储
1354
- const favoriteItem = {
1355
- id: videoObj.id,
1356
- url: videoObj.url,
1357
- title: videoObj.title,
1358
- desc: videoObj.desc,
1359
- duration: videoObj.duration,
1360
- timestamp: new Date().getTime()
1361
- };
1362
-
1363
- // 添加到收藏夹
1364
- favorites.unshift(favoriteItem);
1365
-
1366
- // 保存到本地存储
1367
- localStorage.setItem(STORAGE_KEYS.FAVORITES, JSON.stringify(favorites));
1368
- }
1369
- }
1370
-
1371
- // 从收藏夹中移除
1372
- function removeFromFavorites(videoId) {
1373
- let favorites = JSON.parse(localStorage.getItem(STORAGE_KEYS.FAVORITES)) || [];
1374
-
1375
- // 过滤掉要移除的项
1376
- favorites = favorites.filter(item => item.id !== videoId);
1377
-
1378
- // 保存到本地存储
1379
- localStorage.setItem(STORAGE_KEYS.FAVORITES, JSON.stringify(favorites));
1380
-
1381
- // 如果当前在收藏页面,刷新列表
1382
- if (document.getElementById('favoritesScreen').classList.contains('active')) {
1383
- loadFavoritesList();
1384
- }
1385
- }
1386
-
1387
- // 加载收藏夹列表
1388
- function loadFavoritesList() {
1389
- let favorites = JSON.parse(localStorage.getItem(STORAGE_KEYS.FAVORITES)) || [];
1390
-
1391
- // 按���间戳排序,最新的在前
1392
- favorites.sort((a, b) => b.timestamp - a.timestamp);
1393
-
1394
- // 清空列表
1395
- favoritesList.innerHTML = '';
1396
-
1397
- if (favorites.length === 0) {
1398
- // 显示空状态
1399
- emptyFavorites.style.display = 'flex';
1400
- favoritesList.style.display = 'none';
1401
- } else {
1402
- // 隐藏空状态
1403
- emptyFavorites.style.display = 'none';
1404
- favoritesList.style.display = 'grid';
1405
-
1406
- // 添加收藏夹项
1407
- favorites.forEach(item => {
1408
- const videoItem = createVideoListItem(item, 'favorite');
1409
- favoritesList.appendChild(videoItem);
1410
- });
1411
- }
1412
- }
1413
-
1414
- // 创建视频列表项
1415
- function createVideoListItem(videoData, type) {
1416
- const videoItem = document.createElement('div');
1417
- videoItem.className = 'video-item';
1418
- videoItem.setAttribute('data-id', videoData.id);
1419
-
1420
- const imageUrl = generateThumbnailFromVideo(videoData.url);
1421
-
1422
- videoItem.innerHTML = `
1423
- <div class="video-thumbnail">
1424
- <img src="${imageUrl}" alt="${videoData.title}">
1425
- <div class="video-duration">${formatDuration(videoData.duration)}</div>
1426
- </div>
1427
- <div class="video-item-info">
1428
- <div class="video-item-title">${videoData.title}</div>
1429
- <div class="video-item-meta">
1430
- <div class="time-ago">
1431
- <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
1432
- <path d="M11.99 2C6.47 2 2 6.48 2 12C2 17.52 6.47 22 11.99 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 11.99 2ZM12 20C7.58 20 4 16.42 4 12C4 7.58 7.58 4 12 4C16.42 4 20 7.58 20 12C20 16.42 16.42 20 12 20ZM12.5 7H11V13L16.2 16.2L17 14.9L12.5 12.2V7Z"/>
1433
- </svg>
1434
- ${formatTimeAgo(videoData.timestamp)}
1435
- </div>
1436
- </div>
1437
- </div>
1438
- `;
1439
-
1440
- // 点击项目播放视频
1441
- videoItem.addEventListener('click', function() {
1442
- playVideoFromLibrary(videoData, type);
1443
- });
1444
-
1445
- return videoItem;
1446
- }
1447
-
1448
- // 从库中播放视频
1449
- function playVideoFromLibrary(videoData, type) {
1450
- // 查找视频是否已在当前队列中
1451
- const existingIndex = videos.findIndex(v => v.id === videoData.id);
1452
-
1453
- if (existingIndex !== -1) {
1454
- // 已在队列中,直接切换
1455
- switchToVideo(existingIndex);
1456
- } else {
1457
- // 不在队列中,创建新视频
1458
- const videoUrl = videoData.url;
1459
- createVideoElement(videoUrl);
1460
-
1461
- // 切换到最后一个(新添加的)视频
1462
- switchToVideo(videos.length - 1);
1463
- }
1464
-
1465
- // 切换到主页
1466
- navItems.forEach(item => {
1467
- item.classList.remove('active');
1468
- if (item.getAttribute('data-screen') === 'homeScreen') {
1469
- item.classList.add('active');
1470
- }
1471
- });
1472
-
1473
- screens.forEach(screen => {
1474
- screen.classList.remove('active');
1475
- if (screen.id === 'homeScreen') {
1476
- screen.classList.add('active');
1477
- }
1478
- });
1479
-
1480
- showToast(`正在播放${type === 'favorite' ? '收藏' : '历史'}视频`);
1481
- }
1482
-
1483
- // 显示提示消息
1484
- function showToast(message, duration = 2000) {
1485
- toast.textContent = message;
1486
- toast.classList.add('show');
1487
-
1488
- setTimeout(() => {
1489
- toast.classList.remove('show');
1490
- }, duration);
1491
- }
1492
-
1493
- // 格式化时长
1494
- function formatDuration(seconds) {
1495
- const minutes = Math.floor(seconds / 60);
1496
- const remainingSeconds = Math.floor(seconds % 60);
1497
- return `${minutes}:${remainingSeconds < 10 ? '0' : ''}${remainingSeconds}`;
1498
- }
1499
-
1500
- // 格式化时间戳
1501
- function formatTimeAgo(timestamp) {
1502
- const now = new Date().getTime();
1503
- const diff = now - timestamp;
1504
-
1505
- // 小于1分钟
1506
- if (diff < 60 * 1000) {
1507
- return "刚刚";
1508
- }
1509
-
1510
- // 小于1小时
1511
- if (diff < 60 * 60 * 1000) {
1512
- return Math.floor(diff / (60 * 1000)) + "分钟前";
1513
- }
1514
-
1515
- // 小于24小时
1516
- if (diff < 24 * 60 * 60 * 1000) {
1517
- return Math.floor(diff / (60 * 60 * 1000)) + "小时前";
1518
- }
1519
-
1520
- // 小于7天
1521
- if (diff < 7 * 24 * 60 * 60 * 1000) {
1522
- return Math.floor(diff / (24 * 60 * 60 * 1000)) + "天前";
1523
- }
1524
-
1525
- // 超过7天,显示具体日期
1526
- const date = new Date(timestamp);
1527
- return `${date.getMonth() + 1}月${date.getDate()}日`;
1528
- }
1529
-
1530
- // 生成唯一ID
1531
- function generateId() {
1532
- return 'vid_' + Math.random().toString(36).substr(2, 9) + '_' + Date.now();
1533
- }
1534
-
1535
- // 从视频URL生成缩略图URL
1536
- function generateThumbnailFromVideo(videoUrl) {
1537
- // 在实际应用中,这里应该是从服务器获取缩略图
1538
- // 为了演示,这里使用随机图片
1539
- const randomId = Math.floor(Math.random() * 1000);
1540
- return `https://picsum.photos/id/${randomId}/300/500`;
1541
- }
1542
-
1543
- // 随机视频描述
1544
- function getRandomDescription() {
1545
- const descriptions = [
1546
- "精选高质量视频,带给你视觉享受",
1547
- "每日精选,让你流连忘返",
1548
- "热门推荐,不容错过的精彩瞬间",
1549
- "探索更多精彩内容,尽在VideoFlow",
1550
- "发现生活中的美好瞬间",
1551
- "精彩纷呈,尽在眼前",
1552
- "让心情放松的精选内容",
1553
- "视觉盛宴,触手可及"
1554
- ];
1555
-
1556
- return descriptions[Math.floor(Math.random() * descriptions.length)];
1557
- }
1558
- });
1559
- </script>
1560
- </body>
1561
- </html>