Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Sanity for info site content #134

Merged
merged 3 commits into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions web/info/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@
"@bufbuild/connect": "^0.11.0",
"@bufbuild/connect-web": "^0.11.0",
"@bufbuild/protobuf": "~1.2.0",
"@portabletext/svelte": "^2.0.0",
"@portabletext/types": "^2.0.5",
"@rgossiaux/svelte-headlessui": "^2.0.0",
"@sanity/client": "^6.4.6",
"@sanity/image-url": "^1.0.2",
"@sveltejs/adapter-auto": "^2.0.0",
"@sveltejs/adapter-node": "^1.3.1",
"@sveltejs/adapter-vercel": "^3.0.1",
Expand Down
54 changes: 54 additions & 0 deletions web/info/src/components/portable-text/portable-text.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<script lang="ts">
import CodeSerializer from '$components/portable-text/serializers/code.svelte';
import FeedsSerializer from '$components/portable-text/serializers/feeds.svelte';
import HeadingSerializer from '$components/portable-text/serializers/heading.svelte';
import ImageSerializer from '$components/portable-text/serializers/image.svelte';
import LinkSerializer from '$components/portable-text/serializers/link.svelte';
import OlSerializer from '$components/portable-text/serializers/ordered-list.svelte';
import OlItemSerializer from '$components/portable-text/serializers/ordered-list-item.svelte';
import ParagraphSerializer from '$components/portable-text/serializers/paragraph.svelte';
import UlSerializer from '$components/portable-text/serializers/unordered-list.svelte';
import UlItemSerializer from '$components/portable-text/serializers/unordered-list-item.svelte';
import { PortableText } from '@portabletext/svelte';
import type { InputValue } from '@portabletext/svelte/ptTypes';
import type { FeedInfo } from '$types';
export let content: InputValue,
feeds: { featured: FeedInfo[] | null; feeds: FeedInfo[] | null };
</script>

<PortableText
value={content}
components={{
types: {
feeds: FeedsSerializer,
image: ImageSerializer
},
marks: {
link: LinkSerializer,
code: CodeSerializer
},
block: {
normal: ParagraphSerializer,
h1: HeadingSerializer,
h2: HeadingSerializer,
h3: HeadingSerializer,
h4: HeadingSerializer,
h5: HeadingSerializer
},
list: {
bullet: UlSerializer,
number: OlSerializer
},
listItem: {
bullet: UlItemSerializer,
number: OlItemSerializer,
normal: UlItemSerializer
}
}}
context={{
feeds
}}
/>
16 changes: 16 additions & 0 deletions web/info/src/components/portable-text/serializers/code.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script lang="ts">
import type { MarkComponentProps } from '@portabletext/svelte';
export let portableText: MarkComponentProps;
$: ({ markType } = portableText);
$: ({ plainTextContent } = portableText);
</script>

