mirror of
https://github.com/ragestudio/relic.git
synced 2025-06-09 02:24:18 +00:00
added installation path selector
This commit is contained in:
parent
67db27cf28
commit
f1257ec7f3
@ -34,10 +34,11 @@
|
|||||||
"unzipper": "^0.10.14",
|
"unzipper": "^0.10.14",
|
||||||
"upath": "^2.0.1",
|
"upath": "^2.0.1",
|
||||||
"uuid": "^9.0.1",
|
"uuid": "^9.0.1",
|
||||||
|
"webtorrent": "^2.4.1",
|
||||||
"winston": "^3.13.0"
|
"winston": "^3.13.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@swc/cli": "^0.3.12",
|
"@swc/cli": "^0.3.12",
|
||||||
"@swc/core": "^1.4.11"
|
"@swc/core": "^1.4.11"
|
||||||
}
|
}
|
||||||
}
|
}
|
57
packages/core/src/classes/Settings.js
Normal file
57
packages/core/src/classes/Settings.js
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import fs from "node:fs"
|
||||||
|
import path from "node:path"
|
||||||
|
import Vars from "../vars"
|
||||||
|
|
||||||
|
const settingsPath = path.resolve(Vars.runtime_path, "settings.json")
|
||||||
|
|
||||||
|
export default class Settings {
|
||||||
|
static filePath = settingsPath
|
||||||
|
|
||||||
|
static async initialize() {
|
||||||
|
if (!fs.existsSync(settingsPath)) {
|
||||||
|
await fs.promises.writeFile(settingsPath, "{}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async read() {
|
||||||
|
return JSON.parse(await fs.promises.readFile(settingsPath, "utf8"))
|
||||||
|
}
|
||||||
|
|
||||||
|
static async write(data) {
|
||||||
|
await fs.promises.writeFile(settingsPath, JSON.stringify(data, null, 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
static async get(key) {
|
||||||
|
const data = await this.read()
|
||||||
|
|
||||||
|
if (key) {
|
||||||
|
return data[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
static async has(key) {
|
||||||
|
const data = await this.read()
|
||||||
|
|
||||||
|
return key in data
|
||||||
|
}
|
||||||
|
|
||||||
|
static async set(key, value) {
|
||||||
|
const data = await this.read()
|
||||||
|
|
||||||
|
data[key] = value
|
||||||
|
|
||||||
|
await this.write(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
static async delete(key) {
|
||||||
|
const data = await this.read()
|
||||||
|
|
||||||
|
delete data[key]
|
||||||
|
|
||||||
|
await this.write(data)
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
@ -4,18 +4,21 @@ import ISM_GIT_CLONE from "./git_clone"
|
|||||||
import ISM_GIT_PULL from "./git_pull"
|
import ISM_GIT_PULL from "./git_pull"
|
||||||
import ISM_GIT_RESET from "./git_reset"
|
import ISM_GIT_RESET from "./git_reset"
|
||||||
import ISM_HTTP from "./http"
|
import ISM_HTTP from "./http"
|
||||||
|
import ISM_TORRENT from "./torrent"
|
||||||
|
|
||||||
const InstallationStepsMethods = {
|
const InstallationStepsMethods = {
|
||||||
git_clone: ISM_GIT_CLONE,
|
git_clone: ISM_GIT_CLONE,
|
||||||
git_pull: ISM_GIT_PULL,
|
git_pull: ISM_GIT_PULL,
|
||||||
git_reset: ISM_GIT_RESET,
|
git_reset: ISM_GIT_RESET,
|
||||||
http_file: ISM_HTTP,
|
http_file: ISM_HTTP,
|
||||||
|
torrent: ISM_TORRENT,
|
||||||
}
|
}
|
||||||
|
|
||||||
const StepsOrders = [
|
const StepsOrders = [
|
||||||
"git_clones",
|
"git_clones",
|
||||||
"git_pull",
|
"git_pull",
|
||||||
"git_reset",
|
"git_reset",
|
||||||
|
"torrent",
|
||||||
"http_file",
|
"http_file",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -37,7 +40,7 @@ export default async function processGenericSteps(pkg, steps, logger = Logger, a
|
|||||||
for await (let step of steps) {
|
for await (let step of steps) {
|
||||||
step.type = step.type.toLowerCase()
|
step.type = step.type.toLowerCase()
|
||||||
|
|
||||||
if (abortController.signal.aborted) {
|
if (abortController?.signal?.aborted) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
44
packages/core/src/generic_steps/torrent.js
Normal file
44
packages/core/src/generic_steps/torrent.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import path from "node:path"
|
||||||
|
|
||||||
|
import parseStringVars from "../utils/parseStringVars"
|
||||||
|
//import downloadTorrent from "../helpers/downloadTorrent"
|
||||||
|
|
||||||
|
export default async (pkg, step, logger, abortController) => {
|
||||||
|
throw new Error("Not implemented")
|
||||||
|
|
||||||
|
if (typeof step.path === "undefined") {
|
||||||
|
step.path = `.`
|
||||||
|
}
|
||||||
|
|
||||||
|
step.path = await parseStringVars(step.path, pkg)
|
||||||
|
|
||||||
|
let _path = path.resolve(pkg.install_path, step.path)
|
||||||
|
|
||||||
|
global._relic_eventBus.emit(`pkg:update:state`, {
|
||||||
|
id: pkg.id,
|
||||||
|
status_text: `Preparing torrent...`,
|
||||||
|
})
|
||||||
|
|
||||||
|
logger.info(`Preparing torrent with magnet => [${step.magnet}]`)
|
||||||
|
|
||||||
|
if (step.tmp) {
|
||||||
|
_path = path.resolve(os.tmpdir(), String(new Date().getTime()))
|
||||||
|
}
|
||||||
|
|
||||||
|
const parentDir = path.resolve(_path, "..")
|
||||||
|
|
||||||
|
if (!fs.existsSync(parentDir)) {
|
||||||
|
fs.mkdirSync(parentDir, { recursive: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
await downloadTorrent(step.magnet, _path, {
|
||||||
|
onProgress: (progress) => {
|
||||||
|
global._relic_eventBus.emit(`pkg:update:state`, {
|
||||||
|
id: pkg.id,
|
||||||
|
use_id_only: true,
|
||||||
|
status_text: `Downloaded ${progress.transferredString} / ${progress.totalString} | ${progress.speedString}/s`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
93
packages/core/src/helpers/downloadTorrent.js
Normal file
93
packages/core/src/helpers/downloadTorrent.js
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import fs from "node:fs"
|
||||||
|
import path from "node:path"
|
||||||
|
import cliProgress from "cli-progress"
|
||||||
|
import humanFormat from "human-format"
|
||||||
|
|
||||||
|
function convertSize(size) {
|
||||||
|
return `${humanFormat(size, {
|
||||||
|
decimals: 2,
|
||||||
|
})}B`
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function downloadTorrent(
|
||||||
|
magnet,
|
||||||
|
destination,
|
||||||
|
{
|
||||||
|
onStart,
|
||||||
|
onProgress,
|
||||||
|
onDone,
|
||||||
|
onError,
|
||||||
|
} = {}
|
||||||
|
) {
|
||||||
|
let progressInterval = null
|
||||||
|
let tickProgress = {
|
||||||
|
total: 0,
|
||||||
|
transferred: 0,
|
||||||
|
speed: 0,
|
||||||
|
|
||||||
|
totalString: "0B",
|
||||||
|
transferredString: "0B",
|
||||||
|
speedString: "0B/s",
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = new WebTorrent()
|
||||||
|
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
client.add(magnet, (torrentInstance) => {
|
||||||
|
const progressBar = new cliProgress.SingleBar({
|
||||||
|
format: "[{bar}] {percentage}% | {total_formatted} | {speed}/s | {eta_formatted}",
|
||||||
|
barCompleteChar: "\u2588",
|
||||||
|
barIncompleteChar: "\u2591",
|
||||||
|
hideCursor: true
|
||||||
|
}, cliProgress.Presets.shades_classic)
|
||||||
|
|
||||||
|
if (typeof onStart === "function") {
|
||||||
|
onStart(torrentInstance)
|
||||||
|
}
|
||||||
|
|
||||||
|
progressBar.start(tickProgress.total, 0, {
|
||||||
|
speed: "0B/s",
|
||||||
|
total_formatted: tickProgress.totalString,
|
||||||
|
})
|
||||||
|
|
||||||
|
torrentInstance.on("done", () => {
|
||||||
|
progressBar.stop()
|
||||||
|
clearInterval(progressInterval)
|
||||||
|
|
||||||
|
if (typeof onDone === "function") {
|
||||||
|
onDone(torrentInstance)
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(torrentInstance)
|
||||||
|
})
|
||||||
|
|
||||||
|
torrentInstance.on("error", (error) => {
|
||||||
|
progressBar.stop()
|
||||||
|
clearInterval(progressInterval)
|
||||||
|
|
||||||
|
if (typeof onError === "function") {
|
||||||
|
onError(error)
|
||||||
|
} else {
|
||||||
|
reject(error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
progressInterval = setInterval(() => {
|
||||||
|
tickProgress.speed = torrentInstance.downloadSpeed
|
||||||
|
tickProgress.transferred = torrentInstance.downloaded
|
||||||
|
|
||||||
|
tickProgress.transferredString = convertSize(tickProgress.transferred)
|
||||||
|
tickProgress.totalString = convertSize(tickProgress.total)
|
||||||
|
tickProgress.speedString = convertSize(tickProgress.speed)
|
||||||
|
|
||||||
|
if (typeof onProgress === "function") {
|
||||||
|
onProgress(tickProgress)
|
||||||
|
}
|
||||||
|
|
||||||
|
progressBar.update(tickProgress.transferred, {
|
||||||
|
speed: tickProgress.speedString,
|
||||||
|
})
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
@ -6,6 +6,7 @@ import open from "open"
|
|||||||
import SetupHelper from "./helpers/setup"
|
import SetupHelper from "./helpers/setup"
|
||||||
import Logger from "./logger"
|
import Logger from "./logger"
|
||||||
|
|
||||||
|
import Settings from "./classes/Settings"
|
||||||
import Vars from "./vars"
|
import Vars from "./vars"
|
||||||
import DB from "./db"
|
import DB from "./db"
|
||||||
|
|
||||||
@ -37,10 +38,16 @@ export default class RelicCore {
|
|||||||
async initialize() {
|
async initialize() {
|
||||||
globalThis.relic_core = {
|
globalThis.relic_core = {
|
||||||
tasks: [],
|
tasks: [],
|
||||||
|
vars: Vars,
|
||||||
}
|
}
|
||||||
|
|
||||||
await DB.initialize()
|
await DB.initialize()
|
||||||
|
|
||||||
|
await Settings.initialize()
|
||||||
|
|
||||||
|
if (!await Settings.get("packages_path")) {
|
||||||
|
await Settings.set("packages_path", Vars.packages_path)
|
||||||
|
}
|
||||||
|
|
||||||
onExit(this.onExit)
|
onExit(this.onExit)
|
||||||
}
|
}
|
||||||
@ -71,11 +78,13 @@ export default class RelicCore {
|
|||||||
lastOperationRetry: PackageLastOperationRetry,
|
lastOperationRetry: PackageLastOperationRetry,
|
||||||
}
|
}
|
||||||
|
|
||||||
openPath(pkg_id) {
|
async openPath(pkg_id) {
|
||||||
if (!pkg_id) {
|
if (!pkg_id) {
|
||||||
return open(Vars.runtime_path)
|
return open(Vars.runtime_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
return open(Vars.packages_path + "/" + pkg_id)
|
const packagesPath = await Settings.get("packages_path") ?? Vars.packages_path
|
||||||
|
|
||||||
|
return open(packagesPath + "/" + pkg_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
const request = require('request')
|
import request from "request"
|
||||||
const { v3 } = require('uuid')
|
import {v3} from "uuid"
|
||||||
|
|
||||||
let uuid
|
let uuid
|
||||||
let api_url = 'https://authserver.mojang.com'
|
let api_url = 'https://authserver.mojang.com'
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
const fs = require('fs')
|
import fs from "node:fs"
|
||||||
const path = require('path')
|
import path from "node:path"
|
||||||
const request = require('request')
|
import child from "node:child_process"
|
||||||
const checksum = require('checksum')
|
import request from "request"
|
||||||
const Zip = require('adm-zip')
|
import checksum from "checksum"
|
||||||
const child = require('child_process')
|
import Zip from "adm-zip"
|
||||||
let counter = 0
|
let counter = 0
|
||||||
|
|
||||||
export default class Handler {
|
export default class Handler {
|
||||||
|
@ -8,11 +8,15 @@ import ManifestConfigManager from "../classes/ManifestConfig"
|
|||||||
import resolveOs from "../utils/resolveOs"
|
import resolveOs from "../utils/resolveOs"
|
||||||
import FetchLibraries from "./libraries"
|
import FetchLibraries from "./libraries"
|
||||||
|
|
||||||
|
import Settings from "../classes/Settings"
|
||||||
|
|
||||||
import Vars from "../vars"
|
import Vars from "../vars"
|
||||||
|
|
||||||
async function BuildManifest(baseClass, context, { soft = false } = {}) {
|
async function BuildManifest(baseClass, context, { soft = false } = {}) {
|
||||||
|
const packagesPath = await Settings.get("packages_path") ?? Vars.packages_path
|
||||||
|
|
||||||
// inject install_path
|
// inject install_path
|
||||||
context.install_path = path.resolve(Vars.packages_path, baseClass.id)
|
context.install_path = path.resolve(packagesPath, baseClass.id)
|
||||||
baseClass.install_path = context.install_path
|
baseClass.install_path = context.install_path
|
||||||
|
|
||||||
if (soft === true) {
|
if (soft === true) {
|
||||||
|
9
packages/core/src/utils/resolveUserDataPath.js
Normal file
9
packages/core/src/utils/resolveUserDataPath.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import path from "node:path"
|
||||||
|
import upath from "upath"
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
return upath.normalizeSafe(path.resolve(
|
||||||
|
process.env.APPDATA ||
|
||||||
|
(process.platform == "darwin" ? process.env.HOME + "/Library/Preferences" : process.env.HOME + "/.local/share"),
|
||||||
|
))
|
||||||
|
}
|
@ -1,15 +1,13 @@
|
|||||||
import path from "node:path"
|
import path from "node:path"
|
||||||
import upath from "upath"
|
import upath from "upath"
|
||||||
|
import resolveUserDataPath from "./utils/resolveUserDataPath"
|
||||||
|
|
||||||
const isWin = process.platform.includes("win")
|
const isWin = process.platform.includes("win")
|
||||||
const isMac = process.platform.includes("darwin")
|
const isMac = process.platform.includes("darwin")
|
||||||
|
|
||||||
const runtimeName = "rs-relic"
|
const runtimeName = "rs-relic"
|
||||||
|
|
||||||
const userdata_path = upath.normalizeSafe(path.resolve(
|
const userdata_path = resolveUserDataPath()
|
||||||
process.env.APPDATA ||
|
|
||||||
(process.platform == "darwin" ? process.env.HOME + "/Library/Preferences" : process.env.HOME + "/.local/share"),
|
|
||||||
))
|
|
||||||
const runtime_path = upath.normalizeSafe(path.join(userdata_path, runtimeName))
|
const runtime_path = upath.normalizeSafe(path.join(userdata_path, runtimeName))
|
||||||
const cache_path = upath.normalizeSafe(path.join(runtime_path, "cache"))
|
const cache_path = upath.normalizeSafe(path.join(runtime_path, "cache"))
|
||||||
const packages_path = upath.normalizeSafe(path.join(runtime_path, "packages"))
|
const packages_path = upath.normalizeSafe(path.join(runtime_path, "packages"))
|
||||||
|
@ -52,4 +52,4 @@
|
|||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"vite": "^4.4.9"
|
"vite": "^4.4.9"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import sendToRender from "../utils/sendToRender"
|
import sendToRender from "../utils/sendToRender"
|
||||||
import { ipcMain } from "electron"
|
import { ipcMain, dialog } from "electron"
|
||||||
|
import path from "node:path"
|
||||||
|
|
||||||
export default class CoreAdapter {
|
export default class CoreAdapter {
|
||||||
constructor(electronApp, RelicCore) {
|
constructor(electronApp, RelicCore) {
|
||||||
@ -48,7 +49,7 @@ export default class CoreAdapter {
|
|||||||
return await this.core.package.reinstall(pkg_id)
|
return await this.core.package.reinstall(pkg_id)
|
||||||
},
|
},
|
||||||
"pkg:cancel_install": async (event, pkg_id) => {
|
"pkg:cancel_install": async (event, pkg_id) => {
|
||||||
return await this.core.package.cancelInstall(pkg_id)
|
return await this.core.package.cancelInstall(pkg_id)
|
||||||
},
|
},
|
||||||
"pkg:execute": async (event, pkg_id, { force = false } = {}) => {
|
"pkg:execute": async (event, pkg_id, { force = false } = {}) => {
|
||||||
// check for updates first
|
// check for updates first
|
||||||
@ -77,6 +78,28 @@ export default class CoreAdapter {
|
|||||||
"core:open-path": async (event, pkg_id) => {
|
"core:open-path": async (event, pkg_id) => {
|
||||||
return await this.core.openPath(pkg_id)
|
return await this.core.openPath(pkg_id)
|
||||||
},
|
},
|
||||||
|
"core:change-packages-path": async (event) => {
|
||||||
|
const { canceled, filePaths } = await dialog.showOpenDialog(undefined, {
|
||||||
|
properties: ["openDirectory"]
|
||||||
|
})
|
||||||
|
|
||||||
|
if (canceled) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetPath = path.resolve(filePaths[0], "RelicPackages")
|
||||||
|
|
||||||
|
await global.Settings.set("packages_path", targetPath)
|
||||||
|
|
||||||
|
return targetPath
|
||||||
|
},
|
||||||
|
"core:set-default-packages-path": async (event) => {
|
||||||
|
const { packages_path } = globalThis.relic_core.vars
|
||||||
|
|
||||||
|
await global.Settings.set("packages_path", packages_path)
|
||||||
|
|
||||||
|
return packages_path
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
coreEvents = {
|
coreEvents = {
|
||||||
|
@ -1,20 +1,18 @@
|
|||||||
global.SettingsStore = new Store({
|
|
||||||
name: "settings",
|
|
||||||
watch: true,
|
|
||||||
})
|
|
||||||
import path from "node:path"
|
import path from "node:path"
|
||||||
|
|
||||||
import { app, shell, BrowserWindow, ipcMain } from "electron"
|
import { app, shell, BrowserWindow, ipcMain } from "electron"
|
||||||
import { electronApp, optimizer, is } from "@electron-toolkit/utils"
|
import { electronApp, optimizer, is } from "@electron-toolkit/utils"
|
||||||
import isDev from "electron-is-dev"
|
import isDev from "electron-is-dev"
|
||||||
import Store from "electron-store"
|
|
||||||
|
|
||||||
let RelicCore = null
|
let RelicCore = null
|
||||||
|
let Settings = null
|
||||||
|
|
||||||
if (isDev) {
|
if (isDev) {
|
||||||
RelicCore = require("../../../core").default
|
RelicCore = require("../../../core/dist").default
|
||||||
|
Settings = global.Settings = require("../../../core/dist/classes/Settings").default
|
||||||
} else {
|
} else {
|
||||||
RelicCore = require("@ragestudio/relic-core").default
|
RelicCore = require("@ragestudio/relic-core").default
|
||||||
|
Settings = global.Settings = require("@ragestudio/relic-core/src/classes/Settings").default
|
||||||
}
|
}
|
||||||
|
|
||||||
import CoreAdapter from "./classes/CoreAdapter"
|
import CoreAdapter from "./classes/CoreAdapter"
|
||||||
@ -84,17 +82,17 @@ class ElectronApp {
|
|||||||
autoUpdater.quitAndInstall()
|
autoUpdater.quitAndInstall()
|
||||||
}, 3000)
|
}, 3000)
|
||||||
},
|
},
|
||||||
"settings:get": (event, key) => {
|
"settings:get": async (event, key) => {
|
||||||
return global.SettingsStore.get(key)
|
return await Settings.get(key)
|
||||||
},
|
},
|
||||||
"settings:set": (event, key, value) => {
|
"settings:set": async (event, key, value) => {
|
||||||
return global.SettingsStore.set(key, value)
|
return await Settings.set(key, value)
|
||||||
},
|
},
|
||||||
"settings:delete": (event, key) => {
|
"settings:delete": async (event, key) => {
|
||||||
return global.SettingsStore.delete(key)
|
return await Settings.delete(key)
|
||||||
},
|
},
|
||||||
"settings:has": (event, key) => {
|
"settings:has": async (event, key) => {
|
||||||
return global.SettingsStore.has(key)
|
return await Settings.has(key)
|
||||||
},
|
},
|
||||||
"app:open-logs": async (event) => {
|
"app:open-logs": async (event) => {
|
||||||
const loggerWindow = await this.logsViewer.createWindow()
|
const loggerWindow = await this.logsViewer.createWindow()
|
||||||
|
@ -91,31 +91,53 @@ const SettingItem = (props) => {
|
|||||||
return React.createElement(Component, componentProps)
|
return React.createElement(Component, componentProps)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Footer = () => {
|
||||||
|
if (typeof setting.footer === "undefined") {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof setting.footer === "function") {
|
||||||
|
return setting.footer(componentProps)
|
||||||
|
}
|
||||||
|
|
||||||
|
return <span style={{ fontSize: "0.5rem" }}>{setting.footer}</span>
|
||||||
|
}
|
||||||
|
|
||||||
return <div
|
return <div
|
||||||
className="app_settings-list-item"
|
className="app_settings-list-item"
|
||||||
>
|
>
|
||||||
<div className="app_settings-list-item-info">
|
<div className="app_settings-list-item-row">
|
||||||
<div className="app_settings-list-item-label">
|
<div className="app_settings-list-item-info">
|
||||||
<Icon icon={setting.icon} />
|
<div className="app_settings-list-item-label">
|
||||||
|
<Icon icon={setting.icon} />
|
||||||
|
|
||||||
<h2>
|
<h2>
|
||||||
{setting.name}
|
{setting.name}
|
||||||
</h2>
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="app_settings-list-item-description">
|
||||||
|
<p>
|
||||||
|
{setting.description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="app_settings-list-item-description">
|
<div className="app_settings-list-item-component">
|
||||||
<p>
|
{
|
||||||
{setting.description}
|
loading && <antd.Spin />
|
||||||
</p>
|
}
|
||||||
|
{
|
||||||
|
!loading && <Render />
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="app_settings-list-item-component">
|
<div className="app_settings-list-item-row">
|
||||||
{
|
{
|
||||||
loading && <antd.Spin />
|
!loading && <div className="app_settings-list-item-footer">
|
||||||
}
|
<Footer />
|
||||||
{
|
</div>
|
||||||
!loading && <Render />
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -73,52 +73,61 @@
|
|||||||
gap: 7px;
|
gap: 7px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.app_settings-list-item {
|
.app_settings-list-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&:nth-child(odd) {
|
||||||
|
background-color: mix(#fff, @var-background-color-secondary, 5%);
|
||||||
|
}
|
||||||
|
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
opacity: 0.9;
|
||||||
|
|
||||||
|
.app_settings-list-item-row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.app_settings-list-item-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.app_settings-list-item-label {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
||||||
align-items: center;
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
&:nth-child(odd) {
|
.app_settings-list-item-description {
|
||||||
background-color: mix(#fff, @var-background-color-secondary, 5%);
|
display: inline-flex;
|
||||||
}
|
flex-direction: row;
|
||||||
|
|
||||||
border-radius: 12px;
|
font-size: 0.7rem;
|
||||||
|
|
||||||
padding: 10px;
|
|
||||||
|
|
||||||
opacity: 0.9;
|
|
||||||
|
|
||||||
.app_settings-list-item-info {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
gap: 10px;
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.app_settings-list-item-label {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
|
|
||||||
gap: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app_settings-list-item-description {
|
|
||||||
display: inline-flex;
|
|
||||||
flex-direction: row;
|
|
||||||
|
|
||||||
font-size: 0.7rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.app_settings-list-item-component {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app_settings-list-item-component {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,111 +1,157 @@
|
|||||||
|
import React from "react"
|
||||||
import { Button } from "antd"
|
import { Button } from "antd"
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
{
|
{
|
||||||
id: "services",
|
id: "services",
|
||||||
name: "Services",
|
name: "Services",
|
||||||
icon: "MdAccountTree",
|
icon: "MdAccountTree",
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: "drive_auth",
|
id: "drive_auth",
|
||||||
name: "Google Drive",
|
name: "Google Drive",
|
||||||
description: "Authorize your Google Drive account to be used for bundles installation.",
|
description: "Authorize your Google Drive account to be used for bundles installation.",
|
||||||
icon: "SiGoogledrive",
|
icon: "SiGoogledrive",
|
||||||
type: "button",
|
type: "button",
|
||||||
storaged: false,
|
storaged: false,
|
||||||
watchIpc: ["drive:authorized", "drive:unauthorized"],
|
watchIpc: ["drive:authorized", "drive:unauthorized"],
|
||||||
defaultValue: async () => {
|
defaultValue: async () => {
|
||||||
return await api.settings.get("drive_auth")
|
return await api.settings.get("drive_auth")
|
||||||
},
|
},
|
||||||
render: (props) => {
|
render: (props) => {
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
disabled
|
disabled
|
||||||
type={props.value ? "primary" : "default"}
|
type={props.value ? "primary" : "default"}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (!props.value) {
|
if (!props.value) {
|
||||||
message.info("Authorizing...")
|
message.info("Authorizing...")
|
||||||
|
|
||||||
return ipc.exec("drive:authorize")
|
return ipc.exec("drive:authorize")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ipc.exec("drive:unauthorize")
|
return ipc.exec("drive:unauthorize")
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{props.value ? "Unauthorize" : "Authorize"}
|
{props.value ? "Unauthorize" : "Authorize"}
|
||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "updates",
|
id: "updates",
|
||||||
name: "Updates",
|
name: "Updates",
|
||||||
icon: "MdUpdate",
|
icon: "MdUpdate",
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: "check_update",
|
id: "check_update",
|
||||||
name: "Check for updates",
|
name: "Check for updates",
|
||||||
description: "Check for updates to the app.",
|
description: "Check for updates to the app.",
|
||||||
icon: "MdUpdate",
|
icon: "MdUpdate",
|
||||||
type: "button",
|
type: "button",
|
||||||
props: {
|
props: {
|
||||||
children: "Check",
|
children: "Check",
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
message.info("Checking for updates...")
|
message.info("Checking for updates...")
|
||||||
app.checkUpdates()
|
app.checkUpdates()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
storaged: false
|
storaged: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "pkg_auto_update_on_execute",
|
id: "pkg_auto_update_on_execute",
|
||||||
name: "Packages auto update",
|
name: "Packages auto update",
|
||||||
description: "If a update is available, automatically update the app when it is executed.",
|
description: "If a update is available, automatically update the app when it is executed.",
|
||||||
icon: "MdUpdate",
|
icon: "MdUpdate",
|
||||||
type: "switch",
|
type: "switch",
|
||||||
storaged: true,
|
storaged: true,
|
||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
props: {
|
props: {
|
||||||
disabled: true
|
disabled: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "other",
|
id: "other",
|
||||||
name: "Other",
|
name: "Other",
|
||||||
icon: "MdSettings",
|
icon: "MdSettings",
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: "open_settings_path",
|
id: "change_packages_path",
|
||||||
name: "Open settings path",
|
name: "Change packages path",
|
||||||
description: "Open the folder where all packages are stored.",
|
description: "Change the folder where all packages will be installed.",
|
||||||
icon: "MdFolder",
|
icon: "MdFolder",
|
||||||
type: "button",
|
type: "button",
|
||||||
props: {
|
defaultValue: async () => {
|
||||||
children: "Open",
|
return await ipc.exec("settings:get", "packages_path")
|
||||||
onClick: () => {
|
},
|
||||||
ipc.exec("core:open-path")
|
render: (props) => {
|
||||||
}
|
return <>
|
||||||
},
|
<Button
|
||||||
storaged: false
|
style={{
|
||||||
},
|
width: "100%",
|
||||||
{
|
}}
|
||||||
id: "open_dev_logs",
|
onClick={async () => {
|
||||||
name: "Open internal logs",
|
const path = await ipc.exec("core:change-packages-path")
|
||||||
description: "Open the internal logs of the app.",
|
|
||||||
icon: "MdTerminal",
|
if (path) {
|
||||||
type: "button",
|
props.handleChange(path)
|
||||||
props: {
|
}
|
||||||
children: "Open",
|
}}
|
||||||
onClick: () => {
|
>
|
||||||
ipc.exec("app:open-logs")
|
Change
|
||||||
}
|
</Button>
|
||||||
},
|
<Button
|
||||||
storaged: false
|
type="link"
|
||||||
}
|
size="small"
|
||||||
]
|
onClick={async () => {
|
||||||
}
|
const path = await ipc.exec("core:set-default-packages-path")
|
||||||
|
|
||||||
|
if (path) {
|
||||||
|
props.handleChange(path)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Reset
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
},
|
||||||
|
footer: (props) => {
|
||||||
|
return <span style={{ fontSize: "0.6rem" }}>{props.value}</span>
|
||||||
|
},
|
||||||
|
storaged: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "open_settings_path",
|
||||||
|
name: "Open settings path",
|
||||||
|
description: "Open the folder where all packages are stored.",
|
||||||
|
icon: "MdFolder",
|
||||||
|
type: "button",
|
||||||
|
props: {
|
||||||
|
children: "Open",
|
||||||
|
onClick: () => {
|
||||||
|
ipc.exec("core:open-path")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
storaged: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "open_dev_logs",
|
||||||
|
name: "Open internal logs",
|
||||||
|
description: "Open the internal logs of the app.",
|
||||||
|
icon: "MdTerminal",
|
||||||
|
type: "button",
|
||||||
|
props: {
|
||||||
|
children: "Open",
|
||||||
|
onClick: () => {
|
||||||
|
ipc.exec("app:open-logs")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
storaged: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user