Skip to content

Commit f46e7a8

Browse files
committed
Update components for Svelte5
1 parent 87d5697 commit f46e7a8

31 files changed

Lines changed: 438 additions & 282 deletions

backend/utils/paths.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,30 @@ func DiscordPath(channel string) string {
4848
}
4949
}
5050

51+
// TODO: make this check and attempt to return the base path when full path doesn't exist
5152
func BrowsePath(channel string) string {
5253
var channelName = GetChannelName(channel)
53-
54+
var candidate = ""
5455
switch op := runtime.GOOS; op {
5556
case "windows":
56-
return filepath.Join(os.Getenv("LOCALAPPDATA"), channelName)
57+
candidate = filepath.Join(os.Getenv("LOCALAPPDATA"), channelName)
5758
case "darwin", "linux":
58-
return filepath.Join(Roaming, strings.ToLower(channelName))
59+
candidate = filepath.Join(Roaming, strings.ToLower(channelName))
5960
default:
61+
candidate = ""
62+
}
63+
64+
if Exists(candidate) {
65+
return candidate
66+
}
67+
68+
candidate, err := os.UserHomeDir()
69+
70+
if err != nil {
6071
return ""
6172
}
73+
74+
return candidate
6275
}
6376

6477
func ValidatePath(proposed string) string {

frontend/src/lib/actions/debug.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ function log(entry: string) {
88
});
99
}
1010

