mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
Lazy load toast and screenshot
This commit is contained in:
parent
a33595552d
commit
f28a67b449
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
min/about.min.js
vendored
2
min/about.min.js
vendored
@ -1 +1 @@
|
||||
(()=>{return(t,e)=>{(async()=>{const i=await e.importAsync("aboutHtml");document.body.insertAdjacentHTML("beforeend",i);const o=(t,e)=>t.charCodeAt(0)-e.charCodeAt(0);const n=(t,e)=>o(t.name,e.name);const s=GM_info.script.name.match(/Bilibili Evolved \((.*)\)/);const a=s?s[1]:"Stable";new Vue({el:".bilibili-evolved-about",data:{version:t.currentVersion,clientType:a,logoImage:null,logoImageDark:null,branch:null,authors:[{name:"Grant Howard",link:"https://github.com/the1812"},{name:"Coulomb-G",link:"https://github.com/Coulomb-G"}],contributors:[{name:"PleiadeSubaru",link:"https://github.com/Etherrrr"}].sort(n),fetching:true,participants:[],websites:[{name:"GitHub",link:"https://github.com/the1812/Bilibili-Evolved/"},{name:"Greasy Fork",link:"https://greasyfork.org/zh-CN/scripts/373563-bilibili-evolved"}],components:[{name:"Vue.js",link:"https://cn.vuejs.org/index.html"},{name:"JSZip",link:"https://stuk.github.io/jszip/"},{name:"jQuery",link:"http://jquery.com/"},{name:"debounce",link:"https://github.com/component/debounce/"},{name:"Slip.js",link:"https://github.com/kornelski/slip"},{name:"MDI",link:"https://materialdesignicons.com"}]},mounted(){document.querySelector(".bilibili-evolved-about").addEventListener("be:about-load",()=>{this.init()},{once:true})},methods:{async getLogos(){this.logoImage=await Ajax.getText(`https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/images/bilibili-evolved-wide.svg`);this.logoImageDark=await Ajax.getText(`https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/images/bilibili-evolved-wide-dark.svg`)},async init(){this.branch=/Preview|Local/.test(a)?"preview":"master";this.getLogos();const t=new Set;let e=[];let i=1;do{e=await Ajax.getJson(`https://api.github.com/repos/the1812/Bilibili-Evolved/issues?state=all&direction=asc&per_page=100&page=${i}`).catch(()=>{e=[{name:"电波无法到达(´・_・`)",link:null}]});i++;for(const i of e){t.add(i.user.login)}}while(e.length>0);this.participants=[...t].map(t=>{return{name:t,link:`https://github.com/${t}`}}).filter(({link:t})=>{return!this.authors.some(e=>e.link===t)&&!this.contributors.some(e=>e.link===t)}).sort(n);this.fetching=false}}})})()}})();
|
||||
(()=>{return(t,e)=>{(async()=>{const i=await e.importAsync("aboutHtml");document.body.insertAdjacentHTML("beforeend",i);document.querySelector(".bilibili-evolved-about").addEventListener("be:about-load",()=>{const e=(t,e)=>t.charCodeAt(0)-e.charCodeAt(0);const i=(t,i)=>e(t.name,i.name);const o=GM_info.script.name.match(/Bilibili Evolved \((.*)\)/);const n=o?o[1]:"Stable";new Vue({el:".bilibili-evolved-about",data:{version:t.currentVersion,clientType:n,logoImage:null,logoImageDark:null,branch:null,authors:[{name:"Grant Howard",link:"https://github.com/the1812"},{name:"Coulomb-G",link:"https://github.com/Coulomb-G"}],contributors:[{name:"PleiadeSubaru",link:"https://github.com/Etherrrr"}].sort(i),fetching:true,participants:[],websites:[{name:"GitHub",link:"https://github.com/the1812/Bilibili-Evolved/"},{name:"Greasy Fork",link:"https://greasyfork.org/zh-CN/scripts/373563-bilibili-evolved"}],components:[{name:"Vue.js",link:"https://cn.vuejs.org/index.html"},{name:"JSZip",link:"https://stuk.github.io/jszip/"},{name:"jQuery",link:"http://jquery.com/"},{name:"debounce",link:"https://github.com/component/debounce/"},{name:"Slip.js",link:"https://github.com/kornelski/slip"},{name:"MDI",link:"https://materialdesignicons.com"}]},mounted(){this.init()},methods:{async getLogos(){this.logoImage=await Ajax.getText(`https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/images/bilibili-evolved-wide.svg`);this.logoImageDark=await Ajax.getText(`https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/images/bilibili-evolved-wide-dark.svg`)},async init(){this.branch=/Preview|Local/.test(n)?"preview":"master";this.getLogos();const t=new Set;let e=[];let o=1;do{e=await Ajax.getJson(`https://api.github.com/repos/the1812/Bilibili-Evolved/issues?state=all&direction=asc&per_page=100&page=${o}`).catch(()=>{e=[{name:"电波无法到达(´・_・`)",link:null}]});o++;for(const i of e){t.add(i.user.login)}}while(e.length>0);this.participants=[...t].map(t=>{return{name:t,link:`https://github.com/${t}`}}).filter(({link:t})=>{return!this.authors.some(e=>e.link===t)&&!this.contributors.some(e=>e.link===t)}).sort(i);this.fetching=false}}})},{once:true})})()}})();
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"about.min.css": "839FB8FA5429AFB22AAE52B0B1114EB5474333D12082554BAD790E75936CF48C",
|
||||
"about.min.html": "AE18D23499F4B636B32267440FAE92D67700FCA2F2AA2FBB4E2692018D66DD5F",
|
||||
"about.min.js": "0E79611FC34B3EFB4B9428A18C391DF59674D5C41D34023F6F9DEFB656882A9E",
|
||||
"about.min.js": "B0060D92D0E182A65B8A709627A116F420539BE7EE977C606E6D9C2E18CD4697",
|
||||
"aria2-rpc.min.js": "B13E731DDD503A645A19BB243FF0148BEAC313F0A54454752A07387176F04046",
|
||||
"auto-continue.min.js": "96CD47C367D7397CE1467A69764409BAEFF16E8F535BC8E15523CD0B8A86687E",
|
||||
"auto-draw.min.js": "AE72CF2623DF2D15AD4AF82D125FFAF7EF5B1E6B36D9E9AC646AC98AA6AA8698",
|
||||
@ -58,7 +58,7 @@
|
||||
"full-tweets-title.min.js": "DD57BB732ABEF7739CA84AEFF97E86F8984FCC4A8A75B957213622350B2A7C37",
|
||||
"gui-settings.min.css": "9C7CABF974C76DCFAD6DBECAD8CCA7C1EFA1EAEA9977DF5F0013B3F4FA664FCD",
|
||||
"gui-settings.min.html": "AA990C3CE45A68755AA9BED58AC4B13CAFC88C81FEF7C080DFB40A248D269F46",
|
||||
"gui-settings.min.js": "33DF9A8702A721E660106D225A3BCA000863568FF289E7DBAF90584378E1D273",
|
||||
"gui-settings.min.js": "6391232B3162CA80CA749F9A66DD9F7EC761B263A1C8A431313A87813428F0B8",
|
||||
"haruna-scale.min.js": "7B0F89A664B6A3D0BE21F7501660058DE3DC0881A81FCDA44B9F3C31BBD73D30",
|
||||
"hide-bangumi-reviews.min.js": "CC3CE6B3F1606F8AB0A4ADAD3B16E6DA9245D0676ACF74B97FB143FBFF0C7223",
|
||||
"hide-banner.min.css": "FF157AF84741AF0564FE2930CC49F524F99A41739DB4C44DC944EC6F4F620A0F",
|
||||
@ -105,12 +105,12 @@
|
||||
"remove-top-mask.min.js": "A15C1EC10D2E1A61845B1ADAE51860553F96427059E10443B1E53FAF48F45304",
|
||||
"remove-watermark.min.js": "EF8A48E379DE9400E7FCEA7A455EC966B56ADCE31D722FF02C8111FB92A148AF",
|
||||
"screenshot.min.css": "C8BFD4B0A76A758477B767338ABA1D0A49408EDBA861351EA5CB57070515CE76",
|
||||
"screenshot.min.js": "DF1F34103A1DB88A7A4F6DDAA3C8F55710FC6C11802CED917A026D66A9F7FE3B",
|
||||
"screenshot.min.js": "655DE531468A00BCE2F78B406B9A79C6D00F22A299D37BFC8F5C775E15D26DDC",
|
||||
"scrollbar.min.css": "9792340121B6EE6E618A3F62AABD9C992D9C325803DF4879C8A74F02DA0E2213",
|
||||
"search.vue.min.js": "1A4E23DFE187B1A3792F3D8E7847B9F2E8593043A8527C7B1D644CA171FC8376",
|
||||
"seeds-to-coins.min.js": "3F1D383501A6E989255808A82850903EB10931CBE0ADE652AADED69FB9502C57",
|
||||
"settings-search.min.js": "C3B605AF2581F562415B6AA30F7B1D825A74EB0B2B83A5F17A303B7B5646E261",
|
||||
"settings-side-bar.min.js": "CC0E3477BF8574606720D3261C4A0202713E42B30CFE737403E629CBA97B2A98",
|
||||
"settings-side-bar.min.js": "C945AD84FC42C8F5C1241A61CBC0E6874BA7393E6230B37C77204497D4855CC2",
|
||||
"settings-tooltip.en-US.min.js": "0D70BE86EABBC87E8E8249AD72B298EA249BD721C46B34764FAF10EE39CE1789",
|
||||
"settings-tooltip.ja-JP.min.js": "E02B7D9AD4AD241AF6EBA5F15B11AC6DC2214A1BBDB868A1F0AB7FF0B373BB74",
|
||||
"settings-tooltip.loader.min.js": "F9DFB09E32B8C814A61EE7E7D354C15A6FEF39BBBC22F476A930526DC26DA558",
|
||||
@ -132,7 +132,7 @@
|
||||
"theme-colors.min.js": "3001D5DAD0EFBAEC7F96C51FD3BE2C4677E358AD70D8DD019D2280EA450A34E7",
|
||||
"title.min.js": "0F738220A30AB7707BD1F7EA0380279E55295DDE500D313E8AC39EF713385B2C",
|
||||
"toast.min.css": "6F4343B67FF70C0A1217051F92BC854EE7A510A5AD5F115D98203C61C5A57D27",
|
||||
"toast.min.js": "F363B62C0C53F6CE5C13A186055EA40C0BC3E73A5FFD11586DDB4A17335CC930",
|
||||
"toast.min.js": "9B71F0AC57C75F8BDD267839101881ACAC61ED52EC67DEE30B97965D4CB21713",
|
||||
"touch-navbar.min.js": "21EF203296CF795E2471D04E7C44F5FA734FC7EB3EF6187B5AC6D562572D2649",
|
||||
"touch-player.min.css": "70F9BB443A8D1D629EF30BEDD48BC766C2F6640CBA7C6C35B6B002FCD8BF2A66",
|
||||
"touch-player.min.js": "28F2AF5C066CC4C3A2490D844861188907D1BB7B254F4B8A403F0AB3C7F4FB31",
|
||||
|
||||
BIN
min/bundle.zip
BIN
min/bundle.zip
Binary file not shown.
2
min/gui-settings.min.js
vendored
2
min/gui-settings.min.js
vendored
@ -1 +1 @@
|
||||
(()=>{return(e,t)=>{const{ThemeColors:n}=t.import("theme-colors");const{SettingsSearch:i}=t.import("settings-search");const{Validator:s}=t.import("text-validate");let o=[];let c=[];let r=[];function l(e){let t=e.nextElementSibling;const n=[];while(t!==null&&!t.classList.contains("category")){n.push(t);t=t.nextElementSibling}return n}function a(){r.forEach(t=>t.value=e[t.getAttribute("key")]);c.forEach(t=>t.checked=e[t.getAttribute("key")])}function d(){document.querySelector(".gui-settings-mask").addEventListener("click",()=>{document.querySelectorAll(".gui-settings-widgets-box,.gui-settings-box,.gui-settings-mask,.bilibili-evolved-about").forEach(e=>e.classList.remove("opened"))});r.forEach(t=>{t.setAttribute("placeholder",e[t.getAttribute("key")])});document.querySelectorAll(".gui-settings-content ul li.category").forEach(e=>{e.addEventListener("click",e=>{const t=document.querySelector(".gui-settings-search");if(t.value!==""){t.value="";raiseEvent(t,"input")}e.currentTarget.classList.toggle("folded");l(e.currentTarget).forEach(e=>e.classList.toggle("folded"))})});document.querySelectorAll(".gui-settings-dropdown>input").forEach(e=>{e.addEventListener("click",e=>{e.currentTarget.parentElement.classList.toggle("opened")})})}function u(){c.forEach(t=>{t.addEventListener("change",()=>{const n=t.getAttribute("key");const i=t.checked;e[n]=i})});r.forEach(t=>{t.addEventListener("change",()=>{const n=t.getAttribute("key");const i=s.getValidator(n).validate(t.value);e[n]=i;t.value=i})})}function g(){const e=o.map(e=>[e.getAttribute("dependencies").split(" ").map(e=>o.find(t=>t.getAttribute("key")===e)),e]);const t=e=>e.nodeName.toUpperCase()==="LI"?e:t(e.parentElement);e.forEach(([e,n])=>{if(e[0]===undefined){return}const i=()=>{if(e.every(e=>e.checked)){t(n).classList.remove("disabled")}else{t(n).classList.add("disabled")}};e.forEach(e=>e.addEventListener("change",i));i()})}function f(){if(typeof offlineData!=="undefined"){}}function p(){if(!CSS.supports("backdrop-filter","blur(24px)")&&!CSS.supports("-webkit-backdrop-filter","blur(24px)")){o.find(e=>e.getAttribute("key")==="blurVideoControl").disabled=true;e.blurVideoControl=false}if(window.devicePixelRatio===1){o.find(e=>e.getAttribute("key")==="harunaScale").disabled=true;o.find(e=>e.getAttribute("key")==="imageResolution").disabled=true;e.harunaScale=false;e.imageResolution=false}}function b(){for(const[e,t]of Object.entries(Resource.displayNames)){const n=o.find(t=>t.getAttribute("key")===e);if(!n){continue}switch(n.type){case"checkbox":n.nextElementSibling.nextElementSibling.innerHTML=t;break;case"text":const e=n.parentElement;if(e.classList.contains("gui-settings-textbox-container")){n.previousElementSibling.innerHTML=t}else if(e.classList.contains("gui-settings-dropdown")){e.previousElementSibling.innerHTML=t}break;default:break}}}(async()=>{t.applyStyle("guiSettingsStyle");t.applyImportantStyle("iconsStyle");document.body.classList.add("round-corner");const e=document.body&&unsafeWindow.parent.window!==unsafeWindow;if(e){document.querySelector(".gui-settings-icon-panel").style.display="none"}const s=t.data.guiSettingsHtml.text;document.body.insertAdjacentHTML("beforeend",s);const{style:l}=await t.importAsync("mdi");if(!l){document.body.insertAdjacentHTML("afterbegin",`<link rel="stylesheet" href="//cdn.materialdesignicons.com/3.6.95/css/materialdesignicons.min.css">`)}t.applyDropdownOptions();const m=document.querySelector(".widgets-container");const y=m.querySelector(".empty-tip");Observer.childList(m,()=>{if(m.childElementCount<=1){y.classList.add("show")}else{y.classList.remove("show")}});(new n).setupDom();const h=document.querySelectorAll(".gui-settings-widgets-box,.gui-settings-box");const E=document.querySelector(".gui-settings-icon-panel");E.addEventListener("mouseover",()=>{raiseEvent(E,"be:load");h.forEach(e=>e.classList.add("loaded"));o=[...document.querySelectorAll("input[key]")];c=o.filter(e=>e.type==="checkbox");r=o.filter(e=>e.type==="text"&&!e.parentElement.classList.contains("gui-settings-dropdown"));d();f();a();g();u();p();b();new i},{once:true})})()}})();
|
||||
(()=>{return(e,t)=>{const{ThemeColors:n}=t.import("theme-colors");const{SettingsSearch:i}=t.import("settings-search");const{Validator:s}=t.import("text-validate");let o=[];let r=[];let c=[];function l(e){let t=e.nextElementSibling;const n=[];while(t!==null&&!t.classList.contains("category")){n.push(t);t=t.nextElementSibling}return n}function a(){c.forEach(t=>t.value=e[t.getAttribute("key")]);r.forEach(t=>t.checked=e[t.getAttribute("key")])}function d(){document.querySelector(".gui-settings-mask").addEventListener("click",()=>{document.querySelectorAll(".gui-settings-widgets-box,.gui-settings-box,.gui-settings-mask,.bilibili-evolved-about").forEach(e=>e.classList.remove("opened"))});c.forEach(t=>{t.setAttribute("placeholder",e[t.getAttribute("key")])});document.querySelectorAll(".gui-settings-content ul li.category").forEach(e=>{e.addEventListener("click",e=>{const t=document.querySelector(".gui-settings-search");if(t.value!==""){t.value="";raiseEvent(t,"input")}e.currentTarget.classList.toggle("folded");l(e.currentTarget).forEach(e=>e.classList.toggle("folded"))})});document.querySelectorAll(".gui-settings-dropdown>input").forEach(e=>{e.addEventListener("click",e=>{e.currentTarget.parentElement.classList.toggle("opened")})})}function u(){r.forEach(t=>{t.addEventListener("change",()=>{const n=t.getAttribute("key");const i=t.checked;e[n]=i})});c.forEach(t=>{t.addEventListener("change",()=>{const n=t.getAttribute("key");const i=s.getValidator(n).validate(t.value);e[n]=i;t.value=i})})}function g(){const e=o.map(e=>[e.getAttribute("dependencies").split(" ").map(e=>o.find(t=>t.getAttribute("key")===e)),e]);const t=e=>e.nodeName.toUpperCase()==="LI"?e:t(e.parentElement);e.forEach(([e,n])=>{if(e[0]===undefined){return}const i=()=>{if(e.every(e=>e.checked)){t(n).classList.remove("disabled")}else{t(n).classList.add("disabled")}};e.forEach(e=>e.addEventListener("change",i));i()})}function f(){if(typeof offlineData!=="undefined"){}}function b(){if(!CSS.supports("backdrop-filter","blur(24px)")&&!CSS.supports("-webkit-backdrop-filter","blur(24px)")){o.find(e=>e.getAttribute("key")==="blurVideoControl").disabled=true;e.blurVideoControl=false}if(window.devicePixelRatio===1){o.find(e=>e.getAttribute("key")==="harunaScale").disabled=true;o.find(e=>e.getAttribute("key")==="imageResolution").disabled=true;e.harunaScale=false;e.imageResolution=false}}function p(){for(const[e,t]of Object.entries(Resource.displayNames)){const n=o.find(t=>t.getAttribute("key")===e);if(!n){continue}switch(n.type){case"checkbox":n.nextElementSibling.nextElementSibling.innerHTML=t;break;case"text":const e=n.parentElement;if(e.classList.contains("gui-settings-textbox-container")){n.previousElementSibling.innerHTML=t}else if(e.classList.contains("gui-settings-dropdown")){e.previousElementSibling.innerHTML=t}break;default:break}}}(async()=>{t.applyStyle("guiSettingsStyle");t.applyImportantStyle("iconsStyle");document.body.classList.add("round-corner");const e=document.body&&unsafeWindow.parent.window!==unsafeWindow;if(e){document.querySelector(".gui-settings-icon-panel").style.display="none"}const s=t.data.guiSettingsHtml.text;document.body.insertAdjacentHTML("beforeend",s);const{style:l}=await t.importAsync("mdi");if(!l){document.body.insertAdjacentHTML("afterbegin",`<link rel="stylesheet" href="//cdn.materialdesignicons.com/3.6.95/css/materialdesignicons.min.css">`)}t.applyDropdownOptions();const m=document.querySelector(".widgets-container");const y=m.querySelector(".empty-tip");Observer.childList(m,()=>{if(m.childElementCount<=1){y.classList.add("show")}else{y.classList.remove("show")}});(new n).setupDom();const h=document.querySelectorAll(".gui-settings-widgets-box,.gui-settings-box");const E=document.querySelector(".gui-settings-icon-panel");E.addEventListener("mouseover",()=>{raiseEvent(E,"be:load");raiseEvent(dq(".bilibili-evolved-about"),"be:about-load");h.forEach(e=>e.classList.add("loaded"));o=[...document.querySelectorAll("input[key]")];r=o.filter(e=>e.type==="checkbox");c=o.filter(e=>e.type==="text"&&!e.parentElement.classList.contains("gui-settings-dropdown"));d();f();a();g();u();b();p();new i},{once:true})})()}})();
|
||||
2
min/screenshot.min.js
vendored
2
min/screenshot.min.js
vendored
File diff suppressed because one or more lines are too long
2
min/settings-side-bar.min.js
vendored
2
min/settings-side-bar.min.js
vendored
@ -1 +1 @@
|
||||
(()=>{return(e,t)=>{if(document.querySelector(".gui-settings-icon-panel")===null){document.body.insertAdjacentHTML("beforeend",`\n <div class='gui-settings-icon-panel icons-enabled'>\n <div class='gui-settings-widgets' title='附加功能'>\n <i class="icon-widgets"></i>\n </div>\n <div class='gui-settings' title='设置'>\n <i class="icon-settings"></i>\n </div>\n </div>`);dq(".gui-settings").addEventListener("click",e=>{if(e.shiftKey===false){dqa(".gui-settings-box,.gui-settings-mask").forEach(e=>e.classList.add("opened"))}else{dqa(".bilibili-evolved-about,.gui-settings-mask").forEach(e=>e.classList.add("opened"));raiseEvent(document.querySelector(".bilibili-evolved-about"),"be:about-load")}});dq(".gui-settings-widgets").addEventListener("click",e=>{if(e.shiftKey===false){dqa(".gui-settings-widgets-box,.gui-settings-mask").forEach(e=>e.classList.add("opened"))}else{debugger}});const e=dq(".gui-settings-icon-panel .gui-settings-widgets>i");const t=dq(".gui-settings-icon-panel .gui-settings>i");let i=false;let s=false;const n=()=>{t.classList.remove("icon-info");t.classList.add("icon-settings");t.parentElement.title="设置";e.classList.remove("icon-time");e.classList.add("icon-widgets");e.parentElement.title="附加功能";i=false;s=false};const d=()=>{t.classList.remove("icon-settings");t.classList.add("icon-info");t.parentElement.title="关于";e.classList.remove("icon-widgets");e.classList.add("icon-time");e.parentElement.title="「ザ・ワールド」";if(!i){document.body.addEventListener("keyup",n,{once:true});i=true}if(!s){window.addEventListener("blur",n,{once:true});s=true}};document.body.addEventListener("keydown",e=>{if(document.activeElement&&["input","textarea"].includes(document.activeElement.nodeName.toLowerCase())){return}if(e.shiftKey===true){d()}})}const i=(t=e.sideBarOffset)=>{document.body.style.setProperty("--side-bar-offset",t+"%")};addSettingsListener("sideBarOffset",i);i()}})();
|
||||
(()=>{return(e,t)=>{if(document.querySelector(".gui-settings-icon-panel")===null){document.body.insertAdjacentHTML("beforeend",`\n <div class='gui-settings-icon-panel icons-enabled'>\n <div class='gui-settings-widgets' title='附加功能'>\n <i class="icon-widgets"></i>\n </div>\n <div class='gui-settings' title='设置'>\n <i class="icon-settings"></i>\n </div>\n </div>`);dq(".gui-settings").addEventListener("click",e=>{if(e.shiftKey===false){dqa(".gui-settings-box,.gui-settings-mask").forEach(e=>e.classList.add("opened"))}else{dqa(".bilibili-evolved-about,.gui-settings-mask").forEach(e=>e.classList.add("opened"))}});dq(".gui-settings-widgets").addEventListener("click",e=>{if(e.shiftKey===false){dqa(".gui-settings-widgets-box,.gui-settings-mask").forEach(e=>e.classList.add("opened"))}else{debugger}});const e=dq(".gui-settings-icon-panel .gui-settings-widgets>i");const t=dq(".gui-settings-icon-panel .gui-settings>i");let s=false;let i=false;const n=()=>{t.classList.remove("icon-info");t.classList.add("icon-settings");t.parentElement.title="设置";e.classList.remove("icon-time");e.classList.add("icon-widgets");e.parentElement.title="附加功能";s=false;i=false};const d=()=>{t.classList.remove("icon-settings");t.classList.add("icon-info");t.parentElement.title="关于";e.classList.remove("icon-widgets");e.classList.add("icon-time");e.parentElement.title="「ザ・ワールド」";if(!s){document.body.addEventListener("keyup",n,{once:true});s=true}if(!i){window.addEventListener("blur",n,{once:true});i=true}};document.body.addEventListener("keydown",e=>{if(document.activeElement&&["input","textarea"].includes(document.activeElement.nodeName.toLowerCase())){return}if(e.shiftKey===true){d()}})}const s=(t=e.sideBarOffset)=>{document.body.style.setProperty("--side-bar-offset",t+"%")};addSettingsListener("sideBarOffset",s);s()}})();
|
||||
2
min/toast.min.js
vendored
2
min/toast.min.js
vendored
@ -1 +1 @@
|
||||
(()=>{return(t,s)=>{var e;(function(t){t["Default"]="default";t["Info"]="info";t["Success"]="success";t["Error"]="error"})(e||(e={}));class a{constructor(t="",s="",a=e.Default){this.creationTime=new Date;this.type=a;this.message=t;this.title=s;this.duration=3e3}show(){r.cards.splice(0,0,this);if(this.duration!==undefined){setTimeout(()=>this.dismiss(),this.duration)}}dismiss(){if(r.cards.includes(this)){r.cards.splice(r.cards.indexOf(this),1)}}get element(){return dq(`.toast-card[key='${this.key}']`)}get key(){return this.creationTime.toISOString()}static get container(){return document.querySelector(".toast-card-container")}static createToastContainer(){if(!document.querySelector(".toast-card-container")){document.body.insertAdjacentHTML("beforeend",`\n <transition-group class="toast-card-container" name="toast-card-container" tag="div">\n <toast-card v-for="card of cards" v-bind:key="card.key" v-bind:card="card"></toast-card>\n </transition-group>`)}}static internalShow(t,s,e,r){const n=new a(t,s,r);n.duration=e;n.show();return n}static show(t,s,a){return this.internalShow(t,s,a,e.Default)}static info(t,s,a){return this.internalShow(t,s,a,e.Info)}static success(t,s,a){return this.internalShow(t,s,a,e.Success)}static error(t,s,a){return this.internalShow(t,s,a,e.Error)}}s.applyStyle("toastStyle");Vue.component("toast-card",{props:["card"],template:`\n <div class="toast-card icons-enabled visible" v-bind:class="'toast-' + card.type">\n <div class="toast-card-border"></div>\n <div class="toast-card-header">\n <h1 class="toast-card-title">{{card.title}}</h1>\n <div class="toast-card-dismiss" v-on:click="card.dismiss()">\n <svg style="width:22px;height:22px" viewBox="0 0 24 24">\n <path\n d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />\n </svg>\n </div>\n </div>\n <div class="toast-card-message" v-html="card.message"></div>\n </div>\n `});a.createToastContainer();const r=new Vue({el:".toast-card-container",data:{cards:[]}});return{export:a}}})();
|
||||
(()=>{return(t,s)=>{var a;(function(t){t["Default"]="default";t["Info"]="info";t["Success"]="success";t["Error"]="error"})(a||(a={}));let e;class r{constructor(t="",s="",e=a.Default){this.creationTime=new Date;this.type=e;this.message=t;this.title=s;this.duration=3e3}show(){r.containerVM.cards.splice(0,0,this);if(this.duration!==undefined){setTimeout(()=>this.dismiss(),this.duration)}}dismiss(){if(r.containerVM.cards.includes(this)){r.containerVM.cards.splice(r.containerVM.cards.indexOf(this),1)}}get element(){return dq(`.toast-card[key='${this.key}']`)}get key(){return this.creationTime.toISOString()}static get containerVM(){if(!e){r.createToastContainer()}return e}static createToastContainer(){if(!document.querySelector(".toast-card-container")){document.body.insertAdjacentHTML("beforeend",`\n <transition-group class="toast-card-container" name="toast-card-container" tag="div">\n <toast-card v-for="card of cards" v-bind:key="card.key" v-bind:card="card"></toast-card>\n </transition-group>`);e=new Vue({el:".toast-card-container",components:{"toast-card":{props:["card"],template:`\n <div class="toast-card icons-enabled visible" v-bind:class="'toast-' + card.type">\n <div class="toast-card-border"></div>\n <div class="toast-card-header">\n <h1 class="toast-card-title">{{card.title}}</h1>\n <div class="toast-card-dismiss" v-on:click="card.dismiss()">\n <svg style="width:22px;height:22px" viewBox="0 0 24 24">\n <path\n d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />\n </svg>\n </div>\n </div>\n <div class="toast-card-message" v-html="card.message"></div>\n </div>\n `}},data:{cards:[]}})}}static internalShow(t,s,a,e){const n=new r(t,s,e);n.duration=a;n.show();return n}static show(t,s,e){return this.internalShow(t,s,e,a.Default)}static info(t,s,e){return this.internalShow(t,s,e,a.Info)}static success(t,s,e){return this.internalShow(t,s,e,a.Success)}static error(t,s,e){return this.internalShow(t,s,e,a.Error)}}s.applyStyle("toastStyle");return{export:r}}})();
|
||||
@ -1,114 +1,114 @@
|
||||
(async () => {
|
||||
const html = await import("aboutHtml")
|
||||
document.body.insertAdjacentHTML('beforeend', html)
|
||||
const nameSorter = (a, b) => a.charCodeAt(0) - b.charCodeAt(0)
|
||||
const userSorter = (a, b) => nameSorter(a.name, b.name)
|
||||
const clientTypeMatch = GM_info.script.name.match(/Bilibili Evolved \((.*)\)/)
|
||||
const clientType = clientTypeMatch ? clientTypeMatch[1] : 'Stable'
|
||||
new Vue({
|
||||
el: '.bilibili-evolved-about',
|
||||
data: {
|
||||
version: settings.currentVersion,
|
||||
clientType,
|
||||
logoImage: null,
|
||||
logoImageDark: null,
|
||||
branch: null,
|
||||
authors: [
|
||||
{
|
||||
name: 'Grant Howard',
|
||||
link: 'https://github.com/the1812'
|
||||
},
|
||||
{
|
||||
name: 'Coulomb-G',
|
||||
link: 'https://github.com/Coulomb-G'
|
||||
}
|
||||
],
|
||||
contributors: [
|
||||
{
|
||||
name: 'PleiadeSubaru',
|
||||
link: 'https://github.com/Etherrrr'
|
||||
}
|
||||
].sort(userSorter),
|
||||
fetching: true,
|
||||
participants: [],
|
||||
websites: [
|
||||
{
|
||||
name: 'GitHub',
|
||||
link: 'https://github.com/the1812/Bilibili-Evolved/'
|
||||
},
|
||||
{
|
||||
name: 'Greasy Fork',
|
||||
link: 'https://greasyfork.org/zh-CN/scripts/373563-bilibili-evolved'
|
||||
}
|
||||
],
|
||||
components: [
|
||||
{
|
||||
name: 'Vue.js',
|
||||
link: 'https://cn.vuejs.org/index.html'
|
||||
},
|
||||
{
|
||||
name: 'JSZip',
|
||||
link: 'https://stuk.github.io/jszip/'
|
||||
},
|
||||
{
|
||||
name: 'jQuery',
|
||||
link: 'http://jquery.com/'
|
||||
},
|
||||
{
|
||||
name: 'debounce',
|
||||
link: 'https://github.com/component/debounce/'
|
||||
},
|
||||
{
|
||||
name: 'Slip.js',
|
||||
link: 'https://github.com/kornelski/slip'
|
||||
},
|
||||
{
|
||||
name: 'MDI',
|
||||
link: 'https://materialdesignicons.com'
|
||||
}
|
||||
]
|
||||
},
|
||||
mounted () {
|
||||
document.querySelector('.bilibili-evolved-about').addEventListener('be:about-load', () => {
|
||||
this.init()
|
||||
}, { once: true })
|
||||
},
|
||||
methods: {
|
||||
async getLogos() {
|
||||
this.logoImage = await Ajax.getText(`https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/images/bilibili-evolved-wide.svg`)
|
||||
this.logoImageDark = await Ajax.getText(`https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/images/bilibili-evolved-wide-dark.svg`)
|
||||
document.querySelector('.bilibili-evolved-about').addEventListener('be:about-load', () => {
|
||||
const nameSorter = (a, b) => a.charCodeAt(0) - b.charCodeAt(0)
|
||||
const userSorter = (a, b) => nameSorter(a.name, b.name)
|
||||
const clientTypeMatch = GM_info.script.name.match(/Bilibili Evolved \((.*)\)/)
|
||||
const clientType = clientTypeMatch ? clientTypeMatch[1] : 'Stable'
|
||||
new Vue({
|
||||
el: '.bilibili-evolved-about',
|
||||
data: {
|
||||
version: settings.currentVersion,
|
||||
clientType,
|
||||
logoImage: null,
|
||||
logoImageDark: null,
|
||||
branch: null,
|
||||
authors: [
|
||||
{
|
||||
name: 'Grant Howard',
|
||||
link: 'https://github.com/the1812'
|
||||
},
|
||||
{
|
||||
name: 'Coulomb-G',
|
||||
link: 'https://github.com/Coulomb-G'
|
||||
}
|
||||
],
|
||||
contributors: [
|
||||
{
|
||||
name: 'PleiadeSubaru',
|
||||
link: 'https://github.com/Etherrrr'
|
||||
}
|
||||
].sort(userSorter),
|
||||
fetching: true,
|
||||
participants: [],
|
||||
websites: [
|
||||
{
|
||||
name: 'GitHub',
|
||||
link: 'https://github.com/the1812/Bilibili-Evolved/'
|
||||
},
|
||||
{
|
||||
name: 'Greasy Fork',
|
||||
link: 'https://greasyfork.org/zh-CN/scripts/373563-bilibili-evolved'
|
||||
}
|
||||
],
|
||||
components: [
|
||||
{
|
||||
name: 'Vue.js',
|
||||
link: 'https://cn.vuejs.org/index.html'
|
||||
},
|
||||
{
|
||||
name: 'JSZip',
|
||||
link: 'https://stuk.github.io/jszip/'
|
||||
},
|
||||
{
|
||||
name: 'jQuery',
|
||||
link: 'http://jquery.com/'
|
||||
},
|
||||
{
|
||||
name: 'debounce',
|
||||
link: 'https://github.com/component/debounce/'
|
||||
},
|
||||
{
|
||||
name: 'Slip.js',
|
||||
link: 'https://github.com/kornelski/slip'
|
||||
},
|
||||
{
|
||||
name: 'MDI',
|
||||
link: 'https://materialdesignicons.com'
|
||||
}
|
||||
]
|
||||
},
|
||||
async init () {
|
||||
this.branch = /Preview|Local/.test(clientType) ? 'preview' : 'master'
|
||||
this.getLogos()
|
||||
const allParticipants = new Set()
|
||||
let issues = []
|
||||
let page = 1
|
||||
do {
|
||||
issues = await Ajax.getJson(`https://api.github.com/repos/the1812/Bilibili-Evolved/issues?state=all&direction=asc&per_page=100&page=${page}`)
|
||||
.catch(() => {
|
||||
issues = [{
|
||||
name: '电波无法到达(´・_・`)',
|
||||
link: null
|
||||
}]
|
||||
})
|
||||
page++
|
||||
for (const issue of issues) {
|
||||
allParticipants.add(issue.user.login)
|
||||
mounted () {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
async getLogos () {
|
||||
this.logoImage = await Ajax.getText(`https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/images/bilibili-evolved-wide.svg`)
|
||||
this.logoImageDark = await Ajax.getText(`https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/images/bilibili-evolved-wide-dark.svg`)
|
||||
},
|
||||
async init () {
|
||||
this.branch = /Preview|Local/.test(clientType) ? 'preview' : 'master'
|
||||
this.getLogos()
|
||||
const allParticipants = new Set()
|
||||
let issues = []
|
||||
let page = 1
|
||||
do {
|
||||
issues = await Ajax.getJson(`https://api.github.com/repos/the1812/Bilibili-Evolved/issues?state=all&direction=asc&per_page=100&page=${page}`)
|
||||
.catch(() => {
|
||||
issues = [{
|
||||
name: '电波无法到达(´・_・`)',
|
||||
link: null
|
||||
}]
|
||||
})
|
||||
page++
|
||||
for (const issue of issues) {
|
||||
allParticipants.add(issue.user.login)
|
||||
}
|
||||
}
|
||||
while (issues.length > 0)
|
||||
this.participants = [...allParticipants].map(name => {
|
||||
return {
|
||||
name,
|
||||
link: `https://github.com/${name}`
|
||||
}
|
||||
}).filter(({ link }) => {
|
||||
return !this.authors.some(it => it.link === link) &&
|
||||
!this.contributors.some(it => it.link === link)
|
||||
}).sort(userSorter)
|
||||
this.fetching = false
|
||||
}
|
||||
while (issues.length > 0)
|
||||
this.participants = [...allParticipants].map(name => {
|
||||
return {
|
||||
name,
|
||||
link: `https://github.com/${name}`
|
||||
}
|
||||
}).filter(({ link }) => {
|
||||
return !this.authors.some(it => it.link === link) &&
|
||||
!this.contributors.some(it => it.link === link)
|
||||
}).sort(userSorter)
|
||||
this.fetching = false
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}, { once: true })
|
||||
})()
|
||||
|
||||
@ -157,6 +157,7 @@ function setDisplayNames () {
|
||||
const iconPanel = document.querySelector('.gui-settings-icon-panel')
|
||||
iconPanel.addEventListener('mouseover', () => {
|
||||
raiseEvent(iconPanel, 'be:load')
|
||||
raiseEvent(dq('.bilibili-evolved-about'), 'be:about-load')
|
||||
boxes.forEach(it => it.classList.add('loaded'))
|
||||
inputs = [...document.querySelectorAll('input[key]')]
|
||||
checkBoxes = inputs.filter(it => it.type === 'checkbox')
|
||||
|
||||
@ -13,7 +13,7 @@ if (document.querySelector('.gui-settings-icon-panel') === null) {
|
||||
dqa('.gui-settings-box,.gui-settings-mask').forEach(it => it.classList.add('opened'))
|
||||
} else {
|
||||
dqa('.bilibili-evolved-about,.gui-settings-mask').forEach(it => it.classList.add('opened'))
|
||||
raiseEvent(document.querySelector('.bilibili-evolved-about'), 'be:about-load')
|
||||
// raiseEvent(document.querySelector('.bilibili-evolved-about'), 'be:about-load')
|
||||
}
|
||||
})
|
||||
dq('.gui-settings-widgets').addEventListener('click', e => {
|
||||
|
||||
@ -4,6 +4,7 @@ export enum ToastType {
|
||||
Success = 'success',
|
||||
Error = 'error',
|
||||
}
|
||||
let container: { cards: Toast[] }
|
||||
export class Toast {
|
||||
type: ToastType
|
||||
message: string
|
||||
@ -17,14 +18,14 @@ export class Toast {
|
||||
this.duration = 3000
|
||||
}
|
||||
show() {
|
||||
container.cards.splice(0, 0, this)
|
||||
Toast.containerVM.cards.splice(0, 0, this)
|
||||
if (this.duration !== undefined) {
|
||||
setTimeout(() => this.dismiss(), this.duration)
|
||||
}
|
||||
}
|
||||
dismiss() {
|
||||
if (container.cards.includes(this)) {
|
||||
container.cards.splice(container.cards.indexOf(this), 1)
|
||||
if (Toast.containerVM.cards.includes(this)) {
|
||||
Toast.containerVM.cards.splice(Toast.containerVM.cards.indexOf(this), 1)
|
||||
}
|
||||
}
|
||||
get element() {
|
||||
@ -33,8 +34,11 @@ export class Toast {
|
||||
get key() {
|
||||
return this.creationTime.toISOString()
|
||||
}
|
||||
static get container() {
|
||||
return document.querySelector('.toast-card-container')
|
||||
static get containerVM() {
|
||||
if (!container) {
|
||||
Toast.createToastContainer()
|
||||
}
|
||||
return container
|
||||
}
|
||||
static createToastContainer() {
|
||||
if (!document.querySelector('.toast-card-container')) {
|
||||
@ -42,6 +46,32 @@ export class Toast {
|
||||
<transition-group class="toast-card-container" name="toast-card-container" tag="div">
|
||||
<toast-card v-for="card of cards" v-bind:key="card.key" v-bind:card="card"></toast-card>
|
||||
</transition-group>`)
|
||||
container = new Vue({
|
||||
el: '.toast-card-container',
|
||||
components: {
|
||||
'toast-card': {
|
||||
props: ['card'],
|
||||
template: /*html*/`
|
||||
<div class="toast-card icons-enabled visible" v-bind:class="'toast-' + card.type">
|
||||
<div class="toast-card-border"></div>
|
||||
<div class="toast-card-header">
|
||||
<h1 class="toast-card-title">{{card.title}}</h1>
|
||||
<div class="toast-card-dismiss" v-on:click="card.dismiss()">
|
||||
<svg style="width:22px;height:22px" viewBox="0 0 24 24">
|
||||
<path
|
||||
d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="toast-card-message" v-html="card.message"></div>
|
||||
</div>
|
||||
`,
|
||||
}
|
||||
},
|
||||
data: {
|
||||
cards: [] as Toast[]
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
private static internalShow(message: string, title: string, duration: number | undefined, type: ToastType) {
|
||||
@ -65,32 +95,6 @@ export class Toast {
|
||||
}
|
||||
|
||||
resources.applyStyle('toastStyle')
|
||||
Vue.component('toast-card', {
|
||||
props: ['card'],
|
||||
template: /*html*/`
|
||||
<div class="toast-card icons-enabled visible" v-bind:class="'toast-' + card.type">
|
||||
<div class="toast-card-border"></div>
|
||||
<div class="toast-card-header">
|
||||
<h1 class="toast-card-title">{{card.title}}</h1>
|
||||
<div class="toast-card-dismiss" v-on:click="card.dismiss()">
|
||||
<svg style="width:22px;height:22px" viewBox="0 0 24 24">
|
||||
<path
|
||||
d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="toast-card-message" v-html="card.message"></div>
|
||||
</div>
|
||||
`,
|
||||
})
|
||||
Toast.createToastContainer()
|
||||
const container = new Vue({
|
||||
el: '.toast-card-container',
|
||||
data: {
|
||||
cards: [] as Toast[]
|
||||
},
|
||||
})
|
||||
|
||||
export default {
|
||||
export: Toast
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { getFriendlyTitle } from '../title';
|
||||
|
||||
import { getFriendlyTitle } from '../title'
|
||||
const canvas = document.createElement("canvas");
|
||||
class Screenshot {
|
||||
video: HTMLVideoElement;
|
||||
@ -62,96 +61,96 @@ export const takeScreenshot = (video: HTMLVideoElement, withDanmaku = false) =>
|
||||
const time = video.currentTime
|
||||
return new Screenshot(video, time, withDanmaku)
|
||||
}
|
||||
resources.applyStyle("videoScreenshotStyle");
|
||||
document.body.insertAdjacentHTML("beforeend", /*html*/`
|
||||
<div class="video-screenshot-container">
|
||||
<transition-group class="video-screenshot-list" name="video-screenshot-list" tag="div">
|
||||
<video-screenshot v-for="screenshot of screenshots" v-bind:filename="screenshot.filename"
|
||||
v-bind:object-url="screenshot.url" v-bind:time="screenshot.time" v-on:discard="discard(screenshot)"
|
||||
v-bind:key="screenshot.id"></video-screenshot>
|
||||
</transition-group>
|
||||
<div v-show="showBatch" class="video-screenshot-batch">
|
||||
<a class="batch-link" style="display:none" v-bind:download="batchFilename"></a>
|
||||
<button v-on:click="saveAll">
|
||||
<i class="mdi mdi-content-save"></i>全部保存
|
||||
</button>
|
||||
<button v-on:click="discardAll">
|
||||
<i class="mdi mdi-delete-forever"></i>全部丢弃
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
Vue.component("video-screenshot", {
|
||||
props: {
|
||||
objectUrl: String,
|
||||
filename: String,
|
||||
time: String,
|
||||
},
|
||||
template: /*html*/`
|
||||
<div class="video-screenshot-thumbnail">
|
||||
<img v-if="objectUrl" v-bind:src="objectUrl">
|
||||
<div class="mask" v-if="objectUrl">
|
||||
<a class="link" style="display:none" v-bind:href="objectUrl" v-bind:download="filename"></a>
|
||||
<button v-on:click="save" class="save" title="保存"><i class="mdi mdi-content-save-outline"></i></button>
|
||||
<button v-on:click="discard" title="丢弃" class="discard"><i class="mdi mdi-delete-forever-outline"></i></button>
|
||||
<span class="time">{{time}}</span>
|
||||
</div>
|
||||
<div class="loading" v-else>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
methods: {
|
||||
discard() {
|
||||
this.$emit("discard");
|
||||
},
|
||||
save() {
|
||||
this.$el.querySelector(".link").click();
|
||||
this.discard();
|
||||
},
|
||||
},
|
||||
});
|
||||
const screenShotsList = new Vue({
|
||||
el: ".video-screenshot-container",
|
||||
data: {
|
||||
screenshots: [] as Screenshot[],
|
||||
batchFilename: getFriendlyTitle() + ".zip",
|
||||
},
|
||||
methods: {
|
||||
discard(screenshot: Screenshot) {
|
||||
this.screenshots.splice(this.screenshots.indexOf(screenshot), 1);
|
||||
screenshot.revoke();
|
||||
},
|
||||
async saveAll() {
|
||||
const zip = new JSZip();
|
||||
this.screenshots.forEach((it: Screenshot) => {
|
||||
zip.file(it.filename, it.blob, {
|
||||
date: new Date(it.timeStamp),
|
||||
});
|
||||
});
|
||||
const blob = await zip.generateAsync({ type: "blob" });
|
||||
const link = this.$el.querySelector(".batch-link");
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.click();
|
||||
URL.revokeObjectURL(link.href);
|
||||
link.href = "";
|
||||
this.discardAll();
|
||||
},
|
||||
discardAll() {
|
||||
this.screenshots.forEach((it: Screenshot) => it.revoke());
|
||||
this.screenshots = [];
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
showBatch() {
|
||||
return this.screenshots.length >= 2;
|
||||
},
|
||||
},
|
||||
});
|
||||
const buttonHtml = /*html*/`
|
||||
<div class="video-take-screenshot" title="截图">
|
||||
<span><i class="mdi mdi-camera"></i></span>
|
||||
</div>`;
|
||||
let screenShotsList: { screenshots: Screenshot[] } = { screenshots: [] }
|
||||
Observer.videoChange(async () => {
|
||||
if (!dq('.video-screenshot-container')) {
|
||||
resources.applyStyle("videoScreenshotStyle");
|
||||
document.body.insertAdjacentHTML("beforeend", /*html*/`
|
||||
<div class="video-screenshot-container">
|
||||
<transition-group class="video-screenshot-list" name="video-screenshot-list" tag="div">
|
||||
<video-screenshot v-for="screenshot of screenshots" v-bind:filename="screenshot.filename"
|
||||
v-bind:object-url="screenshot.url" v-bind:time="screenshot.time" v-on:discard="discard(screenshot)"
|
||||
v-bind:key="screenshot.id"></video-screenshot>
|
||||
</transition-group>
|
||||
<div v-show="showBatch" class="video-screenshot-batch">
|
||||
<a class="batch-link" style="display:none" v-bind:download="batchFilename"></a>
|
||||
<button v-on:click="saveAll">
|
||||
<i class="mdi mdi-content-save"></i>全部保存
|
||||
</button>
|
||||
<button v-on:click="discardAll">
|
||||
<i class="mdi mdi-delete-forever"></i>全部丢弃
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
Vue.component("video-screenshot", {
|
||||
props: {
|
||||
objectUrl: String,
|
||||
filename: String,
|
||||
time: String,
|
||||
},
|
||||
template: /*html*/`
|
||||
<div class="video-screenshot-thumbnail">
|
||||
<img v-if="objectUrl" v-bind:src="objectUrl">
|
||||
<div class="mask" v-if="objectUrl">
|
||||
<a class="link" style="display:none" v-bind:href="objectUrl" v-bind:download="filename"></a>
|
||||
<button v-on:click="save" class="save" title="保存"><i class="mdi mdi-content-save-outline"></i></button>
|
||||
<button v-on:click="discard" title="丢弃" class="discard"><i class="mdi mdi-delete-forever-outline"></i></button>
|
||||
<span class="time">{{time}}</span>
|
||||
</div>
|
||||
<div class="loading" v-else>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
methods: {
|
||||
discard() {
|
||||
this.$emit("discard");
|
||||
},
|
||||
save() {
|
||||
this.$el.querySelector(".link").click();
|
||||
this.discard();
|
||||
},
|
||||
},
|
||||
});
|
||||
screenShotsList = new Vue({
|
||||
el: ".video-screenshot-container",
|
||||
data: {
|
||||
screenshots: [] as Screenshot[],
|
||||
batchFilename: getFriendlyTitle() + ".zip",
|
||||
},
|
||||
methods: {
|
||||
discard(screenshot: Screenshot) {
|
||||
this.screenshots.splice(this.screenshots.indexOf(screenshot), 1);
|
||||
screenshot.revoke();
|
||||
},
|
||||
async saveAll() {
|
||||
const zip = new JSZip();
|
||||
this.screenshots.forEach((it: Screenshot) => {
|
||||
zip.file(it.filename, it.blob, {
|
||||
date: new Date(it.timeStamp),
|
||||
});
|
||||
});
|
||||
const blob = await zip.generateAsync({ type: "blob" });
|
||||
const link = this.$el.querySelector(".batch-link");
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.click();
|
||||
URL.revokeObjectURL(link.href);
|
||||
link.href = "";
|
||||
this.discardAll();
|
||||
},
|
||||
discardAll() {
|
||||
this.screenshots.forEach((it: Screenshot) => it.revoke());
|
||||
this.screenshots = [];
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
showBatch() {
|
||||
return this.screenshots.length >= 2;
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const video = await SpinQuery.select("#bofqi video") as HTMLVideoElement;
|
||||
if (video === null) {
|
||||
return;
|
||||
@ -160,6 +159,11 @@ Observer.videoChange(async () => {
|
||||
if (time === null || document.querySelector(".video-take-screenshot")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const buttonHtml = /*html*/`
|
||||
<div class="video-take-screenshot" title="截图">
|
||||
<span><i class="mdi mdi-camera"></i></span>
|
||||
</div>`;
|
||||
time.insertAdjacentHTML("afterend", buttonHtml);
|
||||
const screenshotButton = document.querySelector(".video-take-screenshot") as HTMLElement;
|
||||
screenshotButton.addEventListener("click", async e => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user