{#if markType === 'code'}
<code class="mx-0.5 rounded bg-gray-400 px-1 py-0.5 font-mono text-[0.95rem]"
>{plainTextContent}</code
>
{:else}
<slot />
{/if}
23 changes: 23 additions & 0 deletions web/info/src/components/portable-text/serializers/feeds.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<script lang="ts">
import FeaturedList from '$components/feeds/featured-list.svelte';
import FeedList from '$components/feeds/list.svelte';
import type { CustomBlockComponentProps } from '@portabletext/svelte';
import type { FeedInfo } from '$types';
export let portableText: CustomBlockComponentProps<{ featured: boolean }>;
$: ({ featured, feeds } = (portableText.global.context?.feeds as {
featured: FeedInfo[];
feeds: FeedInfo[];
}) || {
featured: null,
feeds: null
});
</script>

{#if portableText.value.featured}
<FeaturedList {feeds} {featured} />
{:else}
<FeedList {feeds} />
{/if}
47 changes: 47 additions & 0 deletions web/info/src/components/portable-text/serializers/heading.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<script lang="ts">
import { toPlainText } from '@portabletext/svelte';
import type { BlockComponentProps } from '@portabletext/svelte';
export let portableText: BlockComponentProps;
$: ({ value } = portableText);
$: ({ style } = value as { style: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' });
$: plainText = toPlainText(value);
</script>

<svelte:element this={style}>
<a id={value._key} href={`#${value._key}`}>
{plainText}
</a>
</svelte:element>

<style lang="scss">
h1,
h2,
h3,
h4,
h5 {
@apply font-bold text-gray-950;
}
h1 {
@apply mb-6 mt-8 text-4xl;
}
h2 {
@apply mb-5 mt-7 text-3xl;
}
h3 {
@apply mb-4 mt-6 text-2xl;
}
h4 {
@apply mb-3 mt-5 text-xl;
}
h5 {
@apply mb-2 mt-4 text-lg;
}
</style>
35 changes: 35 additions & 0 deletions web/info/src/components/portable-text/serializers/image.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<script lang="ts">
import { getCrop, urlFor } from '$lib/sanity';
import type { CustomBlockComponentProps } from '@portabletext/svelte';
import type { ArbitraryTypedObject } from '@portabletext/types';
import type { ImageCrop } from '$lib/sanity';
import type { SanityImageObject } from '$types';
export let portableText: Omit<CustomBlockComponentProps, 'value'> & {
value: ArbitraryTypedObject & {
asset: SanityImageObject['asset'];
};
};
let imageCrop: ImageCrop;
$: ({ value } = portableText);
$: ({ _key } = value);
$: ({ _ref } = value.asset);
$: (imageCrop = getCrop(value as unknown as SanityImageObject)), value;
</script>

<div class="h-fit w-full">
<img
src={urlFor(_ref)
.width(800)
.rect(imageCrop.left, imageCrop.top, imageCrop.width, imageCrop.height)
.fit('crop')
.auto('format')
.url()}
class="select-none rounded-sm"
alt={_key}
draggable="false"
/>
</div>
21 changes: 21 additions & 0 deletions web/info/src/components/portable-text/serializers/link.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script lang="ts">
import type { MarkComponentProps } from '@portabletext/svelte';
export let portableText: MarkComponentProps;
$: ({ value } = portableText);
$: ({ plainTextContent } = portableText);
$: href = value.href as string;
$: _external = value.external as boolean;
$: newtab = value.blank as boolean;
</script>

<a
class="text-sky-600 underline-offset-1 focus-within:text-sky-700 focus-within:underline hover:text-sky-700 hover:underline"
{href}
target={newtab ? '_blank' : undefined}
rel={newtab ? 'noopener noreferrer' : undefined}
tabindex="0"
>
{plainTextContent}
</a>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script lang="ts">
import type { BlockComponentProps } from '@portabletext/svelte';
export let portableText: BlockComponentProps;
$: ({ value: _value } = portableText);
</script>

<li>
<slot />
</li>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<script lang="ts">
import type { BlockComponentProps } from '@portabletext/svelte';
export let portableText: BlockComponentProps;
const getLevelClass = (level?: number) => {
switch (level) {
case 2:
return 'list-[lower-alpha]';
case 3:
return 'list-[lower-roman]';
default:
return 'list-decimal';
}
};
$: ({ value } = portableText);
$: ({ level } = value);
</script>

<ol class="pt-ol my-6 ml-6 {getLevelClass(level)}">
<slot />
</ol>
11 changes: 11 additions & 0 deletions web/info/src/components/portable-text/serializers/paragraph.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script lang="ts">
import type { BlockComponentProps } from '@portabletext/svelte';
export let portableText: BlockComponentProps;
$: ({ value } = portableText);
</script>

<p class="my-3 text-base">
<slot />
</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script lang="ts">
import type { ListItemComponentProps } from '@portabletext/svelte';
export let portableText: ListItemComponentProps;
$: ({ value: _value } = portableText);
</script>

<li>
<slot />
</li>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script lang="ts">
import type { ListComponentProps } from '@portabletext/svelte';
export let portableText: ListComponentProps;
$: ({ value: _value } = portableText);
</script>

<ul class="pt-ul my-6 ml-6 list-disc">
<slot />
</ul>
14 changes: 14 additions & 0 deletions web/info/src/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,17 @@ export const NAV_OPTIONS = [
text: 'Discord'
}
];

export const VALID_DOC_ROUTES = ['welcome', 'community-guidelines', 'feeds'];

export const DOC_ROUTES_NAMES = {
welcome: 'welcome',
'community-guidelines': 'communityGuidelines',
feeds: 'feeds'
} as const;

export const SANITY_PROJECT_ID = '0ildj6pc' as const;

export const SANITY_DATASET = 'production';

export const SANITY_API_VERSION = '2022-11-29';
79 changes: 79 additions & 0 deletions web/info/src/lib/sanity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { SANITY_API_VERSION, SANITY_DATASET, SANITY_PROJECT_ID } from '$lib/constants';

import { createClient } from '@sanity/client';
import imageUrlBuilder from '@sanity/image-url';

import type {
SanityImageObject,
SanityImageSource
} from '@sanity/image-url/lib/types/types';
import type { DocumentRegistry } from '$types';

const client = createClient({
projectId: SANITY_PROJECT_ID,
dataset: SANITY_DATASET,
useCdn: true,
apiVersion: SANITY_API_VERSION
});

export const getPageDocument = async <T extends string>(
id: T,
preview = false,
token?: string
) => {
const localClient = token ? createClient({ ...client.config(), token }) : client;
const query = `*[_type == "page" && id == "${id}"${
preview ? '' : ' && !(_id in path("drafts.**"))'
}][0]`;
const document = await localClient
.fetch<T extends keyof DocumentRegistry ? DocumentRegistry[T] : never>(query)
.then((response) => {
const document = response;
return document;
})
.catch((err) => {
console.error(err);
return undefined;
});

return document;
};

export interface ImageCrop {
top: number;
left: number;
bottom: number;
right: number;
width: number;
height: number;
}

const builder = imageUrlBuilder(client);

export const urlFor = (source: SanityImageSource) => builder.image(source);

export const getCrop = (image: SanityImageObject | undefined) => {
if (!image || !image?.asset) {
return {
top: 0,
left: 0,
bottom: 0,
right: 0,
width: 0,
height: 0
};
}
const ref = image.asset._ref,
dimensions = ref?.split('-')?.[2]?.split('x'),
crop: ImageCrop = {
top: Math.floor(dimensions[1] * (image?.crop?.top ?? 0)),
left: Math.floor(dimensions[0] * (image?.crop?.left ?? 0)),
bottom: Math.floor(dimensions[1] * (image?.crop?.bottom ?? 0)),
right: Math.floor(dimensions[0] * (image?.crop?.right ?? 0))
} as ImageCrop;

crop.width = Math.floor(dimensions[0] - (crop.left + crop.right));
crop.height = Math.floor(dimensions[1] - (crop.top + crop.bottom));

return crop;
};
Empty file removed web/info/src/params/.gitkeep
Empty file.
7 changes: 7 additions & 0 deletions web/info/src/params/valid_doc_route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { VALID_DOC_ROUTES } from '$lib/constants';

import type { ParamMatcher } from '@sveltejs/kit';

export const match: ParamMatcher = (param) => {
return VALID_DOC_ROUTES.includes(param);
};
Loading
Loading