Greasy Fork

Greasy Fork is available in English.

Bilibili Popups

B站内链助手

当前为 2021-12-12 提交的版本,查看 最新版本

// ==UserScript==
// @name         Bilibili Popups
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  B站内链助手
// @author       Sheep-realms
// @match        *://*.bilibili.com/*
// @icon         https://www.google.com/s2/favicons?domain=bilibili.com
// @require      http://libs.baidu.com/jquery/2.0.0/jquery.min.js
// @license      CC BY-NC-SA 3.0
// @grant        none
// ==/UserScript==

let popupsState = 0;
let popupsTimer;

let mx = 0;
let my = 0

let disable = false;

$(document).mousemove(function(event){
    mx = event.pageX;
    my = event.pageY;
});

$(document).keydown(function(e) {
    disable = e.altKey;
})

$(document).keyup(function(e) {
    disable = e.altKey;
})

$(document).ready(function() {
    var csslist = "";
    csslist += "#popups {max-width: 320px; position: absolute; background-color: #FFF; border: #BBB 1px solid; box-shadow: rgb(50 50 50 / 35%) 0 3px 8px; z-index: 12000; padding: 10px; color: #222;}";
    csslist += ".hide {display: none;}";
    csslist += "#popups .video-stat tr td:first-child {padding-right: 1.5em;}";
    csslist += "#popups .video-stat tr td {line-height: 1.5em;}";
    csslist += "#popups h4 {font-size: 14px; border-bottom: #BBB 1px solid; margin-bottom: 5px; font-weight: bold;}";
    csslist += "#popups p {color: #222; font-size: 12px; line-height: 1.5em;}";
    csslist += "#popups a {color: #00a1d6;}";
    csslist += "#popups .video-desc {max-width: 300px; max-height: 150px; padding: 5px; background-color: #F4F4F4; overflow: hidden;}";

    $('head').append('<style type="text/css" id="vesiter">' + csslist + '</style>');

    $("body").append('<div id="popups" class="hide"><h4 class="title"></h4></div>');

    $("#popups").mouseenter(function() {
        // console.log(">> mouseover #popups");
        popupsState = 1;
        clearTimeout(popupsTimer);
    });

    $("#popups").mouseleave(function() {
        // console.log("<< mouseleave #popups");
        popupsState = 0;
        clearTimeout(popupsTimer);
        popupsTimer = setTimeout(function() {
            $("#popups").addClass('hide');
        }, 500)
    });

});

$(document).on("mouseenter", "a:not(#popups a, .router-link-active)", function() {
    // console.log(">> mouseover a");
    if (disable) return false;
    let a = $(this).offset();
    let $that = $(this);
    popupsState = 1;
    clearTimeout(popupsTimer);

    let mode = "";
    let url = $(this).attr("href");
    let path = getUrlPath($(this).attr("href"));
    let biliAv, biliBv, uid;
    if (path.search(/\/video\/av/) != -1) {
        mode = "av";
        biliAv = path.slice(9);
    } else if (path.search(/\/video\/BV/) != -1) {
        mode = "bv";
        biliBv = path.slice(7);
    } else if (url.search(/space.bilibili.com/) != -1) {
        mode = "user";
        if (path == "space.bilibili.com" || path == "/") return false;
        if (path.search(/\/[a-z]/) != -1) {
            uid = path.slice(1,path.search(/\/[a-z]/));
        } else {
            uid = path.slice(1);
        }
    } else {
        return false;
    }


    popupsTimer = setTimeout(function() {
        $("#popups").html('<h4 class="title"></h4>');
        $("#popups .title").text("加载中...");
        if (mode == "av") {
            getVideoInfoAV(biliAv);
        }
        if (mode == "bv") {
            getVideoInfoBV(biliBv);
        }
        if (mode == "user") {
            getUserInfo(uid);
        }

        $("#popups").removeClass('hide');
        //$("#popups").css("left", a.left).css("top", a.top + 20);
        $("#popups").css("left", mx + 5).css("top", my + 5);
    }, 500)
});

$(document).on("mouseleave", "a:not(#popups a, .router-link-active)", function() {
    // console.log("<< mouseleave a");
    popupsState = 0;
    clearTimeout(popupsTimer);
    popupsTimer = setTimeout(function() {
        $("#popups").addClass('hide');
    }, 500)
});

function getUrlPath(url){
    var arrUrl = url.split("//");

    var start = arrUrl[arrUrl.length - 1].indexOf("/");
    var relUrl = arrUrl[arrUrl.length - 1].substring(start);

    if(relUrl.indexOf("?") != -1){
        relUrl = relUrl.split("?")[0];
    }
    return relUrl;
}

function getJSONInfo(url) {
    $.getJSON(url,
    function (ajson) {
        console.log(ajson);
    });
}

