Skip to content

Commit

Permalink
Added frontend Docs prompt and JSON support for config api
Browse files Browse the repository at this point in the history
  • Loading branch information
CEbbinghaus committed Sep 9, 2024
1 parent 85e13a8 commit 0a28c08
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 12 deletions.
4 changes: 2 additions & 2 deletions .mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ outputs = ['build/bin/backend']
[tasks."build:frontend"]
description = 'Build the Frontend'
run = "node --no-warnings=ExperimentalWarning 'util/build.mjs' -o frontend"
sources = ['package.json', 'lib/package.json', '{src,lib}/**/*.{ts,tsx,codegen}']
outputs = ['dist/index.js']
# sources = ['package.json', 'lib/package.json', '{src,lib}/**/*.*']
# outputs = ['dist/index.js']

[tasks."build:collect"]
depends = ["build:backend", "build:frontend"]
Expand Down
16 changes: 16 additions & 0 deletions backend/src/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,17 @@ impl Config {
let parts: Vec<&str> = name.split(":").collect();

match parts[..] {
["*"] => Ok(serde_json::to_string(&self).unwrap()),
["backend"] => Ok(serde_json::to_string(&self.backend).unwrap()),
["backend", "port"] => Ok(self.backend.port.to_string()),
["backend", "scan_interval"] => Ok(self.backend.scan_interval.to_string()),
["backend", "store_file"] => Ok(self.backend.store_file.to_string_lossy().to_string()),
["backend", "log_file"] => Ok(self.backend.log_file.to_string_lossy().to_string()),
["backend", "log_level"] => Ok(self.backend.log_level.to_string()),
["backend", "startup"] => Ok(serde_json::to_string(&self.backend.startup).unwrap()),
["backend", "startup", "skip_validate"] => Ok(self.backend.startup.skip_validate.to_string()),
["backend", "startup", "skip_clean"] => Ok(self.backend.startup.skip_clean.to_string()),
["frontend"] => Ok(serde_json::to_string(&self.frontend).unwrap()),
["frontend", "dismissed_docs"] => Ok(self.frontend.dismissed_docs.to_string()),
_ => Err(Error::from_str("Invalid property Name")),
}
Expand All @@ -136,6 +140,12 @@ impl Config {
let wrong_value_err = Error::from_str(&format!("The value provided \"{value}\" did not match the expected type"));

match parts[..] {
["*"] => {
*self = serde_json::from_str(value).map_err(|_| wrong_value_err)?;
}
["backend"] => {
self.backend = serde_json::from_str(value).map_err(|_| wrong_value_err)?;
}
["backend", "port"] => {
self.backend.port = value.parse().map_err(|_| wrong_value_err)?;
}
Expand All @@ -151,12 +161,18 @@ impl Config {
["backend", "log_level"] => {
self.backend.log_level = value.parse().map_err(|_| wrong_value_err)?;
}
["backend", "startup"] => {
self.backend.startup = serde_json::from_str(value).map_err(|_| wrong_value_err)?;
}
["backend", "startup", "skip_validate"] => {
self.backend.startup.skip_validate = value.parse().map_err(|_| wrong_value_err)?;
}
["backend", "startup", "skip_clean"] => {
self.backend.startup.skip_clean = value.parse().map_err(|_| wrong_value_err)?;
}
["frontend"] => {
self.frontend = serde_json::from_str(value).map_err(|_| wrong_value_err)?;
}
["frontend", "dismissed_docs"] => {
self.frontend.dismissed_docs = value.parse().map_err(|_| wrong_value_err)?;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cebbinghaus/microsdeck",
"version": "0.10.5",
"version": "0.0.0",
"description": "",
"keywords": [],
"author": "CEbbinghaus",
Expand Down
23 changes: 18 additions & 5 deletions lib/src/MicoSDeck.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Event as BackendEvent, EventType, fetchCardsAndGames, fetchCardsForGame, fetchCreateGame, fetchCurrentCardAndGames, fetchDeleteCard, fetchEventTarget, fetchHealth, fetchLinkCardAndGame, fetchLinkCardAndManyGames, fetchUnlinkCardAndGame, fetchUnlinkCardAndManyGames, fetchUpdateCard, fetchVersion } from "./backend.js";
import { Event as BackendEvent, EventType, fetchCardsAndGames, fetchCardsForGame, fetchCreateGame, fetchCurrentCardAndGames, fetchDeleteCard, fetchEventTarget, fetchGetSetting, fetchHealth, fetchLinkCardAndGame, fetchLinkCardAndManyGames, fetchUnlinkCardAndGame, fetchUnlinkCardAndManyGames, fetchUpdateCard, fetchVersion } from "./backend.js";
import Logger from "lipe";
import { CardAndGames, CardsAndGames, Game, MicroSDCard } from "./types.js"
import { CardAndGames, CardsAndGames, FrontendSettings, Game, MicroSDCard } from "./types.js"

import semverParse from "semver/functions/parse"
import semverEq from "semver/functions/eq.js"
Expand Down Expand Up @@ -87,6 +87,11 @@ export class MicroSDeck {
return this.cardsAndGames;
}

private frontendSettings: FrontendSettings | undefined;
public get FrontendSettings() {
return this.frontendSettings;
}

private pollLock: any | undefined;

private isDestructed = false;
Expand Down Expand Up @@ -120,8 +125,12 @@ export class MicroSDeck {
}
this.backendVersion = await fetchVersion(this.fetchProps);

await this.fetchCurrent();
await this.fetchCardsAndGames();
await Promise.all([
this.fetchCurrent(),
this.fetchCardsAndGames(),
this.fetchFrontendSettings(),
]);

this.eventBus.dispatchEvent(new Event("update"));
this.enabled = true;
}
Expand All @@ -132,13 +141,17 @@ export class MicroSDeck {
async fetchCardsAndGames() {
this.cardsAndGames = await fetchCardsAndGames(this.fetchProps) || this.cardsAndGames || [];
}
async fetchFrontendSettings() {
this.frontendSettings = await fetchGetSetting({ ...this.fetchProps, setting_name: "frontend"}) || this.frontendSettings;
}

getProps() {
return {
enabled: this.enabled,
version: this.backendVersion,
cardsAndGames: this.cardsAndGames,
currentCardAndGames: this.currentCardAndGames
currentCardAndGames: this.currentCardAndGames,
frontendSettings: this.frontendSettings
}
}

Expand Down
29 changes: 28 additions & 1 deletion lib/src/backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,33 @@ export async function fetchVersion({ url, logger }: FetchProps): Promise<string
return await wrapFetch({ url: `${url}/health`, logger });
}

export type SettingNames =
"*" |
"backend" |
"backend:port" |
"backend:scan_interval" |
"backend:store_file" |
"backend:log_file" |
"backend:log_level" |
"backend:startup" |
"backend:startup:skip_validate" |
"backend:startup:skip_clean" |
"frontend" |
"frontend:dismissed_docs";

export async function fetchGetSetting({ url, logger, setting_name }: FetchProps & { setting_name: SettingNames }): Promise<any | undefined> {
const result = await wrapFetch({ url: `${url}/setting/${setting_name}`, logger });
return result && JSON.parse(result) || result;
}

export async function fetchSetSetting({ url, logger, value, setting_name }: FetchProps & { setting_name: SettingNames, value: any }) {
await wrapFetch({ url: `${url}/setting/${setting_name}`, logger }, {
method: "POST",
...ApplicationJsonHeaders,
body: JSON.stringify(value),
});
}

export async function fetchDeleteCard({ url, logger, card }: FetchProps & { card: MicroSDCard }) {
await wrapFetch({ url: `${url}/card/${card.uid}`, logger }, { method: "DELETE" });
}
Expand Down Expand Up @@ -193,4 +220,4 @@ export async function fetchUnlinkCardAndManyGames({ url, logger, card_id, game_i
...ApplicationJsonHeaders,
body: JSON.stringify({card_id, game_ids}),
});
}
}
3 changes: 2 additions & 1 deletion lib/src/components/MicroSDeckContext.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createContext, useContext, useEffect, useState } from "react";
import { MicroSDeck } from "../MicoSDeck.js";
import { CardAndGames, CardsAndGames } from "../types.js";
import { CardAndGames, CardsAndGames, FrontendSettings } from "../types.js";

