From 16790dea4f6bbb4100040115f1346cbdce8b5946 Mon Sep 17 00:00:00 2001 From: AlexFreik Date: Thu, 16 Jan 2025 18:04:47 +0530 Subject: [PATCH] fix edge case when due to missing part it starts skipping to live --- yad/index.html | 37 +- yad/output.css | 1028 ++++++++++++++++++++++++++++++++++++------------ yad/script.js | 56 +-- yad/tools.js | 40 ++ 4 files changed, 857 insertions(+), 304 deletions(-) create mode 100644 yad/tools.js diff --git a/yad/index.html b/yad/index.html index 9a357f4..bee4c26 100644 --- a/yad/index.html +++ b/yad/index.html @@ -4,6 +4,7 @@ YAD: YouTube Auto Delay + @@ -29,15 +30,15 @@ Delay: ... || New Delay - + || - - - - - - + + + + + + || @@ -57,24 +58,24 @@

- This website fixes the + This website addresses the skipping issue in YouTube for delayed streams.

- What is the skipping issue? If you are currently watching a stream 20min behind LIVE and you face some network fluctuations - YouTube might jump to LIVE (i.e. 0sec delay), and these 20min will be lost.

+ What is the skip issue? If you are currently watching a stream that is 15min behind LIVE and you face some network + fluctuations, YouTube may jump to LIVE (i.e. 0sec delay) and those 15min will be lost.

- But if you are using YAD and YouTube tries to skip to LIVE the script will automatically bring you back, so you will not miss + But if you are using YAD and YouTube tries to jump to LIVE, the script will automatically bring you back, so you will not miss anything!

- Note 1: Due to YouTube limitations the script works only for streams that started at least 30min ago. For newly started - streams the script will not be correcting skipping.

+ Note 1: Due to YouTube limitations, the script only works for streams that started at least 30min ago. For newly started + streams, the script will not correct the skipping.

- Note 2: You can't go to LIVE because the minimal possible delay is set to 60s. When you click the LIVE button the - script will think that YouTube skipped and transition you back.

+ Note 2: You can't go to LIVE because the minimum delay is set to 600s (10min). If you click the LIVE button, the + script will think that YouTube skipped and will take you back.

