Skip to content

Commit

Permalink
Navigate seed nodes from explore section
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastinez committed May 29, 2024
1 parent 0c7ea70 commit f3ef653
Show file tree
Hide file tree
Showing 8 changed files with 355 additions and 164 deletions.
6 changes: 5 additions & 1 deletion src/components/Popover.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
</script>

<script lang="ts">
export let popoverContainerMinWidth: string | undefined = undefined;
export let popoverBorderRadius: string | undefined = undefined;
export let popoverPadding: string | undefined = undefined;
export let popoverPositionBottom: string | undefined = undefined;
Expand Down Expand Up @@ -53,7 +54,10 @@

<svelte:window on:click={clickOutside} on:touchstart={clickOutside} />

<div bind:this={thisComponent} class="container">
<div
bind:this={thisComponent}
class="container"
style:min-width={popoverContainerMinWidth}>
<slot name="toggle" {expanded} {toggle} />

{#if expanded}
Expand Down
84 changes: 19 additions & 65 deletions src/lib/seeds.ts
Original file line number Diff line number Diff line change
@@ -1,73 +1,48 @@
import type { BaseUrl } from "@httpd-client";

import storedWritable from "@efstajas/svelte-stored-writable";
import { writable, derived, get } from "svelte/store";
import { number, string, object } from "zod";
import unionBy from "lodash/unionBy";
import { array, number, string, object } from "zod";
import { derived } from "svelte/store";

import { api, httpdStore, type HttpdState } from "./httpd";
import config from "virtual:config";

const preferredSeedSchema = object({
hostname: string(),
port: number(),
scheme: string(),
}).optional();
});

const configuredPreferredSeeds = writable<BaseUrl[] | undefined>(undefined);
export const configuredPreferredSeeds = storedWritable<BaseUrl[]>(
"configuredPreferredSeeds",
array(preferredSeedSchema),
[],
);
const storedPreferredSeed = storedWritable<BaseUrl | undefined>(
"preferredSeed",
preferredSeedSchema,
undefined,
);

async function loadConfiguredPreferredSeeds() {
if (get(httpdStore).state === "stopped") {
configuredPreferredSeeds.set([]);
return;
}

const profile = await api.profile.getProfile();

let newValue = profile.config.preferredSeeds.map(seed => {
const preferredSeedValue = seed?.split("@")[1];
const preferredSeedOrigin = preferredSeedValue?.split(":")[0];

return {
hostname: preferredSeedOrigin,
port: 443,
scheme: "https",
};
});

if (newValue.length === 0) {
newValue = [config.fallbackPreferredSeed];
}

configuredPreferredSeeds.set(newValue);
}