const MicroSDeckContext = createContext<MicroSDeckContext>(null as any);
export const useMicroSDeckContext = () => useContext(MicroSDeckContext);
Expand All @@ -12,6 +12,7 @@ interface ProviderProps {
interface PublicMicroSDeck {
currentCardAndGames: CardAndGames | undefined;
cardsAndGames: CardsAndGames;
frontendSettings: FrontendSettings | undefined;
}

interface MicroSDeckContext extends PublicMicroSDeck {
Expand Down
5 changes: 5 additions & 0 deletions lib/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,8 @@ export type Game = {
export type CardAndGames = [MicroSDCard, Game[]];

export type CardsAndGames = CardAndGames[];


export type FrontendSettings = {
dismissed_docs: boolean
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "microsdeck",
"version": "0.10.5",
"version": "0.0.0",
"description": "A SteamDeck plugin to track games across MicroSD cards",
"type": "module",
"keywords": [
Expand Down
22 changes: 21 additions & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from "@decky/ui";
import { routerHook } from '@decky/api';
import { FaEllipsisH, FaSdCard, FaStar } from "react-icons/fa";
import { GiHamburgerMenu } from "react-icons/gi";
import PatchAppScreen from "./patch/PatchAppScreen";
import { API_URL, DOCUMENTATION_PATH, UNNAMED_CARD_NAME } from "./const";
import { Logger } from "./Logging";
Expand All @@ -21,6 +22,7 @@ import { CardActionsContextMenu } from "./components/CardActions";
import { backend } from "../lib/src";
import { version as libVersion } from "../lib/src";
import { version } from "../package.json";
import { fetchSetSetting } from "../lib/src/backend";

if (!IsMatchingSemver(libVersion, version)) {
throw new Error("How the hell did we get here???");
Expand Down Expand Up @@ -52,7 +54,7 @@ function EditCardButton(props: EditCardButtonProps) {
}

function Content() {
const { currentCardAndGames, cardsAndGames, microSDeck } = useMicroSDeckContext();
const { currentCardAndGames, cardsAndGames, microSDeck, frontendSettings } = useMicroSDeckContext();

const [currentCard] = currentCardAndGames || [undefined];

Expand Down Expand Up @@ -83,9 +85,27 @@ function Content() {
return (<EditCardButton {...{ cardAndGames, currentCard, microSDeck: microSDeck }} />);
}

let docs_card = (<></>);

if (frontendSettings && frontendSettings.dismissed_docs === false) {
docs_card = (
<PanelSection title="Docs">
<div style={{ margin: "5px", marginTop: "0px" }}>
Open the documentation to learn how to use this plugin, For this use the context button <GiHamburgerMenu />
</div>
<DialogButton
style={{ width: "100%" }}
onOKButton={() => { fetchSetSetting({ url: API_URL, logger: Logger, setting_name: "frontend:dismissed_docs", value: true }); }}
onOKActionDescription="Dismiss Docs Reminder">Dismiss</DialogButton>
</PanelSection>
);
}

return (
<>
<Focusable onMenuActionDescription='Open Docs' onMenuButton={() => { Navigation.CloseSideMenus(); Navigation.Navigate(DOCUMENTATION_PATH); }}>
<div style={{marginTop: "25px"}} ></div>
{docs_card}
<div style={{ margin: "5px", marginTop: "0px" }}>
Rename, Reorder or Remove MicroSD Cards
</div>
Expand Down

0 comments on commit 0a28c08

Please sign in to comment.