Skip to content

Commit

Permalink
Rewrite + mod types + collapsible mods
Browse files Browse the repository at this point in the history
  • Loading branch information
Rumrobot committed May 20, 2024
1 parent 6677fd3 commit c71273f
Show file tree
Hide file tree
Showing 15 changed files with 249 additions and 118 deletions.
1 change: 1 addition & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- Clean up the code ofc.
- som error handling for invalid mod folders
- check download hash

## New features

Expand Down
Binary file modified bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"dependencies": {
"@sveltejs/kit": "^2.5.4",
"@tauri-apps/api": "^1",
"bits-ui": "^0.20.0",
"bits-ui": "^0.21.8",
"bottleneck": "^2.19.5",
"clsx": "^2.1.0",
"lucide-svelte": "^0.359.0",
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
},
"package": {
"productName": "Pavlov Map Manager",
"version": "1.1.0"
"version": "1.2.0"
},
"tauri": {
"allowlist": {
Expand Down
10 changes: 8 additions & 2 deletions src/lib/components/modcard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@
let theme: string;
let deletePopup: boolean;
let showType: boolean;
onMount(async () => {
theme = await config.get("theme");
deletePopup = await config.get("deletePopup");
deletePopup = await config.get("delete_popup");
showType = await config.get("show_type");
});
export let mod: string;
Expand All @@ -48,10 +50,14 @@
>
</CardHeader>
<CardContent>
{#if showType}
<p class="flex justify-center mb-1.5 text-lg">{$modsStore[mod].type}</p>
{/if}
<button
on:click={() => open($modsStore[mod].modUrl)}
role="link"
tabindex="0"
class={!showType ? "mt-3" : ""}
>
<img
src={$modsStore[mod].imageUrl}
Expand All @@ -60,7 +66,7 @@
/>
</button>
<div class="mt-1.5 flex flex-row justify-between">
{#if $modsStore[mod].currentVersion != $modsStore[mod].latestVersion }
{#if $modsStore[mod].currentVersion != $modsStore[mod].latestVersion}
<Button
on:click={() => addDownload(mod)}
disabled={$queueStore.includes(mod.toString())}
Expand Down
29 changes: 29 additions & 0 deletions src/lib/components/ui/accordion/accordion-content.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script lang="ts">
import { Accordion as AccordionPrimitive } from "bits-ui";
import { slide } from "svelte/transition";
import { cn } from "$lib/utils.js";
type $$Props = AccordionPrimitive.ContentProps;
let className: $$Props["class"] = undefined;
export let transition: $$Props["transition"] = slide;
export let transitionConfig: $$Props["transitionConfig"] = {
duration: 200,
};
export { className as class };
</script>

<AccordionPrimitive.Content
class={cn("overflow-hidden text-sm", className)}
{transition}
{transitionConfig}
{...$$restProps}
>
<!--
<div class="pb-4 pt-0">
<slot />
</div>
-->
<slot />
</AccordionPrimitive.Content>
14 changes: 14 additions & 0 deletions src/lib/components/ui/accordion/accordion-item.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script lang="ts">
import { Accordion as AccordionPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
type $$Props = AccordionPrimitive.ItemProps;
let className: $$Props["class"] = undefined;
export { className as class };
export let value: $$Props["value"];
</script>

<AccordionPrimitive.Item {value} class={cn("border-b", className)} {...$$restProps}>
<slot />
</AccordionPrimitive.Item>
28 changes: 28 additions & 0 deletions src/lib/components/ui/accordion/accordion-trigger.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<script lang="ts">
import { Accordion as AccordionPrimitive } from "bits-ui";
import ChevronDown from "svelte-radix/ChevronDown.svelte";
import { cn } from "$lib/utils.js";
type $$Props = AccordionPrimitive.TriggerProps;
type $$Events = AccordionPrimitive.TriggerEvents;
let className: $$Props["class"] = undefined;
export let level: AccordionPrimitive.HeaderProps["level"] = 3;
export { className as class };
</script>

<AccordionPrimitive.Header {level} class="flex">
<AccordionPrimitive.Trigger
class={cn(
"flex flex-1 items-center justify-between py-4 gap-2 text-sm font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
className
)}
{...$$restProps}
on:click
>
<slot />
<ChevronDown
class="h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200"
/>
</AccordionPrimitive.Trigger>
</AccordionPrimitive.Header>
17 changes: 17 additions & 0 deletions src/lib/components/ui/accordion/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Accordion as AccordionPrimitive } from "bits-ui";
import Content from "./accordion-content.svelte";
import Item from "./accordion-item.svelte";
import Trigger from "./accordion-trigger.svelte";

const Root = AccordionPrimitive.Root;
export {
Root,
Content,
Item,
Trigger,
//
Root as Accordion,
Content as AccordionContent,
Item as AccordionItem,
Trigger as AccordionTrigger,
};
2 changes: 1 addition & 1 deletion src/lib/components/ui/card/card-header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
export { className as class };
</script>

<div class={cn("flex flex-col space-y-1.5 p-6", className)} {...$$restProps}>
<div class={cn("flex flex-col space-y-1.5 pt-4 pb-1 px-6", className)} {...$$restProps}>
<slot />
</div>
120 changes: 69 additions & 51 deletions src/lib/modio-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,51 @@ export async function modioRequest(
return response;
}

export async function loadMods() {
let mods = get(modsStore);
const app = get(appStore);

app.loading = true;
app.status = "Loading mods";
appStore.set(app);

const localMods = await getLocalMods();
const subscriptions = await getSubscriptions();

for (const modData of subscriptions) {
if (assignModData(modData)) {
mods = get(modsStore);
mods[modData.id].subscribed = true;
}
}

for (const mod of localMods) {
if (!Object.keys(mods).includes(mod)) {
const response = await modioRequest(
`/games/3959/mods/${mod}`,
"GET"
);
if (!response.ok) {
toast.error("Error while fetching map data for map: " + mod);
console.log("Error while fetching map data for map: ", mod, " Error: ", response.status);
continue;
}
const data = await response.json();

if (assignModData(data)) {
mods = get(modsStore);
mods[data.id].subscribed = true;
}
}
mods[mod].currentVersion = await getCurrentVersion(mod);
}

modsStore.set(mods);
app.loading = false;
app.status = "Done";
appStore.set(app);
}

async function downloadQueue() {
let queue = get(queueStore);
const app = get(appStore);
Expand Down Expand Up @@ -82,7 +127,6 @@ async function downloadMap(mod: string) {
const modsPath = await config.get("mods_path");
const oauthToken = await config.get("oauth_token");

console.log("Old version: ", mods[mod].currentVersion)
// Set app data
app.currentlyDownloading = mods[mod].title;
app.downloadStatus = "Checking new mod version";
Expand Down Expand Up @@ -175,9 +219,6 @@ async function downloadMap(mod: string) {
});
mods[mod].currentVersion = await getCurrentVersion(mod);

console.log("New version written: ", mods[mod].currentVersion);
console.log(mods[mod]);

app.downloadStatus = "Done";

modsStore.set(mods);
Expand All @@ -198,59 +239,25 @@ async function getCurrentVersion(mod: string) {
return undefined;
}

return currentVersion;
return parseInt(currentVersion);
}

export async function getMaps() {
let mods = get(modsStore);
async function getLocalMods() {
const modsPath = await config.get("mods_path");

await getSubscriptions();

let localMods: Array<string> = [];
let localMods: Array<any> = [];
try {
localMods = await invoke("ls", { path: modsPath });
} catch (error) {
toast.error("Error while reading maps from path: " + modsPath);
console.log("Error while reading maps from path: ", error);
}
console.log(localMods);

localMods = localMods.filter((map: string) => map.startsWith("UGC"));
localMods = localMods.map((map: string) => map.split("UGC")[1]);
localMods = localMods.map((map: string) => parseInt(map));

console.log(localMods);

for (const mod of localMods) {
if (!Object.keys(mods).includes(mod)) {
const response = await modioRequest(
`/games/3959/mods/${mod}`,
"GET"
);
if (!response.ok) {
toast.error("Error while fetching map data for map: " + mod);
console.log("Error while fetching map data for map: ", mod, " Error: ", response.status);

// Remove the map from the list if it doesn't exist on mod.io
mods = Object.fromEntries(
Object.entries(mods).filter(([key]) => key != mod)
);
continue;
}
const data = await response.json();
assignModData(data);
mods[data.id].subscribed = false;
}

mods[mod].currentVersion = await getCurrentVersion(mod);
console.log("Read version for mod: ", mod, " Version: ", mods[mod].currentVersion)
}
for (let mod of Object.keys(mods)) {
if (mod == "3853484") {
console.log(mods[mod])
}
}
modsStore.set(mods);
return localMods;
}

function assignModData(data: any) {
Expand All @@ -267,25 +274,36 @@ function assignModData(data: any) {
mods[data.id].latestVersion = platform.modfile_live;
}
}

for (const tag of data.tags) {
if (tag.name) {
mods[data.id].type = tag.name;
}
}


if (mods[data.id].latestVersion == undefined) {
mods = Object.fromEntries(
Object.entries(mods).filter(([key]) => key != data.id)
);
modsStore.set(mods);
return Error;
console.log("No windows version for mod: ", data.id);
return false;
}

modsStore.set(mods);
return true;
}

async function getSubscriptions() {
const mods = get(modsStore);

let allRead = false;
let page = 0;

let subscriptions: Array<any> = [];

while (!allRead) {
const response = await modioRequest(
`/me/subscribed?game_id=3959&platforms=windows`,
`/me/subscribed?game_id=3959&platforms=windows&_offset=${page * 100}`,
"GET"
);
if (!response.ok) {
Expand All @@ -296,8 +314,7 @@ async function getSubscriptions() {
const data = await response.json();

for (const mod of data.data) {
assignModData(mod);
mods[mod.id].subscribed = true;
subscriptions.push(mod);
}

if (data.result_count == 100) {
Expand All @@ -306,7 +323,8 @@ async function getSubscriptions() {
allRead = true;
}
}
modsStore.set(mods);

return subscriptions;
}

export async function subscribe(mod: string) {
Expand Down Expand Up @@ -425,7 +443,7 @@ async function setAvatarUrl() {
const data = await response.json();
return data.avatar.thumb_100x100;
} catch (error) {
console.error("Error:", error);
console.error("Error while setting avatar_url:", error);
return;
}
}
Expand Down
7 changes: 3 additions & 4 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ export interface ModData {
title?: string;
imageUrl?: string;
modUrl?: string;
currentVersion?: string;
latestVersion?: string;
type?: string;
currentVersion?: number;
latestVersion?: number;
subscribed?: boolean;
}
}



export interface AppData {
loading: boolean;
status: string;
Expand Down
Loading

0 comments on commit c71273f

Please sign in to comment.