Redesign user info panel (not logged in)

This commit is contained in:
the1812 2019-06-15 10:47:16 +08:00
parent c2e0d1573f
commit 670eb6b75a
9 changed files with 1058 additions and 1233 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -139,8 +139,8 @@ const customNavbarDefaultOrders = {
favoritesList: 16, favoritesList: 16,
historyList: 17, historyList: 17,
upload: 18, upload: 18,
blank3: 19 blank3: 19,
}; }
const settings = { const settings = {
useDarkStyle: false, useDarkStyle: false,
compactLayout: false, compactLayout: false,
@ -153,8 +153,8 @@ const settings = {
touchVideoPlayer: false, touchVideoPlayer: false,
customControlBackgroundOpacity: 0.64, customControlBackgroundOpacity: 0.64,
customControlBackground: true, customControlBackground: true,
darkScheduleStart: "18:00", darkScheduleStart: '18:00',
darkScheduleEnd: "6:00", darkScheduleEnd: '6:00',
darkSchedule: false, darkSchedule: false,
blurVideoControl: false, blurVideoControl: false,
toast: true, toast: true,
@ -167,14 +167,14 @@ const settings = {
hideTopSearch: false, hideTopSearch: false,
touchVideoPlayerDoubleTapControl: false, touchVideoPlayerDoubleTapControl: false,
touchVideoPlayerAnimation: false, touchVideoPlayerAnimation: false,
customStyleColor: "#00A0D8", customStyleColor: '#00A0D8',
preserveRank: true, preserveRank: true,
blurBackgroundOpacity: 0.382, blurBackgroundOpacity: 0.382,
useDefaultPlayerMode: false, useDefaultPlayerMode: false,
applyPlayerModeOnPlay: true, applyPlayerModeOnPlay: true,
defaultPlayerMode: "常规", defaultPlayerMode: '常规',
useDefaultVideoQuality: false, useDefaultVideoQuality: false,
defaultVideoQuality: "自动", defaultVideoQuality: '自动',
useDefaultDanmakuSettings: false, useDefaultDanmakuSettings: false,
enableDanmaku: true, enableDanmaku: true,
rememberDanmakuSettings: false, rememberDanmakuSettings: false,
@ -182,8 +182,8 @@ const settings = {
subtitlesPreserve: false, subtitlesPreserve: false,
smartMask: false, smartMask: false,
}, },
defaultPlayerLayout: "新版", defaultPlayerLayout: '新版',
defaultBangumiLayout: "旧版", defaultBangumiLayout: '旧版',
useDefaultPlayerLayout: false, useDefaultPlayerLayout: false,
skipChargeList: false, skipChargeList: false,
comboLike: false, comboLike: false,
@ -198,10 +198,10 @@ const settings = {
framePlayback: true, framePlayback: true,
useCommentStyle: true, useCommentStyle: true,
imageResolution: false, imageResolution: false,
imageResolutionScale: "auto", imageResolutionScale: 'auto',
toastInternalError: false, toastInternalError: false,
i18n: false, i18n: false,
i18nLanguage: "日本語", i18nLanguage: '日本語',
playerFocus: false, playerFocus: false,
playerFocusOffset: -10, playerFocusOffset: -10,
oldTweets: false, oldTweets: false,
@ -234,13 +234,15 @@ const settings = {
hideOldEntry: true, hideOldEntry: true,
videoScreenshot: false, videoScreenshot: false,
hideBangumiReviews: false, hideBangumiReviews: false,
filenameFormat: "[title][ - ep]", filenameFormat: '[title][ - ep]',
sideBarOffset: 0, sideBarOffset: 0,
noLiveAutoplay: false, noLiveAutoplay: false,
hideHomeLive: false, hideHomeLive: false,
noMiniVideoAutoplay: false, noMiniVideoAutoplay: false,
useDefaultVideoSpeed: false,
defaultVideoSpeed: 1,
cache: {}, cache: {},
}; }
const fixedSettings = { const fixedSettings = {
guiSettings: true, guiSettings: true,
viewCover: true, viewCover: true,
@ -255,16 +257,15 @@ const fixedSettings = {
forceWide: false, forceWide: false,
useNewStyle: false, useNewStyle: false,
overrideNavBar: false, overrideNavBar: false,
latestVersionLink: "https://github.com/the1812/Bilibili-Evolved/raw/preview/bilibili-evolved.preview.user.js", latestVersionLink: 'https://github.com/the1812/Bilibili-Evolved/raw/preview/bilibili-evolved.preview.user.js',
currentVersion: GM_info.script.version, currentVersion: GM_info.script.version,
}; }
const settingsChangeHandlers = {}; const settingsChangeHandlers = {}
function addSettingsListener (key, handler, initCall) { function addSettingsListener (key, handler, initCall) {
if (!settingsChangeHandlers[key]) { if (!settingsChangeHandlers[key]) {
settingsChangeHandlers[key] = [handler]; settingsChangeHandlers[key] = [handler]
} } else {
else { settingsChangeHandlers[key].push(handler)
settingsChangeHandlers[key].push(handler);
} }
if (initCall) { if (initCall) {
const value = settings[key] const value = settings[key]
@ -272,81 +273,63 @@ function addSettingsListener (key, handler, initCall) {
} }
} }
function removeSettingsListener (key, handler) { function removeSettingsListener (key, handler) {
const handlers = settingsChangeHandlers[key]; const handlers = settingsChangeHandlers[key]
if (!handlers) { if (!handlers) {
return; return
} }
handlers.splice(handlers.indexOf(handler), 1); handlers.splice(handlers.indexOf(handler), 1)
} }
function loadSettings () { function loadSettings () {
for (const key in fixedSettings) { for (const key in fixedSettings) {
settings[key] = fixedSettings[key]; settings[key] = fixedSettings[key]
GM_setValue(key, fixedSettings[key]); GM_setValue(key, fixedSettings[key])
} }
if (Object.keys(languageCodeToName).includes(navigator.language)) { if (Object.keys(languageCodeToName).includes(navigator.language)) {
settings.i18n = true; settings.i18n = true
settings.i18nLanguage = languageCodeToName[navigator.language]; settings.i18nLanguage = languageCodeToName[navigator.language]
} }
for (const key in settings) { for (const key in settings) {
let value = GM_getValue(key); let value = GM_getValue(key)
if (value === undefined) { if (value === undefined) {
value = settings[key]; value = settings[key]
GM_setValue(key, settings[key]); GM_setValue(key, settings[key])
} } else if (settings[key] !== undefined && value.constructor === Object) {
else if (settings[key] !== undefined && value.constructor === Object) { value = Object.assign(settings[key], value)
value = Object.assign(settings[key], value);
} }
Object.defineProperty(settings, key, { Object.defineProperty(settings, key, {
get () { get () {
return value; return value
}, },
set (newValue) { set (newValue) {
value = newValue; value = newValue
GM_setValue(key, newValue); GM_setValue(key, newValue)
const handlers = settingsChangeHandlers[key]; const handlers = settingsChangeHandlers[key]
if (handlers) { if (handlers) {
if (key === "useDarkStyle") { if (key === 'useDarkStyle') {
setTimeout(() => handlers.forEach(h => h(newValue, value)), 200); setTimeout(() => handlers.forEach(h => h(newValue, value)), 200)
} } else {
else { handlers.forEach(h => h(newValue, value))
handlers.forEach(h => h(newValue, value));
} }
} }
const input = document.querySelector(`input[key=${key}]`); const input = document.querySelector(`input[key=${key}]`)
if (input !== null) { if (input !== null) {
if (input.type === "checkbox") { if (input.type === 'checkbox') {
input.checked = newValue; input.checked = newValue
} } else if (input.type === 'text' && !input.parentElement.classList.contains('gui-settings-dropdown')) {
else if (input.type === "text" && !input.parentElement.classList.contains("gui-settings-dropdown")) { input.value = newValue
input.value = newValue;
} }
} }
}, }
}); })
// if (settings[key] !== undefined && value.constructor === Object)
// {
// settings[key] = Object.assign(settings[key], value);
// }
// else
// {
// settings[key] = value;
// }
} }
} }
function saveSettings (newSettings) { function saveSettings (newSettings) {
// for (const key in settings)
// {
// GM_setValue(key, newSettings[key]);
// }
} }
function onSettingsChange () { function onSettingsChange () {
// for (const key in settings) console.warn('此功能已弃用.')
// { }
// GM_addValueChangeListener(key, change); ;
// }
console.warn("此功能已弃用.");
};
class Ajax class Ajax
{ {
static send(xhr, body, text = true) static send(xhr, body, text = true)

View File

@ -139,8 +139,8 @@ const customNavbarDefaultOrders = {
favoritesList: 16, favoritesList: 16,
historyList: 17, historyList: 17,
upload: 18, upload: 18,
blank3: 19 blank3: 19,
}; }
const settings = { const settings = {
useDarkStyle: false, useDarkStyle: false,
compactLayout: false, compactLayout: false,
@ -153,8 +153,8 @@ const settings = {
touchVideoPlayer: false, touchVideoPlayer: false,
customControlBackgroundOpacity: 0.64, customControlBackgroundOpacity: 0.64,
customControlBackground: true, customControlBackground: true,
darkScheduleStart: "18:00", darkScheduleStart: '18:00',
darkScheduleEnd: "6:00", darkScheduleEnd: '6:00',
darkSchedule: false, darkSchedule: false,
blurVideoControl: false, blurVideoControl: false,
toast: true, toast: true,
@ -167,14 +167,14 @@ const settings = {
hideTopSearch: false, hideTopSearch: false,
touchVideoPlayerDoubleTapControl: false, touchVideoPlayerDoubleTapControl: false,
touchVideoPlayerAnimation: false, touchVideoPlayerAnimation: false,
customStyleColor: "#00A0D8", customStyleColor: '#00A0D8',
preserveRank: true, preserveRank: true,
blurBackgroundOpacity: 0.382, blurBackgroundOpacity: 0.382,
useDefaultPlayerMode: false, useDefaultPlayerMode: false,
applyPlayerModeOnPlay: true, applyPlayerModeOnPlay: true,
defaultPlayerMode: "常规", defaultPlayerMode: '常规',
useDefaultVideoQuality: false, useDefaultVideoQuality: false,
defaultVideoQuality: "自动", defaultVideoQuality: '自动',
useDefaultDanmakuSettings: false, useDefaultDanmakuSettings: false,
enableDanmaku: true, enableDanmaku: true,
rememberDanmakuSettings: false, rememberDanmakuSettings: false,
@ -182,8 +182,8 @@ const settings = {
subtitlesPreserve: false, subtitlesPreserve: false,
smartMask: false, smartMask: false,
}, },
defaultPlayerLayout: "新版", defaultPlayerLayout: '新版',
defaultBangumiLayout: "旧版", defaultBangumiLayout: '旧版',
useDefaultPlayerLayout: false, useDefaultPlayerLayout: false,
skipChargeList: false, skipChargeList: false,
comboLike: false, comboLike: false,
@ -198,10 +198,10 @@ const settings = {
framePlayback: true, framePlayback: true,
useCommentStyle: true, useCommentStyle: true,
imageResolution: false, imageResolution: false,
imageResolutionScale: "auto", imageResolutionScale: 'auto',
toastInternalError: false, toastInternalError: false,
i18n: false, i18n: false,
i18nLanguage: "日本語", i18nLanguage: '日本語',
playerFocus: false, playerFocus: false,
playerFocusOffset: -10, playerFocusOffset: -10,
oldTweets: false, oldTweets: false,
@ -234,13 +234,15 @@ const settings = {
hideOldEntry: true, hideOldEntry: true,
videoScreenshot: false, videoScreenshot: false,
hideBangumiReviews: false, hideBangumiReviews: false,
filenameFormat: "[title][ - ep]", filenameFormat: '[title][ - ep]',
sideBarOffset: 0, sideBarOffset: 0,
noLiveAutoplay: false, noLiveAutoplay: false,
hideHomeLive: false, hideHomeLive: false,
noMiniVideoAutoplay: false, noMiniVideoAutoplay: false,
useDefaultVideoSpeed: false,
defaultVideoSpeed: 1,
cache: {}, cache: {},
}; }
const fixedSettings = { const fixedSettings = {
guiSettings: true, guiSettings: true,
viewCover: true, viewCover: true,
@ -255,16 +257,15 @@ const fixedSettings = {
forceWide: false, forceWide: false,
useNewStyle: false, useNewStyle: false,
overrideNavBar: false, overrideNavBar: false,
latestVersionLink: "https://github.com/the1812/Bilibili-Evolved/raw/master/bilibili-evolved.user.js", latestVersionLink: 'https://github.com/the1812/Bilibili-Evolved/raw/master/bilibili-evolved.user.js',
currentVersion: GM_info.script.version, currentVersion: GM_info.script.version,
}; }
const settingsChangeHandlers = {}; const settingsChangeHandlers = {}
function addSettingsListener (key, handler, initCall) { function addSettingsListener (key, handler, initCall) {
if (!settingsChangeHandlers[key]) { if (!settingsChangeHandlers[key]) {
settingsChangeHandlers[key] = [handler]; settingsChangeHandlers[key] = [handler]
} } else {
else { settingsChangeHandlers[key].push(handler)
settingsChangeHandlers[key].push(handler);
} }
if (initCall) { if (initCall) {
const value = settings[key] const value = settings[key]
@ -272,81 +273,63 @@ function addSettingsListener (key, handler, initCall) {
} }
} }
function removeSettingsListener (key, handler) { function removeSettingsListener (key, handler) {
const handlers = settingsChangeHandlers[key]; const handlers = settingsChangeHandlers[key]
if (!handlers) { if (!handlers) {
return; return
} }
handlers.splice(handlers.indexOf(handler), 1); handlers.splice(handlers.indexOf(handler), 1)
} }
function loadSettings () { function loadSettings () {
for (const key in fixedSettings) { for (const key in fixedSettings) {
settings[key] = fixedSettings[key]; settings[key] = fixedSettings[key]
GM_setValue(key, fixedSettings[key]); GM_setValue(key, fixedSettings[key])
} }
if (Object.keys(languageCodeToName).includes(navigator.language)) { if (Object.keys(languageCodeToName).includes(navigator.language)) {
settings.i18n = true; settings.i18n = true
settings.i18nLanguage = languageCodeToName[navigator.language]; settings.i18nLanguage = languageCodeToName[navigator.language]
} }
for (const key in settings) { for (const key in settings) {
let value = GM_getValue(key); let value = GM_getValue(key)
if (value === undefined) { if (value === undefined) {
value = settings[key]; value = settings[key]
GM_setValue(key, settings[key]); GM_setValue(key, settings[key])
} } else if (settings[key] !== undefined && value.constructor === Object) {
else if (settings[key] !== undefined && value.constructor === Object) { value = Object.assign(settings[key], value)
value = Object.assign(settings[key], value);
} }
Object.defineProperty(settings, key, { Object.defineProperty(settings, key, {
get () { get () {
return value; return value
}, },
set (newValue) { set (newValue) {
value = newValue; value = newValue
GM_setValue(key, newValue); GM_setValue(key, newValue)
const handlers = settingsChangeHandlers[key]; const handlers = settingsChangeHandlers[key]
if (handlers) { if (handlers) {
if (key === "useDarkStyle") { if (key === 'useDarkStyle') {
setTimeout(() => handlers.forEach(h => h(newValue, value)), 200); setTimeout(() => handlers.forEach(h => h(newValue, value)), 200)
} } else {
else { handlers.forEach(h => h(newValue, value))
handlers.forEach(h => h(newValue, value));
} }
} }
const input = document.querySelector(`input[key=${key}]`); const input = document.querySelector(`input[key=${key}]`)
if (input !== null) { if (input !== null) {
if (input.type === "checkbox") { if (input.type === 'checkbox') {
input.checked = newValue; input.checked = newValue
} } else if (input.type === 'text' && !input.parentElement.classList.contains('gui-settings-dropdown')) {
else if (input.type === "text" && !input.parentElement.classList.contains("gui-settings-dropdown")) { input.value = newValue
input.value = newValue;
} }
} }
}, }
}); })
// if (settings[key] !== undefined && value.constructor === Object)
// {
// settings[key] = Object.assign(settings[key], value);
// }
// else
// {
// settings[key] = value;
// }
} }
} }
function saveSettings (newSettings) { function saveSettings (newSettings) {
// for (const key in settings)
// {
// GM_setValue(key, newSettings[key]);
// }
} }
function onSettingsChange () { function onSettingsChange () {
// for (const key in settings) console.warn('此功能已弃用.')
// { }
// GM_addValueChangeListener(key, change); ;
// }
console.warn("此功能已弃用.");
};
class Ajax class Ajax
{ {
static send(xhr, body, text = true) static send(xhr, body, text = true)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
min/index.min.html Normal file
View File

@ -0,0 +1 @@
<!doctypehtml><html lang=en><meta charset=UTF-8><meta name=viewport content="width=device-width,initial-scale=1"><meta http-equiv=X-UA-Compatible content="ie=edge"><title>Document</title><script src=index.js defer=defer type=module></script>

View File

@ -444,7 +444,36 @@ li.nav-item[report-id='playpage_dynamic'] .i-frame,
width: 240px; width: 240px;
font-size: 12px; font-size: 12px;
} }
.user-info-panel>* .user-info-panel .welcome
{
font-size: 16px;
font-weight: bold;
margin: 46px 0 16px 0;
text-align: center;
}
.user-info-panel .grey-button,
.user-info-panel .theme-button
{
align-self: stretch;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
}
.user-info-panel .grey-button
{
background: #EDEDED;
}
.custom-navbar.dark .user-info-panel .grey-button
{
background: #444;
}
.custom-navbar .user-info-panel .theme-button
{
background: var(--theme-color);
color: var(--foreground-color);
}
/* .user-info-panel>*
{ {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -608,7 +637,7 @@ li.nav-item[report-id='playpage_dynamic'] .i-frame,
.custom-navbar .not-logged-in .sign-up:hover .custom-navbar .not-logged-in .sign-up:hover
{ {
background-color: #8884; background-color: #8884;
} } */
.custom-navbar li:hover .user-face, .custom-navbar li:hover .user-face,
.custom-navbar li:hover .user-pendant .custom-navbar li:hover .user-pendant

View File

@ -1,11 +1,9 @@
if (isIframe()) if (isIframe()) {
{
return; return;
} }
document.body.style.setProperty("--navbar-bounds-padding", `0 ${settings.customNavbarBoundsPadding}%`); document.body.style.setProperty("--navbar-bounds-padding", `0 ${settings.customNavbarBoundsPadding}%`);
document.body.style.setProperty("--navbar-blur-opacity", settings.customNavbarBlurOpacity || 0.7); document.body.style.setProperty("--navbar-blur-opacity", settings.customNavbarBlurOpacity || 0.7);
addSettingsListener("customNavbarBlurOpacity", value => addSettingsListener("customNavbarBlurOpacity", value => {
{
document.body.style.setProperty("--navbar-blur-opacity", value); document.body.style.setProperty("--navbar-blur-opacity", value);
}); });
let showWidget = true; let showWidget = true;
@ -17,24 +15,20 @@ const attributes = {
<span>顶栏布局</span> <span>顶栏布局</span>
</div>`, </div>`,
condition: () => showWidget, condition: () => showWidget,
success: async () => success: async () => {
{
await SpinQuery.select(".custom-navbar-settings"); await SpinQuery.select(".custom-navbar-settings");
await import("slip"); await import("slip");
const { debounce } = await import("debounce"); const { debounce } = await import("debounce");
// const customNavbar = document.querySelector(".custom-navbar"); // const customNavbar = document.querySelector(".custom-navbar");
const button = document.querySelector("#custom-navbar-settings"); const button = document.querySelector("#custom-navbar-settings");
button.addEventListener("click", async () => button.addEventListener("click", async () => {
{
const settingsPanel = await SpinQuery.select(".custom-navbar-settings"); const settingsPanel = await SpinQuery.select(".custom-navbar-settings");
if (settingsPanel) if (settingsPanel) {
{
settingsPanel.classList.toggle("show"); settingsPanel.classList.toggle("show");
document.querySelector(".gui-settings-mask").click(); document.querySelector(".gui-settings-mask").click();
} }
}); });
button.addEventListener("mouseover", () => button.addEventListener("mouseover", () => {
{
const displayNames = { const displayNames = {
blank1: "弹性空白1", blank1: "弹性空白1",
logo: "Logo", logo: "Logo",
@ -72,31 +66,24 @@ const attributes = {
</li> </li>
`, `,
methods: { methods: {
hidden() hidden () {
{
return settings.customNavbarHidden.includes(this.item.name); return settings.customNavbarHidden.includes(this.item.name);
}, },
viewBorder(view) viewBorder (view) {
{
const navbarItem = document.querySelector(`.custom-navbar li[data-name='${this.item.name}']`); const navbarItem = document.querySelector(`.custom-navbar li[data-name='${this.item.name}']`);
if (navbarItem !== null) if (navbarItem !== null) {
{
navbarItem.classList[view ? "add" : "remove"]("view-border"); navbarItem.classList[view ? "add" : "remove"]("view-border");
} }
}, },
toggleHidden() toggleHidden () {
{
const isHidden = this.hidden(); const isHidden = this.hidden();
if (isHidden === false) if (isHidden === false) {
{
settings.customNavbarHidden.push(this.item.name); settings.customNavbarHidden.push(this.item.name);
settings.customNavbarHidden = settings.customNavbarHidden; settings.customNavbarHidden = settings.customNavbarHidden;
} }
else else {
{
const index = settings.customNavbarHidden.indexOf(this.item.name); const index = settings.customNavbarHidden.indexOf(this.item.name);
if (index === -1) if (index === -1) {
{
return; return;
} }
settings.customNavbarHidden.splice(index, 1); settings.customNavbarHidden.splice(index, 1);
@ -104,45 +91,36 @@ const attributes = {
} }
this.$forceUpdate(); this.$forceUpdate();
const navbarItem = document.querySelector(`.custom-navbar li[data-name='${this.item.name}']`); const navbarItem = document.querySelector(`.custom-navbar li[data-name='${this.item.name}']`);
if (navbarItem !== null) if (navbarItem !== null) {
{
navbarItem.style.display = isHidden ? "flex" : "none"; navbarItem.style.display = isHidden ? "flex" : "none";
} }
} }
} }
}); });
const updateBoundsPadding = debounce(value => const updateBoundsPadding = debounce(value => {
{
settings.customNavbarBoundsPadding = value; settings.customNavbarBoundsPadding = value;
document.body.style.setProperty("--navbar-bounds-padding", `0 ${value}%`); document.body.style.setProperty("--navbar-bounds-padding", `0 ${value}%`);
}, 200); }, 200);
new Vue({ new Vue({
el: ".custom-navbar-settings", el: ".custom-navbar-settings",
mounted() mounted () {
{
const list = document.querySelector(".custom-navbar-settings .order-list"); const list = document.querySelector(".custom-navbar-settings .order-list");
const reorder = ({ sourceItem, targetItem, orderBefore, orderAfter }) => const reorder = ({ sourceItem, targetItem, orderBefore, orderAfter }) => {
{ if (orderBefore === orderAfter) {
if (orderBefore === orderAfter)
{
return; return;
} }
const entires = Object.entries(settings.customNavbarOrder); const entires = Object.entries(settings.customNavbarOrder);
const names = entires.sort((a, b) => a[1] - b[1]).map(it => it[0]); const names = entires.sort((a, b) => a[1] - b[1]).map(it => it[0]);
if (orderBefore < orderAfter) if (orderBefore < orderAfter) {
{ for (let i = orderBefore + 1; i <= orderAfter; i++) {
for (let i = orderBefore + 1; i <= orderAfter; i++)
{
const name = names[i]; const name = names[i];
settings.customNavbarOrder[name] = i - 1; settings.customNavbarOrder[name] = i - 1;
document.querySelector(`.custom-navbar li[data-name='${name}']`).style.order = i - 1; document.querySelector(`.custom-navbar li[data-name='${name}']`).style.order = i - 1;
} }
} }
else else {
{ for (let i = orderBefore - 1; i >= orderAfter; i--) {
for (let i = orderBefore - 1; i >= orderAfter; i--)
{
const name = names[i]; const name = names[i];
settings.customNavbarOrder[name] = i + 1; settings.customNavbarOrder[name] = i + 1;
document.querySelector(`.custom-navbar li[data-name='${name}']`).style.order = i + 1; document.querySelector(`.custom-navbar li[data-name='${name}']`).style.order = i + 1;
@ -154,16 +132,13 @@ const attributes = {
list.insertBefore(sourceItem, targetItem); list.insertBefore(sourceItem, targetItem);
}; };
new Slip(list); new Slip(list);
list.addEventListener("slip:beforewait", e => list.addEventListener("slip:beforewait", e => {
{ if (e.target.classList.contains("mdi-menu")) {
if (e.target.classList.contains("mdi-menu"))
{
e.preventDefault(); e.preventDefault();
} }
}, false); }, false);
list.addEventListener("slip:beforeswipe", e => e.preventDefault(), false); list.addEventListener("slip:beforeswipe", e => e.preventDefault(), false);
list.addEventListener("slip:reorder", e => list.addEventListener("slip:reorder", e => {
{
reorder({ reorder({
sourceItem: e.target, sourceItem: e.target,
targetItem: e.detail.insertBefore, targetItem: e.detail.insertBefore,
@ -174,11 +149,9 @@ const attributes = {
}, false); }, false);
}, },
computed: { computed: {
orderList() orderList () {
{
const orders = Object.entries(settings.customNavbarOrder); const orders = Object.entries(settings.customNavbarOrder);
return orders.sort((a, b) => a[1] - b[1]).map(it => return orders.sort((a, b) => a[1] - b[1]).map(it => {
{
return { return {
displayName: displayNames[it[0]], displayName: displayNames[it[0]],
name: it[0], name: it[0],
@ -191,25 +164,20 @@ const attributes = {
boundsPadding: settings.customNavbarBoundsPadding, boundsPadding: settings.customNavbarBoundsPadding,
}, },
watch: { watch: {
boundsPadding(value) boundsPadding (value) {
{
updateBoundsPadding(value); updateBoundsPadding(value);
}, },
}, },
methods: { methods: {
close() close () {
{
document.querySelector(".custom-navbar-settings").classList.remove("show"); document.querySelector(".custom-navbar-settings").classList.remove("show");
}, },
restoreDefault() restoreDefault () {
{ if (typeof customNavbarDefaultOrders === "undefined") {
if (typeof customNavbarDefaultOrders === "undefined")
{
Toast.error("未找到默认值设定, 请更新您的脚本."); Toast.error("未找到默认值设定, 请更新您的脚本.");
return; return;
} }
if (confirm("确定要恢复默认顶栏布局吗? 恢复后页面将刷新.")) if (confirm("确定要恢复默认顶栏布局吗? 恢复后页面将刷新.")) {
{
this.boundsPadding = 5; this.boundsPadding = 5;
settings.customNavbarOrder = customNavbarDefaultOrders; settings.customNavbarOrder = customNavbarDefaultOrders;
location.reload(); location.reload();
@ -220,25 +188,21 @@ const attributes = {
}, { once: true }); }, { once: true });
}, },
}, },
unload: () => unload: () => {
{
const navbar = document.querySelectorAll(".custom-navbar,.custom-navbar-settings"); const navbar = document.querySelectorAll(".custom-navbar,.custom-navbar-settings");
navbar.forEach(it => it.style.display = "none"); navbar.forEach(it => it.style.display = "none");
resources.removeStyle("customNavbarStyle"); resources.removeStyle("customNavbarStyle");
}, },
reload: () => reload: () => {
{
const navbar = document.querySelectorAll(".custom-navbar,.custom-navbar-settings"); const navbar = document.querySelectorAll(".custom-navbar,.custom-navbar-settings");
navbar.forEach(it => it.style.display = "flex"); navbar.forEach(it => it.style.display = "flex");
resources.applyImportantStyle("customNavbarStyle"); resources.applyImportantStyle("customNavbarStyle");
}, },
}; };
const classHandler = (key, value, element) => const classHandler = (key, value, element) => {
{
element.classList[value ? "add" : "remove"](key); element.classList[value ? "add" : "remove"](key);
} }
const darkHandler = value => const darkHandler = value => {
{
document.querySelector(".custom-navbar").classList[value ? "add" : "remove"]("dark"); document.querySelector(".custom-navbar").classList[value ? "add" : "remove"]("dark");
document.querySelector(".custom-navbar-settings").classList[value ? "add" : "remove"]("dark"); document.querySelector(".custom-navbar-settings").classList[value ? "add" : "remove"]("dark");
}; };
@ -262,8 +226,7 @@ const unsupportedUrls = [
"/member.bilibili.com/video/upload", "/member.bilibili.com/video/upload",
] ]
if (!supportedUrls.some(it => document.URL.includes(it)) if (!supportedUrls.some(it => document.URL.includes(it))
|| unsupportedUrls.some(it => document.URL.includes(it))) || unsupportedUrls.some(it => document.URL.includes(it))) {
{
showWidget = false; showWidget = false;
return attributes; return attributes;
} }
@ -272,10 +235,8 @@ let userInfo = {};
let orders = { let orders = {
}; };
class NavbarComponent class NavbarComponent {
{ constructor () {
constructor()
{
this.html = ``; this.html = ``;
this.popupHtml = ``; this.popupHtml = ``;
this.flex = `0 0 auto`; this.flex = `0 0 auto`;
@ -287,51 +248,40 @@ class NavbarComponent
this.touch = settings.touchNavBar; this.touch = settings.touchNavBar;
this.active = false; this.active = false;
} }
get name() get name () {
{
return "undefined"; return "undefined";
} }
get order() get order () {
{
return settings.customNavbarOrder[this.name]; return settings.customNavbarOrder[this.name];
} }
get hidden() get hidden () {
{
return settings.customNavbarHidden.includes(this.name); return settings.customNavbarHidden.includes(this.name);
} }
} }
class Blank extends NavbarComponent class Blank extends NavbarComponent {
{ constructor (number) {
constructor(number)
{
super(); super();
this.number = number; this.number = number;
this.flex = "1 0 auto"; this.flex = "1 0 auto";
this.disabled = true; this.disabled = true;
} }
get name() get name () {
{
return "blank" + this.number; return "blank" + this.number;
} }
} }
class Logo extends NavbarComponent class Logo extends NavbarComponent {
{ constructor () {
constructor()
{
super(); super();
this.href = `https://www.bilibili.com/`; this.href = `https://www.bilibili.com/`;
this.html = /*html*/`<i class="custom-navbar-iconfont custom-navbar-icon-logo"></i>`; this.html = /*html*/`<i class="custom-navbar-iconfont custom-navbar-icon-logo"></i>`;
this.touch = false; this.touch = false;
} }
get name() get name () {
{
return "logo"; return "logo";
} }
} }
class SimpleLink extends NavbarComponent class SimpleLink extends NavbarComponent {
{ constructor (name, link, linkName) {
constructor(name, link, linkName)
{
super(); super();
this.linkName = linkName; this.linkName = linkName;
this.html = name; this.html = name;
@ -339,15 +289,12 @@ class SimpleLink extends NavbarComponent
this.touch = false; this.touch = false;
this.active = document.URL.startsWith(link); this.active = document.URL.startsWith(link);
} }
get name() get name () {
{
return this.linkName + "Link"; return this.linkName + "Link";
} }
} }
class Upload extends NavbarComponent class Upload extends NavbarComponent {
{ constructor () {
constructor()
{
super(); super();
this.href = "https://member.bilibili.com/v2#/upload/video/frame"; this.href = "https://member.bilibili.com/v2#/upload/video/frame";
this.html = /*html*/` this.html = /*html*/`
@ -365,15 +312,12 @@ class Upload extends NavbarComponent
</ul> </ul>
`; `;
} }
get name() get name () {
{
return "upload"; return "upload";
} }
} }
class Messages extends NavbarComponent class Messages extends NavbarComponent {
{ constructor () {
constructor()
{
super(); super();
this.href = "https://message.bilibili.com/"; this.href = "https://message.bilibili.com/";
this.html = "消息"; this.html = "消息";
@ -389,44 +333,35 @@ class Messages extends NavbarComponent
this.active = document.URL.startsWith("https://message.bilibili.com/"); this.active = document.URL.startsWith("https://message.bilibili.com/");
this.init(); this.init();
} }
get name() get name () {
{
return "messages"; return "messages";
} }
async init() async init () {
{
const json = await Ajax.getJsonWithCredentials("https://message.bilibili.com/api/notify/query.notify.count.do"); const json = await Ajax.getJsonWithCredentials("https://message.bilibili.com/api/notify/query.notify.count.do");
const list = await SpinQuery.select("#message-list"); const list = await SpinQuery.select("#message-list");
const items = [...list.querySelectorAll("a[data-name]")]; const items = [...list.querySelectorAll("a[data-name]")];
const names = items.map(it => it.getAttribute("data-name")); const names = items.map(it => it.getAttribute("data-name"));
if (json.code !== 0) if (json.code !== 0) {
{
return; return;
} }
const notifyElement = await SpinQuery.select(`.custom-navbar li[data-name='${this.name}'] .notify-count`); const notifyElement = await SpinQuery.select(`.custom-navbar li[data-name='${this.name}'] .notify-count`);
let totalCount = names.reduce((acc, it) => acc + json.data[it], 0); let totalCount = names.reduce((acc, it) => acc + json.data[it], 0);
if (!totalCount) if (!totalCount) {
{
return; return;
} }
notifyElement.innerHTML = totalCount; notifyElement.innerHTML = totalCount;
names.forEach((name, index) => names.forEach((name, index) => {
{
const count = json.data[name]; const count = json.data[name];
if (count > 0) if (count > 0) {
{
items[index].setAttribute("data-count", count); items[index].setAttribute("data-count", count);
} }
else else {
{
items[index].removeAttribute("data-count"); items[index].removeAttribute("data-count");
} }
}); });
items.forEach(item => items.forEach(item => {
{ item.addEventListener("click", () => {
item.addEventListener("click", () =>
{
const count = item.getAttribute("data-count"); const count = item.getAttribute("data-count");
item.removeAttribute("data-count"); item.removeAttribute("data-count");
totalCount -= count; totalCount -= count;
@ -435,10 +370,8 @@ class Messages extends NavbarComponent
}) })
} }
} }
class Category extends NavbarComponent class Category extends NavbarComponent {
{ constructor () {
constructor()
{
super(); super();
this.html = `主站`; this.html = `主站`;
this.requestedPopup = true; this.requestedPopup = true;
@ -460,8 +393,7 @@ class Category extends NavbarComponent
</li> </li>
</ul> </ul>
`; `;
this.getOnlineInfo().then(info => this.getOnlineInfo().then(info => {
{
new Vue({ new Vue({
el: "#custom-navbar-home-popup", el: "#custom-navbar-home-popup",
data: { data: {
@ -470,15 +402,12 @@ class Category extends NavbarComponent
}); });
}); });
} }
get name() get name () {
{
return "category"; return "category";
} }
async getOnlineInfo() async getOnlineInfo () {
{
const json = await Ajax.getJson("https://api.bilibili.com/x/web-interface/online"); const json = await Ajax.getJson("https://api.bilibili.com/x/web-interface/online");
if (parseInt(json.code) !== 0) if (parseInt(json.code) !== 0) {
{
throw new Error(`[自定义顶栏] 分区投稿信息获取失败: ${json.message}`); throw new Error(`[自定义顶栏] 分区投稿信息获取失败: ${json.message}`);
} }
const regionCount = json.data.region_count; const regionCount = json.data.region_count;
@ -575,11 +504,10 @@ class Category extends NavbarComponent
}; };
} }
} }
class UserInfo extends NavbarComponent class UserInfo extends NavbarComponent {
{ constructor () {
constructor()
{
super(); super();
this.noPadding = true;
this.href = "https://space.bilibili.com"; this.href = "https://space.bilibili.com";
this.html = /*html*/` this.html = /*html*/`
<div class="user-face-container"> <div class="user-face-container">
@ -592,7 +520,8 @@ class UserInfo extends NavbarComponent
<div v-if="isLogin" class="logged-in"> <div v-if="isLogin" class="logged-in">
<a class="name" target="_blank" href="https://space.bilibili.com/">{{uname}}</a> <a class="name" target="_blank" href="https://space.bilibili.com/">{{uname}}</a>
<div class="row"> <div class="row">
<a target="_blank" title="等级" href="https://account.bilibili.com/site/record?type=exp" class="level">LV<strong>{{level_info.current_level}}</strong></a> <a target="_blank" title="等级" href="https://account.bilibili.com/site/record?type=exp"
class="level">LV<strong>{{level_info.current_level}}</strong></a>
<a target="_blank" href="https://account.bilibili.com/account/big" class="type">{{userType}}</a> <a target="_blank" href="https://account.bilibili.com/account/big" class="type">{{userType}}</a>
<div class="level-progress"> <div class="level-progress">
<div class="level-progress-thumb" v-bind:style="levelProgressStyle"></div> <div class="level-progress-thumb" v-bind:style="levelProgressStyle"></div>
@ -602,13 +531,16 @@ class UserInfo extends NavbarComponent
<div class="row"> <div class="row">
<div class="coins-container"> <div class="coins-container">
<a target="_blank" href="https://account.bilibili.com/site/coin" title="硬币" class="coins">{{money}}</a> <a target="_blank" href="https://account.bilibili.com/site/coin" title="硬币" class="coins">{{money}}</a>
<a target="_blank" href="https://pay.bilibili.com/bb_balance.html" title="B币" class="b-coins">{{wallet.bcoin_balance}}</a> <a target="_blank" href="https://pay.bilibili.com/bb_balance.html" title="B币"
class="b-coins">{{wallet.bcoin_balance}}</a>
</div> </div>
<div class="verifications"> <div class="verifications">
<a target="_blank" v-bind:class="{verified: email_verified }" title="邮箱验证" href="https://passport.bilibili.com/account/security#/bindmail"> <a target="_blank" v-bind:class="{verified: email_verified }" title="邮箱验证"
href="https://passport.bilibili.com/account/security#/bindmail">
<i class="mdi mdi-email"></i> <i class="mdi mdi-email"></i>
</a> </a>
<a target="_blank" v-bind:class="{verified: mobile_verified }" title="手机验证" href="https://passport.bilibili.com/account/security#/bindphone"> <a target="_blank" v-bind:class="{verified: mobile_verified }" title="手机验证"
href="https://passport.bilibili.com/account/security#/bindphone">
<i class="mdi mdi-cellphone-android"></i> <i class="mdi mdi-cellphone-android"></i>
</a> </a>
</div> </div>
@ -639,20 +571,19 @@ class UserInfo extends NavbarComponent
</div> </div>
</div> </div>
<div v-else class="not-logged-in"> <div v-else class="not-logged-in">
<a href="https://passport.bilibili.com/login" class="login">登录</a> <h1 class="welcome">欢迎来到 bilibili</h1>
<a href="https://passport.bilibili.com/register/phone.html" class="sign-up">注册</a> <a href="https://passport.bilibili.com/register/phone.html" class="sign-up grey-button">注册</a>
<a href="https://passport.bilibili.com/login" class="login theme-button">登录</a>
</div> </div>
</div> </div>
`; `;
this.requestedPopup = true; this.requestedPopup = true;
this.init(); this.init();
} }
get name() get name () {
{
return "userInfo"; return "userInfo";
} }
async init() async init () {
{
const panel = await SpinQuery.select(".custom-navbar .user-info-panel"); const panel = await SpinQuery.select(".custom-navbar .user-info-panel");
new Vue({ new Vue({
el: panel, el: panel,
@ -660,31 +591,24 @@ class UserInfo extends NavbarComponent
...userInfo, ...userInfo,
}, },
computed: { computed: {
userType() userType () {
{ if (!this.isLogin) {
if (!this.isLogin)
{
return "未登录"; return "未登录";
} }
if (this.level_info.current_level === 0) if (this.level_info.current_level === 0) {
{
return "注册会员"; return "注册会员";
} }
if (this.vipStatus === 1) if (this.vipStatus === 1) {
{ if (this.vipType === 1) {
if (this.vipType === 1)
{
return this.vip_theme_type ? "小会员" : "大会员"; return this.vip_theme_type ? "小会员" : "大会员";
} }
else if (this.vipType === 2) else if (this.vipType === 2) {
{
return this.vip_theme_type ? "年度小会员" : "年度大会员"; return this.vip_theme_type ? "年度小会员" : "年度大会员";
} }
} }
return "正式会员"; return "正式会员";
}, },
levelProgressStyle() levelProgressStyle () {
{
const progress = (this.level_info.next_exp - this.level_info.current_exp) / (this.level_info.next_exp - this.level_info.current_min); const progress = (this.level_info.next_exp - this.level_info.current_exp) / (this.level_info.next_exp - this.level_info.current_min);
return { return {
transform: `scaleX(${progress})` transform: `scaleX(${progress})`
@ -693,41 +617,34 @@ class UserInfo extends NavbarComponent
}, },
}); });
const face = await SpinQuery.select(".custom-navbar .user-face-container .user-face"); const face = await SpinQuery.select(".custom-navbar .user-face-container .user-face");
if (userInfo.isLogin) if (userInfo.isLogin) {
{
const faceUrl = userInfo.face.replace("http", "https"); const faceUrl = userInfo.face.replace("http", "https");
// face.setAttribute("src", faceUrl); // face.setAttribute("src", faceUrl);
const faceBaseSize = 68; const faceBaseSize = 68;
const dpis = [1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4]; const dpis = [1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4];
face.setAttribute("srcset", dpis.map(dpi => face.setAttribute("srcset", dpis.map(dpi => {
{
return `${faceUrl}@${parseInt(faceBaseSize * dpi)}w_${parseInt(faceBaseSize * dpi)}h.jpg ${dpi}x`; return `${faceUrl}@${parseInt(faceBaseSize * dpi)}w_${parseInt(faceBaseSize * dpi)}h.jpg ${dpi}x`;
}).join(",")); }).join(","));
// face.style.backgroundImage = `url('${userInfo.face}@68w_68h.jpg')`; // face.style.backgroundImage = `url('${userInfo.face}@68w_68h.jpg')`;
if (userInfo.pendant.image) if (userInfo.pendant.image) {
{
const pendant = await SpinQuery.select(".custom-navbar .user-face-container .user-pendant"); const pendant = await SpinQuery.select(".custom-navbar .user-face-container .user-pendant");
const pendantUrl = userInfo.pendant.image.replace("http", "https"); const pendantUrl = userInfo.pendant.image.replace("http", "https");
// pendant.setAttribute("src", pendantUrl); // pendant.setAttribute("src", pendantUrl);
const pendantBaseSize = 116; const pendantBaseSize = 116;
pendant.setAttribute("srcset", dpis.reduce((acc, dpi) => pendant.setAttribute("srcset", dpis.reduce((acc, dpi) => {
{
return acc + `, ${pendantUrl}@${parseInt(pendantBaseSize * dpi)}w_${parseInt(pendantBaseSize * dpi)}h.png ${dpi}x`; return acc + `, ${pendantUrl}@${parseInt(pendantBaseSize * dpi)}w_${parseInt(pendantBaseSize * dpi)}h.png ${dpi}x`;
}, "")); }, ""));
// pendant.style.backgroundImage = `url('${userInfo.pendant.image}@116w_116h.jpg')`; // pendant.style.backgroundImage = `url('${userInfo.pendant.image}@116w_116h.jpg')`;
} }
} }
else else {
{
face.setAttribute("src", "https://static.hdslb.com/images/akari.jpg"); face.setAttribute("src", "https://static.hdslb.com/images/akari.jpg");
// face.style.backgroundImage = `url('https://static.hdslb.com/images/akari.jpg')`; // face.style.backgroundImage = `url('https://static.hdslb.com/images/akari.jpg')`;
} }
} }
} }
class SearchBox extends NavbarComponent class SearchBox extends NavbarComponent {
{ constructor () {
constructor()
{
super(); super();
this.disabled = true; this.disabled = true;
this.html = /*html*/` this.html = /*html*/`
@ -744,16 +661,12 @@ class SearchBox extends NavbarComponent
`; `;
this.init(); this.init();
} }
async init() async init () {
{
const form = await SpinQuery.select("#custom-navbar-search"); const form = await SpinQuery.select("#custom-navbar-search");
const keyword = form.querySelector("input[name='keyword']"); const keyword = form.querySelector("input[name='keyword']");
form.addEventListener("submit", e => form.addEventListener("submit", e => {
{ if (keyword.value === "") {
if (keyword.value === "") if (!settings.hideTopSearch) {
{
if (!settings.hideTopSearch)
{
form.querySelector(".recommended-target").click(); form.querySelector(".recommended-target").click();
} }
e.preventDefault(); e.preventDefault();
@ -761,36 +674,28 @@ class SearchBox extends NavbarComponent
} }
return true; return true;
}); });
if (!settings.hideTopSearch) if (!settings.hideTopSearch) {
{
const json = await Ajax.getJson("https://api.bilibili.com/x/web-interface/search/default"); const json = await Ajax.getJson("https://api.bilibili.com/x/web-interface/search/default");
if (json.code === 0) if (json.code === 0) {
{
keyword.setAttribute("placeholder", json.data.show_name); keyword.setAttribute("placeholder", json.data.show_name);
if (json.data.name.startsWith("av")) if (json.data.name.startsWith("av")) {
{
form.querySelector(".recommended-target").setAttribute("href", `https://www.bilibili.com/${json.data.name}`); form.querySelector(".recommended-target").setAttribute("href", `https://www.bilibili.com/${json.data.name}`);
} }
else else {
{
form.querySelector(".recommended-target").setAttribute("href", `https://search.bilibili.com/all?keyword=${json.data.name}`); form.querySelector(".recommended-target").setAttribute("href", `https://search.bilibili.com/all?keyword=${json.data.name}`);
} }
} }
else else {
{
console.error("[自定义顶栏] 获取搜索推荐词失败"); console.error("[自定义顶栏] 获取搜索推荐词失败");
} }
} }
} }
get name() get name () {
{
return "search"; return "search";
} }
} }
class Iframe extends NavbarComponent class Iframe extends NavbarComponent {
{ constructor (name, link, { src, width, height, lazy, iframeName }) {
constructor(name, link, { src, width, height, lazy, iframeName })
{
super(); super();
this.iframeName = iframeName; this.iframeName = iframeName;
this.html = name; this.html = name;
@ -803,46 +708,36 @@ class Iframe extends NavbarComponent
this.touch = false; this.touch = false;
this.transparent = true; this.transparent = true;
} }
get name() get name () {
{
return this.iframeName + "Iframe"; return this.iframeName + "Iframe";
} }
} }
class NotifyIframe extends Iframe class NotifyIframe extends Iframe {
{ constructor (...args) {
constructor(...args)
{
super(...args); super(...args);
this.touch = settings.touchNavBar; this.touch = settings.touchNavBar;
this.getNotifyCount(); this.getNotifyCount();
} }
getApiUrl() getApiUrl () {
{
return null; return null;
} }
getCount() getCount () {
{
return 0; return 0;
} }
async getNotifyCount() async getNotifyCount () {
{
const notifyElement = await SpinQuery.select(`.custom-navbar li[data-name='${this.name}'] .notify-count`); const notifyElement = await SpinQuery.select(`.custom-navbar li[data-name='${this.name}'] .notify-count`);
const json = await Ajax.getJsonWithCredentials(this.getApiUrl()); const json = await Ajax.getJsonWithCredentials(this.getApiUrl());
const count = this.getCount(json); const count = this.getCount(json);
if (json.code === 0 && count) if (json.code === 0 && count) {
{
notifyElement.innerHTML = count; notifyElement.innerHTML = count;
this.onPopup = () => this.onPopup = () => {
{
notifyElement.innerHTML = ''; notifyElement.innerHTML = '';
}; };
} }
} }
} }
class Activities extends NotifyIframe class Activities extends NotifyIframe {
{ constructor () {
constructor()
{
super("动态", super("动态",
settings.oldTweets ? "https://www.bilibili.com/account/dynamic" : "https://t.bilibili.com/", settings.oldTweets ? "https://www.bilibili.com/account/dynamic" : "https://t.bilibili.com/",
{ {
@ -853,17 +748,14 @@ class Activities extends NotifyIframe
}); });
this.active = document.URL.replace(/\?.*$/, "") === "https://t.bilibili.com/"; this.active = document.URL.replace(/\?.*$/, "") === "https://t.bilibili.com/";
} }
getApiUrl() getApiUrl () {
{
const updateNumber = document.cookie.replace(new RegExp(`(?:(?:^|.*;\\s*)bp_t_offset_${userInfo.mid}\\s*\\=\\s*([^;]*).*$)|^.*$`), "$1"); const updateNumber = document.cookie.replace(new RegExp(`(?:(?:^|.*;\\s*)bp_t_offset_${userInfo.mid}\\s*\\=\\s*([^;]*).*$)|^.*$`), "$1");
return `https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_num?rsp_type=1&uid=${userInfo.mid}&update_num_dy_id=${updateNumber}&type_list=8,512,64`; return `https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_num?rsp_type=1&uid=${userInfo.mid}&update_num_dy_id=${updateNumber}&type_list=8,512,64`;
} }
getCount(json) getCount (json) {
{
return json.data.update_num; return json.data.update_num;
} }
get name() get name () {
{
return "activities"; return "activities";
} }
} }
@ -887,10 +779,8 @@ class Activities extends NotifyIframe
// return Object.values(json.data).reduce((a, b) => a + b, 0); // return Object.values(json.data).reduce((a, b) => a + b, 0);
// } // }
// } // }
class VideoList extends NavbarComponent class VideoList extends NavbarComponent {
{ constructor ({ mainUrl, name, apiUrl, listName, listMap }) {
constructor({ mainUrl, name, apiUrl, listName, listMap })
{
super(); super();
this.href = mainUrl; this.href = mainUrl;
this.listName = listName; this.listName = listName;
@ -901,20 +791,16 @@ class VideoList extends NavbarComponent
<li class="loading">加载中...</li> <li class="loading">加载中...</li>
</ol> </ol>
`; `;
this.onPopup = async () => this.onPopup = async () => {
{ if (!listMap) {
if (!listMap)
{
return; return;
} }
const videoListElement = await SpinQuery.select(`.video-list.${listName}`); const videoListElement = await SpinQuery.select(`.video-list.${listName}`);
if (videoListElement === null) if (videoListElement === null) {
{
return; return;
} }
const json = await Ajax.getJsonWithCredentials(apiUrl); const json = await Ajax.getJsonWithCredentials(apiUrl);
if (json.code !== 0) if (json.code !== 0) {
{
logError(`加载${name}信息失败. 错误码: ${json.code} ${json.message}`); logError(`加载${name}信息失败. 错误码: ${json.code} ${json.message}`);
return; return;
} }
@ -925,24 +811,19 @@ class VideoList extends NavbarComponent
videoListElement.classList.add("loaded"); videoListElement.classList.add("loaded");
}; };
} }
get name() get name () {
{
return this.listName + "List"; return this.listName + "List";
} }
} }
class WatchlaterList extends VideoList class WatchlaterList extends VideoList {
{ constructor () {
constructor()
{
super({ super({
name: "稍后再看", name: "稍后再看",
mainUrl: "https://www.bilibili.com/watchlater/#/list", mainUrl: "https://www.bilibili.com/watchlater/#/list",
apiUrl: "https://api.bilibili.com/x/v2/history/toview/web", apiUrl: "https://api.bilibili.com/x/v2/history/toview/web",
listName: "watchlater", listName: "watchlater",
listMap: json => listMap: json => {
{ return json.data.list.slice(0, 6).map(item => {
return json.data.list.slice(0, 6).map(item =>
{
const pages = item.pages.map(it => it.cid); const pages = item.pages.map(it => it.cid);
const page = item.cid === 0 ? 1 : pages.indexOf(item.cid) + 1; const page = item.cid === 0 ? 1 : pages.indexOf(item.cid) + 1;
const href = settings.watchLaterRedirect ? const href = settings.watchLaterRedirect ?
@ -957,19 +838,15 @@ class WatchlaterList extends VideoList
this.active = document.URL.startsWith("https://www.bilibili.com/watchlater/"); this.active = document.URL.startsWith("https://www.bilibili.com/watchlater/");
} }
} }
class FavoritesList extends VideoList class FavoritesList extends VideoList {
{ constructor () {
constructor()
{
super({ super({
name: "收藏", name: "收藏",
mainUrl: `https://space.bilibili.com/${userInfo.mid}/favlist`, mainUrl: `https://space.bilibili.com/${userInfo.mid}/favlist`,
apiUrl: "https://api.bilibili.com/medialist/gateway/coll/resource/recent", apiUrl: "https://api.bilibili.com/medialist/gateway/coll/resource/recent",
listName: "favorites", listName: "favorites",
listMap: json => listMap: json => {
{ return json.data.map(item => {
return json.data.map(item =>
{
return /*html*/`<li> return /*html*/`<li>
<a target="_blank" href="https://www.bilibili.com/video/av${item.id}">${item.title}</a> <a target="_blank" href="https://www.bilibili.com/video/av${item.id}">${item.title}</a>
</li>`; </li>`;
@ -979,39 +856,31 @@ class FavoritesList extends VideoList
this.active = document.URL.replace(/\?.*$/, "") === `https://space.bilibili.com/${userInfo.mid}/favlist`; this.active = document.URL.replace(/\?.*$/, "") === `https://space.bilibili.com/${userInfo.mid}/favlist`;
} }
} }
class HistoryList extends VideoList class HistoryList extends VideoList {
{ constructor () {
constructor()
{
super({ super({
name: "历史", name: "历史",
mainUrl: "https://www.bilibili.com/account/history", mainUrl: "https://www.bilibili.com/account/history",
apiUrl: "https://api.bilibili.com/x/v2/history?pn=1&ps=6", apiUrl: "https://api.bilibili.com/x/v2/history?pn=1&ps=6",
listName: "history", listName: "history",
listMap: json => listMap: json => {
{ return json.data.map(item => {
return json.data.map(item =>
{
let parameter = []; let parameter = [];
let description = ""; let description = "";
const page = item.page ? item.page.page : 1; const page = item.page ? item.page.page : 1;
const progress = item.progress >= 0 ? item.progress / item.duration : 1; const progress = item.progress >= 0 ? item.progress / item.duration : 1;
if (page !== 1) if (page !== 1) {
{
parameter.push(`p=${page}`); parameter.push(`p=${page}`);
description += `看到第${page}`; description += `看到第${page}`;
} }
if (item.progress > 0 && item.progress < item.duration) if (item.progress > 0 && item.progress < item.duration) {
{
parameter.push(`t=${item.progress}`); parameter.push(`t=${item.progress}`);
description += ` ${Math.floor(progress * 100)}%`; description += ` ${Math.floor(progress * 100)}%`;
} }
else if (item.progress === 0) else if (item.progress === 0) {
{
description += ` 刚开始看`; description += ` 刚开始看`;
} }
else else {
{
description += " 100%"; description += " 100%";
} }
return /*html*/`<li class="history-item"> return /*html*/`<li class="history-item">
@ -1028,28 +897,23 @@ class HistoryList extends VideoList
} }
} }
(async () => (async () => {
{
const html = await import("customNavbarHtml"); const html = await import("customNavbarHtml");
const json = await Ajax.getJsonWithCredentials("https://api.bilibili.com/x/web-interface/nav"); const json = await Ajax.getJsonWithCredentials("https://api.bilibili.com/x/web-interface/nav");
userInfo = json.data; userInfo = json.data;
document.body.insertAdjacentHTML("beforeend", html); document.body.insertAdjacentHTML("beforeend", html);
addSettingsListener("useDarkStyle", darkHandler); addSettingsListener("useDarkStyle", darkHandler);
darkHandler(settings.useDarkStyle); darkHandler(settings.useDarkStyle);
["Fill", "Shadow", "Compact", "Blur"].forEach(item => ["Fill", "Shadow", "Compact", "Blur"].forEach(item => {
{
addSettingsListener("customNavbar" + item, value => classHandler(item.toLowerCase(), value, document.querySelector(".custom-navbar"))); addSettingsListener("customNavbar" + item, value => classHandler(item.toLowerCase(), value, document.querySelector(".custom-navbar")));
classHandler(item.toLowerCase(), settings["customNavbar" + item], document.querySelector(".custom-navbar")); classHandler(item.toLowerCase(), settings["customNavbar" + item], document.querySelector(".custom-navbar"));
}); });
SpinQuery.condition(() => document.getElementById("banner_link"), SpinQuery.condition(() => document.getElementById("banner_link"),
banner => banner === null ? null : banner.style.backgroundImage, banner => banner === null ? null : banner.style.backgroundImage,
banner => banner => {
{ Observer.attributes(banner, () => {
Observer.attributes(banner, () =>
{
const blurLayers = document.querySelectorAll(".custom-navbar .blur-layer"); const blurLayers = document.querySelectorAll(".custom-navbar .blur-layer");
blurLayers.forEach(blurLayer => blurLayers.forEach(blurLayer => {
{
blurLayer.style.backgroundImage = banner.style.backgroundImage; blurLayer.style.backgroundImage = banner.style.backgroundImage;
blurLayer.setAttribute("data-image", banner.style.backgroundImage); blurLayer.setAttribute("data-image", banner.style.backgroundImage);
}); });
@ -1083,8 +947,7 @@ class HistoryList extends VideoList
new SearchBox, new SearchBox,
new UserInfo, new UserInfo,
]; ];
if (userInfo.isLogin) if (userInfo.isLogin) {
{
components.push( components.push(
new Messages, new Messages,
new Activities, new Activities,
@ -1100,10 +963,8 @@ class HistoryList extends VideoList
components, components,
}, },
methods: { methods: {
requestPopup(component) requestPopup (component) {
{ if (!component.requestedPopup && !component.disabled && !component.active) {
if (!component.requestedPopup && !component.disabled && !component.active)
{
this.$set(component, `requestedPopup`, true); this.$set(component, `requestedPopup`, true);
component.onPopup && component.onPopup(); component.onPopup && component.onPopup();
} }