diff --git a/README.md b/README.md index d9442773..93cfae98 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,17 @@ A frontend/web-client for YouTube mobile based off the 2015 YT app for Android ## Want the desktop UI instead? Consider checking out Vorapis 2013/V3, another project made by another person in the Old YouTube community, V3 also aims to restore YouTube's old UI, you can configure/stylize it to make it look like YouTube in 2015. CustomTube also exists, however it's discontined/no-longer maintained +## Host YTm15 yourself +YTm15 is completely static, so you can basically host it anywhere. +* `git clone https://github.com/ytm15/ytm15.github.io && cd ytm15.github.io && yes | npx http-server` to create a local server immediately +* Fork the github repo +* Download the `app` folder, PNG's and the `webmanifest.json` and place it on your web server/hosting service + + ## To-do list - Make the newer UIs more accurate and complete - (possibly / tentative) Change this whole project's name (it doesn't just have the 2015 YT UI anymore so it's about time for a name-change) - Add expflags for the player +- (try to) Add compatibility for older browsers #### More info may be added in the future diff --git a/app/2015YTm.css b/app/2015YTm.css index 4421e7a8..d1073728 100644 --- a/app/2015YTm.css +++ b/app/2015YTm.css @@ -915,7 +915,7 @@ ytm15-icon>svg { box-shadow: none; } -.underline button:not(h2):not(.secondary-text):not(.menu-item-button):not(.error-content),.pivot-bar-item-title { +.underline button:not(h2):not(.secondary-text):not(.menu-item-button):not(.error-content),.underline .pivot-bar-item-title { text-decoration: underline; } @@ -992,6 +992,17 @@ ytm15-header-bar[ischannel="true"] { .header-title { font-weight: 500; } +.header-title[aria-label="Library"]::after,.header-title[aria-label="Subscriptions"]::after { + content: "Beta"; + text-transform: uppercase; + font-size: 1.3rem; + margin: 0 8px; + padding: 1px 6px; + background-color: rgba(0, 0, 0, 0.15); + opacity: .6; + font-weight: 500; + border-radius: 2px; +} /* Header content and other header things */ .header-content { @@ -1016,6 +1027,9 @@ ytm15-header-bar[ischannel="true"] { .header-no-shadow ytm15-header-bar { box-shadow: none !important; } +.header-button[aria-label="Left Menu"] { + padding-left:unset; +} /* Header logo */ .youtube-logo-icon.ringo-logo { @@ -1212,7 +1226,7 @@ overflow: hidden; display: block; animation: page-expand-in .2s; } -.no-animations .page-container,.no-animations .error-container,.no-animations page.home,.no-animations .lazy-list,.no-animations .error-content { +.no-animations .page-container,.no-animations .error-container,.no-animations page.home,.no-animations .lazy-list,.no-animations .error-content, .no-animations .searching-overlay ~ .page-container > page { animation: none !important; } .no-animations .ytm15-img.lazy { @@ -2591,6 +2605,9 @@ ytm15-menu-button { .compact-channel.shelf-item .media-item-menu { display: none; } +.no-lines .ytm15-video-owner,.no-lines .watch-next-results-content { + border:unset !important; +} /* About 2015YouTube */ .about-page-heading, .about-page-subheading { @@ -3075,6 +3092,9 @@ ytm15-channels-header { width: 18px; height: 13px; } +.no-subscribe-icon .ytm15-img-icon.subscribe-icon { + display:none; +} .continuation-item ~ .continuation-item { display: none; @@ -3709,6 +3729,18 @@ button.comment-icon-button { height: 14px; margin-right: 2px; } +.collapse-comments .comment-simplebox,.collapse-comments .comment-separator,.comment-section.collapse-comments .lazy-list,.collapse-comments .next-continuation-cont { + display:none; +} +.comment-section .lazy-list { + transition: transform .35s cubic-bezier(.22,.9,.35,1); +} +.condense-comment-buttons .comment-details { + display:inline-flex; +} +.condense-comment-buttons .comment-details #cm-icon-dislike { + margin-left:10px; +} /* Community posts */ [data-is-beta="true"] .posts-header-text::after { @@ -3901,6 +3933,12 @@ ytm15-icon.post-image-icon { border: 1.2px solid rgba(0,0,0,0.1); border-radius: 3px; } +.condense-comment-buttons-2 .post-details { + display:ruby; +} +.condense-comment-buttons-2 .post-details #post-icon-reply { + float:right; +} /* Pivot bar */ [has-pivot-bar="true"] ytm15app { @@ -3929,7 +3967,7 @@ ytm15-pivot-bar { z-index: 2; height: 52px; background-color: #fff; - color: rgba(0, 0, 0, 0.5); + color: #5f5f5f; box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.25); font-size: 1.1rem; } @@ -4240,6 +4278,9 @@ label.radio-label { .helvetica-neue { font-family: 'HelveticaNeue-Light','Helvetica Neue Light','Helvetica Neue',Helvetica,Arial,sans-serif !important; } +.system-font { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Oxygen-Sans, Ubuntu, Cantarell, Roboto, "Helvetica Neue", sans-serif !important; +} /*New error screen*/ .tap-to-retry .error-content { display:unset; @@ -5657,7 +5698,7 @@ html.dark { } .dark ytm15-pivot-bar { background-color: #303030; - color: rgba(255, 255, 255, 0.6); + color: #8f8f8f; } .dark ytm15-pivot-bar.no-shadow { border-top: 1.2px solid rgba(255,255,255,0.1); @@ -6094,3 +6135,85 @@ html.style-2013.dark.dark-21 { .style-2013.dark.dark-21 .ytm15-video-owner .material-button-container[data-style="BRAND"] .material-button { background: linear-gradient(#323232, #252525); } +/* Implementation by legoskid */ +.notification { + position: fixed; + bottom: 0; + /* left: 50%; */ + left: 0; + right: 0; + transform: translate(0, 100%); + /* transition: transform .35s cubic-bezier(.22,.9,.35,1), opacity .25s; */ + transition: transform .3s ease-in-out, opacity .25s; + display: inline-block; + display: block; + /* max-width: calc(100% - 40px); */ + max-width: 400px; + /* padding: 20px 32px; */ + padding: 14px 24px; + background: #2e2e2e; + color: #f1f1f1; + border-radius: unset; + border: unset; + box-shadow: unset; + box-sizing: border-box; + line-height: 1.25; + font-size: 15px; + z-index: 9999; + white-space: normal; + margin: auto; +} +.notification.notification-show { + transform: translate(0, 0); +} +.notification button { + float: right; + color: #2196f3; + text-transform:uppercase; +} +div#offline-bar { + display: flex; + justify-content: center; + position: fixed; + bottom: 0; + left: 0; + right: 0; + padding: 0; + z-index: 2; + background-color: black; + color: white; + font-weight: bold; + padding: 2px; + transform: translateY(100%); + transition: transform .35s cubic-bezier(.22,.9,.35,1), opacity .25s, background .35s cubic-bezier(.22,.9,.35,1) +} +div#offline-bar.offline-bar-show { + transform: translateY(0%); +} +div#offline-bar.offline-bar-online { + background:green; +} +.hamburger-menu { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + z-index: 3; + background-color: rgba(0.5,0.5,0.5,0.5); + animation: overlay-fade .3s; + display:initial; +} +.hamburger-submenu { + height: 100%; + background: white; + width: 28rem; + transform: translateX(-100%); + transition: transform .35s cubic-bezier(.22,.9,.35,1); +} +.hamburger-submenu.hamburger-submenu-show { + transform:unset; +} +.hamburger-menu-hide { + animation: overlay-fade-out .2s; +} \ No newline at end of file diff --git a/app/2015ytm.js b/app/2015ytm.js index 07b53119..a462f1a4 100644 --- a/app/2015ytm.js +++ b/app/2015ytm.js @@ -143,12 +143,16 @@ USE_NEW_SUBSCRIBE_ICON_expflag = localStorage.getItem("USE_NEW_SUBSCRIBE_ICON"); LIFT_PIVOT_BAR_FOR_PHONE_expflag = localStorage.getItem("LIFT_PIVOT_BAR_FOR_PHONE"); PIVOT_SHRINK_SPACING_expflag = localStorage.getItem("PIVOT_SHRINK_SPACING"); PIVOT_HIDE_NOTIFICATIONS_expflag = localStorage.getItem("PIVOT_HIDE_NOTIFICATIONS"); -PIVOT_NOTIFICATIONS_IS_ACTIVITY_expflag = localStorage.getItem("PIVOT_NOTIFICATIONS_IS_ACTIVITY"); +PIVOT_NOTIFICATIONS_ICON_VARIANT_expflag = localStorage.getItem("PIVOT_NOTIFICATIONS_ICON_VARIANT"); +if (PIVOT_NOTIFICATIONS_ICON_VARIANT_expflag == undefined) { + localStorage.setItem("PIVOT_NOTIFICATIONS_ICON_VARIANT", "Notifications"); + PIVOT_NOTIFICATIONS_ICON_VARIANT_expflag = localStorage.getItem("PIVOT_NOTIFICATIONS_ICON_VARIANT"); +} APP_HELVETICA_NEUE_FONT_expflag = localStorage.getItem("APP_HELVETICA_NEUE_FONT"); APP_NEW_ERROR_SCREEN_expflag = localStorage.getItem("APP_NEW_ERROR_SCREEN"); APP_CUSTOM_INVIDIOUS_URL_expflag = localStorage.getItem("APP_CUSTOM_INVIDIOUS_URL"); -if (APP_CUSTOM_INVIDIOUS_URL_expflag == undefined) { - localStorage.setItem("APP_CUSTOM_INVIDIOUS_URL", "https://api.allorigins.win/raw?url=https://yt.omada.cafe/"); +if (APP_CUSTOM_INVIDIOUS_URL_expflag == undefined || APP_CUSTOM_INVIDIOUS_URL_expflag == "") { + localStorage.setItem("APP_CUSTOM_INVIDIOUS_URL", "https://api.codetabs.com/v1/proxy?quest=https://y.com.sb/"); APP_CUSTOM_INVIDIOUS_URL_expflag = localStorage.getItem("APP_CUSTOM_INVIDIOUS_URL"); } APP_DONT_AUTH_TO_INVIDIOUS_expflag = localStorage.getItem("APP_DONT_AUTH_TO_INVIDIOUS"); @@ -163,11 +167,45 @@ DARK_THEME_SEPERATE_BACKGROUND_COLOR_expflag = localStorage.getItem("DARK_THEME_ APP_UNDERLINE_BUTTONS_expflag = localStorage.getItem("APP_UNDERLINE_BUTTONS"); HEADER_CAST_BUTTON_AS_URL_BOX_expflag = localStorage.getItem("HEADER_CAST_BUTTON_AS_URL_BOX"); HEADER_CAST_ALTERNATE_ICON_expflag = localStorage.getItem("HEADER_CAST_ALTERNATE_ICON"); +if (HEADER_CAST_ALTERNATE_ICON_expflag == undefined) { + localStorage.setItem("HEADER_CAST_ALTERNATE_ICON", "Material"); + HEADER_CAST_ALTERNATE_ICON_expflag = localStorage.getItem("HEADER_CAST_ALTERNATE_ICON"); +} APP_STOP_TEXT_SELECTION_expflag = localStorage.getItem("APP_STOP_TEXT_SELECTION"); if (APP_STOP_TEXT_SELECTION_expflag == undefined) { localStorage.setItem("APP_STOP_TEXT_SELECTION", "true"); APP_STOP_TEXT_SELECTION_expflag = localStorage.getItem("APP_STOP_TEXT_SELECTION"); } +WATCH_UI_NO_LINES_expflag = localStorage.getItem("WATCH_UI_NO_LINES"); +WATCH_COMMENT_SECTION_LEFT_expflag = localStorage.getItem("WATCH_COMMENT_SECTION_LEFT"); +WATCH_DOWNLOAD_BUTTON_expflag = localStorage.getItem("WATCH_DOWNLOAD_BUTTON"); +WATCH_SAVE_BUTTON_expflag = localStorage.getItem("WATCH_SAVE_BUTTON"); +WATCH_HIDE_SUBSCRIBE_ICON_expflag = localStorage.getItem("WATCH_HIDE_SUBSCRIBE_ICON"); +HEADER_YOUTUBE_BRANDING_expflag = localStorage.getItem("HEADER_YOUTUBE_BRANDING"); +if (HEADER_YOUTUBE_BRANDING_expflag == undefined) { + localStorage.setItem("HEADER_YOUTUBE_BRANDING", "YouTube"); + HEADER_YOUTUBE_BRANDING_expflag = localStorage.getItem("HEADER_YOUTUBE_BRANDING"); +} +WATCH_AUTOPLAY_SWITCH_expflag = localStorage.getItem("WATCH_AUTOPLAY_SWITCH"); +HEADER_USE_ACCOUNT_ICON_expflag = localStorage.getItem("HEADER_USE_ACCOUNT_ICON"); +HEADER_ACCOUNT_ICON_LINK_expflag = localStorage.getItem("HEADER_ACCOUNT_ICON_LINK"); +if (HEADER_ACCOUNT_ICON_LINK_expflag == undefined) { + localStorage.setItem("HEADER_ACCOUNT_ICON_LINK", ""); + HEADER_ACCOUNT_ICON_LINK_expflag = localStorage.getItem("HEADER_ACCOUNT_ICON_LINK"); +} +WATCH_SAVE_IS_ADD_TO_expflag = localStorage.getItem("WATCH_SAVE_IS_ADD_TO"); +PIVOT_TRENDING_IS_EXPLORE_expflag = localStorage.getItem("PIVOT_TRENDING_IS_EXPLORE"); +PIVOT_LIBRARY_UPDATED_ICON_expflag = localStorage.getItem("PIVOT_LIBRARY_UPDATED_ICON"); +WATCH_SAVE_UPDATED_ICON_expflag = localStorage.getItem("WATCH_SAVE_UPDATED_ICON"); +WATCH_COLLAPSABLE_COMMENTS_expflag = localStorage.getItem("WATCH_COLLAPSABLE_COMMENTS"); +HEADER_ALWAYS_SHOW_YOUTUBE_TITLE_expflag = localStorage.getItem("HEADER_ALWAYS_SHOW_YOUTUBE_TITLE"); +HEADER_MENU_BUTTON_expflag = localStorage.getItem("HEADER_MENU_BUTTON"); +APP_NO_INTERNET_POPUP_NEW_STYLE_expflag = localStorage.getItem("APP_NO_INTERNET_POPUP_NEW_STYLE"); +WATCH_CONDENSE_COMMENT_BUTTONS_expflag = localStorage.getItem("WATCH_CONDENSE_COMMENT_BUTTONS"); +WATCH_FORMAT_LIKE_COUNTS_expflag = localStorage.getItem("WATCH_FORMAT_LIKE_COUNTS"); +APP_IOS_SYSTEM_FONT_expflag = localStorage.getItem("APP_IOS_SYSTEM_FONT"); +WATCH_CONDENSE_COMMUNITY_POST_BUTTONS_expflag = localStorage.getItem("WATCH_CONDENSE_COMMUNITY_POST_BUTTONS"); + newErrorHtml = ` -${item.likeCount.toLocaleString()} +${(WATCH_FORMAT_LIKE_COUNTS_expflag == "true") ? new Intl.NumberFormat('en-US', {notation: "compact",compactDisplay: "short"}).format(item.likeCount) : item.likeCount.toLocaleString()}
@@ -777,7 +876,7 @@ ${pinnedCMBadge}
-${cmReplyCount} +${(WATCH_FORMAT_LIKE_COUNTS_expflag == "true") ? new Intl.NumberFormat('en-US', {notation: "compact",compactDisplay: "short"}).format(cmReplyCount) : cmReplyCount}
`; @@ -822,7 +921,7 @@ ${pinnedCMBadge} const getCommentsTitle = new XMLHttpRequest(); getCommentsTitle.open('GET', APIbaseURL + 'api/v1/channels/' + item.authorId, true); - getCommentsTitle.setRequestHeader('Authorization','Basic eXRtMTU6SlFKNTNLckxBRVk2RTVxaGdjbTM4UGtTenczYlpYbWs='); + if (APP_DONT_AUTH_TO_INVIDIOUS_expflag == "false"){getCommentsTitle.setRequestHeader('Authorization','Basic eXRtMTU6SlFKNTNLckxBRVk2RTVxaGdjbTM4UGtTenczYlpYbWs=');}; getCommentsTitle.onerror = function(event) { console.error("An error occurred with this operation (" + getCommentsTitle.status + ")"); @@ -1111,7 +1210,7 @@ function renderPivotBar(){ { "name": Subs_text_string, "pivotName": "subscriptions", - "iconPath": "M20,8H4V6H20V8M18,2H6V4H18V2M22,12V20A2,2 0 0,1 20,22H4A2,2 0 0,1 2,20V12A2,2 0 0,1 4,10H20A2,2 0 0,1 22,12M16,16L10,12.73V19.26L16,16Z", + "iconPath": "M20 8H4V6h16v2zm-2-6H6v2h12V2zm4 8v12H2V10h20zm-6 6-6-3.27v6.53L16 16z", "link": "subscriptions" }, { @@ -1127,6 +1226,9 @@ function renderPivotBar(){ "link": "library" } ]; + if (PIVOT_NOTIFICATIONS_ICON_VARIANT_expflag == "Inbox") {pivotBarItems[3].iconPath = "M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4-8 5-8-5V6l8 5 8-5v2z"} + if (PIVOT_TRENDING_IS_EXPLORE_expflag == "true") {pivotBarItems[1].iconPath = "M14.19,14.19L6,18L9.81,9.81L18,6M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,10.9A1.1,1.1 0 0,0 10.9,12A1.1,1.1 0 0,0 12,13.1A1.1,1.1 0 0,0 13.1,12A1.1,1.1 0 0,0 12,10.9Z";pivotBarItems[1].name = "Explore"} + if (PIVOT_LIBRARY_UPDATED_ICON_expflag == "true") {pivotBarItems[4].iconPath = "M4,6H2V20A2,2 0 0,0 4,22H18V20H4V6M20,2H8A2,2 0 0,0 6,4V16A2,2 0 0,0 8,18H20A2,2 0 0,0 22,16V4A2,2 0 0,0 20,2M12,14.5V5.5L18,10L12,14.5Z"} pivotBar.innerHTML = ""; pivotBarItems.forEach(function(item){ const pivotBarItem = document.createElement("div"); @@ -1190,7 +1292,7 @@ function renderCompactMediaItem(parent, parentName, itemVideoId, itemThumbnail, } else if (mediaType == "hashtag") { thumbnail.href = "#" + itemVideoId; } - if (mediaType == "video" || mediaType == "shortVideo") { + if (mediaType == "video" || mediaType == "shortVideo" || mediaType == "shorts") { thumbnail.onclick = function(){ if (!app.querySelector("#watchpageFrame_Container")) { app.insertAdjacentElement("afterbegin", watchContainer); @@ -1393,7 +1495,7 @@ function renderCompactMediaItem(parent, parentName, itemVideoId, itemThumbnail, } else if (mediaType == "hashtag") { metaContent.href = "#" + itemVideoId; } - if (mediaType == "video" || mediaType == "shortVideo") { + if (mediaType == "video" || mediaType == "shortVideo" || mediaType == "shorts") { metaContent.onclick = function(){ if (!app.querySelector("#watchpageFrame_Container")) { app.insertAdjacentElement("afterbegin", watchContainer); @@ -1458,7 +1560,7 @@ function renderCompactMediaItem(parent, parentName, itemVideoId, itemThumbnail, menuItemBtnShare.textContent = "Sharing will be implemented soon"; menuItemBtnShare.setAttribute("style", "opacity: .7;") menuItemBtnShare.onclick = function(){ - + }; menuItemShare.appendChild(menuItemBtnShare); @@ -2446,7 +2548,7 @@ setTimeout(function() { function callback(mutationsList, observer) { /* console.log('Mutations:', mutationsList) */ /* console.log('Observer:', observer) */ - mutationsList.forEach(mutation => { + mutationsList.forEach(function(mutation) { if (mutation.attributeName === 'class') { if (mutation.target.classList.contains("has-watchpage")) { metaColorBeforeWP = metaColorElm.content; @@ -2544,7 +2646,7 @@ if (!wasPrevChannelPage) { headerTitle.setAttribute("aria-label", _2015YT_text_string); headerTitle.textContent = _2015YT_text_string; } -if (window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == undefined || window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "trending" || window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "popular" || window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "") { +if (window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == undefined || window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "trending" || window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "popular" || window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "" || window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "library") { renderData(); } else if (window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "about") { aboutYTm15(); @@ -2556,6 +2658,8 @@ if (window.location.hash.split("/").join(',').split("?").join(',').split(',').sl playlistPage(); } else if (window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "comments") { commentsPage(); +} else if (window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "subscriptions") { + subscriptionsPage(); } else { if (document.querySelector(".spinner-container.full-height")) { var spinner = document.querySelector(".spinner-container.full-height"); @@ -2572,6 +2676,43 @@ if (window.location.hash.split("/").join(',').split("?").join(',').split(',').sl function settingsHashDetector() { settingsPage(); } +function showNotification(message, buttonText=undefined, onclick=undefined) { + const n = document.createElement('div'); + n.className = 'notification'; + n.setAttribute('role', 'status'); + n.setAttribute('aria-live', 'polite'); + + const text = document.createElement('span'); + text.textContent = message; + n.appendChild(text); + + if (buttonText) { + const button = document.createElement('button'); + button.textContent = buttonText; + if (onclick && typeof onclick === "function") { + button.addEventListener("click", function(){ + onclick(); + dismiss(n); + }); + } + n.appendChild(button); + } + + document.body.appendChild(n); + void n.offsetHeight; + n.classList.add('notification-show'); + + setTimeout(function(){dismiss(n)}, 3500); + + function dismiss(el) { + el.classList.remove('notification-show'); + el.addEventListener('transitionend', function() { + if (el.parentNode) el.parentNode.removeChild(el); + }, { once: true }); + } + + return n; +} if (window.location.pathname.split("/").slice(2, 3) == "2015YouTube%20(Mobile)") { if (window.location.pathname.split("/").slice(3, 4) == "index.html" || window.location.pathname.split("/").slice(3, 4) == undefined || window.location.pathname.split("/").slice(3, 4) == "") { @@ -2598,4 +2739,58 @@ window.addEventListener('hashchange', function (event) { hashDetector(); } } -}); \ No newline at end of file +}); + +window.addEventListener('offline', function() { + if (APP_NO_INTERNET_POPUP_NEW_STYLE_expflag == true) { + const n = document.createElement('div'); + n.setAttribute('id','offline-bar'); + n.setAttribute('aria-live', 'polite'); + n.innerHTML = "No connection"; + pivotBar.after(n); + void n.offsetHeight; + n.classList.add('offline-bar-show'); + } + else { + showNotification("No connection"); + } +}); +window.addEventListener('online', function() { + if (APP_NO_INTERNET_POPUP_NEW_STYLE_expflag == true) { + const n = document.getElementById('offline-bar'); + n.classList.add('offline-bar-online'); + n.innerHTML = "Back online"; + setTimeout(function(){dismiss(n)}, 3500); + function dismiss(el) { + el.classList.remove('offline-bar-show'); + el.addEventListener('transitionend', function() { + if (el.parentNode) el.parentNode.removeChild(el); + }, { once: true }); + } + } + else { + showNotification("Connection established","Go online",function() {renderData();}); + } +}); + +function openMenu() { + const n = document.createElement('div'); + n.className = "hamburger-menu" + const n1 = document.createElement('div'); + n1.className = "hamburger-submenu" + app.appendChild(n); + n.addEventListener("click", function() {dismiss(n,n1)}); + function dismiss(el,el1) { + el1.classList.remove('hamburger-submenu-show'); + el.classList.add('hamburger-menu-hide'); + void el.offsetHeight + el.addEventListener('animationend', function() { + if (el.parentNode) el.parentNode.removeChild(el); + }, { once: true }); + } + n.appendChild(n1); + void n.offsetHeight + n1.classList.add("hamburger-submenu-show"); + +} + diff --git a/app/Material Spinner/spinner.js b/app/Material Spinner/spinner.js index e83e3aab..9b55fb8a 100644 --- a/app/Material Spinner/spinner.js +++ b/app/Material Spinner/spinner.js @@ -3,8 +3,8 @@ function spinner() { spinner.classList.add("spinner-container"); if (localStorage.getItem("WEB_IOS_SPINNER") == "true") { spinner.innerHTML = ` - - + + `; } else { diff --git a/app/camcorder.svg b/app/camcorder.svg new file mode 100644 index 00000000..644b6a78 --- /dev/null +++ b/app/camcorder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/channel.js b/app/channel.js index adc8a258..9b3b6dc4 100644 --- a/app/channel.js +++ b/app/channel.js @@ -236,6 +236,9 @@ function channelPage() { if (item == "live") { item = "streams"; } + if (item == "search") { + return; + } tab.setAttribute('aria-label', item); if (item == "streams") { tab.setAttribute('aria-label', 'live'); @@ -1042,12 +1045,13 @@ function channelPage() { /* getChannelVideos.open('GET', APIbaseURL + 'api/v1/channels/' + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(2, 3)[0] + '/videos?sort_by=' + window.location.hash.split("?").slice(1, 2).toString().split("&").slice(0, 1).toString().split("sort").slice(1, 2).toString().split("=").slice(1, 2).toString(), true); */ /* getChannelVideos.open('GET', APIbaseURL + 'api/v1/channels/' + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(2, 3)[0] + '/' + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(3, 4)[0] + '?sort_by=' + window.location.hash.split("?").slice(1, 2).toString().split("&").slice(0, 1).toString().split("sort").slice(1, 2).toString().split("=").slice(1, 2).toString(), true); */ /* getChannelVideos.setRequestHeader('Authorization','Basic eXRtMTU6SlFKNTNLckxBRVk2RTVxaGdjbTM4UGtTenczYlpYbWs='); */ - getChannelVideos.open('GET', APIbaseURLNew + 'channel/' + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(3, 4)[0] + '?id=' + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(2, 3)[0] + '&sort_by=' + window.location.hash.split("?").slice(1, 2).toString().split("&").slice(0, 1).toString().split("sort").slice(1, 2).toString().split("=").slice(1, 2).toString(), true); + getChannelVideos.open('POST', APIbaseURLNew + 'channel/' + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(3, 4)[0], true); if (window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(3, 4)[0] == "streams") { getChannelVideos.open('GET', APIbaseURLNew + 'channel/liveStreams?id=' + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(2, 3)[0] + '&sort_by=' + window.location.hash.split("?").slice(1, 2).toString().split("&").slice(0, 1).toString().split("sort").slice(1, 2).toString().split("=").slice(1, 2).toString(), true); } getChannelVideos.setRequestHeader('x-rapidapi-key', '4b0791fe33mshce00ad033774274p196706jsn957349df7a8f'); getChannelVideos.setRequestHeader('x-rapidapi-host', 'yt-api.p.rapidapi.com'); + getChannelVideos.setRequestHeader("content-type", "application/x-www-form-urlencoded"); getChannelVideos.onerror = function(event) { console.error("An error occurred with this operation (" + getChannelVideos.status + ")"); @@ -1070,8 +1074,11 @@ function channelPage() { }; return; }; - - getChannelVideos.send(); + + const getChannelVideosParams = new URLSearchParams(); + getChannelVideosParams.set("id", window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(2, 3)[0]); + getChannelVideosParams.set("sort_by", window.location.hash.split("?").slice(1, 2).toString().split("&").slice(0, 1).toString().split("sort").slice(1, 2).toString().split("=").slice(1, 2).toString()); + getChannelVideos.send(getChannelVideosParams); getChannelVideos.onload = function() { if (getChannelVideos.status === 200) { @@ -1205,6 +1212,7 @@ function channelPage() { compMediaItemAuthor = item.channelTitle; compMediaItemvidId = item.videoId; } + //console.log(item.type + compMediaItemvidId) renderCompactMediaItem(lazyList, "channel-lazy-list", compMediaItemvidId, compMediaItemThumb, compMediaItemLength, compMediaItemTitle, compMediaItemAuthor, item.channelId, item.publishedTimeText, item.viewCount, item.type); }); }; @@ -1238,12 +1246,13 @@ function channelVideosContin(continuation, contItemParent) { /* getChannelVideos1.open('GET', APIbaseURL + 'api/v1/channels/' + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(2, 3)[0] + '/videos?continuation=' + continuation + '&sort_by=' + window.location.hash.split("?").slice(1, 2).toString().split("&").slice(0, 1).toString().split("sort").slice(1, 2).toString().split("=").slice(1, 2).toString(), true); */ /* getChannelVideos1.open('GET', APIbaseURL + 'api/v1/channels/' + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(2, 3)[0] + `/${window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(3, 4)[0]}?continuation=` + continuation + '&sort_by=' + window.location.hash.split("?").slice(1, 2).toString().split("&").slice(0, 1).toString().split("sort").slice(1, 2).toString().split("=").slice(1, 2).toString(), true); */ /* getChannelVideos1.setRequestHeader('Authorization','Basic eXRtMTU6SlFKNTNLckxBRVk2RTVxaGdjbTM4UGtTenczYlpYbWs='); */ - getChannelVideos1.open('GET', APIbaseURLNew + 'channel/' + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(3, 4)[0] + '?id=' + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(2, 3)[0] + '&sort_by=' + window.location.hash.split("?").slice(1, 2).toString().split("&").slice(0, 1).toString().split("sort").slice(1, 2).toString().split("=").slice(1, 2).toString() + '&token=' + continuation, true); + getChannelVideos1.open('POST', APIbaseURLNew + 'channel/' + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(3, 4)[0], true); if (window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(3, 4)[0] == "streams") { getChannelVideos1.open('GET', APIbaseURLNew + 'channel/liveStreams?id=' + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(2, 3)[0] + '&sort_by=' + window.location.hash.split("?").slice(1, 2).toString().split("&").slice(0, 1).toString().split("sort").slice(1, 2).toString().split("=").slice(1, 2).toString() + '&token=' + continuation, true); } getChannelVideos1.setRequestHeader('x-rapidapi-key', '4b0791fe33mshce00ad033774274p196706jsn957349df7a8f'); getChannelVideos1.setRequestHeader('x-rapidapi-host', 'yt-api.p.rapidapi.com'); + getChannelVideos1.setRequestHeader("content-type", "application/x-www-form-urlencoded"); getChannelVideos1.onerror = function(event) { console.error("An error occurred with this operation (" + getChannelVideos1.status + ")"); @@ -1267,7 +1276,11 @@ function channelVideosContin(continuation, contItemParent) { return; }; - getChannelVideos1.send(); + const getChannelVideosParams1 = new URLSearchParams(); + getChannelVideosParams1.set("id", window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(2, 3)[0]); + getChannelVideosParams1.set("sort_by", window.location.hash.split("?").slice(1, 2).toString().split("&").slice(0, 1).toString().split("sort").slice(1, 2).toString().split("=").slice(1, 2).toString()); + getChannelVideosParams1.set("token", continuation); + getChannelVideos1.send(getChannelVideosParams1); getChannelVideos1.onload = function() { if (getChannelVideos1.status === 200) { @@ -1413,7 +1426,7 @@ function channelVideosContin(continuation, contItemParent) { if (window.location.hash.split("?").slice(1, 2).toString().split("&").slice(0, 1).toString().split("sort").slice(1, 2).toString().split("=").slice(1, 2).toString() == "") { getChannelPlaylists.open('GET', APIbaseURL + 'api/v1/channels/' + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(2, 3)[0] + '/playlists', true); } - getChannelPlaylists.setRequestHeader('Authorization','Basic eXRtMTU6SlFKNTNLckxBRVk2RTVxaGdjbTM4UGtTenczYlpYbWs='); + if (APP_DONT_AUTH_TO_INVIDIOUS_expflag == "false"){getChannelPlaylists.setRequestHeader('Authorization','Basic eXRtMTU6SlFKNTNLckxBRVk2RTVxaGdjbTM4UGtTenczYlpYbWs=');}; getChannelPlaylists.onerror = function(event) { console.error("An error occurred with this operation (" + getChannelPlaylists.status + ")"); @@ -1523,7 +1536,7 @@ function channelVideosContin(continuation, contItemParent) { const getChannelPlaylists1 = new XMLHttpRequest(); getChannelPlaylists1.open('GET', APIbaseURL + 'api/v1/channels/' + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(2, 3)[0] + `/playlists?continuation=` + continuation + '&sort_by=' + window.location.hash.split("?").slice(1, 2).toString().split("&").slice(0, 1).toString().split("sort").slice(1, 2).toString().split("=").slice(1, 2).toString(), true); - getChannelPlaylists.setRequestHeader('Authorization','Basic eXRtMTU6SlFKNTNLckxBRVk2RTVxaGdjbTM4UGtTenczYlpYbWs='); + if (APP_DONT_AUTH_TO_INVIDIOUS_expflag == "false"){getChannelPlaylists.setRequestHeader('Authorization','Basic eXRtMTU6SlFKNTNLckxBRVk2RTVxaGdjbTM4UGtTenczYlpYbWs=');}; getChannelPlaylists1.onerror = function(event) { console.error("An error occurred with this operation (" + getChannelVideos1.status + ")"); diff --git a/app/download.svg b/app/download.svg new file mode 100644 index 00000000..2bb3c316 --- /dev/null +++ b/app/download.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/header.js b/app/header.js index f199001d..6cf0164c 100644 --- a/app/header.js +++ b/app/header.js @@ -49,6 +49,18 @@ function renderHeader() { if (DARK_THEME_option == "true") { headerEPSrc = "yt_wordmark_header_dark.png" } + if (HEADER_YOUTUBE_BRANDING_expflag == "Red") { + headerEPSrc = "yt_red_wordmark_header_light.png" + } + if (HEADER_YOUTUBE_BRANDING_expflag == "Red" && DARK_THEME_option == "true") { + headerEPSrc = "yt_red_wordmark_header_dark.png" + } + if (HEADER_YOUTUBE_BRANDING_expflag == "Premium") { + headerEPSrc = "yt_premium_wordmark_header_light.png" + } + if (HEADER_YOUTUBE_BRANDING_expflag == "Premium" && DARK_THEME_option == "true") { + headerEPSrc = "yt_premium_wordmark_header_dark.png" + } headerEP.innerHTML = ``; const backBtn = document.createElement("button"); @@ -214,6 +226,7 @@ function renderHeader() { console.log(url); } catch (err) { console.log('Could not read clipboard: ' + err); + showNotification(err); }; if (!app.querySelector("#watchpageFrame_Container")) { @@ -242,8 +255,11 @@ function renderHeader() { castBtn.setAttribute("aria-label", SearchYT_text_string); castBtn.setAttribute("aria-haspopup", "false"); let alternateIcon = `` - if (HEADER_CAST_ALTERNATE_ICON_expflag == "true") {alternateIcon = ``} - castBtn.innerHTML = `` + alternateIcon + ``; + if (HEADER_CAST_ALTERNATE_ICON_expflag == "Materialv2") {alternateIcon = ``} + if (HEADER_CAST_ALTERNATE_ICON_expflag == "Camera") { + castBtn.innerHTML = ``;} + else { + castBtn.innerHTML = `` + alternateIcon + ``;} if (window.location.pathname.split("/").slice(3, 4) == "results.html") { castBtn.setAttribute("hidden", ""); } @@ -280,6 +296,9 @@ function renderHeader() { const menuBtn = document.createElement("button"); menuBtn.classList.add("icon-button", "header-button", "menu-button"); + if (HEADER_USE_ACCOUNT_ICON_expflag == "true") { + menuBtn.style.marginRight = "5px"; + } menuBtn.onclick = function(){ menuRenderer(); menuCont.setAttribute("style", "top: 0; right: 0; position: fixed;"); @@ -367,7 +386,16 @@ function renderHeader() { }; menuBtn.setAttribute("aria-label", "Menu"); menuBtn.setAttribute("aria-haspopup", "true"); + if (HEADER_USE_ACCOUNT_ICON_expflag == "true" && HEADER_ACCOUNT_ICON_LINK_expflag !== "") { + menuBtn.innerHTML = ` + + + `; + } else if (HEADER_USE_ACCOUNT_ICON_expflag == "true") { + menuBtn.innerHTML = ``; + } else { menuBtn.innerHTML = ``; + } if (APP_DEMATERIALIZE_UI_expflag == "true") { backBtn.innerHTML = ``; @@ -375,6 +403,29 @@ function renderHeader() { menuBtn.innerHTML = ``; }; + const hamburgerMenuButtons = document.createElement("div"); + hamburgerMenuButtons.classList.add("header-buttons"); + + const hamburgerBtn = document.createElement("button"); + hamburgerBtn.classList.add("icon-button", "header-button"); + hamburgerBtn.onclick = function(){openMenu()}; + hamburgerBtn.setAttribute("aria-label", "Left Menu"); + hamburgerBtn.setAttribute("aria-haspopup", "false"); + hamburgerBtn.innerHTML = ``; + if (window.location.pathname.split("/").slice(3, 4) == "results.html") { + hamburgerBtn.setAttribute("hidden", ""); + } + if (window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "results" || window.location.pathname.split("/").slice(3, 4) == "settings.html" || window.location.pathname.split("/").slice(3, 4) == "settings" || window.location.pathname.split("/").slice(2, 3) == "settings.html" || window.location.pathname.split("/").slice(2, 3) == "settings") { + hamburgerBtn.setAttribute("hidden", ""); + } + window.addEventListener('hashchange', function (event) { + if (window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "results" || window.location.pathname.split("/").slice(3, 4) == "settings.html" || window.location.pathname.split("/").slice(3, 4) == "settings" || window.location.pathname.split("/").slice(2, 3) == "settings.html" || window.location.pathname.split("/").slice(2, 3) == "settings") { + hamburgerBtn.setAttribute("hidden", ""); + } else { + hamburgerBtn.removeAttribute("hidden", ""); + } + }); + if (window.location.pathname.split("/").slice(3, 4) == "settings.html" || window.location.pathname.split("/").slice(3, 4) == "settings" || window.location.pathname.split("/").slice(2, 3) == "settings.html" || window.location.pathname.split("/").slice(2, 3) == "settings") { menuBtn.setAttribute("hidden", ""); } @@ -394,9 +445,11 @@ function renderHeader() { form.appendChild(inputWrap); inputWrap.appendChild(input); header.appendChild(headerCont); + if (HEADER_MENU_BUTTON_expflag == "true") {headerCont.appendChild(hamburgerMenuButtons);}; headerCont.appendChild(headerTitle); headerCont.appendChild(headerButtons); if (HEADER_CAST_BUTTON_AS_URL_BOX_expflag == "true") {headerButtons.appendChild(castBtn);}; + if (HEADER_MENU_BUTTON_expflag == "true") {hamburgerMenuButtons.appendChild(hamburgerBtn);}; headerButtons.appendChild(searchBtn); headerButtons.appendChild(menuBtn); diff --git a/app/home.js b/app/home.js index e66410ab..d784785e 100644 --- a/app/home.js +++ b/app/home.js @@ -33,7 +33,7 @@ spinner(); function renderData() { const headerTitle = document.querySelector(".header-title"); headerTitle.setAttribute("aria-label", ""); - headerTitle.textContent = ""; + (HEADER_ALWAYS_SHOW_YOUTUBE_TITLE_expflag == "true") ? headerTitle.textContent = "YouTube" : headerTitle.textContent = ""; const headerBar = document.querySelector("ytm15-header-bar"); @@ -86,7 +86,7 @@ function renderData() { tab2.setAttribute('aria-label', 'Subscriptions'); tab2.setAttribute('aria-selected', 'false'); if (window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "subscriptions") { - tab1.setAttribute('aria-selected', 'true'); + tab2.setAttribute('aria-selected', 'true'); } tab2.href = "#/subscriptions"; tab2.innerHTML = `` @@ -207,7 +207,7 @@ function renderData() { } */ headerTitle.setAttribute("aria-label", Trending_text_string); - headerTitle.textContent = Trending_text_string; + headerTitle.textContent = HEADER_ALWAYS_SHOW_YOUTUBE_TITLE_expflag ? "YouTube" : Trending_text_string; if (WEB_ENABLE_PIVOT_BAR_expflag !== "true") { if (!document.querySelector(".tab-bar")) { @@ -270,6 +270,113 @@ function renderData() { }; } + // library seperator + if (window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "library") { + pageCont.innerHTML = ""; + console.log("EE"); + + var spinner = document.querySelector(".spinner-container.full-height"); + spinner.removeAttribute("hidden"); + + /*if (document.querySelector(".tab-bar")) { + document.querySelector(".tab-bar").setAttribute("hidden", ""); + headerBar.classList.remove('has-tab-bar'); + document.querySelector(".tab-bar").setAttribute("isChannel", "false"); + document.querySelector(".tab-bar").innerHTML = ""; + };*/ + + try { + // { videoId, videoThumbnails: [{...},{...},{...},{url}], lengthSeconds, title, author, authorId, publishedText, viewCount } + const libraryJson = localStorage.getItem('WEB_LIBRARY'); + const data = libraryJson ? JSON.parse(libraryJson) : null; + + var spinner = document.querySelector(".spinner-container.full-height"); + spinner.setAttribute("hidden", ""); + + if (!Array.isArray(data)) { + blankLibraryPage();//showNotification('This shelf is empty'); + return; + } + + headerTitle.setAttribute("aria-label", Library_text_string); + headerTitle.textContent = HEADER_ALWAYS_SHOW_YOUTUBE_TITLE_expflag ? "YouTube" : Library_text_string; + + const page = document.createElement("page"); + page.classList.add('home'); + + const tabContainer = document.createElement("div"); + tabContainer.classList.add('tabs-content-container'); + + const tabContent = document.createElement("div"); + tabContent.classList.add('tab-content'); + tabContent.setAttribute("tab-identifier", "Trending"); + + const tabContent2 = document.createElement("div"); + tabContent2.classList.add('tab-content'); + tabContent2.setAttribute("tab-identifier", "What_to_watch_placeholder"); + + const section = document.createElement("div"); + section.classList.add('section-list'); + + const sectLazyList = document.createElement("div"); + sectLazyList.classList.add('lazy-list'); + section.appendChild(sectLazyList); + + pageCont.innerHTML = ""; + + const parent = document.querySelector(".page-container"); + parent.appendChild(page); + page.appendChild(tabContainer); + tabContainer.appendChild(tabContent2); + tabContainer.appendChild(tabContent); + tabContent.appendChild(section); + + var oldTitle = document.querySelector("title"); + + var title = document.createElement("title"); + title.textContent = Library_text_string + ' - 2015YouTube'; + + oldTitle.parentNode.replaceChild(title, oldTitle); + + data.forEach(function(item) { + renderMediaItem( + sectLazyList, + "sect-lazy-list", + item.videoId, + item.videoThumbnails && item.videoThumbnails[3] ? item.videoThumbnails[3].url : (item.videoThumbnails && item.videoThumbnails[0] ? item.videoThumbnails[0].url : ""), + item.lengthSeconds, + item.title, + item.author, + item.authorId, + item.publishedText, + item.viewCount + ); + }); + } catch (err) { + showNotification(err); + + var spinner = document.querySelector(".spinner-container.full-height"); + spinner.setAttribute("hidden", ""); + + const error = document.createElement("div"); + error.classList.add('error-container'); + error.innerHTML = `
+ +There was an error loading library data +
+
`; + if (APP_NEW_ERROR_SCREEN_expflag == "true"){error.innerHTML=newErrorHtml}; + pageCont.before(error); + error.querySelector("button").onclick = function(){ + renderData(); + error.remove(); + }; + return; + } + + return; + } + /* if (urlpage == "popular") */ if (window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "popular") { pageCont.innerHTML = ""; @@ -337,7 +444,7 @@ function renderData() { } */ headerTitle.setAttribute("aria-label", Popular_text_string); - headerTitle.textContent = Popular_text_string; + headerTitle.textContent = HEADER_ALWAYS_SHOW_YOUTUBE_TITLE_expflag ? "YouTube" : Popular_text_string; const page = document.createElement("page"); page.classList.add('home'); @@ -408,7 +515,12 @@ function renderData() { }; eventListenFunc(); - if (window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "popular" || window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "trending") { + // This makes the library work offline if the invidious instance is down and also unintentionally makes switching tabs fast not start overlapping requests and page loads + if ( + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "popular" || + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "trending" || + window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "library" + ) { return; }; @@ -471,7 +583,7 @@ function renderData() { } */ headerTitle.setAttribute("aria-label", Home_text_string); - headerTitle.textContent = Home_text_string; + headerTitle.textContent = HEADER_ALWAYS_SHOW_YOUTUBE_TITLE_expflag ? "YouTube" : Home_text_string; if (WEB_ENABLE_PIVOT_BAR_expflag !== "true") { if (!document.querySelector(".tab-bar")) { @@ -731,3 +843,126 @@ function renderDataTrending(homeShelfTrendingType, shelfTitle) { } } } + +function subscriptionsPage() { + const headerTitle = document.querySelector(".header-title"); + + const headerBar = document.querySelector("ytm15-header-bar"); + + const pageCont = document.querySelector('.page-container'); + pageCont.innerHTML = ""; + + var spinner = document.querySelector(".spinner-container.full-height"); + spinner.removeAttribute("hidden"); + + if (WEB_ENABLE_PIVOT_BAR_expflag !== "true") { + if (document.querySelector(".tab-bar")) { + document.querySelector(".tab-bar").removeAttribute("hidden"); + document.querySelector(".tab-bar").setAttribute("isChannel", "false"); + headerBar.classList.add('has-tab-bar'); + + const subsTab = document.querySelector('.tab-bar .subscriptions-tab .tab'); + if (subsTab) subsTab.setAttribute('aria-selected', 'true'); + + const homeTab = document.querySelector('.tab-bar .home-tab .tab'); + if (homeTab) homeTab.setAttribute('aria-selected', 'false'); + + const trendingTab = document.querySelector('.tab-bar .trending-tab .tab'); + if (trendingTab) trendingTab.setAttribute('aria-selected', 'false'); + + const accountTab = document.querySelector('.tab-bar .account-tab .tab'); + if (accountTab) accountTab.setAttribute('aria-selected', 'false'); + } + } else { + if (document.querySelector(".tab-bar")) { + document.querySelector(".tab-bar").setAttribute("hidden", ""); + document.querySelector(".tab-bar").setAttribute("isChannel", "false"); + headerBar.classList.remove('has-tab-bar'); + document.querySelector(".tab-bar").innerHTML = ""; + } + } + + var spinner = document.querySelector(".spinner-container.full-height"); + spinner.setAttribute("hidden", ""); + + headerTitle.setAttribute("aria-label", "Subscriptions"); + headerTitle.textContent = "Subscriptions"; + + const page = document.createElement("page"); + + const tabContainer = document.createElement("div"); + tabContainer.classList.add('tabs-content-container'); + + const tabContent = document.createElement("div"); + tabContent.classList.add('tab-content'); + tabContent.setAttribute("tab-identifier", ""); + + const subscriptionsPage = document.createElement("div"); + + const section = document.createElement("div"); + section.classList.add('section-list'); + + const sectLazyList = document.createElement("div"); + sectLazyList.classList.add('lazy-list'); + sectLazyList.innerHTML = `