export function initialize() {
let previousHttpdState: HttpdState["state"] | undefined;

httpdStore.subscribe(async v => {
if (previousHttpdState === v.state) return;

await loadConfiguredPreferredSeeds();

previousHttpdState = v.state;
});
export function addSeedsToConfiguredSeeds(newSeeds: BaseUrl[]) {
configuredPreferredSeeds.update(seeds =>
unionBy(seeds, newSeeds, "hostname"),
);
}

export function selectPreferredSeed(seed: BaseUrl) {
storedPreferredSeed.set(seed);
}

export function removeSeedFromConfiguredSeeds(seedHostname: string) {
configuredPreferredSeeds.update(
seeds => seeds.filter(s => s.hostname !== seedHostname) ?? seeds,
);
}

export const preferredSeeds = derived(
[configuredPreferredSeeds, storedPreferredSeed],
([configuredPreferredSeeds, storedPreferredSeed]) => {
// Not loaded yet
if (!configuredPreferredSeeds) return undefined;

// No configured preferred seeds
if (configuredPreferredSeeds.length === 0)
return {
Expand Down Expand Up @@ -99,24 +74,3 @@ export const preferredSeeds = derived(
};
},
);

export async function waitForLoad(): Promise<{
selected: BaseUrl;
seeds: BaseUrl[];
}> {
if (!get(configuredPreferredSeeds)) {
await new Promise<void>(resolve => {
const unsubscribe = preferredSeeds.subscribe(v => {
if (v) {
unsubscribe();
resolve();
}
});
});
}

const seeds = get(preferredSeeds);
if (!seeds) throw new Error("Preferred seed undefined after loading");

return seeds;
}
56 changes: 18 additions & 38 deletions src/views/home/Index.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import type { ComponentProps } from "svelte";
import type { ProjectInfo } from "@app/components/ProjectCard";
import type { ProjectListQuery } from "@httpd-client";
import type { BaseUrl, ProjectListQuery } from "@httpd-client";
import storedWritable from "@efstajas/svelte-stored-writable";
import { derived } from "svelte/store";
Expand All @@ -23,11 +23,13 @@
import ErrorMessage from "@app/components/ErrorMessage.svelte";
import FilterButton from "./components/FilterButton.svelte";
import HomepageSection from "./components/HomepageSection.svelte";
import IconButton from "@app/components/IconButton.svelte";
import IconSmall from "@app/components/IconSmall.svelte";
import NewProjectButton from "./components/NewProjectButton.svelte";
import Popover from "@app/components/Popover.svelte";
import PreferredSeedDropdown from "./components/PreferredSeedDropdown.svelte";
import IconButton from "@app/components/IconButton.svelte";
export let configPreferredSeeds: BaseUrl[];
const selectedSeed = deduplicateStore(
derived(preferredSeeds, $ => $?.selected),
Expand Down Expand Up @@ -120,33 +122,22 @@
font-size: var(--font-size-small);
font-weight: var(--font-weight-regular);
}
.flex-icon-item {
display: flex;
align-items: center;
gap: 0.5rem;
}
.project-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(21rem, 1fr));
gap: 1rem;
}
.seed {
max-width: 100%;
display: flex;
align-items: center;
gap: 0.125rem;
color: var(--color-foreground-contrast);
}
.seed-name {
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
@media (max-width: 719.98px) {
.wrapper {
width: 100%;
padding: 1rem;
}
.seed-dropdown {
display: none;
}
}
</style>

Expand Down Expand Up @@ -216,18 +207,16 @@
empty={preferredSeedProjects instanceof Error ||
preferredSeedProjects?.length === 0}
title="Explore">
<svelte:fragment slot="title">
<div class="flex-icon-item" style:min-width="0">
<span class="txt-large">Explore</span>
<PreferredSeedDropdown
initialPreferredSeeds={configPreferredSeeds}
selectedSeed={$preferredSeeds.selected} />
</div>
</svelte:fragment>
<svelte:fragment slot="subtitle">
{#if nodeId && $preferredSeeds}
Pinned repositories on your selected seed node
{:else}
Pinned repositories on
<div class="seed">
<IconSmall name="seedling" />
<span class="seed-name">
{$selectedSeed?.hostname}
</span>
</div>
{/if}
Pinned repositories on your selected seed node
{#if !nodeId}
<div class="global-hide-on-mobile-down">
<Popover popoverPositionTop="2.5rem" popoverPositionLeft="0">
Expand All @@ -247,15 +236,6 @@
</div>
{/if}
</svelte:fragment>
<svelte:fragment slot="actions">
<div class="seed-dropdown">
{#if nodeId && $preferredSeeds}
<PreferredSeedDropdown
disabled={!nodeId || preferredSeedProjects === undefined}
preferredSeed={$preferredSeeds?.selected} />
{/if}
</div>
</svelte:fragment>
<svelte:fragment slot="empty">
<div class="empty-state">
{#if preferredSeedProjects instanceof Error}
Expand Down
9 changes: 3 additions & 6 deletions src/views/home/components/HomepageSection.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,11 @@
export let title: string;
export let loading = false;
export let empty: boolean = false;
</script>

<style>
.section-header {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
margin-bottom: 1.5rem;
}
.title {
Expand Down Expand Up @@ -62,7 +57,9 @@
<section>
<div class="section-header">
<div class="title">
<h2>{title}</h2>
<slot name="title">
<h2>{title}</h2>
</slot>
<div class="actions">
<slot name="actions" />
</div>
Expand Down
Loading

0 comments on commit f3ef653

Please sign in to comment.