-
+
YouTube Video ID
- Delay (seconds) + Starting Delay (sec)
diff --git a/yad/output.css b/yad/output.css index 26e6c15..1ce9baf 100644 --- a/yad/output.css +++ b/yad/output.css @@ -1175,6 +1175,36 @@ html { margin-bottom: 0; } +.alert { + display: grid; + width: 100%; + grid-auto-flow: row; + align-content: flex-start; + align-items: center; + justify-items: center; + gap: 1rem; + text-align: center; + border-radius: var(--rounded-box, 1rem); + border-width: 1px; + --tw-border-opacity: 1; + border-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity))); + padding: 1rem; + --tw-text-opacity: 1; + color: var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity))); + --alert-bg: var(--fallback-b2,oklch(var(--b2)/1)); + --alert-bg-mix: var(--fallback-b1,oklch(var(--b1)/1)); + background-color: var(--alert-bg); +} + +@media (min-width: 640px) { + .alert { + grid-auto-flow: column; + grid-template-columns: auto minmax(auto,1fr); + justify-items: start; + text-align: start; + } +} + .avatar.placeholder > div { display: flex; align-items: center; @@ -1231,6 +1261,12 @@ html { .tab:hover { --tw-text-opacity: 1; } + + .table tr.hover:hover, + .table tr.hover:nth-child(even):hover { + --tw-bg-opacity: 1; + background-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity))); + } } .btn { @@ -1278,6 +1314,13 @@ html { pointer-events: none; } +.btn-circle { + height: 3rem; + width: 3rem; + border-radius: 9999px; + padding: 0px; +} + :where(.btn:is(input[type="checkbox"])), :where(.btn:is(input[type="radio"])) { width: auto; @@ -1774,6 +1817,20 @@ html { padding: 1rem; } +.indicator { + position: relative; + display: inline-flex; + width: -moz-max-content; + width: max-content; +} + +.indicator :where(.indicator-item) { + z-index: 1; + position: absolute; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + white-space: nowrap; +} + .input { flex-shrink: 1; -webkit-appearance: none; @@ -2104,19 +2161,35 @@ input.tab:checked + .tab-content, display: block; } -.textarea { - min-height: 3rem; - flex-shrink: 1; - padding-left: 1rem; - padding-right: 1rem; - padding-top: 0.5rem; - padding-bottom: 0.5rem; +.table { + position: relative; + width: 100%; + border-radius: var(--rounded-box, 1rem); + text-align: left; font-size: 0.875rem; line-height: 1.25rem; - line-height: 2; - border-radius: var(--rounded-btn, 0.5rem); - border-width: 1px; - border-color: transparent; +} + +.table :where(.table-pin-rows thead tr) { + position: sticky; + top: 0px; + z-index: 1; + --tw-bg-opacity: 1; + background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity))); +} + +.table :where(.table-pin-rows tfoot tr) { + position: sticky; + bottom: 0px; + z-index: 1; + --tw-bg-opacity: 1; + background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity))); +} + +.table :where(.table-pin-cols tr th) { + position: sticky; + left: 0px; + right: 0px; --tw-bg-opacity: 1; background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity))); } @@ -2182,12 +2255,38 @@ input.tab:checked + .tab-content, var(--togglehandleborder); } -.badge-info { +.badge-neutral { + --tw-border-opacity: 1; + border-color: var(--fallback-n,oklch(var(--n)/var(--tw-border-opacity))); + --tw-bg-opacity: 1; + background-color: var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity))); + --tw-text-opacity: 1; + color: var(--fallback-nc,oklch(var(--nc)/var(--tw-text-opacity))); +} + +.badge-secondary { + --tw-border-opacity: 1; + border-color: var(--fallback-s,oklch(var(--s)/var(--tw-border-opacity))); + --tw-bg-opacity: 1; + background-color: var(--fallback-s,oklch(var(--s)/var(--tw-bg-opacity))); + --tw-text-opacity: 1; + color: var(--fallback-sc,oklch(var(--sc)/var(--tw-text-opacity))); +} + +.badge-success { border-color: transparent; --tw-bg-opacity: 1; - background-color: var(--fallback-in,oklch(var(--in)/var(--tw-bg-opacity))); + background-color: var(--fallback-su,oklch(var(--su)/var(--tw-bg-opacity))); --tw-text-opacity: 1; - color: var(--fallback-inc,oklch(var(--inc)/var(--tw-text-opacity))); + color: var(--fallback-suc,oklch(var(--suc)/var(--tw-text-opacity))); +} + +.badge-warning { + border-color: transparent; + --tw-bg-opacity: 1; + background-color: var(--fallback-wa,oklch(var(--wa)/var(--tw-bg-opacity))); + --tw-text-opacity: 1; + color: var(--fallback-wac,oklch(var(--wac)/var(--tw-text-opacity))); } .badge-error { @@ -2286,6 +2385,22 @@ input.tab:checked + .tab-content, --btn-color: var(--fallback-a); } + .btn-neutral { + --btn-color: var(--fallback-n); + } + + .btn-success { + --btn-color: var(--fallback-su); + } + + .btn-warning { + --btn-color: var(--fallback-wa); + } + + .btn-error { + --btn-color: var(--fallback-er); + } + .prose :where(code):not(:where([class~="not-prose"] *, pre *)) { background-color: var(--fallback-b3,oklch(var(--b3)/1)); } @@ -2342,6 +2457,22 @@ input.tab:checked + .tab-content, .btn-accent { --btn-color: var(--a); } + + .btn-neutral { + --btn-color: var(--n); + } + + .btn-success { + --btn-color: var(--su); + } + + .btn-warning { + --btn-color: var(--wa); + } + + .btn-error { + --btn-color: var(--er); + } } .btn-secondary { @@ -2356,6 +2487,30 @@ input.tab:checked + .tab-content, outline-color: var(--fallback-a,oklch(var(--a)/1)); } +.btn-neutral { + --tw-text-opacity: 1; + color: var(--fallback-nc,oklch(var(--nc)/var(--tw-text-opacity))); + outline-color: var(--fallback-n,oklch(var(--n)/1)); +} + +.btn-success { + --tw-text-opacity: 1; + color: var(--fallback-suc,oklch(var(--suc)/var(--tw-text-opacity))); + outline-color: var(--fallback-su,oklch(var(--su)/1)); +} + +.btn-warning { + --tw-text-opacity: 1; + color: var(--fallback-wac,oklch(var(--wac)/var(--tw-text-opacity))); + outline-color: var(--fallback-wa,oklch(var(--wa)/1)); +} + +.btn-error { + --tw-text-opacity: 1; + color: var(--fallback-erc,oklch(var(--erc)/var(--tw-text-opacity))); + outline-color: var(--fallback-er,oklch(var(--er)/1)); +} + .btn.glass { --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; @@ -2696,6 +2851,18 @@ input.tab:checked + .tab-content, outline-color: var(--fallback-s,oklch(var(--s)/1)); } +.input-error { + --tw-border-opacity: 1; + border-color: var(--fallback-er,oklch(var(--er)/var(--tw-border-opacity))); +} + +.input-error:focus, + .input-error:focus-within { + --tw-border-opacity: 1; + border-color: var(--fallback-er,oklch(var(--er)/var(--tw-border-opacity))); + outline-color: var(--fallback-er,oklch(var(--er)/1)); +} + .input:has(> input[disabled]), .input-disabled, .input:disabled, @@ -2827,42 +2994,6 @@ input.tab:checked + .tab-content, margin-top: 0; } -.mockup-phone .camera { - position: relative; - top: 0px; - left: 0px; - background: #000; - height: 25px; - width: 150px; - margin: 0 auto; - border-bottom-left-radius: 17px; - border-bottom-right-radius: 17px; - z-index: 11; -} - -.mockup-phone .camera:before { - content: ""; - position: absolute; - top: 35%; - left: 50%; - width: 50px; - height: 4px; - border-radius: 5px; - background-color: #0c0b0e; - transform: translate(-50%, -50%); -} - -.mockup-phone .camera:after { - content: ""; - position: absolute; - top: 20%; - left: 70%; - width: 8px; - height: 8px; - border-radius: 5px; - background-color: #0f0b25; -} - .mockup-phone .display { overflow: hidden; border-radius: 40px; @@ -3100,6 +3231,49 @@ input.tab:checked + .tab-content, } } +.swap-rotate .swap-on, +.swap-rotate .swap-indeterminate, +.swap-rotate input:indeterminate ~ .swap-on { + --tw-rotate: 45deg; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.swap-rotate input:checked ~ .swap-off, +.swap-active:where(.swap-rotate) .swap-off, +.swap-rotate input:indeterminate ~ .swap-off { + --tw-rotate: -45deg; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.swap-rotate input:checked ~ .swap-on, +.swap-active:where(.swap-rotate) .swap-on, +.swap-rotate input:indeterminate ~ .swap-indeterminate { + --tw-rotate: 0deg; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.swap-flip .swap-on, +.swap-flip .swap-indeterminate, +.swap-flip input:indeterminate ~ .swap-on { + transform: rotateY(180deg); + backface-visibility: hidden; + opacity: 1; +} + +.swap-flip input:checked ~ .swap-off, +.swap-active:where(.swap-flip) .swap-off, +.swap-flip input:indeterminate ~ .swap-off { + transform: rotateY(-180deg); + backface-visibility: hidden; + opacity: 1; +} + +.swap-flip input:checked ~ .swap-on, +.swap-active:where(.swap-flip) .swap-on, +.swap-flip input:indeterminate ~ .swap-indeterminate { + transform: rotateY(0deg); +} + .tabs-lifted > .tab:focus-visible { border-end-end-radius: 0; border-end-start-radius: 0; @@ -3222,6 +3396,18 @@ input.tab:checked + .tab-content, border-radius: var(--rounded-btn, 0.5rem); } +:is([dir="rtl"] .table) { + text-align: right; +} + +.table :where(th, td) { + padding-left: 1rem; + padding-right: 1rem; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + vertical-align: middle; +} + .table tr.active, .table tr.active:nth-child(even), .table-zebra tbody tr:nth-child(even) { @@ -3236,40 +3422,24 @@ input.tab:checked + .tab-content, background-color: var(--fallback-b3,oklch(var(--b3)/var(--tw-bg-opacity))); } -.textarea-bordered { - border-color: var(--fallback-bc,oklch(var(--bc)/0.2)); -} - -.textarea:focus { - box-shadow: none; - border-color: var(--fallback-bc,oklch(var(--bc)/0.2)); - outline-style: solid; - outline-width: 2px; - outline-offset: 2px; - outline-color: var(--fallback-bc,oklch(var(--bc)/0.2)); -} - -.textarea-disabled, - .textarea:disabled, - .textarea[disabled] { - cursor: not-allowed; +.table :where(thead tr, tbody tr:not(:last-child),tbody tr:first-child:last-child) { + border-bottom-width: 1px; --tw-border-opacity: 1; - border-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity))); - --tw-bg-opacity: 1; - background-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity))); - color: var(--fallback-bc,oklch(var(--bc)/0.4)); + border-bottom-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity))); } -.textarea-disabled::-moz-placeholder, .textarea:disabled::-moz-placeholder, .textarea[disabled]::-moz-placeholder { - color: var(--fallback-bc,oklch(var(--bc)/var(--tw-placeholder-opacity))); - --tw-placeholder-opacity: 0.2; +.table :where(thead, tfoot) { + white-space: nowrap; + font-size: 0.75rem; + line-height: 1rem; + font-weight: 700; + color: var(--fallback-bc,oklch(var(--bc)/0.6)); } -.textarea-disabled::placeholder, - .textarea:disabled::placeholder, - .textarea[disabled]::placeholder { - color: var(--fallback-bc,oklch(var(--bc)/var(--tw-placeholder-opacity))); - --tw-placeholder-opacity: 0.2; +.table :where(tfoot) { + border-top-width: 1px; + --tw-border-opacity: 1; + border-top-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity))); } .timeline hr { @@ -3425,6 +3595,50 @@ input.tab:checked + .tab-content, border-bottom-color: var(--fallback-bc,oklch(var(--bc)/0.2)); } +.artboard.phone-1.horizontal, + .artboard.phone-1.artboard-horizontal { + width: 568px; + height: 320px; +} + +.artboard.phone-2.horizontal, + .artboard.phone-2.artboard-horizontal { + width: 667px; + height: 375px; +} + +.artboard.phone-3.horizontal, + .artboard.phone-3.artboard-horizontal { + width: 736px; + height: 414px; +} + +.artboard.phone-4.horizontal, + .artboard.phone-4.artboard-horizontal { + width: 812px; + height: 375px; +} + +.artboard.phone-5.horizontal, + .artboard.phone-5.artboard-horizontal { + width: 896px; + height: 414px; +} + +.artboard.phone-6.horizontal, + .artboard.phone-6.artboard-horizontal { + width: 1024px; + height: 320px; +} + +.badge-lg { + height: 1.5rem; + font-size: 1rem; + line-height: 1.5rem; + padding-left: 0.688rem; + padding-right: 0.688rem; +} + .btm-nav-xs > *:where(.active) { border-top-width: 1px; } @@ -3560,39 +3774,111 @@ html:has(.drawer-toggle:checked) { scrollbar-gutter: stable; } -.input-xs { - height: 1.5rem; - padding-left: 0.5rem; - padding-right: 0.5rem; - font-size: 0.75rem; - line-height: 1rem; - line-height: 1.625; +.indicator :where(.indicator-item) { + bottom: auto; + inset-inline-end: 0px; + inset-inline-start: auto; + top: 0px; + --tw-translate-y: -50%; + --tw-translate-x: 50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.input-lg { - height: 4rem; - padding-left: 1.5rem; - padding-right: 1.5rem; - font-size: 1.125rem; - line-height: 1.75rem; - line-height: 2; +:is([dir="rtl"] .indicator :where(.indicator-item)) { + --tw-translate-x: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.input-sm { - height: 2rem; - padding-left: 0.75rem; - padding-right: 0.75rem; - font-size: 0.875rem; - line-height: 2rem; +.indicator :where(.indicator-item.indicator-start) { + inset-inline-end: auto; + inset-inline-start: 0px; + --tw-translate-x: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.join.join-vertical { - flex-direction: column; +:is([dir="rtl"] .indicator :where(.indicator-item.indicator-start)) { + --tw-translate-x: 50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.join.join-vertical .join-item:first-child:not(:last-child), - .join.join-vertical *:first-child:not(:last-child) .join-item { - border-end-start-radius: 0; +.indicator :where(.indicator-item.indicator-center) { + inset-inline-end: 50%; + inset-inline-start: 50%; + --tw-translate-x: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +:is([dir="rtl"] .indicator :where(.indicator-item.indicator-center)) { + --tw-translate-x: 50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.indicator :where(.indicator-item.indicator-end) { + inset-inline-end: 0px; + inset-inline-start: auto; + --tw-translate-x: 50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +:is([dir="rtl"] .indicator :where(.indicator-item.indicator-end)) { + --tw-translate-x: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.indicator :where(.indicator-item.indicator-bottom) { + bottom: 0px; + top: auto; + --tw-translate-y: 50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.indicator :where(.indicator-item.indicator-middle) { + bottom: 50%; + top: 50%; + --tw-translate-y: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.indicator :where(.indicator-item.indicator-top) { + bottom: auto; + top: 0px; + --tw-translate-y: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.input-xs { + height: 1.5rem; + padding-left: 0.5rem; + padding-right: 0.5rem; + font-size: 0.75rem; + line-height: 1rem; + line-height: 1.625; +} + +.input-lg { + height: 4rem; + padding-left: 1.5rem; + padding-right: 1.5rem; + font-size: 1.125rem; + line-height: 1.75rem; + line-height: 2; +} + +.input-sm { + height: 2rem; + padding-left: 0.75rem; + padding-right: 0.75rem; + font-size: 0.875rem; + line-height: 2rem; +} + +.join.join-vertical { + flex-direction: column; +} + +.join.join-vertical .join-item:first-child:not(:last-child), + .join.join-vertical *:first-child:not(:last-child) .join-item { + border-end-start-radius: 0; border-end-end-radius: 0; border-start-start-radius: inherit; border-start-end-radius: inherit; @@ -3694,45 +3980,6 @@ html:has(.drawer-toggle:checked) { --tab-padding: 0.5rem; } -.tooltip { - position: relative; - display: inline-block; - --tooltip-offset: calc(100% + 1px + var(--tooltip-tail, 0px)); -} - -.tooltip:before { - position: absolute; - pointer-events: none; - z-index: 1; - content: var(--tw-content); - --tw-content: attr(data-tip); -} - -.tooltip:before, .tooltip-top:before { - transform: translateX(-50%); - top: auto; - left: 50%; - right: auto; - bottom: var(--tooltip-offset); -} - -.avatar.online:before { - content: ""; - position: absolute; - z-index: 10; - display: block; - border-radius: 9999px; - --tw-bg-opacity: 1; - background-color: var(--fallback-su,oklch(var(--su)/var(--tw-bg-opacity))); - outline-style: solid; - outline-width: 2px; - outline-color: var(--fallback-b1,oklch(var(--b1)/1)); - width: 15%; - height: 15%; - top: 7%; - right: 7%; -} - .card-compact .card-body { padding: 1rem; font-size: 0.875rem; @@ -3791,117 +4038,90 @@ html:has(.drawer-toggle:checked) { box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } -.tooltip { - position: relative; - display: inline-block; - text-align: center; - --tooltip-tail: 0.1875rem; - --tooltip-color: var(--fallback-n,oklch(var(--n)/1)); - --tooltip-text-color: var(--fallback-nc,oklch(var(--nc)/1)); - --tooltip-tail-offset: calc(100% + 0.0625rem - var(--tooltip-tail)); +.visible { + visibility: visible; } -.tooltip:before, -.tooltip:after { - opacity: 0; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; - transition-delay: 100ms; - transition-duration: 200ms; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +.invisible { + visibility: hidden; } -.tooltip:after { - position: absolute; - content: ""; - border-style: solid; - border-width: var(--tooltip-tail, 0); - width: 0; - height: 0; - display: block; +.static { + position: static; } -.tooltip:before { - max-width: 20rem; - border-radius: 0.25rem; - padding-left: 0.5rem; - padding-right: 0.5rem; - padding-top: 0.25rem; - padding-bottom: 0.25rem; - font-size: 0.875rem; - line-height: 1.25rem; - background-color: var(--tooltip-color); - color: var(--tooltip-text-color); - width: -moz-max-content; - width: max-content; +.fixed { + position: fixed; } -.tooltip.tooltip-open:before { - opacity: 1; - transition-delay: 75ms; +.absolute { + position: absolute; } -.tooltip.tooltip-open:after { - opacity: 1; - transition-delay: 75ms; +.relative { + position: relative; } -.tooltip:hover:before { - opacity: 1; - transition-delay: 75ms; +.sticky { + position: sticky; } -.tooltip:hover:after { - opacity: 1; - transition-delay: 75ms; +.inset-0 { + inset: 0px; } -.tooltip:has(:focus-visible):after, -.tooltip:has(:focus-visible):before { - opacity: 1; - transition-delay: 75ms; +.bottom-1 { + bottom: 0.25rem; } -.tooltip:not([data-tip]):hover:before, -.tooltip:not([data-tip]):hover:after { - visibility: hidden; - opacity: 0; +.bottom-2 { + bottom: 0.5rem; } -.tooltip:after, .tooltip-top:after { - transform: translateX(-50%); - border-color: var(--tooltip-color) transparent transparent transparent; - top: auto; +.left-0 { + left: 0px; +} + +.left-1\/2 { left: 50%; - right: auto; - bottom: var(--tooltip-tail-offset); } -.fixed { - position: fixed; +.right-1 { + right: 0.25rem; } -.absolute { - position: absolute; +.right-9 { + right: 2.25rem; } -.relative { - position: relative; +.top-0 { + top: 0px; } -.sticky { - position: sticky; +.top-1\/2 { + top: 50%; } -.top-0 { - top: 0px; +.z-10 { + z-index: 10; +} + +.col-span-1 { + grid-column: span 1 / span 1; } .col-start-2 { grid-column-start: 2; } +.row-span-1 { + grid-row: span 1 / span 1; +} + +.row-span-2 { + grid-row: span 2 / span 2; +} + .row-start-\[10\] { grid-row-start: 10; } @@ -4311,6 +4531,11 @@ html:has(.drawer-toggle:checked) { margin-right: 0.25rem; } +.mx-3 { + margin-left: 0.75rem; + margin-right: 0.75rem; +} + .mx-auto { margin-left: auto; margin-right: auto; @@ -4321,6 +4546,11 @@ html:has(.drawer-toggle:checked) { margin-bottom: 0px; } +.my-1 { + margin-top: 0.25rem; + margin-bottom: 0.25rem; +} + .my-10 { margin-top: 2.5rem; margin-bottom: 2.5rem; @@ -4346,11 +4576,6 @@ html:has(.drawer-toggle:checked) { margin-bottom: 1.25rem; } -.my-8 { - margin-top: 2rem; - margin-bottom: 2rem; -} - .-mt-2 { margin-top: -0.5rem; } @@ -4371,8 +4596,8 @@ html:has(.drawer-toggle:checked) { margin-bottom: 1.25rem; } -.mb-8 { - margin-bottom: 2rem; +.ml-0 { + margin-left: 0px; } .ml-1 { @@ -4383,6 +4608,14 @@ html:has(.drawer-toggle:checked) { margin-left: 1rem; } +.mr-0 { + margin-right: 0px; +} + +.mr-1 { + margin-right: 0.25rem; +} + .ms-3 { margin-inline-start: 0.75rem; } @@ -4395,6 +4628,10 @@ html:has(.drawer-toggle:checked) { margin-top: 2.5rem; } +.mt-2 { + margin-top: 0.5rem; +} + .mt-3 { margin-top: 0.75rem; } @@ -4403,6 +4640,10 @@ html:has(.drawer-toggle:checked) { margin-top: 1.25rem; } +.block { + display: block; +} + .inline-block { display: inline-block; } @@ -4419,6 +4660,10 @@ html:has(.drawer-toggle:checked) { display: inline-flex; } +.table { + display: table; +} + .grid { display: grid; } @@ -4431,18 +4676,50 @@ html:has(.drawer-toggle:checked) { height: 2.5rem; } -.h-4 { - height: 1rem; +.h-3 { + height: 0.75rem; } -.h-64 { - height: 16rem; +.h-4 { + height: 1rem; } .h-\[150px\] { height: 150px; } +.h-\[16px\] { + height: 16px; +} + +.h-\[180px\] { + height: 180px; +} + +.h-\[20px\] { + height: 20px; +} + +.h-\[220px\] { + height: 220px; +} + +.h-\[22px\] { + height: 22px; +} + +.h-\[23px\] { + height: 23px; +} + +.h-\[24px\] { + height: 24px; +} + +.h-\[280px\] { + height: 280px; +} + .h-\[30px\] { height: 30px; } @@ -4455,10 +4732,27 @@ html:has(.drawer-toggle:checked) { height: 50px; } +.h-\[80px\] { + height: 80px; +} + +.h-fit { + height: -moz-fit-content; + height: fit-content; +} + .h-full { height: 100%; } +.h-screen { + height: 100vh; +} + +.min-h-0 { + min-height: 0px; +} + .min-h-full { min-height: 100%; } @@ -4467,6 +4761,10 @@ html:has(.drawer-toggle:checked) { min-height: 100vh; } +.w-12 { + width: 3rem; +} + .w-14 { width: 3.5rem; } @@ -4475,30 +4773,26 @@ html:has(.drawer-toggle:checked) { width: 4rem; } -.w-20 { - width: 5rem; -} - .w-24 { width: 6rem; } +.w-3 { + width: 0.75rem; +} + .w-3\/4 { width: 75%; } -.w-32 { - width: 8rem; +.w-36 { + width: 9rem; } .w-4 { width: 1rem; } -.w-5 { - width: 1.25rem; -} - .w-52 { width: 13rem; } @@ -4507,18 +4801,42 @@ html:has(.drawer-toggle:checked) { width: 16rem; } -.w-80 { - width: 20rem; +.w-7 { + width: 1.75rem; } .w-96 { width: 24rem; } +.w-\[120px\] { + width: 120px; +} + .w-\[150px\] { width: 150px; } +.w-\[16px\] { + width: 16px; +} + +.w-\[22px\] { + width: 22px; +} + +.w-\[24px\] { + width: 24px; +} + +.w-\[279px\] { + width: 279px; +} + +.w-\[300px\] { + width: 300px; +} + .w-\[326px\] { width: 326px; } @@ -4531,14 +4849,50 @@ html:has(.drawer-toggle:checked) { width: 35px; } -.w-\[600px\] { - width: 600px; +.w-\[400px\] { + width: 400px; +} + +.w-\[40px\] { + width: 40px; +} + +.w-\[500px\] { + width: 500px; +} + +.w-\[685px\] { + width: 685px; +} + +.w-\[700px\] { + width: 700px; +} + +.w-\[750px\] { + width: 750px; +} + +.w-\[760px\] { + width: 760px; } .w-\[80px\] { width: 80px; } +.w-\[85px\] { + width: 85px; +} + +.w-\[95px\] { + width: 95px; +} + +.w-\[995px\] { + width: 995px; +} + .w-fit { width: -moz-fit-content; width: fit-content; @@ -4552,6 +4906,14 @@ html:has(.drawer-toggle:checked) { width: 100vw; } +.min-w-5 { + min-width: 1.25rem; +} + +.min-w-\[77px\] { + min-width: 77px; +} + .min-w-full { min-width: 100%; } @@ -4560,14 +4922,14 @@ html:has(.drawer-toggle:checked) { max-width: 48rem; } -.max-w-4xl { - max-width: 56rem; -} - .max-w-\[200px\] { max-width: 200px; } +.max-w-\[750px\] { + max-width: 750px; +} + .max-w-full { max-width: 100%; } @@ -4576,10 +4938,6 @@ html:has(.drawer-toggle:checked) { max-width: 28rem; } -.max-w-xs { - max-width: 20rem; -} - .flex-1 { flex: 1 1 0%; } @@ -4592,14 +4950,32 @@ html:has(.drawer-toggle:checked) { flex-grow: 1; } -.cursor-default { - cursor: default; +.-translate-x-1\/2 { + --tw-translate-x: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.-translate-y-1\/2 { + --tw-translate-y: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.transform { + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.cursor-grab { + cursor: grab; } .cursor-pointer { cursor: pointer; } +.grid-cols-\[400px_90px_90px_400px\] { + grid-template-columns: 400px 90px 90px 400px; +} + .grid-cols-\[90px_auto\] { grid-template-columns: 90px auto; } @@ -4620,6 +4996,10 @@ html:has(.drawer-toggle:checked) { grid-template-columns: repeat(7,200px) 400px; } +.grid-rows-\[25px_25px_20px\] { + grid-template-rows: 25px 25px 20px; +} + .grid-rows-\[repeat\(1\2c 30px\)\] { grid-template-rows: repeat(1,30px); } @@ -4736,6 +5116,10 @@ html:has(.drawer-toggle:checked) { align-items: center; } +.justify-start { + justify-content: flex-start; +} + .justify-end { justify-content: flex-end; } @@ -4748,6 +5132,10 @@ html:has(.drawer-toggle:checked) { justify-content: space-between; } +.gap-0 { + gap: 0px; +} + .gap-1 { gap: 0.25rem; } @@ -4772,14 +5160,22 @@ html:has(.drawer-toggle:checked) { overflow: hidden; } -.overflow-scroll { - overflow: scroll; -} - .overflow-y-scroll { overflow-y: scroll; } +.text-ellipsis { + text-overflow: ellipsis; +} + +.text-clip { + text-overflow: clip; +} + +.whitespace-nowrap { + white-space: nowrap; +} + .rounded { border-radius: 0.25rem; } @@ -4800,6 +5196,10 @@ html:has(.drawer-toggle:checked) { border-radius: 0.375rem; } +.rounded-none { + border-radius: 0px; +} + .rounded-xl { border-radius: 0.75rem; } @@ -4834,6 +5234,16 @@ html:has(.drawer-toggle:checked) { border-color: var(--fallback-er,oklch(var(--er)/var(--tw-border-opacity))); } +.border-info { + --tw-border-opacity: 1; + border-color: var(--fallback-in,oklch(var(--in)/var(--tw-border-opacity))); +} + +.border-neutral { + --tw-border-opacity: 1; + border-color: var(--fallback-n,oklch(var(--n)/var(--tw-border-opacity))); +} + .border-neutral-content { --tw-border-opacity: 1; border-color: var(--fallback-nc,oklch(var(--nc)/var(--tw-border-opacity))); @@ -4844,6 +5254,16 @@ html:has(.drawer-toggle:checked) { border-color: var(--fallback-s,oklch(var(--s)/var(--tw-border-opacity))); } +.border-success { + --tw-border-opacity: 1; + border-color: var(--fallback-su,oklch(var(--su)/var(--tw-border-opacity))); +} + +.border-warning { + --tw-border-opacity: 1; + border-color: var(--fallback-wa,oklch(var(--wa)/var(--tw-border-opacity))); +} + .bg-base-100 { --tw-bg-opacity: 1; background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity))); @@ -4863,6 +5283,11 @@ html:has(.drawer-toggle:checked) { background-color: var(--fallback-b3,oklch(var(--b3)/var(--tw-bg-opacity))); } +.bg-black { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); +} + .bg-neutral { --tw-bg-opacity: 1; background-color: var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity))); @@ -4873,6 +5298,38 @@ html:has(.drawer-toggle:checked) { background-color: var(--fallback-nc,oklch(var(--nc)/var(--tw-bg-opacity))); } +.bg-slate-700 { + --tw-bg-opacity: 1; + background-color: rgb(51 65 85 / var(--tw-bg-opacity)); +} + +.bg-success { + --tw-bg-opacity: 1; + background-color: var(--fallback-su,oklch(var(--su)/var(--tw-bg-opacity))); +} + +.bg-warning { + --tw-bg-opacity: 1; + background-color: var(--fallback-wa,oklch(var(--wa)/var(--tw-bg-opacity))); +} + +.fill-current { + fill: currentColor; +} + +.object-contain { + -o-object-fit: contain; + object-fit: contain; +} + +.p-0 { + padding: 0px; +} + +.p-1 { + padding: 0.25rem; +} + .p-2 { padding: 0.5rem; } @@ -4905,14 +5362,19 @@ html:has(.drawer-toggle:checked) { padding-right: 0.5rem; } +.px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; +} + .px-5 { padding-left: 1.25rem; padding-right: 1.25rem; } -.py-10 { - padding-top: 2.5rem; - padding-bottom: 2.5rem; +.py-0 { + padding-top: 0px; + padding-bottom: 0px; } .py-3 { @@ -4925,6 +5387,14 @@ html:has(.drawer-toggle:checked) { padding-bottom: 1.5rem; } +.pb-1 { + padding-bottom: 0.25rem; +} + +.pb-5 { + padding-bottom: 1.25rem; +} + .pb-\[56\.25\%\] { padding-bottom: 56.25%; } @@ -4933,6 +5403,14 @@ html:has(.drawer-toggle:checked) { padding-left: 0px; } +.pl-\[18px\] { + padding-left: 18px; +} + +.pr-\[20px\] { + padding-right: 20px; +} + .text-center { text-align: center; } @@ -4983,6 +5461,11 @@ html:has(.drawer-toggle:checked) { line-height: 1.75rem; } +.text-xs { + font-size: 0.75rem; + line-height: 1rem; +} + .font-bold { font-weight: 700; } @@ -4995,6 +5478,10 @@ html:has(.drawer-toggle:checked) { font-weight: 100; } +.italic { + font-style: italic; +} + .text-base-300 { --tw-text-opacity: 1; color: var(--fallback-b3,oklch(var(--b3)/var(--tw-text-opacity))); @@ -5020,11 +5507,29 @@ html:has(.drawer-toggle:checked) { color: var(--fallback-n,oklch(var(--n)/var(--tw-text-opacity))); } +.text-primary-content { + --tw-text-opacity: 1; + color: var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity))); +} + .text-secondary { --tw-text-opacity: 1; color: var(--fallback-s,oklch(var(--s)/var(--tw-text-opacity))); } +.text-warning { + --tw-text-opacity: 1; + color: var(--fallback-wa,oklch(var(--wa)/var(--tw-text-opacity))); +} + +.opacity-100 { + opacity: 1; +} + +.opacity-80 { + opacity: 0.8; +} + .shadow-xl { --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color); @@ -5150,3 +5655,8 @@ html:has(.drawer-toggle:checked) { .scrollbar-none::-webkit-scrollbar { display: none; } + +.hover\:bg-neutral:hover { + --tw-bg-opacity: 1; + background-color: var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity))); +} diff --git a/yad/script.js b/yad/script.js index 5e6543b..a7dab58 100644 --- a/yad/script.js +++ b/yad/script.js @@ -5,7 +5,7 @@ const DELAY_PARAM = 'd'; const VIDEO_ID_PARAM = 'v'; const PRIVACY_PARAM = 'p'; -const SKIP_MARGIN = 30; +const SKIP_MARGIN = 600; const START_MARGIN = 30; const SKIP_CORRECTION = 5; const STREAM_DURATION_CORRECTION = 3600; @@ -13,7 +13,7 @@ const STREAM_DURATION_CORRECTION = 3600; const DEFAULT_VIDEO_ID = 'jfKfPfyJRdk'; const DEFAULT_DELAY = 900; const DEFAULT_PRIVACY = '0'; -const MINIMAL_DELAY = 60; +const MINIMAL_DELAY = 660; const player = { ytPlayer: null, @@ -22,6 +22,7 @@ const player = { startingDate: -100, videoId: '', connection: null, + startingDelay: -100, delay: -100, savedDelay: -100, privacy: false, @@ -35,7 +36,7 @@ function getDelay() { const delay = parseInt(document.getElementById('delay').value); console.assert(delay >= MINIMAL_DELAY); if (delay < MINIMAL_DELAY) { - console.error("Delay shouldn't be less then minimal delay: " + MINIMAL_DELAY); + console.error(`Delay shouldn't be less than ${MINIMAL_DELAY}s`); return MINIMAL_DELAY; } return delay; @@ -45,22 +46,6 @@ function getPrivacy() { return document.getElementById('privacy').checked; } -function getUrlParam(name) { - const urlParams = new URLSearchParams(window.location.search); - return urlParams.get(name); -} - -function setInputsFromUrlParams() { - const videoIdParam = getUrlParam(VIDEO_ID_PARAM) || DEFAULT_VIDEO_ID; - document.getElementById('videoId').value = videoIdParam; - - const delayParam = getUrlParam(DELAY_PARAM) || DEFAULT_DELAY; - document.getElementById('delay').value = delayParam; - - const privacyParam = getUrlParam(PRIVACY_PARAM) || DEFAULT_PRIVACY; - document.getElementById('privacy').checked = privacyParam === '1'; -} - function loadPlayer() { const playerElem = document.getElementById('player'); const base = player.privacy ? YN_BASE_URL : YT_BASE_URL; @@ -71,7 +56,8 @@ async function loadNewVideo() { player.isReady = false; player.videoId = getVideoId(); - player.delay = getDelay() - SKIP_CORRECTION; + player.startingDelay = getDelay(); + player.delay = player.startingDelay - SKIP_CORRECTION; player.savedDelay = player.delay; if (player.connection) player.connection.close(); @@ -103,10 +89,6 @@ function onYouTubeIframeAPIReady() { }); } -function getCurrentDate() { - return new Date().getTime() / 1000; -} - function onPlayerStateChange(event) { if (event.data == YT.PlayerState.PLAYING) { const duration = player.ytPlayer.getDuration() - STREAM_DURATION_CORRECTION; @@ -171,6 +153,11 @@ function renderStats(duration, delay) { const durationElem = document.getElementById('duration-stat'); const delayElem = document.getElementById('delay-stat'); + if (duration === null || delay === null) { + durationElem.innerHTML = '...'; + delayElem.innerHTML = '...'; + return; + } const dur = duration | 0; const durationHours = (dur / 3600) | 0; const durationMinutes = ((dur / 60) | 0) % 60; @@ -211,9 +198,16 @@ player.savedDelay = player.delay; loadPlayer(); loadPlayerAPI(); +document.getElementById('videoId').onpaste = (e) => { + e.preventDefault(); + const paste = e.clipboardData.getData('text'); + e.target.value = extractYouTubeId(paste); +}; + setInterval(() => { // First 30min after stream started player.getDuration() will always return 3600 if (!player.isReady || player.startingDuration === 0) { + renderStats(null, null); return; } @@ -222,9 +216,14 @@ setInterval(() => { const currentTime = player.ytPlayer.getCurrentTime(); console.assert(!isNaN(actualDuration)); - if (isNaN(currentTime) || currentTime < START_MARGIN || actualDuration < player.delay) { + if (isNaN(currentTime)) { + renderStats(null, null); return; } + if (currentTime < START_MARGIN || actualDuration < player.delay) { + return; + } + const currentDelay = actualDuration - currentTime; console.assert(currentDelay > -10, 'Invalid current delay: ' + currentDelay); @@ -246,7 +245,10 @@ setInterval(() => { player.savedDelay = MINIMAL_DELAY; console.log('New saved delay:', MINIMAL_DELAY); } else { - console.log('Current delay was: ' + currentDelay + ', saved delay: ' + player.savedDelay); - seekDelay(player.savedDelay + SKIP_CORRECTION); + const newDelay = Math.max(player.savedDelay + SKIP_CORRECTION, player.startingDelay); + console.log( + `Current delay was: ${currentDelay}, saved delay: ${player.savedDelay}, seeking delay: ${newDelay}`, + ); + seekDelay(newDelay); } }, 1000); diff --git a/yad/tools.js b/yad/tools.js new file mode 100644 index 0000000..9b48b6b --- /dev/null +++ b/yad/tools.js @@ -0,0 +1,40 @@ +function getCurrentDate() { + return new Date().getTime() / 1000; +} + +function extractYouTubeId(str) { + try { + const url = new URL(str); + const vParam = url.searchParams.get('v'); + if (vParam) { + // https://www.youtube.com/watch?v=12345 + return vParam; + } else if (url.pathname.startsWith('/live/')) { + // https://www.youtube.com/live/12345 + return url.pathname.slice(6); + } else if (url.origin === 'https://youtu.be') { + // https://youtu.be/12345 + return url.pathname.slice(1); + } else { + return str; + } + } catch (error) { + return str; + } +} + +function getUrlParam(name) { + const urlParams = new URLSearchParams(window.location.search); + return urlParams.get(name); +} + +function setInputsFromUrlParams() { + const videoIdParam = getUrlParam(VIDEO_ID_PARAM) || DEFAULT_VIDEO_ID; + document.getElementById('videoId').value = videoIdParam; + + const delayParam = getUrlParam(DELAY_PARAM) || DEFAULT_DELAY; + document.getElementById('delay').value = delayParam; + + const privacyParam = getUrlParam(PRIVACY_PARAM) || DEFAULT_PRIVACY; + document.getElementById('privacy').checked = privacyParam === '1'; +}