summaryrefslogtreecommitdiffstats
path: root/src/lib/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/components')
-rw-r--r--src/lib/components/ExtensionCard.svelte47
-rw-r--r--src/lib/components/ExtensionCategory.svelte24
-rw-r--r--src/lib/components/ExtensionRow.svelte47
-rw-r--r--src/lib/components/Footer.svelte16
-rw-r--r--src/lib/components/MirrorSelector.svelte26
5 files changed, 160 insertions, 0 deletions
diff --git a/src/lib/components/ExtensionCard.svelte b/src/lib/components/ExtensionCard.svelte
new file mode 100644
index 0000000..90769e9
--- /dev/null
+++ b/src/lib/components/ExtensionCard.svelte
@@ -0,0 +1,47 @@
+<script lang="ts">
+ interface Props {
+ repo: {
+ source: string;
+ name: string;
+ path: string;
+ commit?: string;
+ };
+ protocol: string;
+ selectedDomain: string;
+ }
+
+ let { repo, protocol, selectedDomain }: Props = $props();
+</script>
+
+<div class="card">
+ <div class="card-header">
+ <a href={repo.source} target="_blank" class="card-title">
+ {repo.name}
+ </a>
+ <div class="card-meta">
+ {#if repo.commit}
+ Commit:{' '}
+ <a
+ href={`${repo.source}/commit/${repo.commit}`}
+ target="_blank"
+ class="commit-link"
+ >
+ {repo.commit.substring(0, 7)}
+ </a>
+ {:else}
+ Commit: N/A
+ {/if}
+ </div>
+ </div>
+ <div class="card-actions">
+ <a
+ href={`${protocol}://add-repo?url=${selectedDomain}${repo.path}`}
+ class="btn btn-primary"
+ >
+ Add Repo
+ </a>
+ <a href={`${selectedDomain}${repo.path}`} target="_blank" class="btn btn-secondary">
+ JSON
+ </a>
+ </div>
+</div>
diff --git a/src/lib/components/ExtensionCategory.svelte b/src/lib/components/ExtensionCategory.svelte
new file mode 100644
index 0000000..0acf92f
--- /dev/null
+++ b/src/lib/components/ExtensionCategory.svelte
@@ -0,0 +1,24 @@
+<script lang="ts">
+ import ExtensionCard from './ExtensionCard.svelte';
+ import type { ExtensionRepo } from '$lib/types';
+
+ interface Props {
+ category: string;
+ repos: ExtensionRepo[];
+ selectedDomain: string;
+ }
+
+ let { category, repos, selectedDomain }: Props = $props();
+
+ let protocol = $derived(category.toLowerCase() === 'mihon' ? 'tachiyomi' : 'aniyomi');
+ let title = $derived(category.charAt(0).toUpperCase() + category.slice(1));
+</script>
+
+<div class={category}>
+ <h2>{title} Extensions</h2>
+ <div class="grid">
+ {#each repos as repo}
+ <ExtensionCard {repo} {protocol} {selectedDomain} />
+ {/each}
+ </div>
+</div>
diff --git a/src/lib/components/ExtensionRow.svelte b/src/lib/components/ExtensionRow.svelte
new file mode 100644
index 0000000..d2a4102
--- /dev/null
+++ b/src/lib/components/ExtensionRow.svelte
@@ -0,0 +1,47 @@
+<script lang="ts">
+ import type { Extension } from '$lib/types';
+
+ interface Props {
+ extension: Extension;
+ repoUrl: string;
+ }
+
+ let { extension, repoUrl }: Props = $props();
+
+ function handleImageError(e: Event) {
+ const target = e.target as HTMLImageElement;
+ target.src =
+ 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NCIgaGVpZ2h0PSI2NCIgdmlld0JveD0iMCAwIDY0IDY0Ij48cmVjdCB3aWR0aD0iNjQiIGhlaWdodD0iNjQiIGZpbGw9IiMyYzNlNTAiLz48dGV4dCB4PSI1MCUiIHk9IjUwJSIgZG9taW5hbnQtYmFzZWxpbmU9Im1pZGRsZSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZmlsbD0iIzZjOGI5ZiIgZm9udC1zaXplPSIxMiI+TjwvdGV4dD48L3N2Zz4=';
+ }
+</script>
+
+<tr class="extension-row">
+ <td class="icon-cell">
+ <img
+ src={`${repoUrl}/icon/${extension.pkg}.png`}
+ alt={extension.name}
+ class="extension-icon-small"
+ loading="lazy"
+ onerror={handleImageError}
+ />
+ </td>
+ <td class="info-cell">
+ <div class="extension-name">
+ {extension.name}
+ {#if extension.nsfw === 1}
+ <span class="nsfw-badge">NSFW</span>
+ {/if}
+ </div>
+ <div class="extension-pkg">{extension.pkg}</div>
+ {#if extension.sourceName}
+ <div class="extension-source">Source: {extension.sourceName}</div>
+ {/if}
+ </td>
+ <td class="meta-cell">
+ <span class="version">v{extension.version}</span>
+ <span class="lang">{extension.lang}</span>
+ </td>
+ <td class="action-cell">
+ <a href={`${repoUrl}/apk/${extension.apk}`} class="btn btn-primary btn-sm"> Download </a>
+ </td>
+</tr>
diff --git a/src/lib/components/Footer.svelte b/src/lib/components/Footer.svelte
new file mode 100644
index 0000000..3a228ca
--- /dev/null
+++ b/src/lib/components/Footer.svelte
@@ -0,0 +1,16 @@
+<script lang="ts">
+ interface Props {
+ source: string;
+ commitLink: string;
+ latestCommitHash: string;
+ }
+
+ let { source, commitLink, latestCommitHash }: Props = $props();
+</script>
+
+<footer>
+ Source Code: <a href={source} target="_blank">{source}</a>
+ <div>
+ Commit: <a href={commitLink} target="_blank">{latestCommitHash}</a>
+ </div>
+</footer>
diff --git a/src/lib/components/MirrorSelector.svelte b/src/lib/components/MirrorSelector.svelte
new file mode 100644
index 0000000..7db4885
--- /dev/null
+++ b/src/lib/components/MirrorSelector.svelte
@@ -0,0 +1,26 @@
+<script lang="ts">
+ import { selectedDomain } from '$lib/stores/mirror';
+
+ interface Props {
+ domains: string[];
+ }
+
+ let { domains }: Props = $props();
+
+ function getHostname(url: string) {
+ try {
+ return new URL(url).hostname;
+ } catch {
+ return url;
+ }
+ }
+</script>
+
+<div class="controls">
+ <label for="mirror-select">Select Mirror:&nbsp;</label>
+ <select id="mirror-select" bind:value={$selectedDomain}>
+ {#each domains as domain}
+ <option value={domain}>{getHostname(domain)}</option>
+ {/each}
+ </select>
+</div>