Skip to content

Commit 19fa13e

Browse files
committed
UI updates, bug fixes and experience improvements
1 parent d431724 commit 19fa13e

10 files changed

Lines changed: 128 additions & 131 deletions

File tree

deno.json

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,13 @@
11
{
2+
"exclude": [".svelte-kit/"],
23
"fmt": {
34
"useTabs": true,
45
"lineWidth": 120,
5-
"proseWrap": "never",
6-
"exclude": [
7-
"node_modules/",
8-
".svelte-kit/"
9-
]
6+
"proseWrap": "never"
107
},
118
"lint": {
129
"rules": {
13-
"exclude": [
14-
"no-explicit-any"
15-
]
16-
},
17-
"exclude": [
18-
"node_modules/",
19-
".svelte-kit/"
20-
]
10+
"exclude": ["no-explicit-any"]
11+
}
2112
}
2213
}

package.json

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
11
{
2-
"name": "openactionmarketplace",
3-
"version": "0.0.1",
2+
"name": "marketplace",
43
"type": "module",
54
"scripts": {
65
"dev": "vite dev",
76
"build": "vite build",
87
"preview": "vite preview"
98
},
109
"devDependencies": {
11-
"@sveltejs/adapter-auto": "^3.3",
12-
"@sveltejs/kit": "^2.8",
13-
"@sveltejs/vite-plugin-svelte": "^4.0",
14-
"autoprefixer": "^10.4",
15-
"svelte": "^5.2",
16-
"tailwindcss": "^3.4",
17-
"vite": "^5.4"
10+
"@sveltejs/adapter-auto": "^6.1",
11+
"@sveltejs/kit": "^2.43",
12+
"@sveltejs/vite-plugin-svelte": "^6.2",
13+
"@tailwindcss/vite": "^4.1",
14+
"svelte": "^5.39",
15+
"tailwindcss": "^4.1",
16+
"vite": "^7.1"
1817
},
1918
"dependencies": {
2019
"dompurify": "^3.2",
21-
"marked": "^15.0",
20+
"marked": "^16.3",
2221
"marked-base-url": "^1.1",
23-
"phosphor-svelte": "^2.0"
22+
"phosphor-svelte": "^3.0"
2423
}
2524
}

postcss.config.js

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/app.css

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,35 @@
11
@import url("https://rsms.me/inter/inter.css");
2-
3-
@tailwind base;
4-
@tailwind components;
5-
@tailwind utilities;
2+
@import "tailwindcss";
63

74
body {
85
font-family: "Inter", sans-serif;
96
@apply bg-neutral-800;
107
}
118

129
.readme h1, .readme h2, .readme h3, .readme h4, .readme h5, .readme h6 {
13-
@apply text-neutral-200;
10+
@apply font-medium text-neutral-200;
11+
}
12+
.readme h1:not(:first-child), .readme h2:not(:first-child), .readme h3:not(:first-child) {
13+
@apply mt-5;
14+
}
15+
.readme h1, .readme h2, .readme h3 {
16+
@apply mb-3 pb-1.5 border-b border-neutral-600;
1417
}
15-
1618
.readme h1 {
17-
@apply py-1.5 text-3xl font-bold;
19+
@apply text-2xl;
1820
}
19-
2021
.readme h2 {
21-
@apply py-1 text-2xl font-semibold;
22+
@apply text-xl;
2223
}
23-
2424
.readme h3 {
25-
@apply py-0.5 text-xl;
26-
}
27-
28-
.readme h4, .readme h5, .readme h6 {
2925
@apply text-lg;
3026
}
31-
27+
.readme a {
28+
@apply text-blue-400 hover:underline cursor-pointer;
29+
}
3230
.readme ul {
3331
@apply list-disc ml-6;
3432
}
33+
.readme img {
34+
@apply my-3;
35+
}

src/routes/+error.svelte

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { page } from "$app/stores";
33
</script>
44

5-
<div class="m-auto p-4 items-center">
6-
<h1 class="font-bold text-3xl text-neutral-200">{$page.status}: {$page.error?.message}</h1>
7-
</div>
5+
<h1 class="px-6 py-4 font-semibold text-center md:text-left text-2xl text-neutral-200 bg-neutral-900">
6+
<a href="/">OpenAction Marketplace</a>
7+
</h1>
8+
<h1 class="m-4 font-semibold text-center md:text-left text-2xl text-red-200">{$page.status}: {$page.error?.message}</h1>

