Skip to content

Commit

Permalink
Created functionality for OverviewSubPage and it's page items.
Browse files Browse the repository at this point in the history
Created PopUp component for pre-styled dialog modals
  • Loading branch information
exejar committed Mar 1, 2024
1 parent 29e072a commit 46d0c30
Show file tree
Hide file tree
Showing 7 changed files with 329 additions and 91 deletions.
8 changes: 5 additions & 3 deletions src/components/pages/sub/OverviewSubPage.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
import ProcessList from "./items/ProcessList.svelte";
import Analytics from "./items/Analytics.svelte";
let consoleOutput: ConsoleOutput
let instances: number
</script>

<div class="w-full h-full flex flex-row gap-3">
<div id="left" class="w-[50%] h-full flex flex-col gap-3">
<ProcessList/>
<Analytics/>
<ProcessList bind:instances={instances} on:switch_console={(event) => consoleOutput.switchConsole(event.detail)}/>
<Analytics instances={instances}/>
</div>
<div id="right" class="w-[50%] h-full overflow-clip">
<ConsoleOutput/>
<ConsoleOutput bind:this={consoleOutput}/>
</div>
</div>
69 changes: 64 additions & 5 deletions src/components/pages/sub/items/Analytics.svelte
Original file line number Diff line number Diff line change
@@ -1,23 +1,82 @@
<script lang="ts">
import {invoke} from "@tauri-apps/api/tauri";
import type {Analytics} from "../../../../scripts/types";
import {onDestroy, onMount} from "svelte";
export let instances: number
let memoryUsage: string = "N/A"
let avgLaunchTime: string = "N/A"
let timePlayed: string = "None"
function formatTimePlayed(timePlayed: number): string {
const totalSeconds = Math.floor(timePlayed / 1000)
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
return `${hours}h ${minutes}m ${seconds}s`;
}
async function getMemoryUsage() {
try {
const [used, total] = await invoke<number[]>("get_memory_usage")
memoryUsage = (used / 1_000_000).toFixed(1)
} catch (error) {
console.error("Error retrieving memory usage:", error)
memoryUsage = "N/A"
}
}
async function getAnalytics() {
try {
const analytics = await invoke<Analytics>("get_analytics")
if (analytics.average_launch_time == -1)
avgLaunchTime = "N/A"
else
avgLaunchTime = `${analytics.average_launch_time.toFixed(1)}s`
timePlayed = formatTimePlayed(analytics.time_played)
} catch (error) {
console.error("Error retrieving analytics", error)
}
}
let interval: NodeJS.Timer
onMount(async () => {
await getMemoryUsage()
await getAnalytics()
interval = setInterval(async () => {
await getMemoryUsage()
await getAnalytics()
}, 2000)
})
onDestroy(() => {
clearInterval(interval)
})
</script>
<div id="analytics" class="relative w-full h-[40%] bg-surface rounded-xl text-center p-2 flex flex-col gap-2">
<div class="w-full text-center">
<h1>Analytics</h1>
</div>
<div id="analytics-container" class="bg-crust h-full w-full rounded-lg pl-2 pr-4 pt-2 pb-4">
<div id="ram-usage" class="analytic">
<h1 class="font-semibold">Ram Usage</h1>
<h1>0.01%</h1>
<h1>{memoryUsage === "N/A" ? memoryUsage : `${memoryUsage}mb`}</h1>
</div>
<div id="process-count" class="analytic">
<h1 class="font-semibold">MC Processes</h1>
<h1>10 Processes</h1>
<h1 class="font-semibold">MC Process Count</h1>
<h1>{instances} {instances > 1 ? "Processes" : "Process"} </h1>
</div>
<div id="time-played" class="analytic">
<h1 class="font-semibold">Time Played</h1>
<h1>10 Hours</h1>
<h1>{timePlayed}</h1>
</div>
<div id="avg-launch" class="analytic">
<h1 class="font-semibold">Avg. Launch</h1>
<h1>10 Seconds</h1>
<h1>{avgLaunchTime}</h1>
</div>
</div>
</div>
Expand Down
119 changes: 52 additions & 67 deletions src/components/pages/sub/items/ConsoleOutput.svelte
Original file line number Diff line number Diff line change
@@ -1,68 +1,45 @@
<script lang="ts">
const longString = "[14:00:01] [Genesis/main/INFO] Found external file: OptiFine_v1_8.jar\n" +
"[14:00:01] [Genesis/main/INFO] Found classpath URL: common-0.1.0-SNAPSHOT-all.jar with SHA-1 hash 3d1ce015144d9e8c67afb6c7bea44d465088760f\n" +
"[14:00:01] [Genesis/main/INFO] Found classpath URL: genesis-0.1.0-SNAPSHOT-all.jar with SHA-1 hash f4fe0763ee5612babf600ff896c2fcb2817bb441\n" +
"[14:00:01] [Genesis/main/INFO] Found classpath URL: legacy-0.1.0-SNAPSHOT-all.jar with SHA-1 hash 95af94ca8287d1c63c3d6760794b7c73485a061d\n" +
"[14:00:01] [Genesis/main/INFO] Found classpath URL: lunar-lang.jar with SHA-1 hash 8ac3190e3564dd237aa2e33e9da303b906319101\n" +
"[14:00:01] [Genesis/main/INFO] Found classpath URL: lunar-emote.jar with SHA-1 hash b04f3ee8f5e43fa3b162981b50bb72fe1acabb33\n" +
"[14:00:01] [Genesis/main/INFO] Found classpath URL: lunar.jar with SHA-1 hash c4bf1454c42c8bb098a3d81ccd4c98f7f137c6f8\n" +
"[14:00:01] [Genesis/main/INFO] Found classpath URL: optifine-0.1.0-SNAPSHOT-all.jar with SHA-1 hash 8757e4990af8e16689617da7a0ed5b22deb522c2\n" +
"[14:00:02] [Genesis/GameBootstrap/main/INFO] Launching Minecraft 1.8.9 v1_8 (parsed from 1.8.9)\n" +
"[14:00:02] [Genesis/GameBootstrap/main/INFO] Config hash: 988e8644 File hash: e02e703f\n" +
"[14:00:02] [Genesis/Baker/main/INFO] Found class cache: .\\cache\\988e8644\\e02e703f\\bake.cache\n" +
"[14:00:02] [Genesis/Baker/main/INFO] Loading baked classes...\n" +
"[14:00:02] [Genesis/Baker/main/INFO] Loaded 11698 baked classes.\n" +
"LUNARCLIENT_STATUS_PREINIT\n" +
"[14:00:02] [Genesis/GameBootstrap/main/INFO] Starting game!\n" +
"[Weave] Initializing Weave\n" +
"[14:00:02] [OptiFine/main/INFO] Using OptiFine namespace \n" +
"[14:00:02] [OptiFine/main/INFO] Loaded 1050 patches.\n" +
"[14:00:02] [OptiFine/main/INFO] Loaded 72 assets.\n" +
"WARN StatusConsoleListener The use of package scanning to locate plugins is deprecated and will be removed in a future release\n" +
"[14:00:03] [IchorPipeline/main/WARN] MappingSet for com.moonsworth.lunar.RCICHCHORIROCHICROIOOOIOH.RCICCIHHORIHRRIOICRCOIHRR.RROORRROHCICHHRRCROOIRIRR.CCICCHORRCRRRIOORCRCIOIRI has 0 field mappings.\n" +
"WARN StatusConsoleListener The use of package scanning to locate plugins is deprecated and will be removed in a future release\n" +
"WARN StatusConsoleListener The use of package scanning to locate plugins is deprecated and will be removed in a future release\n" +
"WARN StatusConsoleListener The use of package scanning to locate plugins is deprecated and will be removed in a future release\n" +
"[14:00:04] [mixin/INFO] SpongePowered MIXIN Subsystem Version=0.8.5 Source=Unknown Service=Weave Env=CLIENT\n" +
"[14:00:05] [mixin/ERROR] Initialising mixin subsystem after game pre-init phase! Some mixins may be skipped.\n" +
"[Weave] Loading C:\\Users\\Max\\.weave\\mods\\LunarCPSHook-1.0.jar\n" +
"java.lang.reflect.InvocationTargetException\n" +
"\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n" +
"\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)\n" +
"\tat java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)\n" +
"\tat java.base/java.lang.reflect.Method.invoke(Unknown Source)\n" +
"\tat net.weavemc.loader.bootstrap.AgentKt$premain$2.transform(Agent.kt:96)\n" +
"\tat net.weavemc.loader.bootstrap.SafeTransformer$DefaultImpls.transform(SafeTransformer.kt:18)\n" +
"\tat net.weavemc.loader.bootstrap.AgentKt$premain$2.transform(Agent.kt:87)\n" +
"\tat java.instrument/java.lang.instrument.ClassFileTransformer.transform(Unknown Source)\n" +
"\tat java.instrument/sun.instrument.TransformerManager.transform(Unknown Source)\n" +
"\tat java.instrument/sun.instrument.InstrumentationImpl.transform(Unknown Source)\n" +
"\tat java.base/java.lang.ClassLoader.defineClass1(Native Method)\n" +
"\tat java.base/java.lang.ClassLoader.defineClass(Unknown Source)\n" +
"\tat java.base/java.lang.ClassLoader.defineClass(Unknown Source)\n" +
"\tat com.moonsworth.lunar.genesis.RCROHRIHRCRRRCHCOCCCCIHOR.findClass(Unknown Source)\n" +
"\tat com.moonsworth.lunar.genesis.RCROHRIHRCRRRCHCOCCCCIHOR.loadClass(Unknown Source)\n" +
"\tat java.base/java.lang.ClassLoader.loadClass(Unknown Source)\n" +
"\tat java.base/java.lang.Class.forName0(Native Method)\n" +
"\tat java.base/java.lang.Class.forName(Unknown Source)\n" +
"\tat com.moonsworth.lunar.genesis.ClientGameBootstrap.apply(Unknown Source)\n" +
"\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n" +
"\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)\n" +
"\tat java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)\n" +
"\tat java.base/java.lang.reflect.Method.invoke(Unknown Source)\n" +
"\tat com.moonsworth.lunar.genesis.IOHHIIRCOCOHOHRIRHCORIOCI.RCICCIHHORIHRRIOICRCOIHRR(Unknown Source)\n" +
"\tat com.moonsworth.lunar.genesis.Genesis.run(Unknown Source)\n" +
"\tat com.moonsworth.lunar.genesis.Genesis.main(Unknown Source)\n" +
"Caused by: org.spongepowered.asm.launch.MixinInitialisationError: Error initialising mixin config lunarcpshook.mixins.json\n" +
"\tat Genesis//org.spongepowered.asm.mixin.transformer.Config.create(Unknown Source)\n" +
"\tat Genesis//org.spongepowered.asm.mixin.Mixins.createConfiguration(Unknown Source)\n" +
"\tat Genesis//org.spongepowered.asm.mixin.Mixins.addConfiguration(Unknown Source)\n" +
"\tat Genesis//net.weavemc.loader.WeaveLoader.init(WeaveLoader.kt:63)\n" +
"\t... 26 more\n" +
"Caused by: java.lang.IllegalArgumentException: The specified resource 'lunarcpshook.mixins.json' was invalid or could not be read\n" +
"\tat Genesis//org.spongepowered.asm.mixin.transformer.MixinConfig.create(Unknown Source)\n" +
"\tat Genesis//org.spongepowered.asm.mixin.transformer.Config.create(Unknown Source)\n" +
"\t... 29 more\n"
import {shell} from "@tauri-apps/api";
import {onMount} from "svelte";
import {listen} from "@tauri-apps/api/event";
import type {ConsolePayload, MinecraftProcess} from "../../../../scripts/types";
import LoadSpinner from "../../../../components_old/LoadSpinner.svelte";
let output: string[] = []
let currentLogFile: string = ""
let client: string = "None"
let pid: number = -1
let switchingConsole: boolean = false
export function switchConsole(process: MinecraftProcess) {
pid = process.pid
client = process.info.client
switchingConsole = true
}
async function openLogFile() {
await shell.open(currentLogFile)
}
onMount(async () => {
await listen<ConsolePayload>("console_output", (event) => {
console.log("console_ouptput event")
const payload = event.payload
if (currentLogFile != payload.file_path) {
console.log(payload.file_path)
currentLogFile = payload.file_path
output = []
switchingConsole = false
}
// reactive update
output = [...output, payload.line]
})
})
</script>