(Local) Subscriptions are coming to YTm15 Soon!

`; + section.appendChild(sectLazyList); + + const parent = document.querySelector(".page-container"); + parent.appendChild(page); + page.appendChild(tabContainer); + tabContainer.appendChild(tabContent); + tabContent.appendChild(subscriptionsPage); + subscriptionsPage.appendChild(section); + + var title = document.querySelector("title"); + title.textContent = 'Subscriptions'; + + if (APP_DEMATERIALIZE_UI_expflag == "true") { + Array.from(sectLazyList.querySelectorAll(".ap-shelf")).forEach(function(item){ + item.classList.add('card'); + }); + Array.from(sectLazyList.querySelectorAll(".about-page-bottom-title")).forEach(function(item){ + item.classList.add('card'); + }); + } +} + +function blankLibraryPage() { + const page = document.createElement("page"); + + const tabContainer = document.createElement("div"); + tabContainer.classList.add('tabs-content-container'); + + const tabContent = document.createElement("div"); + tabContent.classList.add('tab-content'); + tabContent.setAttribute("tab-identifier", ""); + + const subscriptionsPage = document.createElement("div"); + + const section = document.createElement("div"); + section.classList.add('section-list'); + + const sectLazyList = document.createElement("div"); + sectLazyList.classList.add('lazy-list'); + sectLazyList.innerHTML = `

