diff options
Diffstat (limited to 'youtube/templates/watch.html')
-rw-r--r-- | youtube/templates/watch.html | 905 |
1 files changed, 271 insertions, 634 deletions
diff --git a/youtube/templates/watch.html b/youtube/templates/watch.html index 36b2198..44fc5a7 100644 --- a/youtube/templates/watch.html +++ b/youtube/templates/watch.html @@ -3,378 +3,17 @@ {% import "common_elements.html" as common_elements %} {% import "comments.html" as comments with context %} {% block style %} - details > summary{ - background-color: var(--interface-color); - border-style: outset; - border-width: 2px; - font-weight: bold; - padding-bottom: 2px; - } - details > summary:hover{ - text-decoration: underline; - } - - .playability-error{ - height: 360px; - width: 640px; - grid-column: 2; - background-color: var(--video-background-color); - text-align:center; - } - .playability-error span{ - position: relative; - top: 50%; - transform: translate(-50%, -50%); - } - - .live-url-choices{ - height: 360px; - width: 640px; - grid-column: 2; - background-color: var(--video-background-color); - padding: 25px 0px 0px 25px; - } - .live-url-choices ol{ - list-style: none; - padding:0px; - margin:0px; - margin-top: 15px; - } - .live-url-choices input{ - width: 400px; - } - .url-choice-label{ - display: inline-block; - width: 150px; - } - - {% if settings.theater_mode %} - /* This is the constant aspect ratio trick - Percentages in padding-top declarations are based on the width of the - parent element. We can use this trick to achieve a constant aspect ratio - for video-container-inner by setting height to 0. - - So the video height will decrease if the browser window is narrow, - but it will keep same aspect ratio. Must use absolute positioning on - video to keep it inside its container since the container's height is 0. - - However, because we widen the video player longer than the video's - intrinsic width for long video to make scrubbing easier, we can't use - the aspect ratio to set the height. The height needs to be the - intrinsic height in these cases. So we use a media query so aspect - ratio trick is only used if page width is less than or equal to - intrinsic video width. - */ - #video-container{ - grid-column: 1 / span 5; - justify-self: center; - max-width: 100%; - width: {{ theater_video_target_width }}px; - margin-bottom: 10px; - } - #video-container-inner{ - height: {{ video_height}}px; - position: relative; - } - @media(max-width:{{ video_width }}px){ - #video-container-inner{ - padding-top: calc(100%*{{video_height}}/{{video_width}}); - height: 0px; - } - } - video{ - background-color: var(--video-background-color); - position: absolute; - top: 0px; - left: 0px; - width: 100%; - height: 100%; - } - .side-videos{ - grid-row: 2 /span 3; - width: 400px; - } - .video-info{ - width: 640px; - } - {% else %} - #video-container{ - grid-column: 2; - } - #video-container, #video-container-inner, video{ - height: 360px; - width: 640px; - } - .side-videos{ - grid-row: 1 /span 4; - } - {% endif %} - - main{ - display:grid; - grid-template-columns: 1fr 640px 40px 400px 1fr; - grid-template-rows: auto auto auto auto; - align-content: start; - } - - .video-info{ - grid-column: 2; - grid-row: 2; - display: grid; - grid-template-rows: 0fr 0fr 0fr 20px 0fr 0fr; - grid-template-columns: 1fr 1fr; - align-content: start; - } - .video-info > .title{ - grid-column: 1 / span 2; - min-width: 0; - } - .video-info > .labels{ - justify-self:start; - list-style: none; - padding: 0px; - margin: 5px 0px; - } - .video-info > .labels:empty{ - margin: 0px; - } - .labels > li{ - display: inline; - margin-right:5px; - background-color: var(--interface-color); - padding: 2px 5px; - border-style: solid; - border-width: 1px; - } - .video-info > address{ - grid-column: 1; - grid-row: 3; - justify-self: start; - } - .video-info > .views{ - grid-column: 2; - grid-row: 3; - justify-self:end; - } - .video-info > time{ - grid-column: 1; - grid-row: 4; - justify-self:start; - } - .video-info > .likes-dislikes{ - grid-column: 2; - grid-row: 4; - justify-self:end; - } - .video-info > .external-player-controls{ - justify-self: start; - grid-row: 5; - grid-column: 1; - margin-bottom: 8px; - } - #speed-control{ - width: 65px; - text-align: center; - background-color: var(--interface-color); - color: var(--text-color); - } - .video-info > .checkbox{ - justify-self:end; - align-self: start; - - grid-row: 5; - grid-column: 2; - } - .video-info > .download-dropdown{ - grid-column:1 / span 2; - grid-row: 6; - } - .video-info > .description{ - background-color:var(--interface-color); - margin-top:8px; - white-space: pre-wrap; - min-width: 0; - word-wrap: break-word; - grid-column: 1 / span 2; - grid-row: 7; - padding: 5px; - } - - .music-list{ - grid-row:8; - grid-column: 1 / span 2; - background-color: var(--interface-color); - padding-bottom: 7px; - } - .music-list table,th,td{ - border: 1px solid; - } - .music-list th,td{ - padding-left:4px; - padding-right:5px; - } - .music-list caption{ - text-align:left; - font-weight:bold; - margin-bottom:5px; - } - .more-info{ - grid-row: 9; - grid-column: 1 / span 2; - background-color: var(--interface-color); - } - .more-info > summary{ - font-weight: normal; - border-width: 1px 0px; - border-style: solid; - } - .more-info-content{ - padding: 5px; - } - .more-info-content p{ - margin: 8px 0px; - } - .comments-area-outer{ - grid-column: 2; - grid-row: 3; - margin-top:10px; - } - .comments-disabled{ - background-color: var(--interface-color); - padding: 5px; - font-weight: bold; - } - .comments-area-inner{ - padding-top: 10px; - } - .comment{ - width:640px; - } - - .side-videos{ - grid-column: 4; - max-width: 640px; - } - #transcript-details{ - margin-bottom: 10px; - } - table#transcript-table { - border-collapse: collapse; - width: 100%; - } - table#transcript-table td, th { - border: 1px solid #dddddd; - } - div#transcript-div { - background-color: var(--interface-color); - padding: 5px; - } - .playlist{ - border-style: solid; - border-width: 2px; - border-color: lightgray; - margin-bottom: 10px; - } - .playlist-header{ - background-color: var(--interface-color); - padding: 3px; - border-bottom-style: solid; - border-bottom-width: 2px; - border-bottom-color: lightgray; - } - .playlist-header h3{ - margin: 2px; - } - .playlist-metadata{ - list-style: none; - padding: 0px; - margin: 0px; - } - .playlist-metadata li{ - display: inline; - margin: 2px; - } - .playlist-videos{ - height: 300px; - overflow-y: scroll; - display: grid; - grid-auto-rows: 90px; - grid-row-gap: 10px; - padding-top: 10px; - } - .related-videos-inner{ - padding-top: 10px; - display: grid; - grid-auto-rows: 90px; - grid-row-gap: 10px; - } - .thumbnail-box{ /* overides rule in shared.css */ - height: 90px !important; - width: 120px !important; - } - - /* Put related vids below videos when window is too small */ - /* 1100px instead of 1080 because W3C is full of idiots who include scrollbar width */ - @media (max-width:1100px){ - main{ - grid-template-columns: 1fr 640px 40px 1fr; - } - .side-videos{ - margin-top: 10px; - grid-column: 2; - grid-row: 3; - width: initial; - } - .comments-area-outer{ - grid-row: 4; - } - } - - .download-dropdown-content{ - background-color: var(--interface-color); - padding: 10px; - list-style: none; - margin: 0px; - } - li.download-format{ - margin-bottom: 7px; - } - .format-attributes{ - list-style: none; - padding: 0px; - margin: 0px; - display: flex; - flex-direction: row; - } - .format-attributes li{ - white-space: nowrap; - max-height: 1.2em; - } - .format-ext{ - width: 60px; - } - .format-video-quality{ - width: 140px; - } - .format-audio-quality{ - width: 120px; - } - .format-file-size{ - width: 80px; - } - .format-codecs{ - width: 120px; - } + <link href="/youtube.com/static/watch.css" rel="stylesheet"> {% endblock style %} {% block main %} {% if playability_error %} <div class="playability-error"> <span>{{ 'Error: ' + playability_error }} - {% if invidious_reload_button %} - <a href="{{ video_url }}&use_invidious=0"><br> -Reload without invidious (for usage of new identity button).</a> - {% endif %} + {% if invidious_reload_button %} + <a href="{{ video_url }}&use_invidious=0"><br> + Reload without invidious (for usage of new identity button).</a> + {% endif %} </span> </div> {% elif (video_sources.__len__() == 0 or live) and hls_formats.__len__() != 0 %} @@ -387,143 +26,137 @@ Reload without invidious (for usage of new identity button).</a> </ol> </div> {% else %} - <div id="video-container"> - <div id="video-container-inner"> - <video controls autofocus class="video" height="{{ video_height }}px"> - {% for video_source in video_sources %} - <source src="{{ video_source['src'] }}" type="{{ video_source['type'] }}"> - {% endfor %} + <figure class="sc-video"> + <video id="js-video-player" playsinline controls> + {% for video_source in video_sources %} + <source src="{{ video_source['src'] }}" type="{{ video_source['type'] }}"> + {% endfor %} - {% for source in subtitle_sources %} - {% if source['on'] %} - <track label="{{ source['label'] }}" src="{{ source['url'] }}" kind="subtitles" srclang="{{ source['srclang'] }}" default> - {% else %} - <track label="{{ source['label'] }}" src="{{ source['url'] }}" kind="subtitles" srclang="{{ source['srclang'] }}"> - {% endif %} - {% endfor %} + {% for source in subtitle_sources %} + {% if source['on'] %} + <track label="{{ source['label'] }}" src="{{ source['url'] }}" kind="subtitles" srclang="{{ source['srclang'] }}" default> + {% else %} + <track label="{{ source['label'] }}" src="{{ source['url'] }}" kind="subtitles" srclang="{{ source['srclang'] }}"> + {% endif %} + {% endfor %} + </video> + </figure> - </video> - </div> - </div> {% if time_start != 0 %} <script> - document.querySelector('video').currentTime = {{ time_start|tojson }}; + document.querySelector('js-video-player').currentTime = {{ time_start|tojson }}; </script> {% endif %} {% endif %} - <div class="video-info"> - <h2 class="title">{{ title }}</h2> - <ul class="labels"> - {%- if unlisted -%} - <li class="is-unlisted">Unlisted</li> - {%- endif -%} - {%- if age_restricted -%} - <li class="age-restricted">Age-restricted</li> - {%- endif -%} - {%- if limited_state -%} - <li>Limited state</li> - {%- endif -%} - {%- if live -%} - <li>Live</li> - {%- endif -%} - </ul> - <address>Uploaded by <a href="{{ uploader_channel_url }}">{{ uploader }}</a></address> - <span class="views">{{ view_count }} views</span> - - - <time datetime="$upload_date">Published on {{ time_published }}</time> - <span class="likes-dislikes">{{ like_count }} likes {{ dislike_count }} dislikes</span> - - <div class="external-player-controls"> - <input id="speed-control" type="text"> - <script> - var video = document.querySelector('video'); - var speedInput = document.querySelector('#speed-control'); - speedInput.addEventListener('keyup', (event) => { - if (event.key === 'Enter') { - var speed = parseFloat(speedInput.value); - if(!isNaN(speed)){ - video.playbackRate = speed; - } - } - }); - </script> - </div> - <input class="checkbox" name="video_info_list" value="{{ video_info }}" form="playlist-edit" type="checkbox"> - - <details class="download-dropdown"> - <summary class="download-dropdown-label">Download</summary> - <ul class="download-dropdown-content"> - {% for format in download_formats %} - <li class="download-format"> - <a class="download-link" href="{{ format['url'] }}"> - <ol class="format-attributes"> - <li class="format-ext">{{ format['ext'] }}</li> - <li class="format-video-quality">{{ format['video_quality'] }}</li> - <li class="format-audio-quality">{{ format['audio_quality'] }}</li> - <li class="format-file-size">{{ format['file_size'] }}</li> - <li class="format-codecs">{{ format['codecs'] }}</li> - </ol> - </a> - </li> - {% endfor %} - {% for download in other_downloads %} - <li class="download-format"> - <a href="{{ download['url'] }}"> - <ol class="format-attributes"> - <li class="format-ext">{{ download['ext'] }}</li> - <li class="format-label">{{ download['label'] }}</li> - </ol> - </a> - </li> - {% endfor %} + <div class="sc-info"> + <div class="video-info"> + <h1 class="v-title">{{ title }}</h1> + + <ul class="labels"> + {%- if unlisted -%} + <li class="is-unlisted">Unlisted</li> + {%- endif -%} + {%- if age_restricted -%} + <li class="age-restricted">Age-restricted</li> + {%- endif -%} + {%- if limited_state -%} + <li>Limited state</li> + {%- endif -%} + {%- if live -%} + <li>Live</li> + {%- endif -%} </ul> - </details> + <address class="v-uploaded">Uploaded by <a href="{{ uploader_channel_url }}">{{ uploader }}</a></address> + <span class="v-views">{{ view_count }} views</span> + <time class="v-published" datetime="$upload_date">Published on {{ time_published }}</time> + <span class="v-likes-dislikes">{{ like_count }} likes {{ dislike_count }} dislikes</span> + + <div class="external-player-controls"> + <input class="speed" id="speed-control" type="text"> + <script> + (function main() { + 'use strict'; + const video = document.getElementById('js-video-player'); + const speedInput = document.getElementById('speed-control'); + speedInput.addEventListener('keyup', (event) => { + if (event.key === 'Enter') { + let speed = parseFloat(speedInput.value); + if(!isNaN(speed)){ + video.playbackRate = speed; + } + } + }); + }()); + </script> + </div> - <span class="description">{{ common_elements.text_runs(description)|escape|urlize|timestamps|safe }}</span> - <div class="music-list"> - {% if music_list.__len__() != 0 %} - <hr> - <table> - <caption>Music</caption> - <tr> - {% for attribute in music_attributes %} - <th>{{ attribute }}</th> - {% endfor %} - </tr> - {% for track in music_list %} + <input class="v-checkbox" name="video_info_list" value="{{ video_info }}" form="playlist-edit" type="checkbox"> + + <details class="v-download"> + <summary class="download-dropdown-label">Download</summary> + <ul class="download-dropdown-content"> + {% for format in download_formats %} + <li class="download-format"> + <a class="download-link" href="{{ format['url'] }}" download="{{ title }}.{{ format['ext'] }}"> + {{ format['ext'] }} {{ format['video_quality'] }} {{ format['audio_quality'] }} {{ format['file_size'] }} {{ format['codecs'] }} + </a> + </li> + {% endfor %} + {% for download in other_downloads %} + <li class="download-format"> + <a href="{{ download['url'] }}" download> + {{ download['ext'] }} {{ download['label'] }} + </a> + </li> + {% endfor %} + </ul> + </details> + <span class="v-description">{{ common_elements.text_runs(description)|escape|urlize|timestamps|safe }}</span> + + <div class="v-music-list"> + {% if music_list.__len__() != 0 %} + <hr> + <table> + <caption>Music</caption> <tr> {% for attribute in music_attributes %} - <td>{{ track.get(attribute.lower(), '') }}</td> + <th>{{ attribute }}</th> {% endfor %} </tr> - {% endfor %} - </table> - {% endif %} - </div> - <details class="more-info"> - <summary>More info</summary> - <div class="more-info-content"> - <p>Tor exit node: {{ ip_address }}</p> - {% if invidious_used %} - <p>Used Invidious as fallback.</p> - {% endif %} - <p class="allowed-countries">Allowed countries: {{ allowed_countries|join(', ') }}</p> - - {% if settings.use_sponsorblock_js %} - <ul class="more-actions"> - <li><label><input type=checkbox id=skip_sponsors checked>skip sponsors</label> <span id=skip_n></span> - </ul> + {% for track in music_list %} + <tr> + {% for attribute in music_attributes %} + <td>{{ track.get(attribute.lower(), '') }}</td> + {% endfor %} + </tr> + {% endfor %} + </table> {% endif %} </div> - </details> - </div> + <details class="v-more-info"> + <summary>More info</summary> + <div class="more-info-content"> + <p>Tor exit node: {{ ip_address }}</p> + {% if invidious_used %} + <p>Used Invidious as fallback.</p> + {% endif %} + <p class="allowed-countries">Allowed countries: {{ allowed_countries|join(', ') }}</p> + {% if settings.use_sponsorblock_js %} + <ul class="more-actions"> + <li><label><input type=checkbox id=skip_sponsors checked>skip sponsors</label> <span id=skip_n></span> + </ul> + {% endif %} + </div> + </details> + </div> + + <div class="side-videos"> - <div class="side-videos"> - {% if playlist %} - <div class="playlist"> + <!-- playlist --> + {% if playlist %} + <div class="site-playlist"> <div class="playlist-header"> <a href="{{ playlist['url'] }}" title="{{ playlist['title'] }}"><h3>{{ playlist['title'] }}</h3></a> <ul class="playlist-metadata"> @@ -550,167 +183,171 @@ Reload without invidious (for usage of new identity button).</a> </nav> {% if playlist['current_index'] is not none %} <script> - // from https://stackoverflow.com/a/6969486 - function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string - } - var playability_error = {{ 'true' if playability_error else 'false' }}; - var playlist_id = {{ playlist['id']|tojson }}; - playlist_id = escapeRegExp(playlist_id); - - // read cookies on whether to autoplay thru playlist - // pain in the ass: - // https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie - var cookieValue = document.cookie.replace(new RegExp( - '(?:(?:^|.*;\\s*)autoplay_' + playlist_id + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1'); - var autoplayEnabled = 0; - if(cookieValue.length === 0){ - autoplayEnabled = 0; - } else { - autoplayEnabled = Number(cookieValue); - } - - // check the checkbox if autoplay is on - var checkbox = document.querySelector('#autoplay-toggle'); - if(autoplayEnabled){ - checkbox.checked = true; - } - - // listen for checkbox to turn autoplay on and off - checkbox.addEventListener( 'change', function() { - if(this.checked) { - autoplayEnabled = 1; - document.cookie = 'autoplay_' + playlist_id + '=1'; - } else { - autoplayEnabled = 0; - document.cookie = 'autoplay_' + playlist_id + '=0'; - } - }); - - if(!playability_error){ - // play the video if autoplay is on - var vid = document.querySelector('video'); - if(autoplayEnabled){ - vid.play(); - } - } - - var currentIndex = {{ playlist['current_index']|tojson }}; - {% if playlist['current_index']+1 == playlist['items']|length %} - var nextVideoUrl = null; - {% else %} - var nextVideoUrl = {{ (playlist['items'][playlist['current_index']+1]['url'])|tojson }}; - {% endif %} - var nextVideoDelay = 1000; - - // scroll playlist to proper position - var pl = document.querySelector('.playlist-videos'); - // item height + gap == 100 - pl.scrollTop = 100*currentIndex; - - // go to next video when video ends - // https://stackoverflow.com/a/2880950 - if(nextVideoUrl){ - if(playability_error){ - videoEnded(); - } else { - vid.addEventListener('ended', videoEnded, false); - } - function nextVideo(){ - if(autoplayEnabled){ - window.location.href = nextVideoUrl; - } - } - function videoEnded(e) { - window.setTimeout(nextVideo, nextVideoDelay); - } - } + (function main() { + // from https://stackoverflow.com/a/6969486 + function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string + } + let playability_error = {{ 'true' if playability_error else 'false' }}; + let playlist_id = {{ playlist['id']|tojson }}; + playlist_id = escapeRegExp(playlist_id); + + // read cookies on whether to autoplay thru playlist + // pain in the ass: + // https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie + let cookieValue = document.cookie.replace(new RegExp( + '(?:(?:^|.*;\\s*)autoplay_' + playlist_id + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1'); + let autoplayEnabled = 0; + if(cookieValue.length === 0){ + autoplayEnabled = 0; + } else { + autoplayEnabled = Number(cookieValue); + } + + // check the checkbox if autoplay is on + let checkbox = document.querySelector('#autoplay-toggle'); + if(autoplayEnabled){ + checkbox.checked = true; + } + + // listen for checkbox to turn autoplay on and off + checkbox.addEventListener( 'change', function() { + if(this.checked) { + autoplayEnabled = 1; + document.cookie = 'autoplay_' + playlist_id + '=1'; + } else { + autoplayEnabled = 0; + document.cookie = 'autoplay_' + playlist_id + '=0'; + } + }); + + const vid = document.getElementById('js-video-player'); + if(!playability_error){ + if(autoplayEnabled){ + vid.play(); + } + } + + let currentIndex = {{ playlist['current_index']|tojson }}; + {% if playlist['current_index']+1 == playlist['items']|length %} + let nextVideoUrl = null; + {% else %} + let nextVideoUrl = {{ (playlist['items'][playlist['current_index']+1]['url'])|tojson }}; + {% endif %} + let nextVideoDelay = 1000; + + // scroll playlist to proper position + let pl = document.querySelector('.playlist-videos'); + // item height + gap == 100 + pl.scrollTop = 100*currentIndex; + + // go to next video when video ends + // https://stackoverflow.com/a/2880950 + if(nextVideoUrl){ + if(playability_error){ + videoEnded(); + } else { + vid.addEventListener('ended', videoEnded, false); + } + function nextVideo(){ + if(autoplayEnabled){ + window.location.href = nextVideoUrl; + } + } + function videoEnded(e) { + window.setTimeout(nextVideo, nextVideoDelay); + } + } + }()); </script> {% endif %} {% if playlist['id'] is not none %} <script> - // lazy load playlist images - // copied almost verbatim from - // https://css-tricks.com/tips-for-rolling-your-own-lazy-loading/ - // IntersectionObserver isn't supported in pre-quantum - // firefox versions, but the alternative of making it - // manually is a performance drain, so oh well - var observer = new IntersectionObserver(lazyLoad, { - - // where in relation to the edge of the viewport, we are observing - rootMargin: "100px", - - // how much of the element needs to have intersected - // in order to fire our loading function - threshold: 1.0 - - }); - - function lazyLoad(elements) { - elements.forEach(item => { - if (item.intersectionRatio > 0) { - - // set the src attribute to trigger a load - item.target.src = item.target.dataset.src; - - // stop observing this element. Our work here is done! - observer.unobserve(item.target); - }; - }); - }; - - // Tell our observer to observe all img elements with a "lazy" class - var lazyImages = document.querySelectorAll('img.lazy'); - lazyImages.forEach(img => { - observer.observe(img); - }); + (function main() { + // lazy load playlist images + // copied almost verbatim from + // https://css-tricks.com/tips-for-rolling-your-own-lazy-loading/ + // IntersectionObserver isn't supported in pre-quantum + // firefox versions, but the alternative of making it + // manually is a performance drain, so oh well + let observer = new IntersectionObserver(lazyLoad, { + // where in relation to the edge of the viewport, we are observing + rootMargin: "100px", + // how much of the element needs to have intersected + // in order to fire our loading function + threshold: 1.0 + }); + + function lazyLoad(elements) { + elements.forEach(item => { + if (item.intersectionRatio > 0) { + // set the src attribute to trigger a load + item.target.src = item.target.dataset.src; + // stop observing this element. Our work here is done! + observer.unobserve(item.target); + }; + }); + }; + + // Tell our observer to observe all img elements with a "lazy" class + let lazyImages = document.querySelectorAll('img.lazy'); + lazyImages.forEach(img => { + observer.observe(img); + }); + }()); </script> {% endif %} </div> - {% endif %} + {% endif %} + <!-- /playlist --> + + {% if subtitle_sources %} + <details id="transcript-details"> + <summary>Transcript</summary> + <div id="transcript-div"> + <select id="select-tt"> + {% for source in subtitle_sources %} + <option>{{ source['label'] }}</option> + {% endfor %} + </select> + <label for="transcript-use-table">Table view</label> + <input id="transcript-use-table" type="checkbox"> + <table id="transcript-table"></table> + </div> + </details> + {% endif %} + - {% if subtitle_sources %} - <details id="transcript-details"> - <summary>Transcript</summary> - <div id="transcript-div"> - <select id="select-tt"> - {% for source in subtitle_sources %} - <option>{{ source['label'] }}</option> + {% if settings.related_videos_mode != 0 %} + <details class="related-videos-outer" {{'open' if settings.related_videos_mode == 1 else ''}}> + <summary>Related Videos</summary> + <nav class="related-videos-inner"> + {% for info in related %} + {{ common_elements.item(info, include_badges=false) }} {% endfor %} - </select> - <label for="transcript-use-table">Table view</label> - <input type="checkbox" id="transcript-use-table"> - <table id="transcript-table"></table> - </div> - </details> - {% endif %} + </nav> + </details> + {% endif %} - {% if settings.related_videos_mode != 0 %} - <details class="related-videos-outer" {{'open' if settings.related_videos_mode == 1 else ''}}> - <summary>Related Videos</summary> - <nav class="related-videos-inner"> - {% for info in related %} - {{ common_elements.item(info, include_badges=false) }} - {% endfor %} - </nav> - </details> - {% endif %} - </div> + </div> - {% if settings.comments_mode != 0 %} - {% if comments_disabled %} - <div class="comments-area-outer comments-disabled">Comments disabled</div> - {% else %} - <details class="comments-area-outer" {{'open' if settings.comments_mode == 1 else ''}}> - <summary>{{ comment_count|commatize }} comment{{'s' if comment_count != 1 else ''}}</summary> - <section class="comments-area-inner comments-area"> - {% if comments_info %} - {{ comments.video_comments(comments_info) }} - {% endif %} - </section> - </details> + <!-- comments --> + {% if settings.comments_mode != 0 %} + {% if comments_disabled %} + <div class="comments-area-outer comments-disabled">Comments disabled</div> + {% else %} + <details class="comments-area-outer" {{'open' if settings.comments_mode == 1 else ''}}> + <summary>{{ comment_count|commatize }} comment{{'s' if comment_count != 1 else ''}}</summary> + <div class="comments-area-inner comments-area"> + {% if comments_info %} + {{ comments.video_comments(comments_info) }} + {% endif %} + </div> + </details> + {% endif %} {% endif %} - {% endif %} + + </div> <script> data = {{ js_data|tojson }} </script> <script src="/youtube.com/static/js/common.js"></script> |