<div id="console" class="relative w-full h-full bg-surface rounded-xl text-center overflow-clip p-2">
Expand All @@ -76,14 +53,22 @@
<div id="console-container" class="absolute bg-crust rounded-lg top-10 bottom-2 left-2 right-2 break-words py-2 pl-2 pr-1">
<div id="target-process-container" class="w-full h-6 flex items-center pr-1 gap-2">
<div class="px-2 h-full bg-overlay rounded">
<h1>PName: Lunar</h1>
<h1>Client: {client}</h1>
</div>
<div class="px-2 h-full bg-overlay rounded">
<h1>PID: 5728</h1>
<h1>PID: {pid}</h1>
</div>
</div>
<div id="console-content" class="absolute top-9 bottom-2 left-2 right-1 overflow-y-scroll gap-2 pr-1 text-sm text-start">
{longString}
{#if switchingConsole}
<div class="w-full h-full flex justify-center items-center">
<LoadSpinner/>
</div>
{:else}
{#each [...output.values()] as line}
<p>{line}</p>
{/each}
{/if}
</div>
</div>
</div>
Expand Down
72 changes: 58 additions & 14 deletions src/components/pages/sub/items/ProcessList.svelte
Original file line number Diff line number Diff line change
@@ -1,41 +1,85 @@
<script lang="ts">
import type {MinecraftProcess} from "../../../../scripts/types";
import {type MinecraftInfo, type MinecraftProcess} from "../../../../scripts/types";
import VerticalScroll from "../../../util/VerticalScroll.svelte";
import {createLaunchProfile, showProcessInfo} from "../../../../scripts/shared";
import ButtonBar from "../../../util/ButtonBar.svelte";
import {invoke} from "@tauri-apps/api/tauri";
import {createEventDispatcher, onDestroy, onMount} from "svelte";
import PopUp from "../../../util/PopUp.svelte";
import CreateLaunchProfilePopUp from "../../../popups/CreateLaunchProfilePopUp.svelte";
// <pid, MinecraftProcess>
let processMap = new Map<number, MinecraftProcess>([
[5728, {pid: 5728, info: {client: 'Lunar', cwd: 'dummy', cmd: 'dummy', version: '1.8.9'}}],
[93415, {pid: 93415, info: {client: 'Forge', cwd: 'dummy', cmd: 'dummy', version: '1.7.10'}}],
[689, {pid: 689, info: {client: 'Feather', cwd: 'dummy', cmd: 'dummy', version: '1.12.2'}}],
[52746, {pid: 52746, info: {client: 'Vanilla', cwd: 'dummy', cmd: 'dummy', version: '1.20.1'}}],
[8179, {pid: 8179, info: {client: 'Badlion', cwd: 'dummy', cmd: 'dummy', version: '1.16.5'}}],
[64302, {pid: 64302, info: {client: 'Other', cwd: 'dummy', cmd: 'dummy', version: '1.11'}}]
])
let popup: CreateLaunchProfilePopUp
let processMap = new Map<number, MinecraftProcess>()
export let instances: number = 0
const dispatch = createEventDispatcher()
async function getMinecraftProcesses() {
try {
const processList = await invoke<MinecraftProcess[]>("fetch_minecraft_processes")
const newMap = new Map()
for (const process of processList) {
let version = process.info.version.trim()
if (version.includes("-"))
process.info.version = version.substring(0, version.indexOf("-"))
newMap.set(process.pid, process)
}
processMap = newMap
instances = processMap.size
} catch (err) {
console.error(err)
}
}
async function killProcess(pid: number) {
try {
await invoke("kill_pid", {pid: pid})
} catch (err) {
console.error("Error killing process", err)
}
}
async function swapConsole(process: MinecraftProcess) {
try {
dispatch("switch_console", process)
await invoke("switch_console_output", {pid: process.pid})
} catch (err) {
console.error("Error swapping console", err)
}
}
let processInterval: NodeJS.Timer
onMount(async () => {
await getMinecraftProcesses()
processInterval = setInterval(async () => {
await getMinecraftProcesses()
}, 1000)
})
onDestroy(() => {
clearInterval(processInterval)
})
</script>

<div id="minecraft-processes" class="relative w-full h-full bg-surface rounded-xl p-2">
<div class="relative w-full text-center">
<h1>Minecraft Processes</h1>
</div>
<VerticalScroll columns={1} items={[...processMap.values()]} let:prop={mcProcess}>
<!-- bg-surface w-full h-[3rem] rounded-lg text-lg text-center flex justify-between overflow-clip py-2-->
<div class="w-full h-[3rem] rounded-lg flex gap-5 items-center justify-between p-2 bg-surface">
<button class="w-full h-[3rem] rounded-lg flex gap-5 items-center justify-between p-2 bg-surface">
<div class="h-full w-full flex flex-row justify-between items-center">
<h1 class="w-[33%] text-start">{mcProcess.pid}</h1>
<h1 class="w-[33%] text-center">{mcProcess.info.client}</h1>
<h1 class="w-[33%] text-end">{mcProcess.info.version}</h1>
</div>
<ButtonBar class="gap-2" buttons={[
{label: "Kill Process", action: () => killProcess(mcProcess.pid), icon: "fa-solid fa-skull"},
{label: "Create Launch Profile", action: () => createLaunchProfile(mcProcess), icon: "fa-solid fa-plus"},
{label: "Create Launch Profile", action: () => popup.startCreateLaunchProfile(mcProcess.info), icon: "fa-solid fa-plus"},
{label: "Process Info", action: () => showProcessInfo(mcProcess), icon: "fa-solid fa-info"}
]}/>
</div>
</button>
</VerticalScroll>
<CreateLaunchProfilePopUp bind:this={popup}/>
</div>
Loading

0 comments on commit 46d0c30

Please sign in to comment.