You can add videos to this Library for safe keeping. Enable WATCH_SAVE_BUTTON in YTm15 Experimental Flags. You also need WATCH_ENABLE_NEW_UI enabled, in the future a save button will be added to the player.

`; + section.appendChild(sectLazyList); + + const parent = document.querySelector(".page-container"); + parent.appendChild(page); + page.appendChild(tabContainer); + tabContainer.appendChild(tabContent); + tabContent.appendChild(subscriptionsPage); + subscriptionsPage.appendChild(section); + + var title = document.querySelector("title"); + title.textContent = 'Subscriptions'; + + if (APP_DEMATERIALIZE_UI_expflag == "true") { + Array.from(sectLazyList.querySelectorAll(".ap-shelf")).forEach(function(item){ + item.classList.add('card'); + }); + Array.from(sectLazyList.querySelectorAll(".about-page-bottom-title")).forEach(function(item){ + item.classList.add('card'); + }); + } +} diff --git a/app/ic_download.png b/app/ic_download.png new file mode 100644 index 00000000..1985e620 Binary files /dev/null and b/app/ic_download.png differ diff --git a/app/ic_save.png b/app/ic_save.png new file mode 100644 index 00000000..4daed577 Binary files /dev/null and b/app/ic_save.png differ diff --git a/app/ic_vidcontrol_add_to.png b/app/ic_vidcontrol_add_to.png new file mode 100644 index 00000000..8f03f6f1 Binary files /dev/null and b/app/ic_vidcontrol_add_to.png differ diff --git a/app/ic_vidcontrol_add_to_pressed.png b/app/ic_vidcontrol_add_to_pressed.png new file mode 100644 index 00000000..99e009b3 Binary files /dev/null and b/app/ic_vidcontrol_add_to_pressed.png differ diff --git a/app/ic_vidcontrol_share_alt.png b/app/ic_vidcontrol_share_alt.png new file mode 100644 index 00000000..bb3f8840 Binary files /dev/null and b/app/ic_vidcontrol_share_alt.png differ diff --git a/app/ic_vidcontrol_share_pressed_alt.png b/app/ic_vidcontrol_share_pressed_alt.png new file mode 100644 index 00000000..8796bd22 Binary files /dev/null and b/app/ic_vidcontrol_share_pressed_alt.png differ diff --git a/app/index.html b/app/index.html index cb80a8d0..534ca2b2 100644 --- a/app/index.html +++ b/app/index.html @@ -20,7 +20,7 @@ - + diff --git a/app/mr_ic_media_route_off_holo_dark.png b/app/mr_ic_media_route_off_holo_dark.png new file mode 100644 index 00000000..94e8bfc7 Binary files /dev/null and b/app/mr_ic_media_route_off_holo_dark.png differ diff --git a/app/player.css b/app/player.css index 59219c38..f5b93eda 100644 --- a/app/player.css +++ b/app/player.css @@ -176,6 +176,14 @@ height: 4px; margin: 0 12px; } +.progress::after { + content: ''; + position: absolute; + top: -10px; + bottom: -10px; + left: -10px; + right: -10px; +} .progress-filled { width: 50%; background: #c62118; diff --git a/app/player.js b/app/player.js index 47b5855a..4600c21c 100644 --- a/app/player.js +++ b/app/player.js @@ -193,6 +193,14 @@ playerShareBtn.innerHTML = ``; playerShareBtn.ariaPressed = "false"; controlsTop.appendChild(playerShareBtn); +/*const playerSaveBtn = document.createElement("button"); +playerSaveBtn.classList.add("controls-button", "share-button", "has-ripple"); +playerSaveBtn.title = "Share video"; +playerSaveBtn.ariaLabel = "Share video"; +playerSaveBtn.innerHTML = ` +`; +playerSaveBtn.ariaPressed = "false"; +controlsTop.appendChild(playerSaveBtn);*/ const overflowBtn = document.createElement("button"); overflowBtn.classList.add("controls-button", "overflow-button", "has-ripple"); overflowBtn.title = "More options"; @@ -849,7 +857,12 @@ Sorry about that...`; playerxhttpr.onload = function() { if (playerxhttpr.status === 200) { const data = JSON.parse(playerxhttpr.response); - video.poster = data.thumbnail[3].url; + if (data.code === 403) { + playerxhttpr.onerror(); + return; + } + /* video.poster = data.thumbnail[3].url; */ + video.poster = data.thumbnail[data.thumbnail.length - 1].url; video.innerHTML = ``; video.dataset.title = data.title; /* storyboardURL = "https://inv.tux.pizza" + data.storyboards[2].url; */ @@ -902,4 +915,5 @@ sbxhttpr.onload = function() { playerxhttpr.onerror(); } }; -}; \ No newline at end of file + +}; diff --git a/app/playlists.js b/app/playlists.js index c5f66d52..f5aa9c3d 100644 --- a/app/playlists.js +++ b/app/playlists.js @@ -16,7 +16,7 @@ function playlistPage(){ const getPlaylistData = new XMLHttpRequest(); getPlaylistData.open('GET', APIbaseURL + 'api/v1/playlists/' + window.location.hash.split("?").slice(1, 2).toString().split("&").slice(0, 1).toString().split("list").slice(1, 2).toString().split("=").slice(1, 2).toString(), true); - getPlaylistData.setRequestHeader('Authorization','Basic eXRtMTU6SlFKNTNLckxBRVk2RTVxaGdjbTM4UGtTenczYlpYbWs='); + if (APP_DONT_AUTH_TO_INVIDIOUS_expflag == "false"){getPlaylistData.setRequestHeader('Authorization','Basic eXRtMTU6SlFKNTNLckxBRVk2RTVxaGdjbTM4UGtTenczYlpYbWs=');}; getPlaylistData.onerror = function(event) { console.error("An error occurred with this operation (" + getPlaylistData.status + ")"); diff --git a/app/save.svg b/app/save.svg new file mode 100644 index 00000000..a8c9eba0 --- /dev/null +++ b/app/save.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/settings.js b/app/settings.js index 362540ac..027d89fc 100644 --- a/app/settings.js +++ b/app/settings.js @@ -91,6 +91,8 @@ function renderSettingText(parent, stTitle, stSubtitle, stValue, stPlaceholder, parent.appendChild(settingText); } +function parseImportedText(str) {return str.replace(/^"|"$/g, '');}; // because i can't put quotes in the onclick which is already kinda a mess + function settingsPage() { pageCont.innerHTML = ""; @@ -130,6 +132,18 @@ function settingsPage() { "title": AboutYTm15_text_string, "link": "index.html#/about", "id": "about" + }, + { + "type": "option", + "title": Feedback_text_string, + "link": "#/feedback", + "id": "feedback" + }, + { + "type": "option", + "title": InstallYtm15_text_string, + "link": "#/install", + "id": "install" } ]; @@ -154,6 +168,10 @@ function settingsPage() { settingsPageHeader.innerHTML = Settings_text_string; settingsPageHeader.ariaLabel = settingsPageHeader.innerHTML; + const settingsSaveAndLoad = document.createElement("div"); + settingsSaveAndLoad.style.display = "flex"; + settingsSaveAndLoad.innerHTML = `
`; + const innerSettingsPageCont = document.createElement("div"); innerSettingsPageCont.classList.add("inner-settings-page-container"); innerSettingsPageCont.innerHTML = ` @@ -240,6 +258,54 @@ function settingsPage() { } }); } + if (window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "feedback") { + /* innerSettingsPageCont.innerHTML = ` +
${SettingsMSG2_text_string}
+`; */ + innerSettingsPageCont.innerHTML = ""; + var settingsPage = document.createElement("settings-page"); + settingsPageHeader.id = "expflags"; + settingsPage.classList.add(settingsPageHeader.id); + settingsPage.style.userSelect = "unset"; + settingsPage.style.msUserSelect = "unset"; + settingsPage.style.mozUserSelect = "unset"; + settingsPage.style.khtmlUserSelect = "unset"; + settingsPage.style.webkitUserSelect = "unset"; + settingsPage.style.webkitTouchCallout = "unset"; + settingsPage.style.letterSpacing = "1px"; + innerSettingsPageCont.appendChild(settingsPage); + settingsPageHeader.innerHTML = Feedback_text_string; + settingsPageHeader.id = "feedback"; + headerTitle.setAttribute("aria-label", Feedback_text_string); + headerTitle.textContent = Feedback_text_string; + title.textContent = Feedback_text_string + ' - 2015YouTube'; + + settingsPage.innerHTML="

Open an issue on the YTm15 GitHub:
https://github.com/ytm15/ytm15.github.io/issues

Check for pull requests open (If any of the features you want may be being added):
https://github.com/ytm15/ytm15.github.io/pulls

You can also post on r/oldyoutubelayout (the dev is active there)

"; + } + if (window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "install") { + /* innerSettingsPageCont.innerHTML = ` +
${SettingsMSG2_text_string}
+`; */ + innerSettingsPageCont.innerHTML = ""; + var settingsPage = document.createElement("settings-page"); + settingsPageHeader.id = "expflags"; + settingsPage.classList.add(settingsPageHeader.id); + settingsPage.style.userSelect = "unset"; + settingsPage.style.msUserSelect = "unset"; + settingsPage.style.mozUserSelect = "unset"; + settingsPage.style.khtmlUserSelect = "unset"; + settingsPage.style.webkitUserSelect = "unset"; + settingsPage.style.webkitTouchCallout = "unset"; + settingsPage.style.letterSpacing = "1px"; + innerSettingsPageCont.appendChild(settingsPage); + settingsPageHeader.innerHTML = InstallYtm15_text_string; + settingsPageHeader.id = "install"; + headerTitle.setAttribute("aria-label", InstallYtm15_text_string); + headerTitle.textContent = InstallYtm15_text_string; + title.textContent = InstallYtm15_text_string + ' - 2015YouTube'; + + settingsPage.innerHTML=`
2015YouTube
ytm15.github.io
Get as a Webapp
Modern devices:
  1. Open Safari (iOS)/Chrome (Android)
  2. Go to https://ytm15.github.io/app
  3. Press "share"/the three dots
  4. Press "Add to Home Screen"
YTm15 is not supported on ≤iOS 9, or maybe some old versions of Android, if you are using the native WebView/Browser, but this shouldn't be an issue as you can install a newer browser APK. Hopefully, that will change too. Alternatively, there are websites online that can let you turn a website into an APK, but note what I said if it uses WebView.`; + } if (window.location.hash.split("/").join(',').split("?").join(',').split(',').slice(1, 2)[0] == "expflags") { /* innerSettingsPageCont.innerHTML = `
${SettingsMSG2_text_string}
@@ -253,6 +319,8 @@ function settingsPage() { headerTitle.setAttribute("aria-label", ExpFlags_text_string); headerTitle.textContent = ExpFlags_text_string; title.textContent = ExpFlags_text_string + ' - 2015YouTube'; + settingsPage.appendChild(settingsSaveAndLoad); + settingBlocks = [ { @@ -606,13 +674,32 @@ function settingsPage() { "lsitem": "PIVOT_HIDE_NOTIFICATIONS" }, { - "type": "boolean", - "title": "PIVOT_NOTIFICATIONS_IS_ACTIVITY", + "type": "option-menu", + "title": "PIVOT_NOTIFICATIONS_ICON_VARIANT", "subtitle": "", - "pressed": PIVOT_NOTIFICATIONS_IS_ACTIVITY_expflag == "true", - "pressed-default": false, - "disabled": false, - "lsitem": "PIVOT_NOTIFICATIONS_IS_ACTIVITY" + "options": [ + { + "title": "Notifications", + "selected": PIVOT_NOTIFICATIONS_ICON_VARIANT_expflag == "Notifications", + "selected-default": true + }, + { + "title": "Activity", + "selected": PIVOT_NOTIFICATIONS_ICON_VARIANT_expflag == "Activity", + "selected-default": false + }, + { + "title": "Inbox", + "selected": PIVOT_NOTIFICATIONS_ICON_VARIANT_expflag == "Inbox", + "selected-default": false + }, + { + "title": "Shared", + "selected": PIVOT_NOTIFICATIONS_ICON_VARIANT_expflag == "Shared", + "selected-default": false + } + ], + "lsitem": "PIVOT_NOTIFICATIONS_ICON_VARIANT" }, { "type": "boolean", @@ -635,8 +722,8 @@ function settingsPage() { { "type": "text", "title": "APP_CUSTOM_INVIDIOUS_URL", - "subtitle": "This loads your home page and comments. which should update and not be static
If you have your own invidious instance put it here
You should change CORS policy if you own your instance, otherwise use a CORS redirector", - "value": "https://api.allorigins.win/raw?url=https://yt.omada.cafe/", + "subtitle": "This loads your home page and comments. which should update and not be static
If you are hosting an invidious instance put it here
You should change CORS policy if you own your instance, otherwise use a CORS redirector. If you can use a CORS disabler extension, you can also remove the starting proxy url, it will make it faster.>
Clear the text box to reset the url
If you want to setup an invidious instance just for YTm15, it is not worth it, it is complicated to setup and will take all of your computer's resources.", + "value": "https://api.codetabs.com/v1/proxy?quest=https://y.com.sb/", "placeholder": "", "disabled": false, "lsitem": "APP_CUSTOM_INVIDIOUS_URL" @@ -671,7 +758,7 @@ function settingsPage() { { "type": "boolean", "title": "HEADER_NO_SHADOW", - "subtitle": "", + "subtitle": "Fun fact: there was usually no shadow on non Retina (low-res) devices", "pressed": HEADER_NO_SHADOW_expflag == "true", "pressed-default": false, "disabled": false, @@ -705,12 +792,26 @@ function settingsPage() { "lsitem": "HEADER_CAST_BUTTON_AS_URL_BOX" }, { - "type": "boolean", + "type": "option-menu", "title": "HEADER_CAST_ALTERNATE_ICON", "subtitle": "", - "pressed": HEADER_CAST_ALTERNATE_ICON_expflag == "true", - "pressed-default": false, - "disabled": false, + "options": [ + { + "title": "Material", + "selected": HEADER_CAST_ALTERNATE_ICON_expflag == "Material", + "selected-default": true + }, + { + "title": "Materialv2", + "selected": HEADER_CAST_ALTERNATE_ICON_expflag == "Materialv2", + "selected-default": false + }, + { + "title": "Camera", + "selected": HEADER_CAST_ALTERNATE_ICON_expflag == "Camera", + "selected-default": false + } + ], "lsitem": "HEADER_CAST_ALTERNATE_ICON" }, { @@ -721,6 +822,209 @@ function settingsPage() { "pressed-default": true, "disabled": false, "lsitem": "APP_STOP_TEXT_SELECTION" + }, + { + "type": "boolean", + "title": "WATCH_UI_NO_LINES", + "subtitle": "", + "pressed": WATCH_UI_NO_LINES_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "WATCH_UI_NO_LINES" + }, + { + "type": "boolean", + "title": "WATCH_COMMENT_SECTION_LEFT", + "subtitle": "", + "pressed": WATCH_COMMENT_SECTION_LEFT_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "WATCH_COMMENT_SECTION_LEFT" + }, + { + "type": "boolean", + "title": "WATCH_DOWNLOAD_BUTTON", + "subtitle": "", + "pressed": WATCH_DOWNLOAD_BUTTON_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "WATCH_DOWNLOAD_BUTTON" + }, + { + "type": "boolean", + "title": "WATCH_SAVE_BUTTON", + "subtitle": "Saved videos go to your Library on the homepage.", + "pressed": WATCH_SAVE_BUTTON_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "WATCH_SAVE_BUTTON" + }, + { + "type": "boolean", + "title": "WATCH_HIDE_SUBSCRIBE_ICON", + "subtitle": "", + "pressed": WATCH_HIDE_SUBSCRIBE_ICON_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "WATCH_HIDE_SUBSCRIBE_ICON" + }, + { + "type": "option-menu", + "title": "HEADER_YOUTUBE_BRANDING", + "subtitle": "", + "options": [ + { + "title": "YouTube", + "selected": HEADER_YOUTUBE_BRANDING_expflag == "YouTube", + "selected-default": true + }, + { + "title": "Red", + "selected": HEADER_YOUTUBE_BRANDING_expflag == "Red", + "selected-default": false + }, + { + "title": "Premium", + "selected": HEADER_YOUTUBE_BRANDING_expflag == "Premium", + "selected-default": false + } + ], + "lsitem": "HEADER_YOUTUBE_BRANDING" + }, + { + "type": "boolean", + "title": "WATCH_AUTOPLAY_SWITCH", + "subtitle": "", + "pressed": WATCH_AUTOPLAY_SWITCH_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "WATCH_AUTOPLAY_SWITCH" + }, + { + "type": "boolean", + "title": "HEADER_USE_ACCOUNT_ICON", + "subtitle": "", + "pressed": HEADER_USE_ACCOUNT_ICON_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "HEADER_USE_ACCOUNT_ICON" + }, + { + "type": "text", + "title": "HEADER_ACCOUNT_ICON_LINK", + "subtitle": "", + "value": "", + "placeholder": "", + "disabled": false, + "lsitem": "HEADER_ACCOUNT_ICON_LINK" + }, + { + "type": "boolean", + "title": "WATCH_SAVE_IS_ADD_TO", + "subtitle": "", + "pressed": WATCH_SAVE_IS_ADD_TO_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "WATCH_SAVE_IS_ADD_TO" + }, + { + "type": "boolean", + "title": "PIVOT_TRENDING_IS_EXPLORE", + "subtitle": "", + "pressed": PIVOT_TRENDING_IS_EXPLORE_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "PIVOT_TRENDING_IS_EXPLORE" + }, + { + "type": "boolean", + "title": "PIVOT_LIBRARY_UPDATED_ICON", + "subtitle": "", + "pressed": PIVOT_LIBRARY_UPDATED_ICON_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "PIVOT_LIBRARY_UPDATED_ICON" + }, + { + "type": "boolean", + "title": "WATCH_SAVE_UPDATED_ICON", + "subtitle": "", + "pressed": WATCH_SAVE_UPDATED_ICON_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "WATCH_SAVE_UPDATED_ICON" + }, + { + "type": "boolean", + "title": "WATCH_COLLAPSABLE_COMMENTS", + "subtitle": "", + "pressed": WATCH_COLLAPSABLE_COMMENTS_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "WATCH_COLLAPSABLE_COMMENTS" + }, + { + "type": "boolean", + "title": "HEADER_ALWAYS_SHOW_YOUTUBE_TITLE", + "subtitle": "", + "pressed": HEADER_ALWAYS_SHOW_YOUTUBE_TITLE_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "HEADER_ALWAYS_SHOW_YOUTUBE_TITLE" + }, + { + "type": "boolean", + "title": "HEADER_MENU_BUTTON", + "subtitle": "", + "pressed": HEADER_MENU_BUTTON_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "HEADER_MENU_BUTTON" + }, + { + "type": "boolean", + "title": "APP_NO_INTERNET_POPUP_NEW_STYLE", + "subtitle": "", + "pressed": APP_NO_INTERNET_POPUP_NEW_STYLE_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "APP_NO_INTERNET_POPUP_NEW_STYLE" + }, + { + "type": "boolean", + "title": "WATCH_CONDENSE_COMMENT_BUTTONS", + "subtitle": "", + "pressed": WATCH_CONDENSE_COMMENT_BUTTONS_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "WATCH_CONDENSE_COMMENT_BUTTONS" + }, + { + "type": "boolean", + "title": "WATCH_FORMAT_LIKE_COUNTS", + "subtitle": "", + "pressed": WATCH_FORMAT_LIKE_COUNTS_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "WATCH_FORMAT_LIKE_COUNTS" + }, + { + "type": "boolean", + "title": "APP_IOS_SYSTEM_FONT", + "subtitle": "", + "pressed": APP_IOS_SYSTEM_FONT_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "APP_IOS_SYSTEM_FONT" + }, + { + "type": "boolean", + "title": "WATCH_CONDENSE_COMMUNITY_POST_BUTTONS", + "subtitle": "", + "pressed": WATCH_CONDENSE_COMMUNITY_POST_BUTTONS_expflag == "true", + "pressed-default": false, + "disabled": false, + "lsitem": "WATCH_CONDENSE_COMMUNITY_POST_BUTTONS" } ]; settingBlocks.forEach(function(item){ diff --git a/app/subscriptions.svg b/app/subscriptions.svg new file mode 100644 index 00000000..a3fde931 --- /dev/null +++ b/app/subscriptions.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/watch.js b/app/watch.js index a782e031..5ac4884d 100644 --- a/app/watch.js +++ b/app/watch.js @@ -22,6 +22,27 @@ function renderWatchPage(parent) { insertYTmPlayer(playerCont2); + async function shareVideo() { + if (navigator.share) { + try { + await navigator.share({url:"https://youtu.be/" + playerVideoId}) + } + catch(err) { + if (err.name !== 'AbortError') { + showNotification(err); + } + } + } else { + showNotification("Web Share API not supported!\nTry on Android 6.0+!"); + } + } + function saveVideo(videoId,url,lengthSeconds,title,author,authorId,publishedText,viewCount) { + const library = JSON.parse(localStorage.getItem("WEB_LIBRARY")) || []; + library.unshift({videoId:videoId,videoThumbnails:[{url:url}],lengthSeconds:lengthSeconds,title:title,author:author,authorId:authorId,publishedText:publishedText,viewCount:viewCount}); + localStorage.setItem("WEB_LIBRARY",JSON.stringify(library)); + showNotification("Saved to playlist"); + } + const getWatchData = new XMLHttpRequest(); /* getWatchData.open('GET', APIbaseURL + 'api/v1/videos/' + playerVideoId, true); */ /* getWatchData.open('GET', APIbaseURLWatch + 'api/v1/videos/' + playerVideoId, true); */ @@ -384,6 +405,9 @@ function renderWatchPage(parent) { videoMetadataLikeCount = "Like"; videoMetadataLikeCountAL = "Like this video"; }; + if (WATCH_FORMAT_LIKE_COUNTS_expflag == "true") { + videoMetadataLikeCount = new Intl.NumberFormat('en-US', {notation: "compact",compactDisplay: "short"}).format(videoMetadataLikeCount.replace(/\D/g, "")); + } mtrlBtnCont.innerHTML = `` @@ -413,7 +437,7 @@ function renderWatchPage(parent) { videoMetadataDislikeCount = response.dislikes.toLocaleString(); videoMetadataDislikeCountAL = "Dislike this video along with " + videoMetadataDislikeCount + " other people"; mtrlBtnContDislike.querySelector("button").ariaLabel = videoMetadataDislikeCountAL; - mtrlBtnContDislike.querySelector(".button-text").innerHTML = videoMetadataDislikeCount; + mtrlBtnContDislike.querySelector(".button-text").innerHTML = (WATCH_FORMAT_LIKE_COUNTS_expflag == "true") ? new Intl.NumberFormat('en-US', {notation: "compact",compactDisplay: "short"}).format(videoMetadataDislikeCount.replace(/\D/g, "")) : videoMetadataDislikeCount; } else { console.error("An error occurred with this operation (" + getDislikeCount.status + ")"); } @@ -432,6 +456,28 @@ function renderWatchPage(parent) { mtrlBtnContShare.setAttribute("disabled", "false"); mtrlBtnContShare.innerHTML = `` + + const mtrlBtnContDownload = document.createElement("div"); + mtrlBtnContDownload.classList.add("material-button-container", "compact", "download-button"); + mtrlBtnContDownload.dataset.style = "DEFAULT"; + mtrlBtnContDownload.dataset.iconOnly = "true"; + mtrlBtnContDownload.setAttribute("is-busy", "false"); + mtrlBtnContDownload.ariaBusy = "false"; + mtrlBtnContDownload.setAttribute("disabled", "false"); + mtrlBtnContDownload.innerHTML = `` + + const mtrlBtnContSave = document.createElement("div"); + mtrlBtnContSave.classList.add("material-button-container", "compact", "save-button"); + mtrlBtnContSave.dataset.style = "DEFAULT"; + mtrlBtnContSave.dataset.iconOnly = "true"; + mtrlBtnContSave.setAttribute("is-busy", "false"); + mtrlBtnContSave.ariaBusy = "false"; + mtrlBtnContSave.setAttribute("disabled", "false"); + mtrlBtnContSave.innerHTML = `` if (WATCH_USE_MTRL_ICONS_expflag == "true") { @@ -448,6 +494,25 @@ function renderWatchPage(parent) { transform: scale(1.3); transform-origin: center; ">
${Share_text_string}
+` + + mtrlBtnContDownload.innerHTML = `` + + saveIconSvg = "M14 10H3v2h11v-2zm0-4H3v2h11V6zm4 8v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zM3 16h7v-2H3v2z"; + saveIconScale = "3"; + if (WATCH_SAVE_UPDATED_ICON_expflag == "true") { + saveIconSvg = "M19,11H15V15H13V11H9V9H13V5H15V9H19M20,2H8A2,2 0 0,0 6,4V16A2,2 0 0,0 8,18H20A2,2 0 0,0 22,16V4A2,2 0 0,0 20,2M4,6H2V20A2,2 0 0,0 4,22H18V20H4V6Z"; + saveIconScale = "2"; + } + mtrlBtnContSave.innerHTML = `` metadataActions.classList.add("use-mtrl-icons"); @@ -456,6 +521,8 @@ function renderWatchPage(parent) { mtrlBtnCont.querySelector("button").appendChild(mtrlBtnCont.querySelector(".button-text")); mtrlBtnContDislike.querySelector("button").appendChild(mtrlBtnContDislike.querySelector(".button-text")); mtrlBtnContShare.querySelector("button").appendChild(mtrlBtnContShare.querySelector(".button-text")); + mtrlBtnContDownload.querySelector("button").appendChild(mtrlBtnContDownload.querySelector(".button-text")); + mtrlBtnContSave.querySelector("button").appendChild(mtrlBtnContSave.querySelector(".button-text")); }; const actionsSpacer = document.createElement("div"); @@ -464,7 +531,11 @@ function renderWatchPage(parent) { metadataActions.appendChild(mtrlBtnCont); metadataActions.appendChild(mtrlBtnContDislike); metadataActions.appendChild(mtrlBtnContShare); + mtrlBtnContShare.querySelector("button").addEventListener("click", shareVideo); + mtrlBtnContSave.querySelector("button").addEventListener("click", ()=>{saveVideo(playerVideoId,document.querySelector(".player-poster").style.backgroundImage.slice(4, -1).replace(/["']/g, ""),"0"/*document.querySelector(".player-duration").textContent*/,metaTitle.textContent,document.querySelector(".video-owner-title").textContent,document.querySelector(".profile-img").src,document.querySelector(".video-published-date"),parseInt(document.querySelector(".video-metadata-view-count .secondary-text").textContent.replace(/\D/g, "")),10)}); metadataActions.appendChild(actionsSpacer); + if (WATCH_DOWNLOAD_BUTTON_expflag == "true") {metadataActions.appendChild(mtrlBtnContDownload);}; + if (WATCH_SAVE_BUTTON_expflag == "true" && WATCH_ENABLE_NEW_UI_expflag == "true") {metadataActions.appendChild(mtrlBtnContSave);metadataActions.style.flexWrap = "nowrap"}; const W2ndHalf = document.createElement("div"); W2ndHalf.classList.add("wnr-2nd-half", "watch-next-results-content"); @@ -537,6 +608,9 @@ function renderWatchPage(parent) { if (WATCH_AUTONAV_TITLE_USE_UPNEXT_expflag == "true") { autonavBar.innerHTML = `

${UpNext_text_string}

`; } + if (WATCH_AUTOPLAY_SWITCH_expflag == "true") { + autonavBar.insertAdjacentHTML("beforeend",`

Autoplay

`); + } itemSectRelated.querySelector(".lazy-list").appendChild(autonavBar); data.relatedVideos.data.forEach(function(item) { @@ -571,11 +645,16 @@ function renderWatchPage(parent) { renderCompactMediaItem(itemSectRelated.querySelector(".lazy-list"), "related-media-lazy-list", compMediaItemvidId, compMediaItemThumb, compMediaItemLength, compMediaItemTitle, compMediaItemAuthor, item.channelId, "", item.viewCount, item.type); }); - renderCommentSection(W2ndHalf, "video", playerVideoId, false); + if (WATCH_COMMENT_SECTION_LEFT_expflag == "true") { + renderCommentSection(scwnr, "video", playerVideoId, false); + } else { + renderCommentSection(W2ndHalf, "video", playerVideoId, false); + } parent.innerHTML = ""; parent.appendChild(scwnr); + document.getElementById('autoplay-toggle-button').setAttribute('aria-pressed',localStorage.getItem('WATCH_AUTOPLAY_SWITCH_INTERNAL')); } else { getWatchData.onerror(); } diff --git a/app/yt_premium_wordmark_header_dark.png b/app/yt_premium_wordmark_header_dark.png new file mode 100644 index 00000000..c1893ecc Binary files /dev/null and b/app/yt_premium_wordmark_header_dark.png differ diff --git a/app/yt_premium_wordmark_header_light.png b/app/yt_premium_wordmark_header_light.png new file mode 100644 index 00000000..10f2d746 Binary files /dev/null and b/app/yt_premium_wordmark_header_light.png differ diff --git a/app/yt_red_wordmark_header_dark.png b/app/yt_red_wordmark_header_dark.png new file mode 100644 index 00000000..9d8f7b54 Binary files /dev/null and b/app/yt_red_wordmark_header_dark.png differ diff --git a/app/yt_red_wordmark_header_light.png b/app/yt_red_wordmark_header_light.png new file mode 100644 index 00000000..e0a416ac Binary files /dev/null and b/app/yt_red_wordmark_header_light.png differ