Bilibili File

一款基于哔哩哔哩弹幕网(B站)的文件托管插件( ̄▽ ̄)

目前為 2025-05-18 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Bilibili File
// @namespace    npm/bilibili-file
// @version      1.0.0
// @author       https://github.com/WJZ-P
// @description  一款基于哔哩哔哩弹幕网(B站)的文件托管插件( ̄▽ ̄)
// @license      Eclipse Public License 2.0
// @icon         https://i0.hdslb.com/bfs/material_up/12d89bc3fa38ffd23e1e8bad1e26037ddcf2f152.png
// @match        https://www.bilibili.com/*
// @require      https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/3.2.31/vue.cjs.min.js
// @grant        GM_addStyle
// ==/UserScript==

(e=>{if(typeof GM_addStyle=="function"){GM_addStyle(e);return}const t=document.createElement("style");t.textContent=e,document.head.append(t)})(" .cyber-title[data-v-733968ef]{position:relative;text-align:center;margin:2rem 0;perspective:1000px;width:fit-content;display:flex;justify-content:center}.gradient-text[data-v-733968ef]{font-size:3.5rem;font-weight:900;background:linear-gradient(90deg,#00aeec,#7be7ff,#00aeec,#7be7ff,#00aeec);background-size:200% auto;-webkit-background-clip:text;-webkit-text-fill-color:transparent;animation:gradient-733968ef 4s linear infinite;display:inline-block;transform:translateZ(0);transition:transform .3s;width:fit-content}.glow[data-v-733968ef]{position:absolute;top:0;left:50%;transform:translate(-50%);width:80%;height:100%;background:radial-gradient(circle at 50% 50%,rgba(0,174,236,.4) 0%,transparent 70%);filter:blur(30px);z-index:-1}@keyframes gradient-733968ef{0%{background-position:0% center}to{background-position:-200% center}}.cyber-title:hover .gradient-text[data-v-733968ef]{transform:scale(1.05) rotateX(10deg) rotateY(-5deg);text-shadow:0 10px 20px rgba(0,174,236,.4)}.main-menu[data-v-733968ef]{display:flex;flex-direction:column;justify-content:start;align-items:start;width:100%;height:100%}.file-manager[data-v-733968ef]{display:flex;flex-direction:column;width:95%;margin:20px auto;background:#fff;border-radius:12px;box-shadow:0 4px 12px #0000001a;padding:20px;height:100%;justify-content:center;align-items:center}.action-bar[data-v-733968ef]{width:100%;display:flex;gap:20px;margin-bottom:30px;justify-content:center;align-items:center}.upload-area[data-v-733968ef]{flex:1;border:2px dashed #00aeec;border-radius:8px;padding:20px;display:flex;align-items:center;justify-content:center;gap:10px;cursor:pointer;transition:all .3s}.upload-area[data-v-733968ef]:hover{background:#f5fbff;border-color:#09c}.search-box[data-v-733968ef]{width:320px;position:relative;transition:all .3s cubic-bezier(.4,0,.2,1);display:flex;justify-content:center;height:45px}.search-box input[data-v-733968ef]{width:100%;padding:14px 48px 14px 24px;border:2px solid #00aeec;border-radius:40px;background:#f5fbffcc;font-size:14px;color:#18191c;transition:all .3s}.search-box input[data-v-733968ef]::placeholder{color:#9499a0;font-weight:400}.search-box input[data-v-733968ef]:hover{border-color:#09c;box-shadow:0 2px 8px #00aeec1f}.search-box input[data-v-733968ef]:focus{outline:none;border-color:#0088b7;box-shadow:0 4px 16px #00aeec29;background:#fff}.search-box .iconfont[data-v-733968ef]{position:absolute;right:20px;top:50%;transform:translateY(-50%);color:#00aeec;font-size:20px;transition:all .3s}.search-box:hover .iconfont[data-v-733968ef]{color:#09c;transform:translateY(-50%) scale(1.1)}.search-box input:focus~.iconfont[data-v-733968ef]{color:#0088b7;animation:searchPulse-733968ef 1.5s infinite}@keyframes searchPulse-733968ef{0%,to{transform:translateY(-50%) scale(1)}50%{transform:translateY(-50%) scale(1.15)}}.file-list[data-v-733968ef]{width:100%}.list-header[data-v-733968ef]{width:100%;display:grid;grid-template-columns:3fr 1fr 1.5fr 1fr;padding:12px 0;border-bottom:1px solid #eee;color:#666;font-weight:500}.list-item[data-v-733968ef]{width:100%;display:grid;grid-template-columns:3fr 1fr 1.5fr 1fr;align-items:center;padding:15px 0;border-bottom:1px solid #f5f5f5;transition:background .2s}.list-item[data-v-733968ef]:hover{background:#f9f9f9}.list-item .col-name[data-v-733968ef]{display:flex;align-items:center;gap:10px;color:#333}.list-item .col-name .iconfont[data-v-733968ef]{font-size:20px;color:#00aeec}.col-actions[data-v-733968ef]{display:flex;gap:15px;justify-content:center}.col-actions button[data-v-733968ef]{background:#00c1ff;border:none;padding:6px;border-radius:6px;cursor:pointer;transition:.2s;width:70px;display:flex;justify-content:center}.col-actions button .iconfont[data-v-733968ef]{color:#fff;font-size:18px}.col-actions button[data-v-733968ef]:hover{background:#6cf;transform:translateY(-2px);box-shadow:0 3px 12px #00aeec4d}.col-actions button.btn-delete[data-v-733968ef]{background:#f54b4cdb}.col-actions button.btn-delete[data-v-733968ef]:hover{background:#ff6668;box-shadow:0 3px 12px #ff4d4f4d}.col-actions button.btn-preview[data-v-733968ef]{background:#00ff438f}.storage-progress[data-v-733968ef]{height:8px;background:#f0f0f0;border-radius:4px;overflow:hidden}.storage-progress .progress-inner[data-v-733968ef]{height:100%;background:#00aeec;transition:width .3s}@font-face{font-family:iconfont;src:url(//at.alicdn.com/t/c/font_123456_xxxxxx.css)}.modal-fade-enter-active[data-v-733968ef],.modal-fade-leave-active[data-v-733968ef]{transition:opacity .25s ease}.modal-fade-enter-from[data-v-733968ef],.modal-fade-leave-to[data-v-733968ef]{opacity:0}.preview-modal[data-v-733968ef]{position:fixed;top:0;right:0;bottom:0;left:0;background:#e5e8e833;z-index:9999;display:flex;justify-content:center;align-items:center;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.modal-container[data-v-733968ef]{position:relative;background:#fff;border-radius:12px;box-shadow:0 12px 24px #66ccff59;max-width:90vw;max-height:90vh;overflow:hidden}.close-btn[data-v-733968ef]{position:absolute;top:16px;right:16px;background:#ffffff1a;border:none;border-radius:50%;width:40px;height:40px;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;z-index:1}.close-btn[data-v-733968ef]:hover{background:#fff3;transform:scale(1.1)}.icon-close[data-v-733968ef]{color:#fff;font-size:24px}.image-wrapper[data-v-733968ef]{position:relative;width:80vw;max-width:2000px;height:80vh;display:flex;align-items:center;justify-content:center;padding:40px}.image-wrapper img[data-v-733968ef]{max-width:100%;max-height:100%;object-fit:contain;border-radius:8px}.loading-indicator[data-v-733968ef]{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);display:flex;flex-direction:column;align-items:center;color:#fffc}.spinner[data-v-733968ef]{width:40px;height:40px;border:4px solid rgba(255,255,255,.1);border-top-color:#00aeec;border-radius:50%;animation:spin-733968ef 1s linear infinite;margin-bottom:12px}@keyframes spin-733968ef{to{transform:rotate(360deg)}}.error-message[data-v-733968ef]{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#ff4d4f;font-size:1.2em}.file-info[data-v-733968ef]{position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,#66ccffc2);color:#1e1d1d;padding:15px;text-align:center;font-size:1em;-webkit-backdrop-filter:blur(1px);backdrop-filter:blur(1px)}.footer-info[data-v-733968ef]{width:100%;text-align:center;padding:10px;color:#777;font-size:.9em;border-top:1px solid #eee;margin-top:-20px}.footer-info a[data-v-733968ef]{color:#6cf}.main-container{width:100%;height:100%;display:flex;justify-content:center;align-items:center} ");