11-
export default async function(discordPaths: string[]) {
11+
export default async function(channels: string[], discordPaths: string[]) {
1212
discordPaths.forEach(v => log(v));
1313
setTimeout(() => {progress.set(10);}, 200);
1414
setTimeout(() => {progress.set(25);}, 500);

frontend/src/lib/components/Button.svelte

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,30 @@
11
<script lang="ts">
2-
export let type = "secondary";
2+
import type {Snippet} from "svelte";
33
4-
const types = ["primary", "secondary"];
4+
interface Props {
5+
style?: "primary" | "secondary";
6+
tabindex?: number|string;
7+
disabled?: boolean;
8+
onkeypress?(event: KeyboardEvent): void;
9+
onclick?(event: MouseEvent): void;
10+
children: Snippet;
11+
}
12+
13+
const {style = "secondary", onkeypress, onclick, children, tabindex, disabled = false}: Props = $props();
14+
15+
const styles = ["primary", "secondary"];
516
</script>
617

718
<button
8-
class="button {types.includes(type) ? `type-${type}` : "type-secondary"}"
19+
class="button {styles.includes(style) ? `style-${style}` : "style-secondary"}"
920
type="button"
10-
on:keypress
11-
on:click|preventDefault|stopPropagation
12-
{...$$restProps}
21+
{onkeypress}
22+
{onclick}
23+
tabindex={tabindex as number}
24+
{disabled}
1325
>
1426
<span>
15-
<slot></slot>
27+
{@render children()}
1628
</span>
1729
</button>
1830

@@ -45,23 +57,23 @@
4557
text-overflow: ellipsis;
4658
}
4759
48-
.button.type-primary {
60+
.button.style-primary {
4961
border: 1px solid transparent;
5062
background-color: var(--accent);
5163
color: #ffffff;
5264
}
5365
54-
.button.type-primary:hover {
66+
.button.style-primary:hover {
5567
background-color: var(--accent-hover);
5668
}
5769
58-
.button.type-secondary {
70+
.button.style-secondary {
5971
background-color: transparent;
6072
border: 1px solid rgba(255, 255, 255, 0.05);
6173
color: var(--text-normal);
6274
}
6375
64-
.button.type-secondary:hover {
76+
.button.style-secondary:hover {
6577
border-color: rgba(255, 255, 255, 0.1);
6678
}
6779
</style>

frontend/src/lib/components/ButtonGroup.svelte

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
<script lang="ts"></script>
1+
<script lang="ts">
2+
import type {Snippet} from "svelte";
23
3-
<div class="button-group" {...$$restProps}>
4-
<slot></slot>
4+
const {children}: {children: Snippet} = $props();
5+
</script>
6+
7+
8+
<div class="button-group">
9+
{@render children()}
510
</div>
611

12+
713
<style>
814
.button-group {
915
display: flex;

frontend/src/lib/components/Checkbox.svelte

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,31 @@
22
// NOTES: preventing the default click event behavior is needed to stop the change event being fired twice when the spacebar is pressed.
33
import {handleKeyboardToggle, checkItem} from "../stores/controls";
44
5-
export let checked = false;
6-
export let label = undefined; // eslint-disable-line no-undef-init
75
8-
let checkbox;
6+
interface Props {
7+
checked: boolean;
8+
label?: string;
9+
onchange?(e: Event): void;
10+
}
11+
12+
// eslint-disable-next-line prefer-const
13+
let {checked, label, onchange}: Props = $props();
14+
15+
let checkbox: HTMLInputElement;
916
10-
function handleKeyDown(e) {
17+
function handleKeyDown(e: KeyboardEvent) {
1118
if (e.key === " ") {
1219
e.preventDefault();
1320
checkItem(checkbox);
1421
}
1522
}
1623
</script>
1724

18-
<!-- svelte-ignore a11y-label-has-associated-control -->
19-
<!-- https://github.com/sveltejs/svelte/issues/5528 -->
20-
<label class="checkbox-container" on:keypress={handleKeyboardToggle(checkbox)}>
25+
26+
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
27+
<label class="checkbox-container" onkeypress={(e: KeyboardEvent) => handleKeyboardToggle(e, checkbox)}>
2128
<div class="checkbox-inner">
22-
<input class="checkbox" type="checkbox" bind:this={checkbox} bind:checked on:change on:keydown={handleKeyDown} {...$$restProps} />
29+
<input class="checkbox" type="checkbox" bind:this={checkbox} bind:checked {onchange} onkeydown={handleKeyDown} />
2330
<svg class="checkbox-glyph" viewBox="0 0 24 24">
2431
<path d="M0.73, 11.91 8.1,19.28 22.79,4.59" fill="none" />
2532
</svg>
@@ -29,6 +36,7 @@
2936
{/if}
3037
</label>
3138

39+
3240
<style>
3341
.checkbox-container {
3442
display: flex;

frontend/src/lib/components/Footer.svelte

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
<script lang="ts">
2-
// const electron = require("electron");
3-
42
import Button from "./Button.svelte";
53
import ButtonGroup from "./ButtonGroup.svelte";
64
import SocialLinks from "./SocialLinks.svelte";
75
import {canGoForward, canGoBack, nextPage, state} from "../stores/navigation";
8-
// import {push, pop, location} from "svelte-spa-router";
96
import quit from "../actions/quit";
10-
import {goto, pushState} from "$app/navigation";
7+
import {goto, onNavigate} from "$app/navigation";
118
import {page} from "$app/state";
9+
import {base} from "$app/paths";
10+
1211
1312
let nextButtonContent = "Next";
1413
1514
async function goToNext() {
1615
state.direction = 1;
17-
if ($nextPage) goto($nextPage, page.state);
16+
if ($nextPage) goto(`${base}${$nextPage}`, page.state);
1817
else await quit();
1918
}
2019
@@ -23,16 +22,18 @@
2322
window.history.back();
2423
}
2524
26-
$: if (window.location.pathname.startsWith("/setup/")) {
27-
const action = window.location.pathname.slice(7);
28-
const actionText = action[0].toUpperCase() + action.slice(1);
29-
nextButtonContent = actionText;
30-
}
31-
else {
32-
nextButtonContent = "Next";
33-
}
25+
onNavigate(() => {
26+
if (window.location.pathname.startsWith("/actions/setup/")) {
27+
const action = window.location.pathname.slice(15);
28+
const actionText = action[0].toUpperCase() + action.slice(1);
29+
nextButtonContent = actionText;
30+
}
31+
else {
32+
nextButtonContent = "Next";
33+
}
34+
});
3435
35-
function navigatePage() {
36+
function navigatePage(event: KeyboardEvent) {
3637
if ((event.key === "ArrowRight" && event.ctrlKey) && $canGoForward) {
3738
goToNext();
3839
}
@@ -48,8 +49,8 @@
4849
<footer class="install-footer">
4950
<SocialLinks />
5051
<ButtonGroup>
51-
<Button type="secondary" disabled={!$canGoBack} on:click={goBack}>Back</Button>
52-
<Button type="primary" disabled={!$canGoForward} on:click={goToNext}>{#if $nextPage}{nextButtonContent}{:else}Close{/if}</Button>
52+
<Button style="secondary" disabled={!$canGoBack} onclick={goBack}>Back</Button>
53+
<Button style="primary" disabled={!$canGoForward} onclick={goToNext}>{#if $nextPage}{nextButtonContent}{:else}Close{/if}</Button>
5354
</ButtonGroup>
5455
</footer>
5556

frontend/src/lib/components/Multiselect.svelte

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,45 @@
11
<script lang="ts">
22
import Button from "./Button.svelte";
33
import {handleKeyboardToggle} from "../stores/controls";
4-
import {createEventDispatcher} from "svelte";
4+
import type {Snippet} from "svelte";
55
6-
export let value;
7-
export let description;
8-
export let disabled = false;
9-
export let checked = false;
6+
// export let value: string;
7+
// export let description;
8+
// export let disabled = false;
9+
// export let checked = false;
10+
// export let onclick;
11+
// export let onchange;
1012
11-
let checkbox;
12-
13-
const dispatch = createEventDispatcher();
14-
function click() {
15-
dispatch("click", value);
13+
interface Props {
14+
description: string;
15+
disabled?: boolean
16+
checked?: boolean;
17+
onclick?(event: MouseEvent): void;
18+
onchange?(event: Event): void;
19+
icon?: Snippet;
20+
children?: Snippet;
1621
}
1722
23+
const {children, icon, description, disabled = false, checked = false, onclick, onchange}: Props = $props();
24+
25+
let checkbox: HTMLInputElement;
26+
1827
</script>
1928

20-
<label class="check-container" {...$$restProps}>
21-
<input bind:this={checkbox} type="checkbox" hidden {disabled} {checked} on:change {value} />
22-
<div on:keypress={handleKeyboardToggle(checkbox)} tabindex="0" class="check-item" class:disabled role="listbox">
29+
<label class="check-container">
30+
<input bind:this={checkbox} type="checkbox" hidden {disabled} {checked} {onchange} />
31+
<div onkeypress={(e: KeyboardEvent) => handleKeyboardToggle(e, checkbox)} tabindex="0" class="check-item" class:disabled role="listbox">
2332
<div class="icon">
24-
<slot name="icon" />
33+
{@render icon?.()}
2534
</div>
2635
<div class="content">
2736
<h5>
28-
<slot>Unknown</slot>
37+
{@render children?.()}
2938
</h5>
3039
<span title={description}>{description}</span>
3140
</div>
32-
<div class="controls" on:keypress={e => e.stopPropagation()}>
33-
<Button type="secondary" on:click={click}>Browse</Button>
41+
<div class="controls" role="presentation" onkeypress={e => e.stopPropagation()}>
42+
<Button style="secondary" {onclick}>Browse</Button>
3443
</div>
3544
</div>
3645
</label>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<script lang="ts">
2+
import type {Snippet} from "svelte";
3+
import PageHeader from "./PageHeader.svelte";
4+
import page from "$lib/transitions/page";
5+
6+
7+
interface Props {
8+
children: Snippet;
9+
icon?: Snippet;
10+
title?: string;
11+
}
12+
13+
const {children, icon, title = "BetterDiscord"}: Props = $props();
14+
</script>
15+
16+
17+
<div style:display="contents">
18+
{#key title}
19+
<section class="page" in:page|global out:page|global={{out: true}}>
20+
<PageHeader {icon}>{title}</PageHeader>
21+
{@render children()}
22+
</section>
23+
{/key}
24+
</div>
25+
26+
27+
<style>
28+
.page {
29+
flex: 1 1 auto;
30+
overflow: visible;
31+
display: flex;
32+
flex-direction: column;
33+
position: absolute;
34+
width: 100%;
35+
height: 100%;
36+
}
37+
</style>

frontend/src/lib/components/PageHeader.svelte

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
11
<script lang="ts">
2+
import type {Snippet} from "svelte";
23
import Text from "./Text.svelte";
4+
5+
interface Props {
6+
children: Snippet;
7+
icon?: Snippet;
8+
}
9+
10+
const {children, icon}: Props = $props();
311
</script>
412

513
<div class="page-header">
6-
<slot name="icon">
14+
{#if icon}
15+
{@render icon()}
16+
{:else}
717
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
818
<path d="M18.5 20C18.5 20.275 18.276 20.5 18 20.5H12.2678C11.9806 21.051 11.6168 21.5557 11.1904 22H18C19.104 22 20 21.104 20 20V9.828C20 9.298 19.789 8.789 19.414 8.414L13.585 2.586C13.57 2.57105 13.5531 2.55808 13.5363 2.5452C13.5238 2.53567 13.5115 2.5262 13.5 2.516C13.429 2.452 13.359 2.389 13.281 2.336C13.2557 2.31894 13.2281 2.30548 13.2005 2.29207C13.1845 2.28426 13.1685 2.27647 13.153 2.268C13.1363 2.25859 13.1197 2.24897 13.103 2.23933C13.0488 2.20797 12.9944 2.17648 12.937 2.152C12.74 2.07 12.528 2.029 12.313 2.014C12.2933 2.01274 12.2738 2.01008 12.2542 2.00741C12.2271 2.00371 12.1999 2 12.172 2H6C4.896 2 4 2.896 4 4V11.4982C4.47417 11.3004 4.97679 11.1572 5.5 11.0764V4C5.5 3.725 5.724 3.5 6 3.5H12V8C12 9.104 12.896 10 14 10H18.5V20ZM13.5 4.621L17.378 8.5H14C13.724 8.5 13.5 8.275 13.5 8V4.621ZM1 17.5C1 20.5376 3.46243 23 6.5 23C9.53757 23 12 20.5376 12 17.5C12 14.4624 9.53757 12 6.5 12C3.46243 12 1 14.4624 1 17.5ZM5.75 20.75C5.75 20.3358 6.08579 20 6.5 20C6.91421 20 7.25 20.3358 7.25 20.75C7.25 21.1642 6.91421 21.5 6.5 21.5C6.08579 21.5 5.75 21.1642 5.75 20.75ZM4.5 16C4.5 14.8954 5.39543 14 6.5 14C7.60457 14 8.5 14.8954 8.5 16C8.5 16.7305 8.28822 17.1397 7.74605 17.7079L7.48196 17.9775L7.36602 18.1025C7.08257 18.4207 7 18.6294 7 19C7 19.2761 6.77614 19.5 6.5 19.5C6.22386 19.5 6 19.2761 6 19C6 18.2695 6.21178 17.8603 6.75395 17.2921L7.01804 17.0225L7.13398 16.8975C7.41743 16.5793 7.5 16.3706 7.5 16C7.5 15.4477 7.05228 15 6.5 15C5.94772 15 5.5 15.4477 5.5 16C5.5 16.2761 5.27614 16.5 5 16.5C4.72386 16.5 4.5 16.2761 4.5 16Z" />
919
</svg>
10-
</slot>
20+
{/if}
1121
<Text type="header">
12-
<slot>Unknown</slot>
22+
{@render children()}
1323
</Text>
1424
</div>
1525

0 commit comments

Comments
 (0)