Skip to content

Commit

Permalink
Implement editing for item page
Browse files Browse the repository at this point in the history
  • Loading branch information
MaddyGuthridge committed Sep 2, 2024
1 parent 0d97858 commit adf6ba3
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 31 deletions.
6 changes: 5 additions & 1 deletion src/components/chip/ItemChipList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
const dispatch = createEventDispatcher<{
filter: FilterOptions,
click: { groupId: string, itemId: string }
}>();
// Update filter status
Expand All @@ -117,7 +118,10 @@
itemId={filterItem.itemId}
selected={filterItem.selected}
{link}
on:click={() => updateFilterStatus(outer, inner)}
on:click={() => {
updateFilterStatus(outer, inner);
dispatch('click', { groupId: filterItem.groupId, itemId: filterItem.itemId });
}}
/>
{/each}
<!-- Last classifier doesn't have a separator -->
Expand Down
153 changes: 123 additions & 30 deletions src/routes/[group]/[item]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,83 @@
import Paper from '$components/Paper.svelte';
import EditableMarkdown from '$components/markdown';
import api from '$endpoints';
import consts from '$lib/consts';
import { generateKeywords } from '$lib/seo';
import consts from '$lib/consts';
import { generateKeywords } from '$lib/seo';
import EditControls from '$components/EditControls.svelte';
// import AsciinemaPlayer from "$components";
export let data: import('./$types').PageData;
$: groupData = data.globals.groups[data.groupId];
$: itemData = data.globals.items[data.groupId][data.itemId];
let groupData = data.globals.groups[data.groupId];
let itemData = data.globals.items[data.groupId][data.itemId];
let editing = false;
let readme = '';
let chipLinks = itemData.info.links.filter(([l]) => l.style === 'chip');
let cardLinks = itemData.info.links.filter(([l]) => l.style === 'card');
function beginEditing() {
editing = true;
}
async function finishEditing(save: boolean) {
editing = false;
if (save) {
itemData.readme = readme;
await api().group.withId(data.groupId).item.withId(data.itemId).readme.set(readme);
// Update other info
await api().group.withId(data.groupId).item.withId(data.itemId).info.set(itemData.info);
}
// Reset data
setupData(data.groupId, data.itemId);
}
function setupData(groupId: string, itemId: string) {
editing = false;
groupData = data.globals.groups[groupId];
itemData = data.globals.items[groupId][itemId];
readme = itemData.readme;
chipLinks = itemData.info.links.filter(([l]) => l.style === 'chip');
cardLinks = itemData.info.links.filter(([l]) => l.style === 'card');
}
function changeLinkTitle(linkedGroup: string, newTitle: string) {
const linkInfo = itemData.info.links.find(link => link[0].groupId === linkedGroup);
if (!linkInfo) {
// This shouldn't happen
throw Error(`changeLinkTitle: linkInfo not found for ${linkedGroup}`);
}
linkInfo[0].title = newTitle;
}
async function toggleLink(linkedGroup: string, linkedItem: string) {
const linkInfo = itemData.info.links.find(link => link[0].groupId === linkedGroup);
if (!linkInfo) {
// This shouldn't happen
throw Error(`toggleLink: linkInfo not found for ${linkedGroup}/${linkedItem}`);
}
const newState = !linkInfo[1].includes(linkedItem);
if (newState) {
// Create link
await api().group.withId(data.groupId).item.withId(data.itemId).links.create(linkedGroup, linkedItem);
// Update state in browser to match
linkInfo[1].push(linkedItem);
} else {
// Unlink
await api().group.withId(data.groupId).item.withId(data.itemId).links.remove(linkedGroup, linkedItem);
linkInfo[1] = linkInfo[1].filter(item => item !== linkedItem);
}
// Force update chip and card links
chipLinks = [...chipLinks];
cardLinks = [...cardLinks];
}
$: setupData(data.groupId, data.itemId);
</script>

<!-- TODO: Find a less repetitive way to get this working nicely -->
<!-- TODO: Find a less repetitive way to get SEO working nicely -->
<svelte:head>
<title>{itemData.info.name} - {groupData.info.name} - {data.globals.config.siteShortName}</title>
<meta name="description" content="{itemData.info.pageDescription}">
Expand All @@ -37,22 +103,23 @@
/>

<main>
<Paper>
{#if itemData.info.banner}
<img
src="/{data.groupId}/{data.itemId}/{itemData.info.banner}"
alt="Banner for {itemData.info.name}"
class="banner-image"
/>
{/if}
<div id="info-container">
<EditableMarkdown
source={itemData.readme}
editing={false}
/>
<!-- Display linked items as chips -->
<div id="chip-links">
{#each itemData.info.links.filter(([l]) => l.style === 'chip') as [linkOptions, linkedItems]}
<EditControls {editing} on:beginEdits={beginEditing} on:finishEdits={e => finishEditing(e.detail)}/>
{#if itemData.info.banner}
<img
src="/{data.groupId}/{data.itemId}/{itemData.info.banner}"
alt="Banner for {itemData.info.name}"
class="banner-image"
/>
{/if}
<div id="info-container">
<EditableMarkdown
source={readme}
{editing}
/>
<!-- Display linked items as chips -->
<div id="chip-links">
{#each chipLinks as [linkOptions, linkedItems]}
{#if !editing}
<div class="chip-link-row">
<h2>{linkOptions.title}</h2>
<ItemChipList
Expand All @@ -61,10 +128,21 @@
link={true}
/>
</div>
{/each}
</div>
{:else}
<div class="chip-link-row">
<input type="text" bind:value={linkOptions.title} on:input={() => changeLinkTitle(linkOptions.groupId, linkOptions.title)} />
<div class="chip-link-items">
<ItemChipList
globals={data.globals}
items={[Object.keys(data.globals.items[linkOptions.groupId]).map(itemId => ({ groupId: linkOptions.groupId, itemId, selected: linkedItems.includes(itemId) }))]}
on:click={e => toggleLink(e.detail.groupId, e.detail.itemId)}
/>
</div>
</div>
{/if}
{/each}
</div>
</Paper>
</div>

<!-- Display URLs if needed -->
<div id="urls-list">
Expand Down Expand Up @@ -112,8 +190,10 @@

<!-- Display linked items as cards -->
<div id="card-links">
{#each itemData.info.links.filter(([l]) => l.style === 'card') as [linkOptions, linkedItems]}
<h2>{linkOptions.title}</h2>
{#each cardLinks as [linkOptions, linkedItems]}
<h2 contenteditable={editing}>
{linkOptions.title}
</h2>
<ItemCardGrid
globals={data.globals}
groupId={linkOptions.groupId}
Expand All @@ -133,29 +213,42 @@
#info-container {
padding: 20px;
margin: 10px;
width: 99%;
}
.banner-image {
width: 100%;
border-radius: 10px 10px 0 0;
max-width: 80%;
max-height: 30%;
border-radius: 10px;
}
#chip-links {
width: 100%;
}
.chip-link-row {
display: flex;
align-items: baseline;
gap: 5px;
margin: 10px 0;
width: 100%;
}
.chip-link-row > h2 {
margin: 0;
height: min-content;
}
.chip-link-items {
overflow-x: scroll;
}
#urls-list {
width: 80%;
width: 100%;
}
#card-links {
width: 80%;
width: 100%;
}
#card-links > h2 {
margin: 20px;
}
</style>

0 comments on commit adf6ba3

Please sign in to comment.