Warning: fopen(/www/sites/update.greasyfork.icu/index/store/temp/60fdb9775059ec25c60a4744f758426c.js): failed to open stream: No space left on device in /www/sites/update.greasyfork.icu/index/scriptControl.php on line 65
// ==UserScript==
// @name bilibili订阅+
// @namespace https://github.com/YanxinTang/Tampermonkey
// @version 0.7.9
// @description bilibili导航添加订阅按钮以及订阅列表
// @author tyx1703
// @license MIT
// @noframes
// @require https://cdn.jsdelivr.net/npm/vue@2/dist/vue.min.js
// @match *.bilibili.com/*
// @exclude *://live.bilibili.com/*
// @exclude *://manga.bilibili.com/*
// @exclude *://bw.bilibili.com/*
// @exclude *://show.bilibili.com/*
// @downloadURL https://update.greasyfork.icu/scripts/30283/bilibili%E8%AE%A2%E9%98%85%2B.user.js
// @updateURL https://update.greasyfork.icu/scripts/30283/bilibili%E8%AE%A2%E9%98%85%2B.meta.js
// ==/UserScript==
(async function () {
const DedeUserID = getCookie("DedeUserID");
const loginStatus = DedeUserID !== "";
if (!loginStatus) {
log("少侠请先登录~ 哔哩哔哩 (゜-゜)つロ 干杯~");
return;
}
const PER_PAGE = 15;
try {
const lastPopoverButton = await getLastPopoverButton();
const subscribeMenuEl = document.createElement("li");
subscribeMenuEl.setAttribute("id", "subscribe");
lastPopoverButton.after(subscribeMenuEl);
const getBangumis = (page) => {
return fetch(
`//api.bilibili.com/x/space/bangumi/follow/list?type=1&follow_status=0&pn=${page}&ps=${PER_PAGE}&vmid=${DedeUserID}`,
{
method: "GET",
credentials: "include",
}
)
.then((response) => response.json())
.then((response) => response.data)
.then(({ list, ...rest }) => {
return {
list: list.map((item) => ({ ...item, id: item.media_id })),
...rest,
};
});
};
const getCinemas = (page) => {
return fetch(
`//api.bilibili.com/x/space/bangumi/follow/list?type=2&follow_status=0&pn=${page}&ps=${PER_PAGE}&vmid=${DedeUserID}`,
{
method: "GET",
credentials: "include",
}
)
.then((response) => response.json())
.then((response) => response.data)
.then(({ list, ...rest }) => {
return {
list: list.map((item) => ({ ...item, id: item.media_id })),
...rest,
};
});
};
const getFloowings = (page) => {
return fetch(
`//api.bilibili.com/x/relation/followings?&pn=${page}&ps=${PER_PAGE}&vmid=${DedeUserID}&order=desc`,
{
method: "GET",
credentials: "include",
}
)
.then((response) => response.json())
.then((response) => {
return {
list: response.data.list.map((item) => ({
...item,
id: item.mid,
})),
total: response.data.total,
pn: page,
};
});
};
const VideoItem = {
props: ["item"],
computed: {
coverURL() {
return this.item.cover.replace("http:", "");
},
},
template: `
`,
};
const UserItem = {
props: ["item"],
computed: {
spaceURL() {
return `https://space.bilibili.com/${this.item.mid}`;
},
avatarURL() {
return this.item.face.replace("http:", "");
},
},
template: `
`,
};
new Vue({
el: subscribeMenuEl,
components: { VideoItem, UserItem },
data() {
return {
isPanelVisible: false,
loading: false,
inLeaveAnimation: false,
activeTab: "bangumis",
tabs: [
{ key: "bangumis", name: "追番" },
{ key: "cinemas", name: "追剧" },
{ key: "floowings", name: "关注" },
],
dataset: {
bangumis: {
list: [],
total: 0,
page: 0,
component: "VideoItem",
},
cinemas: {
list: [],
total: 0,
page: 0,
component: "VideoItem",
},
floowings: {
list: [],
total: 0,
page: 0,
component: "UserItem",
},
},
};
},
created() {
this.load();
},
computed: {
list() {
return this.dataset[this.activeTab].list;
},
total() {
return this.dataset[this.activeTab].total;
},
page() {
return this.dataset[this.activeTab].page;
},
tabComponent() {
return this.dataset[this.activeTab].component;
},
},
methods: {
async load() {
const tab = this.activeTab;
let request;
if (tab === "bangumis") {
request = getBangumis;
}
if (tab === "cinemas") {
request = getCinemas;
}
if (tab === "floowings") {
request = getFloowings;
}
try {
this.loading = true;
const { list, total, pn } = await request(this.page + 1);
this.dataset[tab].list = [...this.dataset[tab].list, ...list];
this.dataset[tab].total = total;
this.dataset[tab].page = pn;
} catch (error) {
throw error;
} finally {
this.loading = false;
}
},
changeTabHandler(tab) {
this.activeTab = tab.key;
if (this.list.length <= 0) {
this.load();
}
},
onMouseoverHandler() {
if (!this.inLeaveAnimation) {
this.isPanelVisible = true;
}
},
onMouseleaveHandler() {
this.isPanelVisible = false;
},
onContentBeforeLeaveHandler() {
this.inLeaveAnimation = true;
},
onContentAfterLeaveHandler() {
this.inLeaveAnimation = false;
},
onScrollHandler() {
const panelContent = this.$refs.panelContent;
if (
!this.loading &&
this.list.length < this.total &&
panelContent.scrollHeight - panelContent.scrollTop - 50 <=
panelContent.clientHeight
) {
this.load();
}
},
},
template: `
订阅
`,
});
} catch (error) {
log(error);
}
function getLastPopoverButton(count = 1) {
if (count >= 30) {
return Promise.reject("获取顶部按列表超时");
}
return new Promise((resolve) => {
const popoverButtons = document.body.querySelectorAll(
".bili-header .bili-header__bar .right-entry>.v-popover-wrap"
);
if (popoverButtons.length) {
resolve(popoverButtons[popoverButtons.length - 1]);
return;
}
setTimeout(() => {
resolve(getLastPopoverButton(count++));
}, 100);
});
}
/**
* Get cookie by name
* @param {string} name
*/
function getCookie(name) {
const value = "; " + document.cookie;
let parts = value.split("; " + name + "=");
if (parts.length == 2) {
return parts.pop().split(";").shift();
}
return "";
}
/**
* print something in console with custom style
* @param {*} stuff
*/
function log(stuff) {
console.log(
"%cbilibili订阅+:",
"background: #f25d8e; border-radius: 3px; color: #fff; padding: 0 8px",
stuff
);
}
})();