function getVideoInfoAV(aid) {
    $.getJSON("https://api.bilibili.com/x/web-interface/view?aid=" + aid,
    function (ajson) {
        if (ajson.code == 0) {
            factoryVideoInfo(ajson.data);
        } else {
            getVideoInfoError();
        }
    });
}

function getVideoInfoBV(bvid) {
    $.getJSON("https://api.bilibili.com/x/web-interface/view?bvid=" + bvid,
    function (ajson) {
        if (ajson.code == 0) {
            factoryVideoInfo(ajson.data);
        } else {
            getVideoInfoError();
        }
    });
}

function factoryVideoInfo(obj) {
    $("#popups .title").text(obj.title);
    $("#popups").append('<p><a target="_blank" href="https://www.bilibili.com/video/av'+obj.aid+'">av'+obj.aid+'</a> | <a target="_blank" href="https://www.bilibili.com/video/'+obj.bvid+'">'+obj.bvid+'</a></p>');
    $("#popups").append('<p>作者:<a target="_blank" href="https://space.bilibili.com/'+obj.owner.mid+'">'+obj.owner.name+'</a>(<a target="_blank" href="https://space.bilibili.com/'+obj.owner.mid+'/dynamic">动态</a> | <a target="_blank" href="https://space.bilibili.com/'+obj.owner.mid+'/video">投稿</a> | <a target="_blank" href="https://space.bilibili.com/'+obj.owner.mid+'/channel/series">列表</a>)</p>');
    $("#popups").append('<p>分区:<span>'+obj.tname+'</span></p>');
    $("#popups").append('<p>发布时间:<span>'+getDateTime(obj.pubdate)+'</span></p>');
    $("#popups").append('<p>播放:<span>'+obj.stat.view+'</span></p>');
    $("#popups").append('<table class="video-stat"></table>');
    $("#popups .video-stat").append('<tr><td>点赞:<span>'+obj.stat.like+'</span></td><td>投币:<span>'+obj.stat.coin+'</span></td></tr>');
    $("#popups .video-stat").append('<tr><td>弹幕:<span>'+obj.stat.danmaku+'</span></td><td>评论:<span>'+obj.stat.reply+'</span></td></tr>');
    $("#popups .video-stat").append('<tr><td>收藏:<span>'+obj.stat.favorite+'</span></td><td>分享:<span>'+obj.stat.share+'</span></td></tr>');
    //$("#popups").append('<p>时长:<span>'+obj.duration+'</span></p>');
    $("#popups").append('<p><a target="_blank" href="https://www.biliplus.com/video/'+obj.bvid+'">BiliPlus</a></p>');
    $("#popups").append('<p><a target="_blank" href="'+obj.pic+'">查看视频封面</a></p>');
    $("#popups").append('<p>简介:</p>');
    $("#popups").append('<p class="video-desc">'+obj.desc+'</p>');
}

function getVideoInfoError() {
    $("#popups").html('<h4 class="title">出错啦!</h4>');
    $("#popups").append('<p>未能获取视频信息,可能是网络问题,或是视频已被删除。</p>');
}

function getUserInfo(uid) {
    $("#popups").append('<p>UID:<span class="user-uid">...</span></p>');
    $("#popups").append('<p>关注:<span class="user-friend	">...</span> | 粉丝:<span class="user-fans">...</span></p>');

    $.getJSON("https://api.bilibili.com/x/space/acc/info?mid="+uid,
    function (ajson) {
        if (ajson.code == 0) {
            let obj = ajson.data;
            $("#popups .title").text(obj.name);
            $("#popups .user-uid").text(obj.mid);
            $("#popups").append('<p>等级:<span>Lv'+obj.level+'</span></p>');
            $("#popups").append('<p><a target="_blank" href="https://space.bilibili.com/'+obj.mid+'/dynamic">动态</a> | <a target="_blank" href="https://space.bilibili.com/'+obj.mid+'/video">投稿</a> | <a target="_blank" href="https://space.bilibili.com/'+obj.mid+'/channel/series">列表</a></p>');
            $("#popups").append('<p><a target="_blank" href="'+obj.face+'">查看头像</a></p>');
            $("#popups").append('<p><a target="_blank" href="'+obj.top_photo+'">查看主页头图</a></p>');
        }
    });

    $.getJSON("https://api.bilibili.com/x/web-interface/card?mid="+uid,
    function (ajson) {
        if (ajson.code == 0) {
            let obj = ajson.data.card;
            $("#popups .user-friend	").text(obj.friend);
            $("#popups .user-fans").text(obj.fans);
        }
    });
}

function getDateTime(stamp) {
    let t = new Date(stamp * 1000);
    return t.getFullYear() + '-' + (t.getMonth() + 1) + '-' + t.getDate() + ' ' + t.getHours() + ':' + t.getMinutes() + ':' + t.getSeconds();
}