-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow setting home page, show titles instead of
filename in sidebar, override data and make it optional
- Loading branch information
1 parent
c3a8244
commit 347c66b
Showing
8 changed files
with
272 additions
and
169 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,75 @@ | ||
import PocketBase from 'pocketbase'; | ||
import { getAuthenticatedPocketBase } from '$lib/server/auth'; | ||
import PocketBase from "pocketbase"; | ||
import { getAuthenticatedPocketBase } from "$lib/server/auth"; | ||
|
||
const pb = await getAuthenticatedPocketBase(); | ||
|
||
export async function load({ params }) { | ||
try { | ||
const mdbase = await pb.collections.getOne('mdbase'); | ||
|
||
const records = await pb.collection('mdbase').getList(1, 10, { sort: '-created' }); | ||
const posts = Object.values(records.items).map((item) => ({ | ||
title: item.title, | ||
id: item.id, | ||
date: item.created, | ||
url: item.url | ||
})); | ||
return { posts }; | ||
} catch (error) { | ||
return { posts: [], err: error }; | ||
} | ||
try { | ||
const mdbase = await pb.collections.getOne("mdbase"); | ||
|
||
const records = await pb.collection("mdbase").getList(1, 1, { | ||
filter: "frontmatter.home = true", | ||
sort: "-created", | ||
}); | ||
|
||
let post = null; | ||
if (records.items.length > 0) { | ||
post = records.items[0]; | ||
} | ||
|
||
if (post) { | ||
const backlinks = await getBacklinks(`${post.frontmatter.mdpath}`); | ||
|
||
const tags = post.expand?.tags.map((tag) => { | ||
return { | ||
name: tag.tag, | ||
}; | ||
}); | ||
return { post, title: post.title, backlinks, tags }; | ||
} else { | ||
return { post: null, title: "", backlinks: [], tags: [] }; | ||
} | ||
} catch (error) { | ||
console.error(`Failed to fetch post: ${error}`); | ||
return { message: `Failed to fetch post: ${error}` }; | ||
} | ||
} | ||
|
||
async function getBacklinks(url) { | ||
const mdbaseCollection = pb.collection("mdbase"); | ||
const documentUrl = url; | ||
try { | ||
if (!documentUrl) { | ||
return new Response( | ||
JSON.stringify({ message: "URL parameter is required" }), | ||
{ | ||
status: 400, | ||
}, | ||
); | ||
} | ||
|
||
const documents = await mdbaseCollection.getList(1, 1, { | ||
filter: `url="${documentUrl}"`, | ||
expand: "backlinks", | ||
}); | ||
|
||
if (documents.items.length === 0) { | ||
return new Response(JSON.stringify({ message: "Document not found" }), { | ||
status: 404, | ||
}); | ||
} | ||
|
||
const document = documents.items[0]; | ||
|
||
const backLinks = (document.expand?.backlinks || []).map((link) => ({ | ||
id: link.id, | ||
title: link.title, | ||
url: link.url, | ||
})); | ||
|
||
return backLinks; | ||
} catch (error: any) { | ||
console.error("Error in backlinks API:", error); | ||
return {}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,59 @@ | ||
<script> | ||
export let data; | ||
<script lang="ts"> | ||
import MDsvexRenderer from '$lib/components/MDsvexRenderer.svelte'; | ||
import MDGraph from '$lib/components/MDGraph.svelte'; | ||
import { CalendarDays } from 'lucide-svelte'; | ||
function formatDate(dateString) { | ||
const date = new Date(dateString); | ||
// Format the date as DD MMM YYYY | ||
return date.toLocaleDateString('en-GB', { | ||
day: '2-digit', | ||
month: 'short', | ||
year: 'numeric' | ||
}); | ||
} | ||
export let data: { content: string }; | ||
$: content = data.post?.content; | ||
$: tags = data?.tags; | ||
$: date = data.post?.created; | ||
</script> | ||
|
||
<div class="mb-6 text-4xl font-bold">Latest</div> | ||
<div class="flex flex-col items-start justify-center gap-4"> | ||
{#if data && data.posts.length > 0} | ||
{#each data.posts as p, id (id)} | ||
<div class="flex flex-col items-start justify-center gap-0.5"> | ||
<div class="text-xl"><a href="/{p.url}">{p.title}</a></div> | ||
<div class="text-sm text-gray-400">{formatDate(p.date)}</div> | ||
{#if data.post} | ||
<div class="mb-10 mt-6 text-wrap md:w-[700px]"> | ||
<div class="my-4 text-6xl md:text-8xl"> | ||
{data.title} | ||
</div> | ||
|
||
<div class="flex flex-col justify-center gap-1"> | ||
{#if data?.post?.frontmatter?.date} | ||
<div class="flex items-center gap-1"> | ||
<CalendarDays class="text-carbongray-400" size={15} /> | ||
<div class="text-base text-carbongray-400">{data.post.frontmatter.date.split(' ')[0]}</div> | ||
</div> | ||
{/if} | ||
{#if tags} | ||
<div class="flex flex-wrap gap-1"> | ||
{#each tags as tag (tag.name)} | ||
<span class="mx-0.5 rounded-sm bg-[#fedc69] p-0.5 text-carbongray-900" | ||
><a class="text-carbongray-900 dark:text-carbongray-900" href="/tags/{tag.name}" | ||
>{tag.name}</a | ||
></span | ||
> | ||
{/each} | ||
</div> | ||
{/each} | ||
{:else} | ||
<div class="text-lg">Please upload markdown files to begin</div> | ||
{/if} | ||
</div> | ||
<hr class="mt-6" /> | ||
</div> | ||
<MDsvexRenderer bind:content /> | ||
<div> | ||
{#if data?.backlinks?.length > 0} | ||
<hr class="my-4 w-[700px]" /> | ||
<div class="mb-2 mt-4 text-2xl font-light">BACKLINKS</div> | ||
{/if} | ||
{#each data?.backlinks || [] as bl (bl.id)} | ||
<div><a href={`/${bl.url.trim()}`} class="text-large">{bl.title}</a></div> | ||
{/each} | ||
</div> | ||
{:else} | ||
<div class="mb-10 mt-6 text-wrap md:w-[700px]"> | ||
Set homepage in the frontmatter of one of your markdown files to display it as home | ||
</div> | ||
{/if} | ||
|
||
<style> | ||
:global(.tag a) { | ||
@apply mx-0.5 bg-[#fedc69] p-1 text-carbongray-900; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,95 +1,107 @@ | ||
import { json } from '@sveltejs/kit'; | ||
import type { RequestHandler } from './$types'; | ||
import PocketBase from 'pocketbase'; | ||
import { promises as fs } from 'fs'; | ||
import { getAuthenticatedPocketBase } from '$lib/server/auth'; | ||
import { json } from "@sveltejs/kit"; | ||
import type { RequestHandler } from "./$types"; | ||
import PocketBase from "pocketbase"; | ||
import { promises as fs } from "fs"; | ||
import { getAuthenticatedPocketBase } from "$lib/server/auth"; | ||
|
||
const pb = await getAuthenticatedPocketBase(); | ||
|
||
async function getBacklinks(url) { | ||
const mdbaseCollection = pb.collection('mdbase'); | ||
const documentUrl = url; | ||
try { | ||
if (!documentUrl) { | ||
return new Response(JSON.stringify({ message: 'URL parameter is required' }), { | ||
status: 400 | ||
}); | ||
} | ||
const mdbaseCollection = pb.collection("mdbase"); | ||
const documentUrl = url; | ||
try { | ||
if (!documentUrl) { | ||
return new Response( | ||
JSON.stringify({ message: "URL parameter is required" }), | ||
{ | ||
status: 400, | ||
}, | ||
); | ||
} | ||
|
||
const documents = await mdbaseCollection.getList(1, 1, { | ||
filter: `url="${documentUrl}"`, | ||
expand: 'backlinks' | ||
}); | ||
const documents = await mdbaseCollection.getList(1, 1, { | ||
filter: `url="${documentUrl}"`, | ||
expand: "backlinks", | ||
}); | ||
|
||
if (documents.items.length === 0) { | ||
return new Response(JSON.stringify({ message: 'Document not found' }), { status: 404 }); | ||
} | ||
if (documents.items.length === 0) { | ||
return new Response(JSON.stringify({ message: "Document not found" }), { | ||
status: 404, | ||
}); | ||
} | ||
|
||
const document = documents.items[0]; | ||
const document = documents.items[0]; | ||
|
||
const backLinks = (document.expand?.backlinks || []).map((link) => ({ | ||
id: link.id, | ||
title: link.title, | ||
url: link.url | ||
})); | ||
const backLinks = (document.expand?.backlinks || []).map((link) => ({ | ||
id: link.id, | ||
title: link.title, | ||
url: link.url, | ||
})); | ||
|
||
return backLinks; | ||
} catch (error: any) { | ||
console.error('Error in backlinks API:', error); | ||
return {}; | ||
} | ||
return backLinks; | ||
} catch (error: any) { | ||
console.error("Error in backlinks API:", error); | ||
return {}; | ||
} | ||
} | ||
|
||
async function computeGraphData(fileUrl) { | ||
const currentPage = await pb.collection('mdbase').getFirstListItem(`url="${fileUrl}"`); | ||
const relatedPages = await pb.collection('mdbase').getList(1, 50, { | ||
filter: `id ?~ "${currentPage.backlinks}" || id ?~ "${currentPage.links}"` | ||
}); | ||
const currentPage = await pb | ||
.collection("mdbase") | ||
.getFirstListItem(`url="${fileUrl}"`); | ||
const relatedPages = await pb.collection("mdbase").getList(1, 50, { | ||
filter: `id ?~ "${currentPage.backlinks}" || id ?~ "${currentPage.links}"`, | ||
}); | ||
|
||
// Use a Set to store unique node IDs | ||
const uniqueNodeIds = new Set([currentPage.id]); | ||
// Use a Set to store unique node IDs | ||
const uniqueNodeIds = new Set([currentPage.id]); | ||
|
||
// Create nodes array with current page | ||
const nodes = [{ id: currentPage.id, label: currentPage.title, color: '#ff0000' }]; | ||
// Create nodes array with current page | ||
const nodes = [ | ||
{ id: currentPage.id, label: currentPage.title, color: "#ff0000" }, | ||
]; | ||
|
||
// Add related pages to nodes array, avoiding duplicates | ||
relatedPages.items.forEach((p) => { | ||
if (!uniqueNodeIds.has(p.id)) { | ||
uniqueNodeIds.add(p.id); | ||
nodes.push({ id: p.id, label: p.title, color: '#00ff00' }); | ||
} | ||
}); | ||
// Add related pages to nodes array, avoiding duplicates | ||
relatedPages.items.forEach((p) => { | ||
if (!uniqueNodeIds.has(p.id)) { | ||
uniqueNodeIds.add(p.id); | ||
nodes.push({ id: p.id, label: p.title, color: "#00ff00" }); | ||
} | ||
}); | ||
|
||
// Create edges array | ||
const edges = [ | ||
...currentPage.links.map((link) => ({ from: currentPage.id, to: link })), | ||
...currentPage.backlinks.map((backlink) => ({ from: backlink, to: currentPage.id })) | ||
]; | ||
// Create edges array | ||
const edges = [ | ||
...currentPage.links.map((link) => ({ from: currentPage.id, to: link })), | ||
...currentPage.backlinks.map((backlink) => ({ | ||
from: backlink, | ||
to: currentPage.id, | ||
})), | ||
]; | ||
|
||
return { nodes, edges }; | ||
return { nodes, edges }; | ||
} | ||
// Main load function | ||
export async function load({ params, fetch, locals }) { | ||
try { | ||
// Step 1: Authenticate | ||
/* console.log(pb); */ | ||
console.log(params.post); | ||
const post = await pb | ||
.collection('mdbase') | ||
.getFirstListItem(`url="${params.post}.md"`, { expand: 'tags' }); | ||
const backlinks = await getBacklinks(`${params.post}.md`); | ||
const graphData = await computeGraphData(`${params.post}.md`); | ||
try { | ||
// Step 1: Authenticate | ||
/* console.log(pb); */ | ||
console.log(params.post); | ||
const post = await pb | ||
.collection("mdbase") | ||
.getFirstListItem(`url="${params.post}.md"`, { expand: "tags" }); | ||
const backlinks = await getBacklinks(`${params.post}.md`); | ||
// const graphData = await computeGraphData(`${params.post}.md`); | ||
|
||
const tags = post.expand?.tags.map((tag) => { | ||
return { | ||
name: tag.tag | ||
}; | ||
}); | ||
console.log(tags); | ||
const tags = post.expand?.tags.map((tag) => { | ||
return { | ||
name: tag.tag, | ||
}; | ||
}); | ||
console.log(tags); | ||
|
||
return { post, title: post.title, backlinks, tags }; | ||
} catch (error) { | ||
console.error(`Failed to fetch post: ${error}`); | ||
return { message: `Failed to fetch post: ${error}` }; | ||
} | ||
return { post, title: post.title, backlinks, tags }; | ||
} catch (error) { | ||
console.error(`Failed to fetch post: ${error}`); | ||
return { message: `Failed to fetch post: ${error}` }; | ||
} | ||
} |
Oops, something went wrong.