(function (vue) {
  'use strict';

  var _a;
  const uploadUrl = "https://member.bilibili.com/x/material/up/upload";
  const pixelPath = "https://i0.hdslb.com/bfs/material_up/49f20d9277765f51227fecb4db010350c3ed90ad.gif";
  const headers = new Headers({
    "accept": "*/*",
    "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,zh-TW;q=0.5",
    "origin": "https://member.bilibili.com",
    //"priority": "u=1, i",
    "referer": "https://member.bilibili.com/york/image-material-upload",
    "sec-ch-ua": '"Chromium";v="136", "Microsoft Edge";v="136", "Not.A/Brand";v="99"',
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": '"Windows"',
    "sec-fetch-dest": "empty",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "same-origin",
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0"
    //"Cookie": credentials.cookie
  });
  const credentials = {};
  async function uploadFile(file) {
    if (!file || !(credentials == null ? void 0 : credentials.bili_jct)) {
      throw new Error("缺少必要参数:file/csrf");
    }
    if (!isImage(file)) {
      const pixelBuffer = await (await fetch(pixelPath)).arrayBuffer();
      const mergedBlob = new Blob([pixelBuffer, new Blob([file])]);
      file = new File([mergedBlob], file.name);
    }
    const formData = new FormData();
    const filename = file.name || `bili_upload_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
    formData.append("bucket", "material_up");
    formData.append("dir", "");
    formData.append("file", file, filename);
    formData.append("csrf", credentials.bili_jct);
    try {
      const response = await fetch(uploadUrl, {
        method: "POST",
        headers,
        body: formData,
        redirect: "follow",
        credentials: "include"
      });
      const result = await response.json();
      if (result.code !== 0)
        return new Error(`上传失败: ${result.message} (code: ${result.code})`);
      return result;
    } catch (error) {
      console.error("上传请求异常:", error);
      throw new Error(`网络请求失败: ${error.message}`);
    }
  }
  function isImage(file) {
    var _a2;
    const imageExtensions = ["jpg", "jpeg", "png", "gif", "webp", "bmp"];
    const extension = ((_a2 = file.name.split(".").pop()) == null ? void 0 : _a2.toLowerCase()) || "";
    return imageExtensions.includes(extension);
  }
  const SAVE_FILES_KEY = "bili_files";
  function saveFiles(files) {
    try {
      localStorage.setItem(SAVE_FILES_KEY, JSON.stringify(files));
    } catch (error) {
      console.error("[Bilibili-File] 本地存储失败", error);
    }
  }
  function loadFiles() {
    try {
      const data = localStorage.getItem(SAVE_FILES_KEY);
      return data ? JSON.parse(data) : [];
    } catch (error) {
      console.log("存储读取失败", error);
      return [];
    }
  }
  const _export_sfc = (sfc, props) => {
    const target = sfc.__vccOpts || sfc;
    for (const [key, val] of props) {
      target[key] = val;
    }
    return target;
  };
  const _hoisted_1$1 = { class: "main-menu" };
  const _hoisted_2 = { class: "file-manager" };
  const _hoisted_3 = { class: "cyber-title" };
  const _hoisted_4 = { class: "gradient-text" };
  const _hoisted_5 = { class: "action-bar" };
  const _hoisted_6 = { class: "search-box" };
  const _hoisted_7 = { class: "file-list" };
  const _hoisted_8 = {
    class: "col-name",
    style: { "text-align": "center" }
  };
  const _hoisted_9 = {
    key: 0,
    class: "iconfont icon-file"
  };
  const _hoisted_10 = {
    key: 1,
    class: "iconfont icon-file"
  };
  const _hoisted_11 = {
    key: 2,
    class: "iconfont icon-file"
  };
  const _hoisted_12 = {
    class: "col-size",
    style: { "text-align": "center" }
  };
  const _hoisted_13 = {
    class: "col-date",
    style: { "text-align": "center" }
  };
  const _hoisted_14 = { class: "col-actions" };
  const _hoisted_15 = ["onClick"];
  const _hoisted_16 = ["onClick"];
  const _hoisted_17 = ["onClick"];
  const _hoisted_18 = { class: "modal-container" };
  const _hoisted_19 = { class: "image-wrapper" };
  const _hoisted_20 = ["src", "alt"];
  const _hoisted_21 = {
    key: 0,
    class: "loading-indicator"
  };
  const _hoisted_22 = { class: "file-info" };
  const sliceIndex = 35;
  const _sfc_main$1 = {
    __name: "MainMenu",
    setup(__props) {
      const fileInputEl = vue.ref(null);
      const isHovered = vue.ref(false);
      const files = vue.ref([]);
      const previewImg = vue.ref(null);
      const loading = vue.ref(false);
      const loadError = vue.ref(false);
      const showViewModel = vue.ref(false);
      const searchQuery = vue.ref("");
      vue.onMounted(() => {
        files.value = loadFiles();
      });
      const filteredFiles = vue.computed(() => {
        if (!searchQuery.value.trim()) return files.value;
        const query = searchQuery.value.trim().toLowerCase();
        return files.value.filter((file) => {
          return file.name.toLowerCase().includes(query);
        });
      });
      const handleUpload = () => fileInputEl.value.click();
      const handleFileSelect = async (event) => {
        console.log("下面打印出传入的文件参数");
        console.log(event.target.files);
        for (let file of event.target.files) {
          const result = await uploadFile(file);
          console.log(result);
          const resultFile = {};
          resultFile.name = file.name;
          resultFile.size = file.size;
          resultFile.url = result.data.location.replace(/^http:\/\//i, "https://");
          resultFile.lastModified = Date.now();
          files.value.push(resultFile);
        }
        saveFiles(files.value);
      };
      const formatDate = (timestamp) => {
        const date = new Date(timestamp);
        return date.toISOString().split("T")[0];
      };
      const formatSize = (bytes) => {
        if (bytes === 0) return "0 B";
        const units = ["B", "KB", "MB", "GB"];
        const i = Math.floor(Math.log(bytes) / Math.log(1024));
        return `${(bytes / Math.pow(1024, i)).toFixed(2)} ${units[i]}`;
      };
      const handleDownload = async (file) => {
        try {
          const response = await fetch(file.url);
          let blob = await response.blob();
          if (!isImage2(file)) blob = blob.slice(sliceIndex);
          const url = URL.createObjectURL(blob);
          const a = document.createElement("a");
          a.href = url;
          a.download = file.name;
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          URL.revokeObjectURL(url);
        } catch (error) {
          console.error("下载失败:", error);
        }
      };
      const handleDelete = (file) => {
        files.value = files.value.filter(
          (f) => !(f.name === file.name && f.size === file.size)
        );
        console.log("删除后的总文件列表");
        console.log(files.value);
        saveFiles(files.value);
      };
      const handlePreview = (file) => {
        showViewModel.value = true;
        previewImg.value = file;
      };
      const closePreview = () => {
        showViewModel.value = false;
        previewImg.value = null;
      };
      const handleImageLoad = () => {
        loading.value = false;
      };
      const handleImageError = () => {
        loading.value = false;
        loadError.value = true;
      };
      function isImage2(file) {
        var _a2;
        const imageExtensions = ["jpg", "jpeg", "png", "gif", "webp", "bmp"];
        const extension = ((_a2 = file.name.split(".").pop()) == null ? void 0 : _a2.toLowerCase()) || "";
        return imageExtensions.includes(extension);
      }
      function isCompressed(file) {
        var _a2;
        const compressedExtensions = [
          "zip",
          "rar",
          "7z",
          "tar",
          "gz",
          "bz2",
          "xz",
          "dmg",
          "iso",
          "cab",
          "arj",
          "z",
          "lz",
          "lzma",
          "tgz"
        ];
        const extension = ((_a2 = file.name.split(".").pop()) == null ? void 0 : _a2.toLowerCase()) || "";
        return compressedExtensions.includes(extension);
      }
      const handleMouseEnter = () => isHovered.value = true;
      const handleMouseLeave = () => isHovered.value = false;
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
          vue.createElementVNode("div", _hoisted_1$1, [
            vue.createElementVNode("div", _hoisted_2, [
              vue.createElementVNode("h1", _hoisted_3, [
                vue.createElementVNode("a", {
                  href: "https://github.com/WJZ-P/Bilibili-File",
                  target: "_blank",
                  rel: "noopener noreferrer",
                  class: "title-link",
                  onMouseenter: handleMouseEnter,
                  onMouseleave: handleMouseLeave
                }, [
                  vue.createElementVNode("span", _hoisted_4, [
                    !isHovered.value ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
                      vue.createTextVNode("Bilibili File ( 。・▽・。 )ノ")
                    ], 64)) : (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
                      vue.createTextVNode("Bilibili File (*ノωノ)")
                    ], 64))
                  ]),
                  _cache[2] || (_cache[2] = vue.createElementVNode("span", { class: "glow" }, null, -1))
                ], 32)
              ]),
              vue.createElementVNode("div", _hoisted_5, [
                vue.createElementVNode("div", {
                  class: "upload-area",
                  onClick: handleUpload
                }, [
                  _cache[3] || (_cache[3] = vue.createElementVNode("i", { class: "iconfont icon-upload" }, null, -1)),
                  _cache[4] || (_cache[4] = vue.createElementVNode("span", null, "点击上传文件", -1)),
                  vue.createElementVNode("input", {
                    type: "file",
                    ref_key: "fileInputEl",
                    ref: fileInputEl,
                    multiple: "",
                    style: { "display": "none" },
                    onChange: handleFileSelect
                  }, null, 544)
                ]),
                vue.createElementVNode("div", _hoisted_6, [
                  vue.withDirectives(vue.createElementVNode("input", {
                    type: "text",
                    "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => searchQuery.value = $event),
                    placeholder: "搜索文件...",
                    onInput: _cache[1] || (_cache[1] = (...args) => _ctx.handleSearch && _ctx.handleSearch(...args))
                  }, null, 544), [
                    [vue.vModelText, searchQuery.value]
                  ]),
                  _cache[5] || (_cache[5] = vue.createElementVNode("i", { class: "iconfont icon-search" }, [
                    vue.createElementVNode("svg", {
                      xmlns: "http://www.w3.org/2000/svg",
                      height: "24px",
                      viewBox: "0 -960 960 960",
                      width: "24px",
                      fill: "#5f6368"
                    }, [
                      vue.createElementVNode("path", { d: "M781.69-136.92 530.46-388.16q-30 24.77-69 38.77-39 14-80.69 14-102.55 0-173.58-71.01-71.03-71.01-71.03-173.54 0-102.52 71.01-173.6 71.01-71.07 173.54-71.07 102.52 0 173.6 71.03 71.07 71.03 71.07 173.58 0 42.85-14.38 81.85-14.39 39-38.39 67.84l251.23 251.23-42.15 42.16ZM380.77-395.38q77.31 0 130.96-53.66 53.66-53.65 53.66-130.96t-53.66-130.96q-53.65-53.66-130.96-53.66t-130.96 53.66Q196.15-657.31 196.15-580t53.66 130.96q53.65 53.66 130.96 53.66Z" })
                    ])
                  ], -1))
                ])
              ]),
              vue.createElementVNode("div", _hoisted_7, [
                _cache[12] || (_cache[12] = vue.createStaticVNode('<div class="list-header" data-v-733968ef><div class="col-name" data-v-733968ef>文件名</div><div class="col-size" style="text-align:center;" data-v-733968ef>大小</div><div class="col-date" style="text-align:center;" data-v-733968ef>上传日期</div><div class="col-actions" style="text-align:center;" data-v-733968ef>操作</div></div>', 1)),
                (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(filteredFiles.value, (file) => {
                  return vue.openBlock(), vue.createElementBlock("div", {
                    class: "list-item",
                    key: file.name + file.size
                  }, [
                    vue.createElementVNode("div", _hoisted_8, [
                      isImage2(file) ? (vue.openBlock(), vue.createElementBlock("i", _hoisted_9, _cache[6] || (_cache[6] = [
                        vue.createElementVNode("svg", {
                          xmlns: "http://www.w3.org/2000/svg",
                          height: "24px",
                          viewBox: "0 -960 960 960",
                          width: "24px",
                          fill: "#5f6368"
                        }, [
                          vue.createElementVNode("path", { d: "M212.31-140Q182-140 161-161q-21-21-21-51.31v-535.38Q140-778 161-799q21-21 51.31-21h535.38Q778-820 799-799q21 21 21 51.31v535.38Q820-182 799-161q-21 21-51.31 21H212.31Zm0-60h535.38q4.62 0 8.46-3.85 3.85-3.84 3.85-8.46v-535.38q0-4.62-3.85-8.46-3.84-3.85-8.46-3.85H212.31q-4.62 0-8.46 3.85-3.85 3.84-3.85 8.46v535.38q0 4.62 3.85 8.46 3.84 3.85 8.46 3.85ZM270-290h423.07L561.54-465.38 449.23-319.23l-80-102.31L270-290Zm-70 90v-560 560Z" })
                        ], -1)
                      ]))) : isCompressed(file) ? (vue.openBlock(), vue.createElementBlock("i", _hoisted_10, _cache[7] || (_cache[7] = [
                        vue.createElementVNode("svg", {
                          xmlns: "http://www.w3.org/2000/svg",
                          height: "24px",
                          viewBox: "0 -960 960 960",
                          width: "24px",
                          fill: "#5f6368"
                        }, [
                          vue.createElementVNode("path", { d: "M640-480v-80h80v80h-80Zm0 80h-80v-80h80v80Zm0 80v-80h80v80h-80ZM447.38-640l-80-80H172.31q-5.39 0-8.85 3.46t-3.46 8.85v455.38q0 5.39 3.46 8.85t8.85 3.46H560v-80h80v80h147.69q5.39 0 8.85-3.46t3.46-8.85v-375.38q0-5.39-3.46-8.85t-8.85-3.46H640v80h-80v-80H447.38ZM172.31-180Q142-180 121-201q-21-21-21-51.31v-455.38Q100-738 121-759q21-21 51.31-21h219.61l80 80h315.77Q818-700 839-679q21 21 21 51.31v375.38Q860-222 839-201q-21 21-51.31 21H172.31ZM160-240v-480 480Z" })
                        ], -1)
                      ]))) : (vue.openBlock(), vue.createElementBlock("i", _hoisted_11, _cache[8] || (_cache[8] = [
                        vue.createElementVNode("svg", {
                          xmlns: "http://www.w3.org/2000/svg",
                          height: "24px",
                          viewBox: "0 -960 960 960",
                          width: "24px",
                          fill: "#5f6368"
                        }, [
                          vue.createElementVNode("path", { d: "M330-250h300v-60H330v60Zm0-160h300v-60H330v60Zm-77.69 310Q222-100 201-121q-21-21-21-51.31v-615.38Q180-818 201-839q21-21 51.31-21H570l210 210v477.69Q780-142 759-121q-21 21-51.31 21H252.31ZM540-620v-180H252.31q-4.62 0-8.46 3.85-3.85 3.84-3.85 8.46v615.38q0 4.62 3.85 8.46 3.84 3.85 8.46 3.85h455.38q4.62 0 8.46-3.85 3.85-3.84 3.85-8.46V-620H540ZM240-800v180-180V-160v-640Z" })
                        ], -1)
                      ]))),
                      vue.createTextVNode(" " + vue.toDisplayString(file.name), 1)
                    ]),
                    vue.createElementVNode("div", _hoisted_12, vue.toDisplayString(formatSize(file.size)), 1),
                    vue.createElementVNode("div", _hoisted_13, vue.toDisplayString(formatDate(file.lastModified)), 1),
                    vue.createElementVNode("div", _hoisted_14, [
                      isImage2(file) ? (vue.openBlock(), vue.createElementBlock("button", {
                        key: 0,
                        class: "btn-preview",
                        onClick: vue.withModifiers(($event) => handlePreview(file), ["stop"])
                      }, _cache[9] || (_cache[9] = [
                        vue.createElementVNode("i", { class: "iconfont icon-preview" }, [
                          vue.createElementVNode("svg", {
                            xmlns: "http://www.w3.org/2000/svg",
                            height: "20px",
                            viewBox: "0 -960 960 960",
                            width: "20px",
                            fill: "#5f6368"
                          }, [
                            vue.createElementVNode("path", { d: "M480.09-336.92q67.99 0 115.49-47.59t47.5-115.58q0-67.99-47.59-115.49t-115.58-47.5q-67.99 0-115.49 47.59t-47.5 115.58q0 67.99 47.59 115.49t115.58 47.5ZM480-392q-45 0-76.5-31.5T372-500q0-45 31.5-76.5T480-608q45 0 76.5 31.5T588-500q0 45-31.5 76.5T480-392Zm.05 172q-137.97 0-251.43-76.12Q115.16-372.23 61.54-500q53.62-127.77 167.02-203.88Q341.97-780 479.95-780q137.97 0 251.43 76.12Q844.84-627.77 898.46-500q-53.62 127.77-167.02 203.88Q618.03-220 480.05-220ZM480-500Zm0 220q113 0 207.5-59.5T832-500q-50-101-144.5-160.5T480-720q-113 0-207.5 59.5T128-500q50 101 144.5 160.5T480-280Z" })
                          ])
                        ], -1),
                        vue.createElementVNode("span", null, "预览", -1)
                      ]), 8, _hoisted_15)) : vue.createCommentVNode("", true),
                      vue.createElementVNode("button", {
                        class: "btn-download",
                        onClick: vue.withModifiers(($event) => handleDownload(file), ["stop"])
                      }, _cache[10] || (_cache[10] = [
                        vue.createElementVNode("i", { class: "iconfont icon-download" }, [
                          vue.createElementVNode("svg", {
                            xmlns: "http://www.w3.org/2000/svg",
                            height: "20px",
                            viewBox: "0 -960 960 960",
                            width: "20px",
                            fill: "#5f6368"
                          }, [
                            vue.createElementVNode("path", { d: "M480-328.46 309.23-499.23l42.16-43.38L450-444v-336h60v336l98.61-98.61 42.16 43.38L480-328.46ZM252.31-180Q222-180 201-201q-21-21-21-51.31v-108.46h60v108.46q0 4.62 3.85 8.46 3.84 3.85 8.46 3.85h455.38q4.62 0 8.46-3.85 3.85-3.84 3.85-8.46v-108.46h60v108.46Q780-222 759-201q-21 21-51.31 21H252.31Z" })
                          ])
                        ], -1),
                        vue.createElementVNode("span", null, "下载", -1)
                      ]), 8, _hoisted_16),
                      vue.createElementVNode("button", {
                        class: "btn-delete",
                        onClick: vue.withModifiers(($event) => handleDelete(file), ["stop"])
                      }, _cache[11] || (_cache[11] = [
                        vue.createElementVNode("i", { class: "iconfont icon-delete" }, [
                          vue.createElementVNode("svg", {
                            xmlns: "http://www.w3.org/2000/svg",
                            height: "20px",
                            viewBox: "0 -960 960 960",
                            width: "20px",
                            fill: "#5f6368"
                          }, [
                            vue.createElementVNode("path", { d: "M292.31-140q-29.92 0-51.12-21.19Q220-182.39 220-212.31V-720h-40v-60h180v-35.38h240V-780h180v60h-40v507.69Q740-182 719-161q-21 21-51.31 21H292.31ZM680-720H280v507.69q0 5.39 3.46 8.85t8.85 3.46h375.38q4.62 0 8.46-3.85 3.85-3.84 3.85-8.46V-720ZM376.16-280h59.99v-360h-59.99v360Zm147.69 0h59.99v-360h-59.99v360ZM280-720v520-520Z" })
                          ])
                        ], -1),
                        vue.createElementVNode("span", null, "删除", -1)
                      ]), 8, _hoisted_17)
                    ])
                  ]);
                }), 128))
              ])
            ]),
            _cache[13] || (_cache[13] = vue.createElementVNode("div", { class: "footer-info" }, [
              vue.createTextVNode(" © 2024 "),
              vue.createElementVNode("a", {
                href: "https://github.com/WJZ-P/Bilibili-File",
                target: "_blank",
                title: "GitHub地址"
              }, "Bilibili File"),
              vue.createTextVNode(". Made by WJZ_P with love. ( ̄▽ ̄) ")
            ], -1))
          ]),
          (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
            vue.createVNode(vue.Transition, { name: "modal-fade" }, {
              default: vue.withCtx(() => [
                showViewModel.value ? (vue.openBlock(), vue.createElementBlock("div", {
                  key: 0,
                  class: "preview-modal",
                  onClick: vue.withModifiers(closePreview, ["self"])
                }, [
                  vue.createElementVNode("div", _hoisted_18, [
                    vue.createElementVNode("button", {
                      class: "close-btn",
                      onClick: closePreview
                    }, _cache[14] || (_cache[14] = [
                      vue.createElementVNode("i", { class: "iconfont icon-close" }, [
                        vue.createElementVNode("svg", {
                          xmlns: "http://www.w3.org/2000/svg",
                          height: "24px",
                          viewBox: "0 -960 960 960",
                          width: "24px",
                          fill: "#5f6368"
                        }, [
                          vue.createElementVNode("path", { d: "M256-213.85 213.85-256l224-224-224-224L256-746.15l224 224 224-224L746.15-704l-224 224 224 224L704-213.85l-224-224-224 224Z" })
                        ])
                      ], -1)
                    ])),
                    vue.createElementVNode("div", _hoisted_19, [
                      vue.createElementVNode("img", {
                        src: previewImg.value.url,
                        alt: previewImg.value.name,
                        onLoad: handleImageLoad,
                        onError: handleImageError
                      }, null, 40, _hoisted_20),
                      loading.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_21, _cache[15] || (_cache[15] = [
                        vue.createElementVNode("div", { class: "spinner" }, null, -1),
                        vue.createElementVNode("span", null, "加载中...", -1)
                      ]))) : vue.createCommentVNode("", true)
                    ]),
                    vue.createElementVNode("div", _hoisted_22, vue.toDisplayString(previewImg.value.name), 1)
                  ])
                ])) : vue.createCommentVNode("", true)
              ]),
              _: 1
            })
          ]))
        ], 64);
      };
    }
  };
  const MainMenu = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-733968ef"]]);
  const _hoisted_1 = { class: "main-container" };
  const _sfc_main = {
    __name: "App",
    setup(__props) {
      return (_ctx, _cache) => {
        return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
          vue.createVNode(MainMenu)
        ]);
      };
    }
  };
  const urls = ["https://www.bilibili.com/", "https://www.bilibili.com", "http://www.bilibili.com/", "http://www.bilibili.com"];
  vue.createApp(_sfc_main).mount(
    (() => {
      if (document.contentType !== "text/html" || window.location.href !== "https://www.bilibili.com/bilibili-file") return;
      const app = document.createElement("div");
      document.querySelector(".error-container").remove();
      document.body.append(app);
      return app;
    })()
  );
  console.log("[Bilibili-File] 启动");
  credentials["bili_jct"] = (_a = document.cookie.split("; ").find((row) => row.startsWith("bili_jct="))) == null ? void 0 : _a.split("=")[1];
  credentials["cookie"] = document.cookie;
  if (urls.includes(window.location.href)) addMyBtn();
  else console.log("[Bilibili-File] 不在B站首页,不添加上传按钮");
  if (window.location.href.includes("bilibili-file")) {
    document.title = "文件上传 - Bilibili-File";
  }
  function addMyBtn() {
    const list = document.querySelector(".right-entry");
    const button = document.querySelector(".right-entry-item--upload");
    let cloneBtn;
    if (list && button) {
      cloneBtn = button.cloneNode(true);
      cloneBtn.id = "bilibili-file-uploadFile";
      list.appendChild(cloneBtn);
    } else {
      console.log("[Bilibili-File] 元素未找到,添加上传按钮失败");
    }
    cloneBtn.querySelector(".header-upload-entry__text").textContent = "传输";
    cloneBtn.querySelector(".header-upload-entry__icon").innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="#ffffff"><path d="M450-224.62h60V-402l74 74 42.15-42.77L480-516.92 333.85-370.77l42.77 42.15L450-402v177.38ZM252.31-100Q222-100 201-121q-21-21-21-51.31v-615.38Q180-818 201-839q21-21 51.31-21H570l210 210v477.69Q780-142 759-121q-21 21-51.31 21H252.31ZM540-620v-180H252.31q-4.62 0-8.46 3.85-3.85 3.84-3.85 8.46v615.38q0 4.62 3.85 8.46 3.84 3.85 8.46 3.85h455.38q4.62 0 8.46-3.85 3.85-3.84 3.85-8.46V-620H540ZM240-800v180-180V-160v-640Z"/></svg>`;
    cloneBtn.onclick = null;
    cloneBtn.removeAttribute("onclick");
    cloneBtn.addEventListener("click", (event) => {
      window.location.href = "https://www.bilibili.com/bilibili-file";
    });
  }

})(Vue);

QingJ © 2025

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