✨ 增加镜像源下载
This commit is contained in:
parent
357cc473c7
commit
1f246e3966
@ -1,244 +1,280 @@
|
|||||||
import electron, {app, BrowserWindow, ipcMain, net, shell} from "electron";
|
import electron, { app, BrowserWindow, ipcMain, net, shell } from "electron";
|
||||||
import {deleteVersionById, insertVersion, listVersion} from "../storage/version";
|
import {
|
||||||
|
deleteVersionById,
|
||||||
|
insertVersion,
|
||||||
|
listVersion
|
||||||
|
} from "../storage/version";
|
||||||
|
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const zlib = require("zlib");
|
const zlib = require("zlib");
|
||||||
const {download} = require("electron-dl");
|
const { download } = require("electron-dl");
|
||||||
const AdmZip = require('adm-zip');
|
const AdmZip = require("adm-zip");
|
||||||
const log = require('electron-log');
|
const log = require("electron-log");
|
||||||
|
|
||||||
const versionRelation = {
|
const versionRelation = {
|
||||||
"win32_x64": ["window", "amd64"],
|
win32_x64: ["window", "amd64"],
|
||||||
"win32_arm64": ["window", "arm64"],
|
win32_arm64: ["window", "arm64"],
|
||||||
"win32_ia32": ["window", "386"],
|
win32_ia32: ["window", "386"],
|
||||||
"darwin_arm64": ["darwin", "arm64"],
|
darwin_arm64: ["darwin", "arm64"],
|
||||||
"darwin_x64": ["darwin", "amd64"],
|
darwin_x64: ["darwin", "amd64"],
|
||||||
"darwin_amd64": ["darwin", "amd64"],
|
darwin_amd64: ["darwin", "amd64"],
|
||||||
"linux_x64": ["linux", "amd64"],
|
linux_x64: ["linux", "amd64"],
|
||||||
"linux_arm64": ["linux", "arm64"],
|
linux_arm64: ["linux", "arm64"]
|
||||||
}
|
};
|
||||||
const platform = process.platform;
|
const platform = process.platform;
|
||||||
const arch = process.arch;
|
const arch = process.arch;
|
||||||
let currArch = `${platform}_${arch}`
|
let currArch = `${platform}_${arch}`;
|
||||||
const frpArch = versionRelation[currArch]
|
const frpArch = versionRelation[currArch];
|
||||||
|
|
||||||
const unTarGZ = (tarGzPath: string, targetPath: string) => {
|
const unTarGZ = (tarGzPath: string, targetPath: string) => {
|
||||||
const tar = require("tar");
|
const tar = require("tar");
|
||||||
const unzip = zlib.createGunzip();
|
const unzip = zlib.createGunzip();
|
||||||
log.debug(`开始解压tar.gz:${tarGzPath} 目标目录:${targetPath}`);
|
log.debug(`开始解压tar.gz:${tarGzPath} 目标目录:${targetPath}`);
|
||||||
const readStream = fs.createReadStream(tarGzPath);
|
const readStream = fs.createReadStream(tarGzPath);
|
||||||
if (!fs.existsSync(unzip)) {
|
if (!fs.existsSync(unzip)) {
|
||||||
fs.mkdirSync(targetPath, {recursive: true});
|
fs.mkdirSync(targetPath, { recursive: true });
|
||||||
}
|
}
|
||||||
readStream.pipe(unzip).pipe(
|
readStream.pipe(unzip).pipe(
|
||||||
tar.extract({
|
tar.extract({
|
||||||
cwd: targetPath,
|
cwd: targetPath,
|
||||||
filter: filePath => path.basename(filePath) === "frpc"
|
filter: filePath => path.basename(filePath) === "frpc"
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
const frpcPath = path.join("frp", path.basename(tarGzPath, ".tar.gz"));
|
const frpcPath = path.join("frp", path.basename(tarGzPath, ".tar.gz"));
|
||||||
log.debug(`解压完成 解压后目录:${frpcPath}`);
|
log.debug(`解压完成 解压后目录:${frpcPath}`);
|
||||||
return frpcPath;
|
return frpcPath;
|
||||||
// .on("finish", () => {
|
// .on("finish", () => {
|
||||||
// console.log("解压完成!");
|
// console.log("解压完成!");
|
||||||
// });
|
// });
|
||||||
};
|
};
|
||||||
|
|
||||||
const unZip = (zipPath: string, targetPath: string) => {
|
const unZip = (zipPath: string, targetPath: string) => {
|
||||||
if (!fs.existsSync(path.join(targetPath, path.basename(zipPath, ".zip")))) {
|
if (!fs.existsSync(path.join(targetPath, path.basename(zipPath, ".zip")))) {
|
||||||
fs.mkdirSync(path.join(targetPath, path.basename(zipPath, ".zip")), {recursive: true});
|
fs.mkdirSync(path.join(targetPath, path.basename(zipPath, ".zip")), {
|
||||||
}
|
recursive: true
|
||||||
log.debug(`开始解压zip:${zipPath} 目标目录:${targetPath}`);
|
});
|
||||||
/**
|
}
|
||||||
* unzipper解压
|
log.debug(`开始解压zip:${zipPath} 目标目录:${targetPath}`);
|
||||||
*/
|
/**
|
||||||
// fs.createReadStream(zipPath)
|
* unzipper解压
|
||||||
// .pipe(unzipper.Extract({ path: targetPath }))
|
*/
|
||||||
// // 只解压frpc.exe
|
// fs.createReadStream(zipPath)
|
||||||
// // .pipe(unzipper.ParseOne('frpc'))
|
// .pipe(unzipper.Extract({ path: targetPath }))
|
||||||
// // .pipe(fs.createWriteStream(path.join(targetPath, path.basename(zipPath, ".zip"), "frpc.exe")))
|
// // 只解压frpc.exe
|
||||||
// .on('finish', () => {
|
// // .pipe(unzipper.ParseOne('frpc'))
|
||||||
// console.log('File extracted successfully.');
|
// // .pipe(fs.createWriteStream(path.join(targetPath, path.basename(zipPath, ".zip"), "frpc.exe")))
|
||||||
// })
|
// .on('finish', () => {
|
||||||
// .on('error', (err) => {
|
// console.log('File extracted successfully.');
|
||||||
// console.error('Error extracting file:', err);
|
// })
|
||||||
// });
|
// .on('error', (err) => {
|
||||||
|
// console.error('Error extracting file:', err);
|
||||||
|
// });
|
||||||
|
|
||||||
const zip = new AdmZip(zipPath)
|
const zip = new AdmZip(zipPath);
|
||||||
zip.extractAllTo(targetPath, true); // 第二个参数为 true,表示覆盖已存在的文件
|
zip.extractAllTo(targetPath, true); // 第二个参数为 true,表示覆盖已存在的文件
|
||||||
const frpcPath = path.join("frp", path.basename(zipPath, ".zip"));
|
const frpcPath = path.join("frp", path.basename(zipPath, ".zip"));
|
||||||
log.debug(`解压完成 解压后目录:${frpcPath}`);
|
log.debug(`解压完成 解压后目录:${frpcPath}`);
|
||||||
return frpcPath
|
return frpcPath;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const initGitHubApi = () => {
|
export const initGitHubApi = () => {
|
||||||
// 版本
|
// 版本
|
||||||
let versions: FrpVersion[] = [];
|
let versions: FrpVersion[] = [];
|
||||||
|
|
||||||
const getVersion = versionId => {
|
const getVersion = versionId => {
|
||||||
return versions.find(f => f.id === versionId);
|
return versions.find(f => f.id === versionId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAdaptiveAsset = versionId => {
|
const getAdaptiveAsset = versionId => {
|
||||||
const {assets} = getVersion(versionId);
|
const { assets } = getVersion(versionId);
|
||||||
const asset = assets.find(
|
const asset = assets.find(f => {
|
||||||
f => {
|
// const a = versionRelation[currArch]
|
||||||
// const a = versionRelation[currArch]
|
const a = frpArch;
|
||||||
const a = frpArch
|
if (a) {
|
||||||
if (a) {
|
const flag = a.every(item => f.name.includes(item));
|
||||||
const flag = a.every(item => f.name.includes(item))
|
return flag;
|
||||||
return flag;
|
}
|
||||||
}
|
return false;
|
||||||
return false;
|
});
|
||||||
}
|
if (asset) {
|
||||||
|
log.info(`找到对应版本 ${asset.name}`);
|
||||||
|
}
|
||||||
|
return asset;
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatBytes = (bytes: number, decimals: number = 2): string => {
|
||||||
|
if (bytes === 0) return "0 Bytes";
|
||||||
|
const k = 1024; // 1 KB = 1024 Bytes
|
||||||
|
const dm = decimals < 0 ? 0 : decimals; // 确保小数位数不小于 0
|
||||||
|
const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
|
||||||
|
|
||||||
|
const i = Math.floor(Math.log(bytes) / Math.log(k)); // 计算单位索引
|
||||||
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i]; // 返回格式化的字符串
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取github上的frp所有版本
|
||||||
|
*/
|
||||||
|
ipcMain.on("github.getFrpVersions", async event => {
|
||||||
|
const request = net.request({
|
||||||
|
method: "get",
|
||||||
|
url: "https://api.github.com/repos/fatedier/frp/releases?page=1&per_page=1000"
|
||||||
|
});
|
||||||
|
request.on("response", response => {
|
||||||
|
let responseData: Buffer = Buffer.alloc(0);
|
||||||
|
response.on("data", (data: Buffer) => {
|
||||||
|
responseData = Buffer.concat([responseData, data]);
|
||||||
|
});
|
||||||
|
response.on("end", () => {
|
||||||
|
versions = JSON.parse(responseData.toString());
|
||||||
|
// const borderContent: Electron.WebContents =
|
||||||
|
// BrowserWindow.getFocusedWindow().webContents;
|
||||||
|
const downloadPath = path.join(app.getPath("userData"), "download");
|
||||||
|
log.info(
|
||||||
|
`开始获取frp版本 当前架构:${currArch} 对应frp架构:${frpArch}`
|
||||||
);
|
);
|
||||||
if (asset) {
|
const returnVersionsData = versions
|
||||||
log.info(`找到对应版本 ${asset.name}`)
|
.filter(f => getAdaptiveAsset(f.id))
|
||||||
}
|
.map(m => {
|
||||||
return asset;
|
const asset = getAdaptiveAsset(m.id);
|
||||||
};
|
const download_count = m.assets.reduce(
|
||||||
|
(sum, item) => sum + item.download_count,
|
||||||
/**
|
0
|
||||||
* 获取github上的frp所有版本
|
);
|
||||||
*/
|
if (asset) {
|
||||||
ipcMain.on("github.getFrpVersions", async event => {
|
const absPath = `${downloadPath}/${asset.name}`;
|
||||||
const request = net.request({
|
m.absPath = absPath;
|
||||||
method: "get",
|
m.download_completed = fs.existsSync(absPath);
|
||||||
url: "https://api.github.com/repos/fatedier/frp/releases?page=1&per_page=1000"
|
m.download_count = download_count;
|
||||||
});
|
m.size = formatBytes(asset.size);
|
||||||
request.on("response", response => {
|
|
||||||
let responseData: Buffer = Buffer.alloc(0);
|
|
||||||
response.on("data", (data: Buffer) => {
|
|
||||||
responseData = Buffer.concat([responseData, data]);
|
|
||||||
});
|
|
||||||
response.on("end", () => {
|
|
||||||
versions = JSON.parse(responseData.toString());
|
|
||||||
// const borderContent: Electron.WebContents =
|
|
||||||
// BrowserWindow.getFocusedWindow().webContents;
|
|
||||||
const downloadPath = path.join(app.getPath("userData"), "download");
|
|
||||||
log.info(`开始获取frp版本 当前架构:${currArch} 对应frp架构:${frpArch}`)
|
|
||||||
const returnVersionsData = versions
|
|
||||||
.filter(f => getAdaptiveAsset(f.id))
|
|
||||||
.map(m => {
|
|
||||||
const asset = getAdaptiveAsset(m.id);
|
|
||||||
if (asset) {
|
|
||||||
const absPath = `${downloadPath}/${asset.name}`;
|
|
||||||
m.absPath = absPath;
|
|
||||||
m.download_completed = fs.existsSync(absPath);
|
|
||||||
}
|
|
||||||
return m;
|
|
||||||
});
|
|
||||||
// log.debug(`获取到frp版本:${JSON.stringify(returnVersionsData)}`)
|
|
||||||
event.reply("Download.frpVersionHook", returnVersionsData);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
request.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下载请求
|
|
||||||
*/
|
|
||||||
ipcMain.on("github.download", async (event, args) => {
|
|
||||||
const version = getVersion(args);
|
|
||||||
const asset = getAdaptiveAsset(args);
|
|
||||||
const {browser_download_url} = asset;
|
|
||||||
log.info(`开始下载frp url:${browser_download_url} asset:${asset.name}`)
|
|
||||||
// 数据目录
|
|
||||||
await download(BrowserWindow.getFocusedWindow(), browser_download_url, {
|
|
||||||
filename: `${asset.name}`,
|
|
||||||
directory: path.join(app.getPath("userData"), "download"),
|
|
||||||
onProgress: progress => {
|
|
||||||
event.reply("Download.frpVersionDownloadOnProgress", {
|
|
||||||
id: args,
|
|
||||||
progress: progress
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onCompleted: () => {
|
|
||||||
log.info(`frp下载完成 url:${browser_download_url} asset:${asset.name}`)
|
|
||||||
const targetPath = path.resolve(path.join(app.getPath("userData"), "frp"));
|
|
||||||
const ext = path.extname(asset.name)
|
|
||||||
let frpcVersionPath = ""
|
|
||||||
if (ext === '.zip') {
|
|
||||||
frpcVersionPath = unZip(path.join(
|
|
||||||
path.join(app.getPath("userData"), "download"),
|
|
||||||
`${asset.name}`
|
|
||||||
),
|
|
||||||
targetPath)
|
|
||||||
} else if (ext === '.gz' && asset.name.includes(".tar.gz")) {
|
|
||||||
frpcVersionPath = unTarGZ(
|
|
||||||
path.join(
|
|
||||||
path.join(app.getPath("userData"), "download"),
|
|
||||||
`${asset.name}`
|
|
||||||
),
|
|
||||||
targetPath
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
version["frpcVersionPath"] = frpcVersionPath;
|
|
||||||
insertVersion(version, (err, document) => {
|
|
||||||
if (!err) {
|
|
||||||
listVersion((err, doc) => {
|
|
||||||
event.reply("Config.versions.hook", { err, data: doc });
|
|
||||||
event.reply("Download.frpVersionDownloadOnCompleted", args);
|
|
||||||
version.download_completed = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
return m;
|
||||||
|
});
|
||||||
|
// log.debug(`获取到frp版本:${JSON.stringify(returnVersionsData)}`)
|
||||||
|
event.reply("Download.frpVersionHook", returnVersionsData);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
request.end();
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除下载
|
* 下载请求
|
||||||
*/
|
*/
|
||||||
ipcMain.on("github.deleteVersion", async (event, args) => {
|
ipcMain.on("github.download", async (event, args) => {
|
||||||
const {absPath, id} = args;
|
const { versionId, mirror } = args;
|
||||||
if (fs.existsSync(absPath)) {
|
const version = getVersion(versionId);
|
||||||
deleteVersionById(id, () => {
|
const asset = getAdaptiveAsset(versionId);
|
||||||
fs.unlinkSync(absPath)
|
const { browser_download_url } = asset;
|
||||||
})
|
|
||||||
|
let url = browser_download_url;
|
||||||
|
if (mirror === "ghproxy") {
|
||||||
|
url = "https://mirror.ghproxy.com/" + url;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info(`开始下载frp url:${url} asset:${asset.name}`);
|
||||||
|
// 数据目录
|
||||||
|
await download(BrowserWindow.getFocusedWindow(), url, {
|
||||||
|
filename: `${asset.name}`,
|
||||||
|
directory: path.join(app.getPath("userData"), "download"),
|
||||||
|
onProgress: progress => {
|
||||||
|
event.reply("Download.frpVersionDownloadOnProgress", {
|
||||||
|
id: versionId,
|
||||||
|
progress: progress
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onCompleted: () => {
|
||||||
|
log.info(`frp下载完成 url:${url} asset:${asset.name}`);
|
||||||
|
const targetPath = path.resolve(
|
||||||
|
path.join(app.getPath("userData"), "frp")
|
||||||
|
);
|
||||||
|
const ext = path.extname(asset.name);
|
||||||
|
let frpcVersionPath = "";
|
||||||
|
if (ext === ".zip") {
|
||||||
|
frpcVersionPath = unZip(
|
||||||
|
path.join(
|
||||||
|
path.join(app.getPath("userData"), "download"),
|
||||||
|
`${asset.name}`
|
||||||
|
),
|
||||||
|
targetPath
|
||||||
|
);
|
||||||
|
} else if (ext === ".gz" && asset.name.includes(".tar.gz")) {
|
||||||
|
frpcVersionPath = unTarGZ(
|
||||||
|
path.join(
|
||||||
|
path.join(app.getPath("userData"), "download"),
|
||||||
|
`${asset.name}`
|
||||||
|
),
|
||||||
|
targetPath
|
||||||
|
);
|
||||||
}
|
}
|
||||||
listVersion((err, doc) => {
|
|
||||||
event.reply("Config.versions.hook", { err, data: doc });
|
|
||||||
event.reply("Download.deleteVersion.hook", { err: null, data: "删除成功" });
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
version["frpcVersionPath"] = frpcVersionPath;
|
||||||
* 获取最后版本
|
insertVersion(version, (err, document) => {
|
||||||
*/
|
if (!err) {
|
||||||
ipcMain.on("github.getFrpcDesktopLastVersions", async event => {
|
listVersion((err, doc) => {
|
||||||
const request = net.request({
|
event.reply("Config.versions.hook", { err, data: doc });
|
||||||
method: "get",
|
event.reply("Download.frpVersionDownloadOnCompleted", versionId);
|
||||||
url: "https://api.github.com/repos/luckjiawei/frpc-desktop/releases/latest"
|
version.download_completed = true;
|
||||||
});
|
|
||||||
request.on("response", response => {
|
|
||||||
let responseData: Buffer = Buffer.alloc(0);
|
|
||||||
response.on("data", (data: Buffer) => {
|
|
||||||
responseData = Buffer.concat([responseData, data]);
|
|
||||||
});
|
|
||||||
response.on("end", () => {
|
|
||||||
versions = JSON.parse(responseData.toString());
|
|
||||||
// const borderContent: Electron.WebContents =
|
|
||||||
// BrowserWindow.getFocusedWindow().webContents;
|
|
||||||
// const downloadPath = path.join(app.getPath("userData"), "download");
|
|
||||||
// log.info(`开始获取frp版本 当前架构:${currArch} 对应frp架构:${frpArch}`)
|
|
||||||
// const returnVersionsData = versions
|
|
||||||
// .filter(f => getAdaptiveAsset(f.id))
|
|
||||||
// .map(m => {
|
|
||||||
// const asset = getAdaptiveAsset(m.id);
|
|
||||||
// if (asset) {
|
|
||||||
// const absPath = `${downloadPath}/${asset.name}`;
|
|
||||||
// m.absPath = absPath;
|
|
||||||
// m.download_completed = fs.existsSync(absPath);
|
|
||||||
// }
|
|
||||||
// return m;
|
|
||||||
// });
|
|
||||||
// log.debug(`获取到frp版本:${JSON.stringify(returnVersionsData)}`)
|
|
||||||
event.reply("github.getFrpcDesktopLastVersionsHook", versions);
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
request.end();
|
}
|
||||||
})
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除下载
|
||||||
|
*/
|
||||||
|
ipcMain.on("github.deleteVersion", async (event, args) => {
|
||||||
|
const { absPath, id } = args;
|
||||||
|
if (fs.existsSync(absPath)) {
|
||||||
|
deleteVersionById(id, () => {
|
||||||
|
fs.unlinkSync(absPath);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
listVersion((err, doc) => {
|
||||||
|
event.reply("Config.versions.hook", { err, data: doc });
|
||||||
|
event.reply("Download.deleteVersion.hook", {
|
||||||
|
err: null,
|
||||||
|
data: "删除成功"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取最后版本
|
||||||
|
*/
|
||||||
|
ipcMain.on("github.getFrpcDesktopLastVersions", async event => {
|
||||||
|
const request = net.request({
|
||||||
|
method: "get",
|
||||||
|
url: "https://api.github.com/repos/luckjiawei/frpc-desktop/releases/latest"
|
||||||
|
});
|
||||||
|
request.on("response", response => {
|
||||||
|
let responseData: Buffer = Buffer.alloc(0);
|
||||||
|
response.on("data", (data: Buffer) => {
|
||||||
|
responseData = Buffer.concat([responseData, data]);
|
||||||
|
});
|
||||||
|
response.on("end", () => {
|
||||||
|
versions = JSON.parse(responseData.toString());
|
||||||
|
// const borderContent: Electron.WebContents =
|
||||||
|
// BrowserWindow.getFocusedWindow().webContents;
|
||||||
|
// const downloadPath = path.join(app.getPath("userData"), "download");
|
||||||
|
// log.info(`开始获取frp版本 当前架构:${currArch} 对应frp架构:${frpArch}`)
|
||||||
|
// const returnVersionsData = versions
|
||||||
|
// .filter(f => getAdaptiveAsset(f.id))
|
||||||
|
// .map(m => {
|
||||||
|
// const asset = getAdaptiveAsset(m.id);
|
||||||
|
// if (asset) {
|
||||||
|
// const absPath = `${downloadPath}/${asset.name}`;
|
||||||
|
// m.absPath = absPath;
|
||||||
|
// m.download_completed = fs.existsSync(absPath);
|
||||||
|
// }
|
||||||
|
// return m;
|
||||||
|
// });
|
||||||
|
// log.debug(`获取到frp版本:${JSON.stringify(returnVersionsData)}`)
|
||||||
|
event.reply("github.getFrpcDesktopLastVersionsHook", versions);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
request.end();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
@ -20,3 +20,20 @@
|
|||||||
|
|
||||||
html {
|
html {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.h2 {
|
||||||
|
color: #5a3daa;
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
|
||||||
|
"Microsoft YaHei", "微软雅黑", Arial, sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
padding: 6px 10px 6px 15px;
|
||||||
|
border-left: 5px solid #5a3daa;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #eeebf6;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-border {
|
||||||
|
border-left: 5px solid #5a3daa;
|
||||||
|
}
|
||||||
|
@ -950,19 +950,6 @@ onUnmounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.h2 {
|
|
||||||
color: #5a3daa;
|
|
||||||
font-size: 16px;
|
|
||||||
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
|
|
||||||
"Microsoft YaHei", "微软雅黑", Arial, sans-serif;
|
|
||||||
font-weight: 700;
|
|
||||||
padding: 6px 10px 6px 15px;
|
|
||||||
border-left: 5px solid #5a3daa;
|
|
||||||
border-radius: 4px;
|
|
||||||
background-color: #eeebf6;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-input {
|
.button-input {
|
||||||
width: calc(100% - 68px);
|
width: calc(100% - 68px);
|
||||||
}
|
}
|
||||||
|
7
types/global.d.ts
vendored
7
types/global.d.ts
vendored
@ -45,6 +45,8 @@ declare global {
|
|||||||
name: string;
|
name: string;
|
||||||
published_at: string;
|
published_at: string;
|
||||||
download_completed: boolean;
|
download_completed: boolean;
|
||||||
|
size: string;
|
||||||
|
download_count: number;
|
||||||
absPath: string;
|
absPath: string;
|
||||||
assets: Asset[]
|
assets: Asset[]
|
||||||
};
|
};
|
||||||
@ -75,6 +77,11 @@ declare global {
|
|||||||
transportHeartbeatTimeout: number;
|
transportHeartbeatTimeout: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type GitHubMirror = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
export {};
|
export {};
|
Loading…
Reference in New Issue
Block a user