Skip to content

Commit

Permalink
Add Guild Events
Browse files Browse the repository at this point in the history
  • Loading branch information
MacFJA committed Jul 8, 2024
1 parent 83c81f7 commit a92128c
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 7 deletions.
3 changes: 2 additions & 1 deletion packages/service/src/collector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import { GuildService } from "./services/guild-service.js";
import { PackageService } from "./services/package-service.js";
import { type ConnectedService, SocietyStatsService } from "./services/society-stats-service.js";
import { VideoService } from "./services/video-service.js";
import {GuildEventService} from "./services/guild-event-service.js";

// biome-ignore lint/suspicious/noExplicitAny:
export class CollectorService extends ComposedService<any> {
private readonly stats = new SocietyStatsService();
constructor(private userService: ConnectedService) {
super([new VideoService(), new PackageService(), new ArticleService(), new GuildService()]);
super([new VideoService(), new PackageService(), new ArticleService(), new GuildService(), new GuildEventService()]);
}

async getInformation(metadata: ServiceMetadata): Promise<ContentData & StatsData & Record<string, unknown>> {
Expand Down
104 changes: 104 additions & 0 deletions packages/service/src/services/guild-event-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import {Memorize, shortTermCache} from "../cache.js";
import type { ContentData, ServiceInterface, ServiceMetadata } from "./abstract.js";

export const TYPE = "guild-event" as const;

export class GuildEventService implements ServiceInterface<{ cover: string, startAt: string, venue?: [number, number] }> {
canHandle(metadata: ServiceMetadata): Promise<boolean> {
return Promise.resolve(metadata.type === TYPE);
}
async getInformation(metadata: ServiceMetadata): Promise<(ContentData & { cover: string, startAt: string, venue?: [number, number] }) | never> {
let event = (await this.getGuildEvents('svelte-society')).events.edges.find(event => event.node.id === metadata.identifier)?.node

if (event === undefined) {
event = await this.getOneEvent(metadata.identifier)
}

if (event) {
return {
type: TYPE,
cover: event.generatedSocialCardURL,
keywords: [],
url: `http://guild.host/events/${event.prettyUrl}`,
author: event.owner.name,
venue: event.hasVenue && event.venue?.address.location !== null ? event.venue?.address.location.geojson.coordinates : undefined,
description: event.description,
name: event.name,
startAt: event.startAt
}
}

throw new Error("Event not found");
}

@Memorize(shortTermCache)
private getGuildEvents(id: string): Promise<GuildHostGuildEventsResponse> {
return fetch(`https://guild.host/api/next/${id}/events`).then(response => response.json())
}

@Memorize(shortTermCache)
private getOneEvent(id: string): Promise<GuildHostEventResponse> {
return fetch(`https://guild.host/api/next/node/${id}`).then(response => response.json())
}

async getAllServiceMetadata(): Promise<Array<ServiceMetadata>> {
return this.getGuildEvents('svelte-society').then(response => response.events.edges.map(event => ({
type: TYPE,
identifier: event.node.id
})))
}
}

type GuildHostGuildEventsResponse = {
"__typename": "Guild", "events": {
"edges": Array<{
"node": GuildHostEventResponse,
"cursor": string
}>,
"pageInfo": {
"hasPreviousPage": boolean,
"hasNextPage": boolean,
"startCursor": string,
"endCursor": string
}
}, "__isNode": "Guild", "id": string
};

type GuildHostEventResponse = {
"__typename"?: "Event",
"id": string,
"slug": string,
"prettyUrl": string,
"name": string,
"description": string,
"startAt": string,
"endAt": string,
"timeZone": string,
"visibility": "PUBLIC",
"hasVenue": boolean,
"hasExternalUrl": boolean,
"owner": {
"__typename": "Guild",
"id": string,
"name": string,
"__isNode": "Guild"
},
"uploadedSocialCard": null | {
"url": string,
"id": string
},
"generatedSocialCardURL": string,
"presentations": { "edges": [] },
"venue": null | {
"address": {
"location": null | {
"__typename": "GeometryPoint",
"geojson": { "type": "Point", "coordinates": [number, number] }
},
"id": string
},
"id": string
},
"createdAt": string,
"updatedAt": string
}
16 changes: 11 additions & 5 deletions sites/www/src/lib/ui/ContentCard.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import Tags from './Tags.svelte';
import SvelteMarkdown from "svelte-markdown";
import { formatDistanceToNow } from "date-fns/formatDistanceToNow";
import SvelteMarkdown from 'svelte-markdown';
import { formatDistanceToNow } from 'date-fns/formatDistanceToNow';
let { id, title, description, type, author, time, views, likes, tags, url, children } = $props();
</script>

Expand All @@ -10,7 +10,11 @@
<div class="flex">
<span class="font-semibold">{type}&nbsp;</span>
<span class="flex text-gray-500"
><span>by {author}&nbsp;•{#if time}&nbsp;{formatDistanceToNow(time)}&nbsp;•{/if}&nbsp;</span>
><span
>by {author}&nbsp;•{#if time}&nbsp;{formatDistanceToNow(time, {
addSuffix: true
})}&nbsp;•{/if}&nbsp;</span
>
<span class="flex items-center gap-1">
{views}
<svg width="12" height="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
Expand Down Expand Up @@ -60,7 +64,7 @@
</form>
</div>

<h2 class="mb-2 text-xl font-bold"><a href="{url}">{title}</a></h2>
<h2 class="mb-2 text-xl font-bold"><a href={url}>{title}</a></h2>
<p class="mb-4 text-gray-700"><SvelteMarkdown source={description} /></p>

{@render children()}
Expand All @@ -70,6 +74,8 @@
<Tags {tags} />
</div>

{#if time}<div class="text-xs text-gray-500">&nbsp;{formatDistanceToNow(time)}</div>{/if}
{#if time}<div class="text-xs text-gray-500">
&nbsp;{formatDistanceToNow(time, { addSuffix: true })}
</div>{/if}
</div>
</div>
62 changes: 62 additions & 0 deletions sites/www/src/lib/ui/cards/GuildEventCard.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<script lang="ts">
import Content from '../ContentCard.svelte';
let {
id,
children,
cover,
startAt,
venue,
title,
...props
}: {
id: string;
children: unknown;
cover: undefined | string;
startAt: string;
venue: undefined | [number, number];
title: string;
} = $props();
</script>

<Content
{...props}
time={startAt}
tags={[{ id: venue ? 'physical' : 'online', name: venue ? 'Physical' : 'Online' }]}
{title}
type="Event"
>
{#if cover}
<figure>
<img src={cover} alt={title} />
</figure>
{/if}
{#if Array.isArray(venue)}
<section>
<iframe
title="Venue address"
frameborder="0"
src="https://www.google.com/maps/embed/v1/place?q={venue[1]},{venue[0]}&key=AIzaSyBFw0Qbyq9zTFTd-tUY6dZWTgaQzuU17R8"
></iframe>
</section>
{/if}
</Content>

<style>
figure {
margin: 0;
padding: 0;
}
figure img {
width: 100%;
border-radius: 8px;
}
iframe {
max-width: 100%;
overflow: hidden;
aspect-ratio: 3/1;
width: 100%;
border: 0;
border-radius: 8px;
}
</style>
4 changes: 3 additions & 1 deletion sites/www/src/routes/(app)/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { CollectorService } from 'sveltesociety.dev-service/src/collector.js';
import { GuildService } from 'sveltesociety.dev-service/src/services/guild-service';
import { ConnectedService } from 'sveltesociety.dev-service/src/services/society-stats-service.js';
import type { PageServerLoad } from './$types';
import { GuildEventService } from 'sveltesociety.dev-service/src/services/guild-event-service';

export const load: PageServerLoad = async () => {
// TODO: get user info from request (cookie?)
Expand All @@ -18,7 +19,8 @@ export const load: PageServerLoad = async () => {
{ type: 'package', identifier: 'svelte' },
{ type: 'package', identifier: 'svelte-atoms' },
{ type: 'guild', identifier: 'london-javascript' },
...(await new GuildService().getAllServiceMetadata())
...(await new GuildService().getAllServiceMetadata()),
...(await new GuildEventService().getAllServiceMetadata())
])
};
};
3 changes: 3 additions & 0 deletions sites/www/src/routes/(app)/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import PackageCard from '$lib/ui/cards/PackageCard.svelte';
import RecipeCard from '$lib/ui/cards/RecipeCard.svelte';
import VideoCard from '$lib/ui/cards/VideoCard.svelte';
import GuildEventCard from '$lib/ui/cards/GuildEventCard.svelte';
export let data: PageData;
let tags = [
Expand Down Expand Up @@ -52,5 +53,7 @@
/>
{:else if item.type === 'guild'}
<GuildCard {...item} title={item.name} time={item.lastUpdate} tags={[]} />
{:else if item.type === 'guild-event'}
<GuildEventCard {...item} title={item.name} tags={[]} />
{/if}
{/each}

0 comments on commit a92128c

Please sign in to comment.