added support for options & patches

This commit is contained in:
srgooglo 2023-11-20 18:31:05 +01:00
parent e390ea6823
commit 084c083c6d
4 changed files with 288 additions and 9 deletions

View File

@ -10,7 +10,7 @@ const ManifestInfo = (props) => {
const [error, setError] = React.useState(null)
async function handleInstall() {
await ipc.exec("bundle:install", props.manifest)
await ipc.exec("pkg:install", props.manifest)
if (typeof props.close === "function") {
props.close()
@ -21,7 +21,7 @@ const ManifestInfo = (props) => {
setLoading(true)
try {
const result = await ipc.exec("bundle:read", url)
const result = await ipc.exec("pkg:read", url)
setManifest(JSON.parse(result))
@ -58,7 +58,7 @@ const ManifestInfo = (props) => {
</div>
<h1>
{manifest.pack_name}
{manifest.name}
</h1>
</div>

View File

@ -6,6 +6,8 @@ import BarLoader from "react-spinners/BarLoader"
import { MdFolder, MdDelete, MdPlayArrow, MdUpdate, MdOutlineMoreVert, MdSettings, MdInfoOutline } from "react-icons/md"
import PackageOptions from "../PackageOptions"
import "./index.less"
const PackageItem = (props) => {
@ -20,17 +22,17 @@ const PackageItem = (props) => {
title: "Update",
content: `Are you sure you want to update ${manifest.id}?`,
onOk: () => {
ipc.exec("bundle:update", manifest.id)
ipc.exec("pkg:update", manifest.id)
},
})
}
const onClickPlay = () => {
ipc.exec("bundle:exec", manifest.id)
ipc.exec("pkg:exec", manifest.id)
}
const onClickFolder = () => {
ipc.exec("bundle:open", manifest.id)
ipc.exec("pkg:open", manifest.id)
}
const onClickDelete = () => {
@ -38,11 +40,20 @@ const PackageItem = (props) => {
title: "Uninstall",
content: `Are you sure you want to uninstall ${manifest.id}?`,
onOk: () => {
ipc.exec("bundle:uninstall", manifest.id)
ipc.exec("pkg:uninstall", manifest.id)
},
})
}
const onClickOptions = () => {
app.modal.open(PackageOptions, {
manifest: manifest,
close: () => {
app.modal.close()
}
})
}
function handleUpdate(event, data) {
setManifest({
...manifest,
@ -76,7 +87,7 @@ const PackageItem = (props) => {
key: "options",
label: "Options",
icon: <MdSettings />,
disabled: true
onClick: onClickOptions,
},
{
type: "divider"
@ -123,7 +134,7 @@ const PackageItem = (props) => {
<div className="installation_item_info">
<h2>
{
manifest.pack_name
manifest.name ?? manifest.pack_name
}
</h2>
<p>

View File

@ -0,0 +1,201 @@
import React from "react"
import * as antd from "antd"
import "./index.less"
const Options = (props) => {
const { options = {} } = props
if (Object.keys(options).length === 0) {
return <p>
No options available
</p>
}
return Object.keys(options).map((key, index) => {
return <div
key={index}
id={key}
className="package_options-option"
>
<antd.Switch
defaultChecked={options[key]}
onChange={(e) => {
props.onChange(key, e)
}}
/>
<span>
{key}
</span>
</div>
})
}
const Patches = (props) => {
const { patches = [], applied_patches = [] } = props
if (patches.length === 0) {
return <p>
No patches available
</p>
}
return patches.map((patch, index) => {
const isInstalled = applied_patches.includes(patch.id)
return <div
key={index}
id={patch.id}
>
<antd.Checkbox
defaultChecked={isInstalled}
onChange={(e) => {
props.onChange(patch.id, e.target.checked)
}}
>
{patch.name}
</antd.Checkbox>
</div>
})
}
const PackageOptions = (props) => {
const { manifest } = props
const [changes, setChanges] = React.useState({
options: manifest.options ?? {},
patches: Object.fromEntries(manifest.patches.map((p) => {
return [p.id, manifest.applied_patches.includes(p.id)]
}))
})
function applyChanges() {
if (props.onClose) {
props.onClose()
}
if (props.close) {
props.close()
}
ipc.exec("pkg:apply_changes", manifest.id, changes)
}
function handleChanges(field, key, value) {
setChanges((prev) => {
return {
...prev,
[field]: {
...prev[field],
[key]: value
}
}
})
}
return <div className="package_options">
<div className="package_options-field">
<div className="package_options-field-header">
<p>Options</p>
</div>
<div className="package_options-field-body">
<Options
options={manifest.options}
onChange={(key, value) => {
handleChanges("options", key, value)
}}
/>
</div>
</div>
<div className="package_options-field">
<div className="package_options-field-header">
<p>Patches</p>
</div>
<div className="package_options-field-body">
<Patches
patches={manifest.patches}
applied_patches={manifest.applied_patches}
onChange={(key, value) => {
handleChanges("patches", key, value)
}}
/>
</div>
</div>
<div className="package_options-info">
<div className="package_options-info-item">
<div className="package_options-info-item-label">
Package ID
</div>
<div className="package_options-info-item-value">
<span>
{manifest.id}
</span>
</div>
</div>
<div className="package_options-info-item">
<div className="package_options-info-item-label">
Disk Usage
</div>
<div className="package_options-info-item-value">
<span>
{manifest.disk_usage ?? "unknown"}
</span>
</div>
</div>
<div className="package_options-info-item">
<div className="package_options-info-item-label">
Install path
</div>
<div className="package_options-info-item-value">
<span>
{manifest.install_path ?? "unknown"}
</span>
</div>
</div>
<div className="package_options-info-item">
<div className="package_options-info-item-label">
Manifest URL
</div>
<div className="package_options-info-item-value">
<p>
{manifest.remote_url ?? "unknown"}
</p>
</div>
</div>
<div className="package_options-info-item">
<div className="package_options-info-item-label">
Version
</div>
<div className="package_options-info-item-value">
<p>
{manifest.version ?? "unknown"}
</p>
</div>
</div>
</div>
<div className="package_options-actions">
<antd.Button
type="primary"
onClick={applyChanges}
>
Apply
</antd.Button>
</div>
</div>
}
export default PackageOptions

View File

@ -0,0 +1,67 @@
.package_options {
display: flex;
flex-direction: column;
gap: 10px;
font-size: 1rem;
.package_options-field {
display: flex;
flex-direction: column;
.package_options-field-header {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
font-size: 1rem;
}
.package_options-field-body {
display: flex;
flex-direction: column;
padding: 10px;
gap: 5px;
}
}
.ant-checkbox:not(.ant-checkbox-checked) {
.ant-checkbox-inner {
border-color: #fff;
}
}
.package_options-info {
display: flex;
flex-direction: column;
gap: 7px;
font-size: 0.6rem;
.package_options-info-item {
display: flex;
flex-direction: column;
.package_options-info-item-label {
display: flex;
flex-direction: row;
}
.package_options-info-item-value {
display: inline-flex;
flex-direction: row;
align-items: center;
padding-left: 5px;
}
}
}
}