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

fix: put state into context #47

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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: 3 additions & 1 deletion src/lib/components/Metadata.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import Comment from '../icons/Comment.svelte';
import HeartOutline from '$lib/icons/HeartOutline.svelte';
import Heart from '$lib/icons/Heart.svelte';
import { state } from '$lib/state.js';
import { getStateContext } from '$lib/state.js';

export let photo: PhotoListItem;

const { state } = getStateContext();
</script>

<a class="flex items-center" href="/{photo.name}/{photo.id}">
Expand Down
3 changes: 2 additions & 1 deletion src/lib/components/PhotoList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import Scroller from '$lib/components/Scroller.svelte';
import Modal from '$lib/components/Modal.svelte';
import PhotoPage from '../../routes/[account]/[photo]/+page.svelte';
import { init_photos, state } from '$lib/state.js';
import { getStateContext } from '$lib/state.js';
import { ago, now } from '$lib/utils.js';
import { page } from '$app/stores';
import { createEventDispatcher } from 'svelte';
Expand All @@ -25,6 +25,7 @@
}

const dispatch = createEventDispatcher();
const { init_photos } = getStateContext();

let scroller: Scroller;
let loading = false;
Expand Down
85 changes: 48 additions & 37 deletions src/lib/state.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,56 @@
import { writable } from 'svelte/store';
import type { Account, Comment, Photo, PhotoListItem } from './types';
import { getContext, setContext } from 'svelte';

// note: this store will leak memory on the server! luckily, we're using
// serverless functions, which means we don't need to care — the
// function won't be kept alive long enough for it to matter.

const { subscribe, update } = writable(
{} as {
[id: string]: {
num_comments: number;
num_likes: number;
liked_by_user: boolean;
};
}
);

export const state = { subscribe };

export function init_photos(photos: PhotoListItem[]) {
update((lookup) => {
for (const photo of photos) {
if (!lookup[photo.id]) {
lookup[photo.id] = {
num_comments: photo.num_comments,
num_likes: photo.num_likes,
liked_by_user: photo.liked_by_user
};
}
const key = {};

function init() {
const { subscribe, update } = writable(
{} as {
[id: string]: {
num_comments: number;
num_likes: number;
liked_by_user: boolean;
};
}
);

const state = { subscribe };

function init_photos(photos: PhotoListItem[]) {
update((lookup) => {
for (const photo of photos) {
if (!lookup[photo.id]) {
lookup[photo.id] = {
num_comments: photo.num_comments,
num_likes: photo.num_likes,
liked_by_user: photo.liked_by_user
};
}
}

return lookup;
});
}

function update_photo(photo: Photo, comments: Comment[], likes: Account[], user?: Account) {
update((lookup) => {
lookup[photo.id] = {
num_comments: comments.length,
num_likes: likes.length,
liked_by_user: !!user && likes.some((like) => like.name === user.name)
};
return lookup;
});
}

return { state, init_photos, update_photo };
}

return lookup;
});
export function setStateContext() {
setContext(key, init());
}

export function update_photo(photo: Photo, comments: Comment[], likes: Account[], user?: Account) {
update((lookup) => {
lookup[photo.id] = {
num_comments: comments.length,
num_likes: likes.length,
liked_by_user: !!user && likes.some((like) => like.name === user.name)
};
return lookup;
});
export function getStateContext() {
return getContext(key) as ReturnType<typeof init>;
}
3 changes: 3 additions & 0 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
import Login from '$lib/components/Login.svelte';
import Uploader from '$lib/components/Uploader.svelte';
import Logo from '$lib/icons/Logo.svelte';
import { setStateContext } from '$lib/state';
import '../app.css';

export let data;

setStateContext();
</script>

<nav
Expand Down
4 changes: 3 additions & 1 deletion src/routes/[account]/[photo]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import Heart from '$lib/icons/Heart.svelte';
import HeartOutline from '$lib/icons/HeartOutline.svelte';
import Trash from '$lib/icons/Trash.svelte';
import { update_photo } from '$lib/state.js';
import { getStateContext } from '$lib/state.js';
import { ago, now } from '$lib/utils.js';
import autosize from 'svelte-autosize';

Expand All @@ -16,6 +16,8 @@

sync();

const { update_photo } = getStateContext();

function sync() {
update_photo(data.photo, data.comments, data.likes, data.user);
}
Expand Down