mirror of
https://github.com/mediacms-io/mediacms.git
synced 2025-11-09 08:58:53 -05:00
fix: Improve autoplay countdown
This commit is contained in:
parent
fcdeac4977
commit
bb70888748
@ -1,11 +1,11 @@
|
|||||||
/* Autoplay Countdown Overlay Styles */
|
/* Minimal Circular Countdown Overlay */
|
||||||
.vjs-autoplay-countdown-overlay {
|
.vjs-autoplay-countdown-overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc(100% - 46px); /* Account for control bar */
|
height: 100%;
|
||||||
background: rgba(0, 0, 0, 0.85);
|
background: rgba(0, 0, 0, 0.7);
|
||||||
display: none;
|
display: none;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -13,9 +13,8 @@
|
|||||||
z-index: 100000;
|
z-index: 100000;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
backdrop-filter: blur(4px);
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.3s ease-in-out;
|
transition: opacity 0.2s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vjs-autoplay-countdown-overlay.autoplay-countdown-show {
|
.vjs-autoplay-countdown-overlay.autoplay-countdown-show {
|
||||||
@ -23,522 +22,174 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.autoplay-countdown-content {
|
.autoplay-countdown-content {
|
||||||
background: linear-gradient(135deg, rgba(0, 0, 0, 0.95), rgba(20, 20, 20, 0.9));
|
|
||||||
border-radius: 20px;
|
|
||||||
padding: 50px;
|
|
||||||
max-width: 480px;
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
box-shadow:
|
|
||||||
0 20px 60px rgba(0, 0, 0, 0.4),
|
|
||||||
0 8px 32px rgba(0, 0, 0, 0.2),
|
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
||||||
backdrop-filter: blur(20px);
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autoplay-countdown-content::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
height: 1px;
|
|
||||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.autoplay-countdown-content::after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: -50%;
|
|
||||||
left: -50%;
|
|
||||||
width: 200%;
|
|
||||||
height: 200%;
|
|
||||||
background: radial-gradient(circle, rgba(255, 0, 0, 0.05) 0%, transparent 70%);
|
|
||||||
animation: backgroundPulse 4s ease-in-out infinite;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes backgroundPulse {
|
|
||||||
0%,
|
|
||||||
100% {
|
|
||||||
opacity: 0.3;
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
opacity: 0.6;
|
|
||||||
transform: scale(1.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.autoplay-countdown-header {
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autoplay-countdown-header h3 {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 26px;
|
|
||||||
font-weight: 400;
|
|
||||||
margin: 0 0 10px 0;
|
|
||||||
line-height: 1.3;
|
|
||||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
|
||||||
.autoplay-countdown-header h3 span {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autoplay-countdown-video-info {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 20px;
|
gap: 12px;
|
||||||
text-align: center;
|
max-width: 350px;
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
margin: 0 0 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.next-video-thumbnail {
|
|
||||||
flex-shrink: 0;
|
|
||||||
width: 180px;
|
|
||||||
height: 101px;
|
|
||||||
border-radius: 12px;
|
|
||||||
overflow: hidden;
|
|
||||||
background: #333;
|
|
||||||
position: relative;
|
|
||||||
box-shadow:
|
|
||||||
0 12px 32px rgba(0, 0, 0, 0.4),
|
|
||||||
0 4px 16px rgba(0, 0, 0, 0.2);
|
|
||||||
border: 2px solid rgba(255, 255, 255, 0.1);
|
|
||||||
transition:
|
|
||||||
transform 0.3s ease,
|
|
||||||
box-shadow 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.next-video-thumbnail:hover {
|
|
||||||
transform: translateY(-4px) scale(1.02);
|
|
||||||
box-shadow:
|
|
||||||
0 16px 40px rgba(0, 0, 0, 0.5),
|
|
||||||
0 8px 24px rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.next-video-thumbnail img {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
display: block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.play-overlay {
|
.countdown-label {
|
||||||
position: absolute;
|
color: rgba(255, 255, 255, 0.8);
|
||||||
top: 50%;
|
font-size: 14px;
|
||||||
left: 50%;
|
font-weight: 400;
|
||||||
transform: translate(-50%, -50%);
|
margin: 0;
|
||||||
background: rgba(0, 0, 0, 0.8);
|
text-transform: uppercase;
|
||||||
border-radius: 50%;
|
letter-spacing: 1px;
|
||||||
width: 64px;
|
|
||||||
height: 64px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: white;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
box-shadow:
|
|
||||||
0 8px 24px rgba(0, 0, 0, 0.5),
|
|
||||||
0 4px 16px rgba(0, 0, 0, 0.3);
|
|
||||||
border: 3px solid rgba(255, 255, 255, 0.2);
|
|
||||||
backdrop-filter: blur(8px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.play-overlay:hover {
|
|
||||||
background: rgba(0, 0, 0, 0.9);
|
|
||||||
transform: translate(-50%, -50%) scale(1.1);
|
|
||||||
box-shadow:
|
|
||||||
0 12px 32px rgba(0, 0, 0, 0.6),
|
|
||||||
0 6px 20px rgba(0, 0, 0, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.play-overlay svg {
|
|
||||||
margin-left: 4px;
|
|
||||||
width: 28px;
|
|
||||||
height: 28px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.next-video-details {
|
|
||||||
flex-grow: 1;
|
|
||||||
min-width: 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.next-video-title {
|
.next-video-title {
|
||||||
color: #999;
|
color: #fff;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: 500;
|
font-weight: 600;
|
||||||
margin: 0 0;
|
margin: 0 0 12px 0;
|
||||||
line-height: 1.4;
|
line-height: 1.3;
|
||||||
|
max-width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
-webkit-line-clamp: 2;
|
-webkit-line-clamp: 2;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.next-video-author {
|
|
||||||
color: #bbb;
|
|
||||||
font-size: 16px;
|
|
||||||
margin: 0 0 8px 0;
|
|
||||||
line-height: 1.3;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.next-video-duration {
|
|
||||||
color: #999;
|
|
||||||
font-size: 14px;
|
|
||||||
margin: 0;
|
|
||||||
line-height: 1.2;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autoplay-countdown-actions {
|
|
||||||
display: flex;
|
|
||||||
gap: 24px;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
padding: 0;
|
|
||||||
margin-top: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button.autoplay-play-button,
|
|
||||||
button.autoplay-cancel-button {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 10px 20px;
|
|
||||||
border: none;
|
|
||||||
border-radius: 8px;
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 600;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
min-width: 140px;
|
|
||||||
height: 48px;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.3px;
|
|
||||||
line-height: 1;
|
|
||||||
white-space: nowrap;
|
|
||||||
box-shadow:
|
|
||||||
0 6px 20px rgba(0, 0, 0, 0.3),
|
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.autoplay-play-button {
|
.next-video-author {
|
||||||
background: linear-gradient(135deg, #ff0000, #e60000);
|
color: rgba(255, 255, 255, 0.7);
|
||||||
color: #fff;
|
font-size: 14px;
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
font-weight: 400;
|
||||||
|
margin: -8px 0 0 0;
|
||||||
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.autoplay-play-button::before {
|
.circular-countdown {
|
||||||
content: "";
|
position: relative;
|
||||||
position: absolute;
|
cursor: pointer;
|
||||||
top: 0;
|
transition: transform 0.2s ease;
|
||||||
left: -100%;
|
margin: 10px 0;
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
|
||||||
transition: left 0.5s ease;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.autoplay-play-button:hover {
|
.circular-countdown:hover {
|
||||||
background: linear-gradient(135deg, #ff1a1a, #cc0000);
|
transform: scale(1.05);
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow:
|
|
||||||
0 8px 25px rgba(255, 0, 0, 0.4),
|
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.autoplay-play-button:hover::before {
|
.countdown-circle {
|
||||||
left: 100%;
|
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.3));
|
||||||
}
|
}
|
||||||
|
|
||||||
.autoplay-play-button:active {
|
.countdown-progress {
|
||||||
transform: translateY(-1px);
|
stroke-linecap: round;
|
||||||
box-shadow:
|
stroke-dasharray: 282.74;
|
||||||
0 4px 15px rgba(255, 0, 0, 0.3),
|
stroke-dashoffset: 282.74;
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.2);
|
}
|
||||||
|
|
||||||
|
.play-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circular-countdown:hover .play-icon circle {
|
||||||
|
fill: rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.circular-countdown:hover .play-icon path {
|
||||||
|
fill: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.autoplay-cancel-button {
|
.autoplay-cancel-button {
|
||||||
background: linear-gradient(135deg, #404040, #2a2a2a);
|
background: transparent;
|
||||||
color: #fff;
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
color: rgba(255, 255, 255, 0.9);
|
||||||
box-shadow:
|
padding: 10px 24px;
|
||||||
0 6px 20px rgba(0, 0, 0, 0.3),
|
border-radius: 6px;
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.autoplay-cancel-button:hover {
|
.autoplay-cancel-button:hover {
|
||||||
background: linear-gradient(135deg, #505050, #3a3a3a);
|
background: rgba(255, 255, 255, 0.1);
|
||||||
transform: translateY(-2px);
|
border-color: rgba(255, 255, 255, 0.5);
|
||||||
box-shadow:
|
color: #fff;
|
||||||
0 8px 25px rgba(0, 0, 0, 0.4),
|
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.autoplay-cancel-button:active {
|
|
||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
box-shadow:
|
|
||||||
0 4px 15px rgba(0, 0, 0, 0.3),
|
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.autoplay-play-button svg,
|
/* Mobile Responsive */
|
||||||
.autoplay-cancel-button svg {
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3));
|
|
||||||
transition: transform 0.3s ease;
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
display: block;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autoplay-play-button:hover svg {
|
|
||||||
transform: scale(1.05);
|
|
||||||
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.4));
|
|
||||||
}
|
|
||||||
|
|
||||||
.autoplay-cancel-button svg {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autoplay-cancel-button:hover svg {
|
|
||||||
transform: scale(1.05) rotate(90deg);
|
|
||||||
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.4));
|
|
||||||
}
|
|
||||||
|
|
||||||
.autoplay-play-button span,
|
|
||||||
.autoplay-cancel-button span {
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
line-height: 1;
|
|
||||||
font-size: inherit;
|
|
||||||
font-weight: inherit;
|
|
||||||
letter-spacing: inherit;
|
|
||||||
text-transform: inherit;
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
max-width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
height: auto;
|
|
||||||
align-self: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure perfect alignment of button content */
|
|
||||||
.autoplay-play-button > *,
|
|
||||||
.autoplay-cancel-button > * {
|
|
||||||
vertical-align: middle;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fix any baseline alignment issues */
|
|
||||||
.autoplay-play-button,
|
|
||||||
.autoplay-cancel-button {
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure text and icons are perfectly aligned */
|
|
||||||
.autoplay-play-button svg,
|
|
||||||
.autoplay-cancel-button svg {
|
|
||||||
vertical-align: middle;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Autoplay Toggle Button Styles */
|
|
||||||
/* .vjs-autoplay-toggle {
|
|
||||||
width: 3em !important;
|
|
||||||
height: 3em !important;
|
|
||||||
flex: none;
|
|
||||||
padding: 0 !important;
|
|
||||||
margin: 0 4px !important;
|
|
||||||
line-height: 3em !important;
|
|
||||||
position: relative;
|
|
||||||
} */
|
|
||||||
|
|
||||||
/* .vjs-autoplay-toggle .vjs-autoplay-icon {
|
|
||||||
width: 1.2em;
|
|
||||||
height: 1.2em;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin: auto;
|
|
||||||
} */
|
|
||||||
|
|
||||||
.vjs-autoplay-toggle .vjs-autoplay-icon svg {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Responsive design */
|
|
||||||
@media (max-width: 767px) {
|
@media (max-width: 767px) {
|
||||||
.autoplay-countdown-video-info {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
.autoplay-countdown-content {
|
.autoplay-countdown-content {
|
||||||
padding: 24px;
|
gap: 8px;
|
||||||
max-width: 400px;
|
max-width: 280px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.autoplay-countdown-header h3 {
|
.countdown-label {
|
||||||
font-size: 20px;
|
font-size: 13px;
|
||||||
}
|
margin: 0;
|
||||||
|
|
||||||
.next-video-thumbnail {
|
|
||||||
width: 140px;
|
|
||||||
height: 78px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.play-overlay {
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.play-overlay svg {
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.next-video-title {
|
.next-video-title {
|
||||||
font-size: 18px;
|
font-size: 16px;
|
||||||
|
margin: 0 0 8px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.next-video-author {
|
.next-video-author {
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
|
margin: -6px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circular-countdown {
|
||||||
|
margin: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circular-countdown svg {
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.autoplay-play-button,
|
|
||||||
.autoplay-cancel-button {
|
.autoplay-cancel-button {
|
||||||
padding: 12px 24px;
|
padding: 8px 20px;
|
||||||
font-size: 14px;
|
font-size: 12px;
|
||||||
min-width: 120px;
|
margin-top: 4px;
|
||||||
height: 44px;
|
|
||||||
gap: 6px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autoplay-play-button svg {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autoplay-cancel-button svg {
|
|
||||||
width: 14px;
|
|
||||||
height: 14px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
@media (max-width: 480px) {
|
||||||
.autoplay-countdown-content {
|
.autoplay-countdown-content {
|
||||||
padding: 20px;
|
gap: 6px;
|
||||||
max-width: 350px;
|
max-width: 260px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.autoplay-countdown-header h3 {
|
.countdown-label {
|
||||||
font-size: 18px;
|
font-size: 12px;
|
||||||
}
|
margin: 0;
|
||||||
|
|
||||||
.countdown-timer {
|
|
||||||
font-size: 24px;
|
|
||||||
padding: 10px 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autoplay-countdown-video-info {
|
|
||||||
gap: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.next-video-thumbnail {
|
|
||||||
width: 120px;
|
|
||||||
height: 68px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.play-overlay {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.play-overlay svg {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.next-video-title {
|
.next-video-title {
|
||||||
font-size: 16px;
|
font-size: 15px;
|
||||||
|
margin: 0 0 6px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.next-video-author {
|
.next-video-author {
|
||||||
font-size: 13px;
|
font-size: 12px;
|
||||||
|
margin: -4px 0 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.autoplay-countdown-actions {
|
.circular-countdown {
|
||||||
gap: 5px;
|
margin: 2px 0;
|
||||||
padding: 0;
|
}
|
||||||
}
|
|
||||||
button.autoplay-play-button,
|
.circular-countdown svg {
|
||||||
button.autoplay-cancel-button {
|
width: 70px;
|
||||||
padding: 10px 20px;
|
height: 70px;
|
||||||
width: 120px;
|
|
||||||
height: 40px;
|
|
||||||
min-width: 120px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.autoplay-play-button,
|
|
||||||
.autoplay-cancel-button {
|
.autoplay-cancel-button {
|
||||||
width: 100%;
|
padding: 6px 16px;
|
||||||
min-width: 100%;
|
font-size: 11px;
|
||||||
height: 46px;
|
margin-top: 2px;
|
||||||
gap: 6px;
|
|
||||||
padding: 10px 20px;
|
|
||||||
font-size: 13px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autoplay-play-button svg {
|
|
||||||
width: 14px;
|
|
||||||
height: 14px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autoplay-cancel-button svg {
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ class AutoplayCountdownOverlay extends Component {
|
|||||||
this.onCancel = options.onCancel || (() => {});
|
this.onCancel = options.onCancel || (() => {});
|
||||||
|
|
||||||
this.currentCountdown = this.countdownSeconds;
|
this.currentCountdown = this.countdownSeconds;
|
||||||
this.countdownInterval = null;
|
this.startTime = null;
|
||||||
this.isActive = false;
|
this.isActive = false;
|
||||||
|
|
||||||
// Bind methods
|
// Bind methods
|
||||||
@ -32,57 +32,38 @@ class AutoplayCountdownOverlay extends Component {
|
|||||||
|
|
||||||
// Get next video title or fallback
|
// Get next video title or fallback
|
||||||
const nextVideoTitle = this.nextVideoData?.title || 'Next Video';
|
const nextVideoTitle = this.nextVideoData?.title || 'Next Video';
|
||||||
const nextVideoThumbnail = this.nextVideoData?.thumbnail || '';
|
|
||||||
|
|
||||||
overlay.innerHTML = `
|
overlay.innerHTML = `
|
||||||
<div class="autoplay-countdown-content">
|
<div class="autoplay-countdown-content">
|
||||||
<div class="autoplay-countdown-header">
|
<div class="countdown-label">Up Next</div>
|
||||||
<h3>Up next in <span class="countdown-timer">${this.countdownSeconds}</span></h3>
|
|
||||||
|
<div class="next-video-title">${nextVideoTitle}</div>
|
||||||
|
${this.nextVideoData?.author ? `<div class="next-video-author">${this.nextVideoData.author}</div>` : ''}
|
||||||
|
|
||||||
|
<div class="circular-countdown">
|
||||||
|
<svg class="countdown-circle" viewBox="0 0 100 100" width="100" height="100">
|
||||||
|
<circle cx="50" cy="50" r="45" stroke="rgba(255,255,255,0.2)" stroke-width="3" fill="none"/>
|
||||||
|
<circle class="countdown-progress" cx="50" cy="50" r="45" stroke="white" stroke-width="3" fill="none"
|
||||||
|
stroke-dasharray="282.74" stroke-dashoffset="282.74" transform="rotate(-90 50 50)"/>
|
||||||
|
<g class="play-icon">
|
||||||
|
<circle cx="50" cy="50" r="20" fill="rgba(255,255,255,0.9)" stroke="none"/>
|
||||||
|
<path d="M45 40l15 10-15 10z" fill="#000"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="autoplay-countdown-video-info">
|
<span class="autoplay-cancel-button">
|
||||||
${
|
CANCEL
|
||||||
nextVideoThumbnail
|
</span>
|
||||||
? `<div class="next-video-thumbnail">
|
|
||||||
<img src="${nextVideoThumbnail}" alt="${nextVideoTitle}" />
|
|
||||||
<div class="play-overlay">
|
|
||||||
<svg viewBox="0 0 24 24" width="28" height="28" fill="currentColor">
|
|
||||||
<path d="M8 5v14l11-7z"/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>`
|
|
||||||
: ''
|
|
||||||
}
|
|
||||||
<div class="next-video-details">
|
|
||||||
<h4 class="next-video-title">${nextVideoTitle}</h4>
|
|
||||||
${this.nextVideoData?.author ? `<p class="next-video-author">${this.nextVideoData.author}</p>` : ''}
|
|
||||||
${this.nextVideoData?.duration ? `<p class="next-video-duration">${this.formatDuration(this.nextVideoData.duration)}</p>` : ''}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="autoplay-countdown-actions">
|
|
||||||
<button class="autoplay-play-button" type="button">
|
|
||||||
<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" fill="currentColor">
|
|
||||||
<path d="M8 5v14l11-7z"/>
|
|
||||||
</svg>
|
|
||||||
Play Now
|
|
||||||
</button>
|
|
||||||
<button class="autoplay-cancel-button" type="button">
|
|
||||||
<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" fill="currentColor">
|
|
||||||
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
|
|
||||||
</svg>
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// Add event listeners with explicit binding
|
// Add event listeners with explicit binding
|
||||||
const playButton = overlay.querySelector('.autoplay-play-button');
|
const circularCountdown = overlay.querySelector('.circular-countdown');
|
||||||
const cancelButton = overlay.querySelector('.autoplay-cancel-button');
|
const cancelButton = overlay.querySelector('.autoplay-cancel-button');
|
||||||
|
|
||||||
if (playButton) {
|
if (circularCountdown) {
|
||||||
playButton.addEventListener('click', (e) => {
|
circularCountdown.addEventListener('click', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.handlePlayNext();
|
this.handlePlayNext();
|
||||||
});
|
});
|
||||||
@ -104,35 +85,48 @@ class AutoplayCountdownOverlay extends Component {
|
|||||||
startCountdown() {
|
startCountdown() {
|
||||||
this.isActive = true;
|
this.isActive = true;
|
||||||
this.currentCountdown = this.countdownSeconds;
|
this.currentCountdown = this.countdownSeconds;
|
||||||
|
this.startTime = Date.now();
|
||||||
|
|
||||||
|
// Show immediately and start countdown without delay
|
||||||
this.show();
|
this.show();
|
||||||
this.updateCountdownDisplay();
|
this.updateCountdownDisplay();
|
||||||
|
|
||||||
// Start countdown interval
|
// Use requestAnimationFrame for smooth animation
|
||||||
this.countdownInterval = setInterval(() => {
|
const animate = () => {
|
||||||
this.currentCountdown--;
|
if (!this.isActive) return;
|
||||||
|
|
||||||
|
const elapsed = (Date.now() - this.startTime) / 1000;
|
||||||
|
this.currentCountdown = Math.max(0, this.countdownSeconds - elapsed);
|
||||||
this.updateCountdownDisplay();
|
this.updateCountdownDisplay();
|
||||||
|
|
||||||
if (this.currentCountdown <= 0) {
|
if (this.currentCountdown <= 0) {
|
||||||
this.stopCountdown();
|
this.stopCountdown();
|
||||||
// Auto-play next video when countdown reaches 0
|
// Auto-play next video when countdown reaches 0
|
||||||
this.handlePlayNext();
|
this.handlePlayNext();
|
||||||
|
} else {
|
||||||
|
requestAnimationFrame(animate);
|
||||||
}
|
}
|
||||||
}, 1000);
|
};
|
||||||
|
|
||||||
|
// Start the animation
|
||||||
|
requestAnimationFrame(animate);
|
||||||
}
|
}
|
||||||
|
|
||||||
stopCountdown() {
|
stopCountdown() {
|
||||||
this.isActive = false;
|
this.isActive = false;
|
||||||
if (this.countdownInterval) {
|
|
||||||
clearInterval(this.countdownInterval);
|
|
||||||
this.countdownInterval = null;
|
|
||||||
}
|
|
||||||
this.hide();
|
this.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCountdownDisplay() {
|
updateCountdownDisplay() {
|
||||||
const timerElement = this.el().querySelector('.countdown-timer');
|
const progressCircle = this.el().querySelector('.countdown-progress');
|
||||||
if (timerElement) {
|
if (progressCircle) {
|
||||||
timerElement.textContent = this.currentCountdown;
|
// Calculate progress (282.74 is the circumference of the circle with radius 45)
|
||||||
|
const circumference = 2 * Math.PI * 45; // 282.74
|
||||||
|
const progress = (this.countdownSeconds - this.currentCountdown) / this.countdownSeconds;
|
||||||
|
const offset = circumference - circumference * progress;
|
||||||
|
|
||||||
|
// Apply the animation
|
||||||
|
progressCircle.style.strokeDashoffset = offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,9 +151,13 @@ class AutoplayCountdownOverlay extends Component {
|
|||||||
show() {
|
show() {
|
||||||
if (this.el()) {
|
if (this.el()) {
|
||||||
this.el().style.display = 'flex';
|
this.el().style.display = 'flex';
|
||||||
// Add animation class for smooth entrance
|
// Force immediate display and add animation class
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
if (this.el()) {
|
||||||
this.el().classList.add('autoplay-countdown-show');
|
this.el().classList.add('autoplay-countdown-show');
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hide() {
|
hide() {
|
||||||
@ -190,29 +188,15 @@ class AutoplayCountdownOverlay extends Component {
|
|||||||
// Re-render the content if the overlay exists
|
// Re-render the content if the overlay exists
|
||||||
if (this.el()) {
|
if (this.el()) {
|
||||||
const nextVideoTitle = this.nextVideoData?.title || 'Next Video';
|
const nextVideoTitle = this.nextVideoData?.title || 'Next Video';
|
||||||
const nextVideoThumbnail = this.nextVideoData?.thumbnail || '';
|
const titleElement = this.el().querySelector('.next-video-title');
|
||||||
|
const authorElement = this.el().querySelector('.next-video-author');
|
||||||
|
|
||||||
const videoInfoElement = this.el().querySelector('.autoplay-countdown-video-info');
|
if (titleElement) {
|
||||||
if (videoInfoElement) {
|
titleElement.textContent = nextVideoTitle;
|
||||||
videoInfoElement.innerHTML = `
|
|
||||||
${
|
|
||||||
nextVideoThumbnail
|
|
||||||
? `<div class="next-video-thumbnail">
|
|
||||||
<img src="${nextVideoThumbnail}" alt="${nextVideoTitle}" />
|
|
||||||
<div class="play-overlay">
|
|
||||||
<svg viewBox="0 0 24 24" width="28" height="28" fill="currentColor">
|
|
||||||
<path d="M8 5v14l11-7z"/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>`
|
|
||||||
: ''
|
|
||||||
}
|
}
|
||||||
<div class="next-video-details">
|
|
||||||
<h4 class="next-video-title">${nextVideoTitle}</h4>
|
if (authorElement && this.nextVideoData?.author) {
|
||||||
${this.nextVideoData?.author ? `<p class="next-video-author">${this.nextVideoData.author}</p>` : ''}
|
authorElement.textContent = this.nextVideoData.author;
|
||||||
${this.nextVideoData?.duration ? `<p class="next-video-duration">${this.formatDuration(this.nextVideoData.duration)}</p>` : ''}
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1046,8 +1046,8 @@ function VideoJSPlayer({ videoId = 'default-video' }) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// other
|
// other
|
||||||
useRoundedCorners: true,
|
useRoundedCorners: false,
|
||||||
isPlayList: true,
|
isPlayList: false,
|
||||||
previewSprite: {
|
previewSprite: {
|
||||||
url: 'https://deic.mediacms.io/media/original/thumbnails/user/thorkild/2ca18fadeef8475eae513c12cc0830d3.19990812hd_1920_1080_30fps.mp4sprites.jpg',
|
url: 'https://deic.mediacms.io/media/original/thumbnails/user/thorkild/2ca18fadeef8475eae513c12cc0830d3.19990812hd_1920_1080_30fps.mp4sprites.jpg',
|
||||||
frame: { width: 160, height: 90, seconds: 10 },
|
frame: { width: 160, height: 90, seconds: 10 },
|
||||||
@ -1685,7 +1685,7 @@ function VideoJSPlayer({ videoId = 'default-video' }) {
|
|||||||
notSupportedMessage: undefined,
|
notSupportedMessage: undefined,
|
||||||
|
|
||||||
// Prevent title attributes on UI elements for better accessibility
|
// Prevent title attributes on UI elements for better accessibility
|
||||||
noUITitleAttributes: false,
|
noUITitleAttributes: true,
|
||||||
|
|
||||||
// Array of playback speed options (e.g., [0.5, 1, 1.5, 2])
|
// Array of playback speed options (e.g., [0.5, 1, 1.5, 2])
|
||||||
playbackRates: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],
|
playbackRates: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],
|
||||||
@ -1834,6 +1834,9 @@ function VideoJSPlayer({ videoId = 'default-video' }) {
|
|||||||
|
|
||||||
// Preload text tracks
|
// Preload text tracks
|
||||||
preloadTextTracks: true,
|
preloadTextTracks: true,
|
||||||
|
|
||||||
|
// Play inline
|
||||||
|
playsinline: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
// ===== COMPONENT CONFIGURATION =====
|
// ===== COMPONENT CONFIGURATION =====
|
||||||
@ -1981,7 +1984,7 @@ function VideoJSPlayer({ videoId = 'default-video' }) {
|
|||||||
handleAutoplay();
|
handleAutoplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
const setupMobilePlayPause = () => {
|
/* const setupMobilePlayPause = () => {
|
||||||
const playerEl = playerRef.current.el();
|
const playerEl = playerRef.current.el();
|
||||||
const videoEl = playerEl.querySelector('video');
|
const videoEl = playerEl.querySelector('video');
|
||||||
|
|
||||||
@ -2049,8 +2052,8 @@ function VideoJSPlayer({ videoId = 'default-video' }) {
|
|||||||
videoEl.addEventListener('touchstart', handleTouchStart, { passive: true });
|
videoEl.addEventListener('touchstart', handleTouchStart, { passive: true });
|
||||||
videoEl.addEventListener('touchend', handleTouchEnd, { passive: false });
|
videoEl.addEventListener('touchend', handleTouchEnd, { passive: false });
|
||||||
}
|
}
|
||||||
};
|
}; */
|
||||||
setTimeout(setupMobilePlayPause, 100);
|
//setTimeout(setupMobilePlayPause, 100);
|
||||||
|
|
||||||
// Get control bar and its children
|
// Get control bar and its children
|
||||||
const controlBar = playerRef.current.getChild('controlBar');
|
const controlBar = playerRef.current.getChild('controlBar');
|
||||||
@ -2526,7 +2529,7 @@ function VideoJSPlayer({ videoId = 'default-video' }) {
|
|||||||
// Store components reference for potential cleanup
|
// Store components reference for potential cleanup
|
||||||
|
|
||||||
// BEGIN: Fix Android seekbar touch functionality
|
// BEGIN: Fix Android seekbar touch functionality
|
||||||
if (isTouchDevice) {
|
/* if (isTouchDevice) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const progressControl = playerRef.current
|
const progressControl = playerRef.current
|
||||||
.getChild('controlBar')
|
.getChild('controlBar')
|
||||||
@ -2616,7 +2619,7 @@ function VideoJSPlayer({ videoId = 'default-video' }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
} */
|
||||||
// END: Fix Android seekbar touch functionality
|
// END: Fix Android seekbar touch functionality
|
||||||
|
|
||||||
// BEGIN: Add comprehensive keyboard event handling
|
// BEGIN: Add comprehensive keyboard event handling
|
||||||
@ -2772,10 +2775,10 @@ function VideoJSPlayer({ videoId = 'default-video' }) {
|
|||||||
autoplayCountdown = null;
|
autoplayCountdown = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show autoplay countdown
|
// Show autoplay countdown immediately
|
||||||
autoplayCountdown = new AutoplayCountdownOverlay(playerRef.current, {
|
autoplayCountdown = new AutoplayCountdownOverlay(playerRef.current, {
|
||||||
nextVideoData: nextVideoData,
|
nextVideoData: nextVideoData,
|
||||||
countdownSeconds: 500,
|
countdownSeconds: 5,
|
||||||
onPlayNext: () => {
|
onPlayNext: () => {
|
||||||
goToNextVideo();
|
goToNextVideo();
|
||||||
},
|
},
|
||||||
@ -2790,8 +2793,13 @@ function VideoJSPlayer({ videoId = 'default-video' }) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
playerRef.current.addChild(autoplayCountdown);
|
playerRef.current.addChild(autoplayCountdown);
|
||||||
|
// Start countdown immediately without any delay
|
||||||
|
setTimeout(() => {
|
||||||
|
if (autoplayCountdown && !autoplayCountdown.isDisposed()) {
|
||||||
autoplayCountdown.startCountdown();
|
autoplayCountdown.startCountdown();
|
||||||
}
|
}
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Autoplay disabled or no next video - show regular end screen
|
// Autoplay disabled or no next video - show regular end screen
|
||||||
showEndScreen();
|
showEndScreen();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user