mirror of
https://github.com/ragestudio/relic.git
synced 2025-06-09 02:24:18 +00:00
merge from local
This commit is contained in:
parent
fd6358ef11
commit
01d6031473
43
packages/core/src/handlers/checkUpdate.js
Normal file
43
packages/core/src/handlers/checkUpdate.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import Logger from "../logger"
|
||||||
|
import DB from "../db"
|
||||||
|
|
||||||
|
import softRead from "./read"
|
||||||
|
|
||||||
|
const Log = Logger.child({ service: "CHECK_UPDATE" })
|
||||||
|
|
||||||
|
export default async function checkUpdate(pkg_id) {
|
||||||
|
const pkg = await DB.getPackages(pkg_id)
|
||||||
|
|
||||||
|
if (!pkg) {
|
||||||
|
Log.error("Package not found")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.info(`Checking update for [${pkg_id}]`)
|
||||||
|
|
||||||
|
const remoteSoftManifest = await softRead(pkg.remote_manifest, {
|
||||||
|
soft: true
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!remoteSoftManifest) {
|
||||||
|
Log.error("Cannot read remote manifest")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkg.version === remoteSoftManifest.version) {
|
||||||
|
Log.info("No update available")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.info("Update available")
|
||||||
|
Log.info("Local:", pkg.version)
|
||||||
|
Log.info("Remote:", remoteSoftManifest.version)
|
||||||
|
Log.info("Changelog:", remoteSoftManifest.changelog_url)
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: pkg.id,
|
||||||
|
local: pkg.version,
|
||||||
|
remote: remoteSoftManifest.version,
|
||||||
|
changelog: remoteSoftManifest.changelog_url,
|
||||||
|
}
|
||||||
|
}
|
@ -92,7 +92,9 @@ export default async () => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await fs.promises.rm(prerequisite.destination)
|
if (fs.existsSync(prerequisite.destination)) {
|
||||||
|
await fs.promises.rm(prerequisite.destination)
|
||||||
|
}
|
||||||
|
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
@ -153,6 +155,12 @@ export default async () => {
|
|||||||
|
|
||||||
if (Array.isArray(prerequisite.moveDirs)) {
|
if (Array.isArray(prerequisite.moveDirs)) {
|
||||||
for (const dir of prerequisite.moveDirs) {
|
for (const dir of prerequisite.moveDirs) {
|
||||||
|
if (Array.isArray(dir.requireOs)) {
|
||||||
|
if (!dir.requireOs.includes(resolveOs())) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Log.info(`Moving ${dir.from} to ${dir.to}...`)
|
Log.info(`Moving ${dir.from} to ${dir.to}...`)
|
||||||
|
|
||||||
global._relic_eventBus.emit("app:setup", {
|
global._relic_eventBus.emit("app:setup", {
|
||||||
@ -182,9 +190,10 @@ export default async () => {
|
|||||||
message: error.message,
|
message: error.message,
|
||||||
})
|
})
|
||||||
|
|
||||||
Log.error(error)
|
|
||||||
Log.error("Aborting setup due to an error...")
|
Log.error("Aborting setup due to an error...")
|
||||||
return false
|
Log.error(error)
|
||||||
|
|
||||||
|
throw error
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.info(`All prerequisites are ready!`)
|
Log.info(`All prerequisites are ready!`)
|
||||||
|
@ -17,6 +17,7 @@ import PackageApply from "./handlers/apply"
|
|||||||
import PackageList from "./handlers/list"
|
import PackageList from "./handlers/list"
|
||||||
import PackageRead from "./handlers/read"
|
import PackageRead from "./handlers/read"
|
||||||
import PackageAuthorize from "./handlers/authorize"
|
import PackageAuthorize from "./handlers/authorize"
|
||||||
|
import PackageCheckUpdate from "./handlers/checkUpdate"
|
||||||
|
|
||||||
export default class RelicCore {
|
export default class RelicCore {
|
||||||
constructor(params) {
|
constructor(params) {
|
||||||
@ -27,6 +28,8 @@ export default class RelicCore {
|
|||||||
|
|
||||||
logger = Logger
|
logger = Logger
|
||||||
|
|
||||||
|
db = DB
|
||||||
|
|
||||||
async initialize() {
|
async initialize() {
|
||||||
await DB.initialize()
|
await DB.initialize()
|
||||||
|
|
||||||
@ -52,6 +55,7 @@ export default class RelicCore {
|
|||||||
list: PackageList,
|
list: PackageList,
|
||||||
read: PackageRead,
|
read: PackageRead,
|
||||||
authorize: PackageAuthorize,
|
authorize: PackageAuthorize,
|
||||||
|
checkUpdate: PackageCheckUpdate
|
||||||
}
|
}
|
||||||
|
|
||||||
openPath(pkg_id) {
|
openPath(pkg_id) {
|
||||||
|
@ -26,7 +26,7 @@ export default [
|
|||||||
{
|
{
|
||||||
id: "rclone-bin",
|
id: "rclone-bin",
|
||||||
finalBin: Vars.rclone_bin,
|
finalBin: Vars.rclone_bin,
|
||||||
url: resolveRemoteBinPath(`${baseURL}/rclone-bin`, "rclone-bin.zip"),
|
url: resolveRemoteBinPath(`${baseURL}/rclone`, "rclone-bin.zip"),
|
||||||
destination: path.resolve(Vars.binaries_path, "rclone-bin.zip"),
|
destination: path.resolve(Vars.binaries_path, "rclone-bin.zip"),
|
||||||
extract: path.resolve(Vars.binaries_path, "rclone-bin"),
|
extract: path.resolve(Vars.binaries_path, "rclone-bin"),
|
||||||
requireOs: ["win32"],
|
requireOs: ["win32"],
|
||||||
@ -58,6 +58,7 @@ export default [
|
|||||||
extractTargetFromName: true,
|
extractTargetFromName: true,
|
||||||
moveDirs: [
|
moveDirs: [
|
||||||
{
|
{
|
||||||
|
requireOs: ["macos"],
|
||||||
from: path.resolve(Vars.binaries_path, "java_jre_bin", "zulu-22.jre", "Contents"),
|
from: path.resolve(Vars.binaries_path, "java_jre_bin", "zulu-22.jre", "Contents"),
|
||||||
to: path.resolve(Vars.binaries_path, "java_jre_bin", "Contents"),
|
to: path.resolve(Vars.binaries_path, "java_jre_bin", "Contents"),
|
||||||
deleteParentBefore: true
|
deleteParentBefore: true
|
||||||
|
@ -3,7 +3,7 @@ global.SettingsStore = new Store({
|
|||||||
watch: true,
|
watch: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
import RelicCore from "@ragestudio/relic-core/src"
|
import RelicCore from "../../../core/src"
|
||||||
import CoreAdapter from "./classes/CoreAdapter"
|
import CoreAdapter from "./classes/CoreAdapter"
|
||||||
|
|
||||||
import sendToRender from "./utils/sendToRender"
|
import sendToRender from "./utils/sendToRender"
|
||||||
@ -63,7 +63,16 @@ class ElectronApp {
|
|||||||
"pkg:uninstall": async (event, pkg_id) => {
|
"pkg:uninstall": async (event, pkg_id) => {
|
||||||
return await this.core.package.uninstall(pkg_id)
|
return await this.core.package.uninstall(pkg_id)
|
||||||
},
|
},
|
||||||
"pkg:execute": async (event, pkg_id) => {
|
"pkg:execute": async (event, pkg_id, { force = false } = {}) => {
|
||||||
|
// check for updates first
|
||||||
|
if (!force) {
|
||||||
|
const update = await this.core.package.checkUpdate(pkg_id)
|
||||||
|
|
||||||
|
if (update) {
|
||||||
|
return sendToRender("pkg:update_available", update)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return await this.core.package.execute(pkg_id)
|
return await this.core.package.execute(pkg_id)
|
||||||
},
|
},
|
||||||
"pkg:open": async (event, pkg_id) => {
|
"pkg:open": async (event, pkg_id) => {
|
||||||
@ -93,18 +102,22 @@ class ElectronApp {
|
|||||||
try {
|
try {
|
||||||
await this.core.initialize()
|
await this.core.initialize()
|
||||||
await this.core.setup()
|
await this.core.setup()
|
||||||
} catch (err) {
|
|
||||||
console.error(err)
|
|
||||||
|
|
||||||
sendToRender("new:notification", {
|
return {
|
||||||
message: "Setup failed",
|
pkg: pkg,
|
||||||
description: err.message
|
authorizedServices: {}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
|
||||||
|
sendToRender("app:init:failed", {
|
||||||
|
message: "Initalization failed",
|
||||||
|
error: error,
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pkg: pkg,
|
error
|
||||||
authorizedServices: {}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
packages/gui/src/renderer/assets/bruh_fox.jpg
Normal file
BIN
packages/gui/src/renderer/assets/bruh_fox.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 330 KiB |
@ -59,7 +59,9 @@ class App extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
updateAvailable: true,
|
appUpdate: {
|
||||||
|
available: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
app.appUpdateAvailable(data)
|
app.appUpdateAvailable(data)
|
||||||
@ -79,15 +81,23 @@ class App extends React.Component {
|
|||||||
app.pkgUpdateAvailable(data)
|
app.pkgUpdateAvailable(data)
|
||||||
},
|
},
|
||||||
"pkg:installation:invoked": (event, data) => {
|
"pkg:installation:invoked": (event, data) => {
|
||||||
if (this.state.initializing) {
|
if (this.state.initializing) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
app.invokeInstall(data)
|
app.invokeInstall(data)
|
||||||
|
},
|
||||||
|
"app:init:failed": (event, data) => {
|
||||||
|
this.setState({
|
||||||
|
crash: data,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount = async () => {
|
componentDidMount = async () => {
|
||||||
|
console.log(`React version > ${versions["react"]}`)
|
||||||
|
console.log(`DOMRouter version > ${versions["react-router-dom"]}`)
|
||||||
|
|
||||||
window.app.style.appendClassname("initializing")
|
window.app.style.appendClassname("initializing")
|
||||||
|
|
||||||
for (const event in this.ipcEvents) {
|
for (const event in this.ipcEvents) {
|
||||||
@ -96,10 +106,12 @@ class App extends React.Component {
|
|||||||
|
|
||||||
const mainInitialization = await ipc.exec("app:init")
|
const mainInitialization = await ipc.exec("app:init")
|
||||||
|
|
||||||
console.log(`React version > ${versions["react"]}`)
|
|
||||||
console.log(`DOMRouter version > ${versions["react-router-dom"]}`)
|
|
||||||
console.log(`app:init() | Result >`, mainInitialization)
|
console.log(`app:init() | Result >`, mainInitialization)
|
||||||
|
|
||||||
|
if (mainInitialization.error) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
await this.setState({
|
await this.setState({
|
||||||
initializing: false,
|
initializing: false,
|
||||||
pkg: mainInitialization.pkg,
|
pkg: mainInitialization.pkg,
|
||||||
|
@ -29,12 +29,6 @@ class GlobalStyleController {
|
|||||||
export default class GlobalCTXApp {
|
export default class GlobalCTXApp {
|
||||||
static style = GlobalStyleController
|
static style = GlobalStyleController
|
||||||
|
|
||||||
static applyUpdate = () => {
|
|
||||||
message.loading("Updating, please wait...")
|
|
||||||
|
|
||||||
ipc.exec("updater:apply")
|
|
||||||
}
|
|
||||||
|
|
||||||
static invokeInstall = (manifest) => {
|
static invokeInstall = (manifest) => {
|
||||||
console.log(`installation invoked >`, manifest)
|
console.log(`installation invoked >`, manifest)
|
||||||
|
|
||||||
@ -80,6 +74,12 @@ export default class GlobalCTXApp {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static applyUpdate = () => {
|
||||||
|
message.loading("Updating, please wait...")
|
||||||
|
|
||||||
|
ipc.exec("updater:apply")
|
||||||
|
}
|
||||||
|
|
||||||
static checkUpdates = () => {
|
static checkUpdates = () => {
|
||||||
ipc.exec("updater:check")
|
ipc.exec("updater:check")
|
||||||
}
|
}
|
||||||
|
27
packages/gui/src/renderer/src/components/Crash/index.jsx
Normal file
27
packages/gui/src/renderer/src/components/Crash/index.jsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import React from "react"
|
||||||
|
import "./index.less"
|
||||||
|
|
||||||
|
const Crash = (props) => {
|
||||||
|
const { crash } = props
|
||||||
|
|
||||||
|
return <div className="app-crash">
|
||||||
|
<div className="crash-icon">
|
||||||
|
<img
|
||||||
|
src="/assets/bruh_fox.jpg"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1>Crash</h1>
|
||||||
|
<p>The application has encontered a critical error that cannot handle it, so must be terminated.</p>
|
||||||
|
|
||||||
|
<div className="crash-details">
|
||||||
|
<p>Detailed error:</p>
|
||||||
|
|
||||||
|
<code>
|
||||||
|
{JSON.stringify(crash, null, 2)}
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Crash
|
56
packages/gui/src/renderer/src/components/Crash/index.less
Normal file
56
packages/gui/src/renderer/src/components/Crash/index.less
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
.app-crash {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
gap: 20px;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.crash-icon {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
|
||||||
|
object-fit: contain;
|
||||||
|
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.crash-details {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
gap: 7px;
|
||||||
|
|
||||||
|
code {
|
||||||
|
background-color: var(--background-color-secondary);
|
||||||
|
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
font-family: "DM Mono", monospace;
|
||||||
|
|
||||||
|
font-size: 0.8rem;
|
||||||
|
|
||||||
|
word-break: break-all;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,7 +16,7 @@ const PackageUpdateAvailable = ({ update, close }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleUpdate() {
|
function handleUpdate() {
|
||||||
ipc.exec("pkg:update", update.manifest.id, {
|
ipc.exec("pkg:update", update.id, {
|
||||||
execOnFinish: true
|
execOnFinish: true
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ const PackageUpdateAvailable = ({ update, close }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleContinue() {
|
function handleContinue() {
|
||||||
ipc.exec("pkg:execute", update.manifest.id, {
|
ipc.exec("pkg:execute", update.id, {
|
||||||
force: true
|
force: true
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ const PackageUpdateAvailable = ({ update, close }) => {
|
|||||||
|
|
||||||
<code>
|
<code>
|
||||||
<p>
|
<p>
|
||||||
<b>{update.current_version}</b> {`->`} <b>{update.new_version}</b>
|
<b>{update.local}</b> {`->`} <b>{update.remote}</b>
|
||||||
</p>
|
</p>
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
|
@ -22,11 +22,13 @@ const Splash = (props) => {
|
|||||||
|
|
||||||
{
|
{
|
||||||
globalState.appSetup.message && <>
|
globalState.appSetup.message && <>
|
||||||
|
<div className="app-setup_message-wrapper">
|
||||||
<div className="app-setup_message">
|
<div className="app-setup_message">
|
||||||
<span>
|
<span>
|
||||||
{globalState.appSetup.message}
|
{globalState.appSetup.message}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<BarLoader
|
<BarLoader
|
||||||
className="app_loader"
|
className="app_loader"
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
|
padding-top: 30px;
|
||||||
|
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
@ -19,14 +21,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-setup_message {
|
.app-setup_message-wrapper {
|
||||||
padding: 15px 10px;
|
display: flex;
|
||||||
border-radius: 12px;
|
flex-direction: column;
|
||||||
|
|
||||||
transition: all 150ms ease-in-out;
|
height: 100%;
|
||||||
|
|
||||||
background-color: var(--background-color-secondary);
|
justify-content: center;
|
||||||
|
|
||||||
font-family: "DM Mono", monospace;
|
.app-setup_message {
|
||||||
|
padding: 15px 10px;
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
transition: all 150ms ease-in-out;
|
||||||
|
|
||||||
|
background-color: var(--background-color-secondary);
|
||||||
|
|
||||||
|
font-family: "DM Mono", monospace;
|
||||||
|
|
||||||
|
word-break: break-all;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -62,13 +62,13 @@ const Header = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ctx.updateAvailable && <antd.Button
|
ctx.appUpdate?.available && <antd.Button
|
||||||
size="small"
|
size="small"
|
||||||
icon={<Icons.MdDownload />}
|
icon={<Icons.MdDownload />}
|
||||||
onClick={app.applyUpdate}
|
onClick={app.applyUpdate}
|
||||||
type="primary"
|
type="primary"
|
||||||
>
|
>
|
||||||
Update now
|
Update app
|
||||||
</antd.Button>
|
</antd.Button>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import loadable from "@loadable/component"
|
|||||||
import GlobalStateContext from "contexts/global"
|
import GlobalStateContext from "contexts/global"
|
||||||
|
|
||||||
import SplashScreen from "components/Splash"
|
import SplashScreen from "components/Splash"
|
||||||
|
import CrashError from "components/Crash"
|
||||||
|
|
||||||
const DefaultNotFoundRender = () => {
|
const DefaultNotFoundRender = () => {
|
||||||
return <div>Not found</div>
|
return <div>Not found</div>
|
||||||
@ -130,6 +131,18 @@ export const InternalRouter = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const PageRender = (props) => {
|
export const PageRender = (props) => {
|
||||||
|
const globalState = React.useContext(GlobalStateContext)
|
||||||
|
|
||||||
|
if (globalState.crash) {
|
||||||
|
return <CrashError
|
||||||
|
crash={globalState.crash}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|
||||||
|
if (globalState.initializing) {
|
||||||
|
return <SplashScreen />
|
||||||
|
}
|
||||||
|
|
||||||
const routes = React.useMemo(() => {
|
const routes = React.useMemo(() => {
|
||||||
let paths = {
|
let paths = {
|
||||||
...import.meta.glob("/src/pages/**/[a-z[]*.jsx"),
|
...import.meta.glob("/src/pages/**/[a-z[]*.jsx"),
|
||||||
@ -154,12 +167,6 @@ export const PageRender = (props) => {
|
|||||||
return paths
|
return paths
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const globalState = React.useContext(GlobalStateContext)
|
|
||||||
|
|
||||||
if (globalState.initializing) {
|
|
||||||
return <SplashScreen />
|
|
||||||
}
|
|
||||||
|
|
||||||
return <Routes>
|
return <Routes>
|
||||||
{
|
{
|
||||||
routes.map((route, index) => {
|
routes.map((route, index) => {
|
||||||
|
@ -15,6 +15,19 @@
|
|||||||
--app_global_padding: @var-app_global_padding;
|
--app_global_padding: @var-app_global_padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user