src/routes/+page.svelte

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,36 +15,36 @@
1515
<link rel="icon" href="/favicon.png" />
1616
</svelte:head>
1717

18-
<div class="p-3">
19-
<div class="mx-8 mt-6 flex flex-col md:flex-row items-center justify-between">
20-
<h1 class="pb-1.5 font-bold text-2xl md:text-3xl text-neutral-200">OpenAction Marketplace</h1>
21-
<input
22-
bind:value={searchString}
23-
placeholder="Search for plugins"
24-
class="mt-6 md:mt-0 mx-4 md:mr-0 p-4 w-full md:w-72 lg:w-[32rem] h-12 text-center text-neutral-300 bg-neutral-700 rounded-xl"
25-
/>
26-
</div>
27-
28-
{#if data}
29-
<div class="p-8 gap-x-4 gap-y-12 grid" style="grid-template-columns: repeat(auto-fill, minmax(300px, 1fr))">
30-
{#each Object.entries(data) as [id, plugin]}
31-
{#if plugin.name.toLowerCase().includes(searchString.toLowerCase())}
32-
<a href={"/plugin/" + id} class="p-5 items-center flex flex-col text-xl bg-neutral-700 rounded-3xl">
33-
<img
34-
src={"https://openactionapi.github.io/plugins/icons/" + id + ".png"}
35-
alt={plugin.name}
36-
class="size-32 rounded-2xl"
37-
loading="lazy"
38-
/>
39-
<p class="pt-4 !font-semibold text-[18px] text-neutral-300">
40-
{plugin.name}
41-
</p>
42-
<p class="text-[16px] text-neutral-300">
43-
by {plugin.author}
44-
</p>
45-
</a>
46-
{/if}
47-
{/each}
48-
</div>
49-
{/if}
18+
<div class="flex flex-col md:flex-row items-center justify-between px-6 py-4 bg-neutral-900">
19+
<h1 class="font-semibold text-2xl text-neutral-200">OpenAction Marketplace</h1>
20+
<input
21+
bind:value={searchString}
22+
placeholder="Search for plugins"
23+
class="mt-6 md:mt-0 mx-4 md:mr-0 p-3 w-full md:w-72 h-8 text-center text-sm text-neutral-300 bg-neutral-700 rounded-lg"
24+
/>
5025
</div>
26+
27+
{#if data}
28+
<div class="grid gap-x-4 gap-y-4 p-8" style="grid-template-columns: repeat(auto-fill, minmax(300px, 1fr))">
29+
{#each Object.entries(data) as [id, plugin]}
30+
{#if plugin.name.toLowerCase().includes(searchString.toLowerCase())}
31+
<a href={"/plugin/" + id} class="flex flex-col items-center p-5 text-xl bg-neutral-700 rounded-3xl">
32+
<img
33+
src={"https://openactionapi.github.io/plugins/icons/" + id + ".png"}
34+
alt={plugin.name}
35+
class="size-32 rounded-2xl"
36+
loading="lazy"
37+
/>
38+
<p class="pt-4 !font-semibold text-[18px] text-neutral-300 text-nowrap">
39+
{plugin.name}
40+
</p>
41+
<p class="text-[16px] text-neutral-300">
42+
by {plugin.author}
43+
</p>
44+
</a>
45+
{/if}
46+
{/each}
47+
</div>
48+
{:else}
49+
<h2 class="m-4 text-center md:text-left text-xl text-neutral-200">Loading plugins...</h2>
50+
{/if}

src/routes/plugin/[id]/+page.svelte

Lines changed: 58 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,20 @@
99
import ArrowSquareOut from "phosphor-svelte/lib/ArrowSquareOut";
1010
import DownloadSimple from "phosphor-svelte/lib/DownloadSimple";
1111
12-
let pluginDetails: { repository: string; name: string; author: string; download_url: string | undefined };
13-
let readme = "## Loading plugin details...";
14-
let download_count = 0;
12+
type Plugin = { repository: string; name: string; author: string; download_url: string | undefined };
13+
14+
let pluginDetails: Plugin | 0;
15+
let readme = "<strong>Loading plugin details...</strong>";
16+
let downloadCount = 0;
1517
1618
async function getTotalDownloadCount(repo: string): Promise<number> {
1719
const response = await fetch("https://api.github.com/repos/" + repo + "/releases");
20+
if (!response.ok) return 0;
1821
const releases = await response.json();
1922
2023
let totalCount = 0;
21-
for (let release of releases) {
22-
for (let asset of release.assets) {
24+
for (const release of releases) {
25+
for (const asset of release.assets) {
2326
totalCount += asset.download_count;
2427
}
2528
}
@@ -28,37 +31,48 @@
2831
}
2932
3033
async function getReadme(repo: string): Promise<string> {
31-
let response = await fetch("https://raw.githubusercontent.com/" + repo + "/master/README.md");
32-
marked.use(baseUrl("https://raw.githubusercontent.com/" + repo + "/master/"));
33-
return DOMPurify.sanitize(await response.text());
34+
const renderer = new marked.Renderer();
35+
renderer.link = function (token) {
36+
const rendered = marked.Renderer.prototype.link.call(this, token);
37+
return rendered.replace("<a", `<a target="_blank" `);
38+
};
39+
marked.use({ renderer });
40+
const urls = [
41+
"https://raw.githubusercontent.com/" + repo + "/main/README.md",
42+
"https://raw.githubusercontent.com/" + repo + "/main/readme.md",
43+
"https://raw.githubusercontent.com/" + repo + "/master/README.md",
44+
"https://raw.githubusercontent.com/" + repo + "/master/readme.md",
45+
];
46+
for (const url of urls) {
47+
const response = await fetch(url);
48+
if (response.ok) {
49+
marked.use(baseUrl(url));
50+
return await marked.parse(DOMPurify.sanitize(await response.text()).replace(/<a/g, '<a target="_blank" '));
51+
}
52+
}
53+
return await marked.parse("**Plugin README file not found**\n\n[View plugin on GitHub](https://github.com/" + repo + ")");
3454
}
3555
3656
onMount(async () => {
3757
const response = await fetch("https://openactionapi.github.io/plugins/catalogue.json");
3858
if (!response.ok) return;
3959
4060
const data = await response.json();
41-
pluginDetails = data[$page.params.id];
61+
pluginDetails = data[$page.params.id!];
4262
if (!pluginDetails) {
43-
// @ts-expect-error
44-
pluginDetails = -1;
63+
pluginDetails = 0;
4564
return;
4665
}
4766
4867
const repo = pluginDetails.repository.split("/")[3] + "/" + pluginDetails.repository.split("/")[4];
4968
readme = await getReadme(repo);
50-
download_count = await getTotalDownloadCount(repo);
69+
downloadCount = await getTotalDownloadCount(repo);
5170
});
5271
5372
function openDeepLink() {
54-
let iframe = document.getElementById("deeplink-iframe") as HTMLIFrameElement;
73+
const iframe = document.getElementById("deeplink-iframe") as HTMLIFrameElement;
5574
iframe.src = "opendeck://installPlugin/" + $page.params.id;
5675
}
57-
58-
function getDownloadAction(): string {
59-
if (pluginDetails.download_url) return pluginDetails.download_url;
60-
return pluginDetails.repository + "/releases/latest";
61-
}
6276
</script>
6377

6478
<svelte:head>
@@ -72,24 +86,32 @@
7286
/>
7387
</svelte:head>
7488

75-
{#if pluginDetails}
76-
<div class="mx-[2.5%] my-[2.5%] p-10 w-[95vw] h-[90vh] flex flex-col bg-neutral-700 rounded-3xl">
89+
<h1 class="px-6 py-4 font-semibold text-center md:text-left text-2xl text-neutral-200 bg-neutral-900">
90+
<a href="/">OpenAction Marketplace</a>
91+
</h1>
92+
93+
{#if pluginDetails == 0}
94+
<div class="m-4 text-center md:text-left text-red-200">
95+
<h1 class="mb-1 font-semibold text-2xl">404: Plugin Not Found</h1>
96+
<h1 class="text-xl">Please check that the plugin ID was entered correctly</h1>
97+
</div>
98+
{:else if pluginDetails}
99+
<div class="m-6 md:m-8">
77100
<div class="flex flex-col md:flex-row items-center md:items-start justify-between">
78101
<div class="flex flex-row items-center md:items-start">
79102
<img
80103
src={"https://openactionapi.github.io/plugins/icons/" + $page.params.id + ".png"}
81104
alt={pluginDetails.name}
82105
class="size-16 md:size-48 rounded-2xl"
83106
/>
84-
<div class="ml-8 flex flex-col">
107+
<div class="flex flex-col ml-8">
85108
<div class="text-3xl text-neutral-200">{pluginDetails.name}</div>
86-
<div class="mt-2 flex items-center text-lg text-neutral-400">
109+
<div class="flex items-center mt-2 text-lg text-neutral-400">
87110
<span class="mr-2">by</span>
88111
<img
89-
src={"https://avatars.githubusercontent.com/" +
90-
pluginDetails.repository.split("/")[3]}
112+
src={"https://avatars.githubusercontent.com/" + pluginDetails.repository.split("/")[3]}
91113
alt="Avatar URL"
92-
class="mr-1.5 size-7 rounded-full"
114+
class="size-7 mr-1.5 rounded-full"
93115
/>
94116
<a
95117
href={"https://github.com/" + pluginDetails.repository.split("/")[3]}
@@ -106,36 +128,34 @@
106128

107129
<button
108130
on:click={() => openDeepLink()}
109-
class="px-8 py-1.5 md:py-3 active:translate-y-0.5 font-semibold text-lg text-neutral-100 bg-indigo-600 rounded-l-lg"
131+
class="active:translate-y-0.5 px-8 py-1.5 md:py-3 font-semibold text-lg text-neutral-100 bg-indigo-600 rounded-l-lg"
110132
>
111133
Install
112134
</button>
113135

114136
<button
115-
on:click={async () => window.open(getDownloadAction())}
116-
class="ml-1 p-2 md:p-3.5 active:translate-y-0.5 text-lg text-neutral-100 bg-indigo-600 rounded-r-lg"
137+
on:click={async () =>
138+
window.open(
139+
(pluginDetails as Plugin).download_url ?? (pluginDetails as Plugin).repository + "/releases/latest",
140+
)}
141+
class="active:translate-y-0.5 ml-1 p-2 md:p-3.5 text-lg text-neutral-100 bg-indigo-600 rounded-r-lg"
117142
>
118143
<ArrowSquareOut size={24} />
119144
</button>
120145

121-
{#if download_count}
122-
<div class="flex flex-row text-neutral-300 ml-8">
123-
<span class="mr-1 text-lg"> {download_count} </span>
146+
{#if downloadCount}
147+
<div class="flex flex-row ml-8 text-neutral-300">
148+
<span class="mr-1 text-lg"> {downloadCount} </span>
124149
<DownloadSimple size={28} />
125150
</div>
126151
{/if}
127152
</div>
128153
</div>
129154

130-
<div class="md:mt-8 p-6 h-full overflow-scroll border-4 border-neutral-600 rounded-xl">
155+
<div class="md:mt-8 p-6 border-4 border-neutral-600 rounded-xl">
131156
<p class="readme text-neutral-300">
132-
{@html marked.parse(readme)}
157+
{@html readme}
133158
</p>
134159
</div>
135160
</div>
136-
{:else if pluginDetails == -1}
137-
<div class="m-auto p-4 items-center">
138-
<h1 class="font-bold text-3xl text-neutral-200">404 Plugin not found</h1>
139-
<h1 class="font-semibold text-xl text-neutral-200">Please check that the plugin ID was entered correctly</h1>
140-
</div>
141161
{/if}

tailwind.config.js

Lines changed: 0 additions & 11 deletions
This file was deleted.

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"extends": "./.svelte-kit/tsconfig.json",
33
"compilerOptions": {
44
"target": "ES2021",
5+
"allowImportingTsExtensions": true,
56
"allowJs": true,
67
"checkJs": true,
78
"esModuleInterop": true,

0 commit comments

Comments
 (0)