我的白菜菊花

Cloud sync for bcjh.xyz

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

// ==UserScript==
// @name         我的白菜菊花
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Cloud sync for bcjh.xyz
// @author       You
// @match        https://bcjh.gitee.io/
// @icon         https://www.google.com/s2/favicons?domain=gitee.io
// @grant        GM_addStyle
// @grant        GM_xmlhttpRequest
// @run-at       document-start
// ==/UserScript==

GM_addStyle ( `
    .el-input input {
    border: 1px solid #dcdfe6;
    box-sizing: border-box;
    border-radius: 4px;
    height: 26px;
    line-height: 24px;
    padding-left: 10px;
    padding-right: 23px;
    color: #606266;
    }
    .sync-indicator {
    position: absolute;
    right:0;
    top:0;
    width: 10px;
    height: 10px;
    opacity: 0.8;
    border-radius: 50%;
    background: gray;
    }
    .sync-indicator.unsync {
    background: red;
    }
    .sync-indicator.sync {
    background: green;
    }
    .sync-indicator.syncing {
    background: yellow !important;
    }
` );

const server = "https://keystore.mactype.win:10512"

let localstore = {
    _setItem: window.localStorage.setItem,
    _getItem: window.localStorage.getItem,
    setItem(name, value) {
        return this._setItem.call(window.localStorage, name, value)
    },
    getItem(name) {
        return this._getItem.call(window.localStorage, name)
    }
}

let lastUser = localStorage.getItem("fishcloud") || ""
let vueRoot = null, importCloud = false

let cloudServer = {
    delayedupload() {
        if (!lastUser) return
        let value = window.localStorage.getItem("data")
        syncIndicator.syncing()
        console.log("Changes detected, uploading...")
        GM_xmlhttpRequest({
            url: server + "/put",
            method: "post",
            data: JSON.stringify({
                user: lastUser,
                key: "data",
                value: value
            }),
            onload: ()=>{
                syncIndicator.synced()
            }
        })
    },
    t: null,
    upload() {
        syncIndicator.syncing()
        if (this.t) {
            clearTimeout(this.t)
        }
        this.t = setTimeout(()=>{
            this.t = null
            this.delayedupload()
        }, 1000)
    },
    download(quiet = true) {
        if (!lastUser) return
        syncIndicator.syncing()
        GM_xmlhttpRequest({
            url: server + "/get",
            method: "post",
            data: JSON.stringify({
                user: lastUser,
                key: "data"
            }),
            onload: ({responseText})=>{
                if (responseText) {
                    importCloud = true
                    localstore.setItem("data", responseText)
                    vueRoot && vueRoot.getUserData()
                    setTimeout(()=>{
                        importCloud = false
                    }, 500)
                }
                syncIndicator.synced()
                if (!quiet) {
                    alert("数据已同步")
                }
            },
            onerror: err=>{
                syncIndicator.fail()
                if (!quiet) {
                    alert("同步失败")
                }
            }
        })
    }
}

var syncIndicator = {
    el: null,
    create() {
        $("body").append("<div class='sync-indicator'></div>")
        this.el = $(".sync-indicator")
    },
    syncing() {
        this.el.addClass("syncing")
    },
    fail() {
        this.el.removeClass("syncing sync").addClass("unsync")
    },
    synced() {
        this.el.removeClass("syncing unsync").addClass("sync")
    },
    nop() {
        this.el.removeClass("syncing unsync sync")
    }
}

function hookUltimateNavi(e) {
    if (document.getElementById("mycloud")) return
    let box = document.getElementsByClassName("ultimate-box")
    if (box.length) {
        $(box).prepend('<div class="title" id="mycloud">大鱼云同步</div><div class="hr"></div><div class="box-body"><div class="el-input"><span style="margin-right:5px">请输入雨云用户名:</span><input type="text" value="'+lastUser+'" name="fishcloud"></div></div>')
        $(box).find("input[name=fishcloud]").on("change", function (){
            let newUser = this.value
            if (newUser !== lastUser && lastUser !=="") {
                if (!confirm("确定要从用户 \""+lastUser+"\" 切换到用户 \""+newUser+"\" 吗?")) {
                    this.value = lastUser
                    return
                }
            }
            lastUser = newUser
            localstore.setItem("fishcloud", this.value)
            if (confirm("您已登录(不可用)为用户 "+newUser+",点击【确定】下载该用户数据,点击【取消】上传当前数据")) {
                cloudServer.download(false)
            } else {
                cloudServer.upload()
            }
        })
    }
}

function hookOpIcon(e) {
    let navs = document.getElementsByClassName("nav")
    if (navs.length) {
        console.log("found navigators")
        $(e.currentTarget).off("click", hookOpIcon)
        $(navs[8]).on("click", hookUltimateNavi)
    }
}

var i = 0

function hookLocalStorage() {
    window.localStorage.__proto__.setItem = function(name, value) {
        let result = localstore.setItem(name, value)
        if (vueRoot && !vueRoot.loading && !importCloud) {  // 忽略所有中途读写
            cloudServer.upload()
        }
        return result
    }
}

function hookVue() {
    let pVue = null
    Object.defineProperty(unsafeWindow,'Vue',{
        get: function(){
            return pVue
        },

        set: function(val){
            pVue = new Proxy(val, {
                construct: function(target, args) {
                    var obj = new target(...args)
                    if (args.length && typeof args[0]==="object" && args[0].el==="#main") {
                        vueRoot = obj
                    }
                    return obj
                },
            })
        },
        configurable: true,
    });
}

function oneTimeSyncOnLoad() {
    if (lastUser === "") return
    if (!vueRoot || vueRoot.loading) {
        setTimeout(oneTimeSyncOnLoad, 1000)
    } else {
        console.log("Syncing cloud profile...")
        cloudServer.download()
    }
}

(function() {
    'use strict';
    console.log("Welcome to MyBCJHCloud 1.0")

    hookLocalStorage()
    hookVue()
    window.addEventListener('load', ()=>{
        new Promise(r=>{
            let checker = ()=>{
                let opIcon = document.getElementsByClassName("el-icon-s-operation icon-btn")
                if (opIcon.length) {
                    r(opIcon)
                } else {
                    setTimeout(checker, 500)
                }
            }
            checker()
        }).then((icon)=>{
            $(icon).on("click", hookOpIcon)
            syncIndicator.create()
            oneTimeSyncOnLoad()
        })
    })
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址