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) {
|
||||
await fs.promises.rm(prerequisite.destination)
|
||||
if (fs.existsSync(prerequisite.destination)) {
|
||||
await fs.promises.rm(prerequisite.destination)
|
||||
}
|
||||
|
||||
throw error
|
||||
}
|
||||
@ -153,6 +155,12 @@ export default async () => {
|
||||
|
||||
if (Array.isArray(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}...`)
|
||||
|
||||
global._relic_eventBus.emit("app:setup", {
|
||||
@ -182,9 +190,10 @@ export default async () => {
|
||||
message: error.message,
|
||||
})
|
||||
|
||||
Log.error(error)
|
||||
Log.error("Aborting setup due to an error...")
|
||||
return false
|
||||
Log.error(error)
|
||||
|
||||
throw error
|
||||
}
|
||||
|
||||
Log.info(`All prerequisites are ready!`)
|
||||
|
@ -17,6 +17,7 @@ import PackageApply from "./handlers/apply"
|
||||
import PackageList from "./handlers/list"
|
||||
import PackageRead from "./handlers/read"
|
||||
import PackageAuthorize from "./handlers/authorize"
|
||||
import PackageCheckUpdate from "./handlers/checkUpdate"
|
||||
|
||||
export default class RelicCore {
|
||||
constructor(params) {
|
||||
@ -27,6 +28,8 @@ export default class RelicCore {
|
||||
|
||||
logger = Logger
|
||||
|
||||
db = DB
|
||||
|
||||
async initialize() {
|
||||
await DB.initialize()
|
||||
|
||||
@ -52,6 +55,7 @@ export default class RelicCore {
|
||||
list: PackageList,
|
||||
read: PackageRead,
|
||||
authorize: PackageAuthorize,
|
||||
checkUpdate: PackageCheckUpdate
|
||||
}
|
||||
|
||||
openPath(pkg_id) {
|
||||
|
@ -26,7 +26,7 @@ export default [
|
||||
{
|
||||
id: "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"),
|
||||
extract: path.resolve(Vars.binaries_path, "rclone-bin"),
|
||||
requireOs: ["win32"],
|
||||
@ -58,6 +58,7 @@ export default [
|
||||
extractTargetFromName: true,
|
||||
moveDirs: [
|
||||
{
|
||||
requireOs: ["macos"],
|
||||
from: path.resolve(Vars.binaries_path, "java_jre_bin", "zulu-22.jre", "Contents"),
|
||||
to: path.resolve(Vars.binaries_path, "java_jre_bin", "Contents"),
|
||||
deleteParentBefore: true
|
||||
|
@ -3,7 +3,7 @@ global.SettingsStore = new Store({
|
||||
watch: true,
|
||||
})
|
||||
|
||||
import RelicCore from "@ragestudio/relic-core/src"
|
||||
import RelicCore from "../../../core/src"
|
||||
import CoreAdapter from "./classes/CoreAdapter"
|
||||
|
||||
import sendToRender from "./utils/sendToRender"
|
||||
@ -63,7 +63,16 @@ class ElectronApp {
|
||||
"pkg:uninstall": async (event, 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)
|
||||
},
|
||||
"pkg:open": async (event, pkg_id) => {
|
||||
@ -93,18 +102,22 @@ class ElectronApp {
|
||||
try {
|
||||
await this.core.initialize()
|
||||
await this.core.setup()
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
|
||||
sendToRender("new:notification", {
|
||||
message: "Setup failed",
|
||||
description: err.message
|
||||
return {
|
||||
pkg: pkg,
|
||||
authorizedServices: {}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
|
||||
sendToRender("app:init:failed", {
|
||||
message: "Initalization failed",
|
||||
error: error,
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
pkg: pkg,
|
||||
authorizedServices: {}
|
||||
return {
|
||||
error
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
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({
|
||||
updateAvailable: true,
|
||||
appUpdate: {
|
||||
available: true,
|
||||
},
|
||||
})
|
||||
|
||||
app.appUpdateAvailable(data)
|
||||
@ -79,15 +81,23 @@ class App extends React.Component {
|
||||
app.pkgUpdateAvailable(data)
|
||||
},
|
||||
"pkg:installation:invoked": (event, data) => {
|
||||
if (this.state.initializing) {
|
||||
return false
|
||||
}
|
||||
if (this.state.initializing) {
|
||||
return false
|
||||
}
|
||||
|
||||
app.invokeInstall(data)
|
||||
app.invokeInstall(data)
|
||||
},
|
||||
"app:init:failed": (event, data) => {
|
||||
this.setState({
|
||||
crash: data,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount = async () => {
|
||||
console.log(`React version > ${versions["react"]}`)
|
||||
console.log(`DOMRouter version > ${versions["react-router-dom"]}`)
|
||||
|
||||
window.app.style.appendClassname("initializing")
|
||||
|
||||
for (const event in this.ipcEvents) {
|
||||
@ -96,10 +106,12 @@ class App extends React.Component {
|
||||
|
||||
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)
|
||||
|
||||
if (mainInitialization.error) {
|
||||
return false
|
||||
}
|
||||
|
||||
await this.setState({
|
||||
initializing: false,
|
||||
pkg: mainInitialization.pkg,
|
||||
|
@ -29,12 +29,6 @@ class GlobalStyleController {
|
||||
export default class GlobalCTXApp {
|
||||
static style = GlobalStyleController
|
||||
|
||||
static applyUpdate = () => {
|
||||
message.loading("Updating, please wait...")
|
||||
|
||||
ipc.exec("updater:apply")
|
||||
}
|
||||
|
||||
static invokeInstall = (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 = () => {
|
||||
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() {
|
||||
ipc.exec("pkg:update", update.manifest.id, {
|
||||
ipc.exec("pkg:update", update.id, {
|
||||
execOnFinish: true
|
||||
})
|
||||
|
||||
@ -24,7 +24,7 @@ const PackageUpdateAvailable = ({ update, close }) => {
|
||||
}
|
||||
|
||||
function handleContinue() {
|
||||
ipc.exec("pkg:execute", update.manifest.id, {
|
||||
ipc.exec("pkg:execute", update.id, {
|
||||
force: true
|
||||
})
|
||||
|
||||
@ -38,7 +38,7 @@ const PackageUpdateAvailable = ({ update, close }) => {
|
||||
|
||||
<code>
|
||||
<p>
|
||||
<b>{update.current_version}</b> {`->`} <b>{update.new_version}</b>
|
||||
<b>{update.local}</b> {`->`} <b>{update.remote}</b>
|
||||
</p>
|
||||
</code>
|
||||
|
||||
|
@ -22,11 +22,13 @@ const Splash = (props) => {
|
||||
|
||||
{
|
||||
globalState.appSetup.message && <>
|
||||
<div className="app-setup_message-wrapper">
|
||||
<div className="app-setup_message">
|
||||
<span>
|
||||
{globalState.appSetup.message}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<BarLoader
|
||||
className="app_loader"
|
||||
|
@ -12,6 +12,8 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
padding-top: 30px;
|
||||
|
||||
gap: 10px;
|
||||
|
||||
h1 {
|
||||
@ -19,14 +21,26 @@
|
||||
}
|
||||
}
|
||||
|
||||
.app-setup_message {
|
||||
padding: 15px 10px;
|
||||
border-radius: 12px;
|
||||
.app-setup_message-wrapper {
|
||||
display: flex;
|
||||
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"
|
||||
icon={<Icons.MdDownload />}
|
||||
onClick={app.applyUpdate}
|
||||
type="primary"
|
||||
>
|
||||
Update now
|
||||
Update app
|
||||
</antd.Button>
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ import loadable from "@loadable/component"
|
||||
import GlobalStateContext from "contexts/global"
|
||||
|
||||
import SplashScreen from "components/Splash"
|
||||
import CrashError from "components/Crash"
|
||||
|
||||
const DefaultNotFoundRender = () => {
|
||||
return <div>Not found</div>
|
||||
@ -130,6 +131,18 @@ export const InternalRouter = (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(() => {
|
||||
let paths = {
|
||||
...import.meta.glob("/src/pages/**/[a-z[]*.jsx"),
|
||||
@ -154,12 +167,6 @@ export const PageRender = (props) => {
|
||||
return paths
|
||||
}, [])
|
||||
|
||||
const globalState = React.useContext(GlobalStateContext)
|
||||
|
||||
if (globalState.initializing) {
|
||||
return <SplashScreen />
|
||||
}
|
||||
|
||||
return <Routes>
|
||||
{
|
||||
routes.map((route, index) => {
|
||||
|
@ -15,6 +15,19 @@
|
||||
--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,
|
||||
body {
|
||||
padding: 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user