Remove old components

This commit is contained in:
Fred Boniface 2023-11-04 00:53:29 +00:00
parent 855ac37971
commit bb41208e15
31 changed files with 9 additions and 717 deletions

View File

@ -1,14 +0,0 @@
<script lang="ts">
export let url: string;
</script>
<a href={url}>
<img src="/logos/color/git.svg" alt="Git Repository" />
</a><br /><br />
<style>
img {
height: 25px;
width: 25px;
}
</style>

View File

@ -1,30 +0,0 @@
<script lang="ts">
import type { ArticleSummary } from '$lib/posts/types';
import EmptyCard from './cards/EmptyCard.svelte';
import PostCard from './cards/PostCard.svelte';
export let length: number = 6; // Number of posts to return
async function getPosts(length: number): Promise<ArticleSummary[]> {
const res = await fetch('/posts/latest');
const json = await res.json();
console.log(json);
return json;
}
</script>
{#await getPosts(length)}
<EmptyCard><p class="message">Awaiting posts</p></EmptyCard>
{:then posts}
{#each posts as post}
<PostCard {post} />
{/each}
{:catch}
<EmptyCard><p class="message">Unable to fetch posts</p></EmptyCard>
{/await}
<style>
.message {
color: var(--island-txt-color);
}
</style>

View File

@ -1,32 +0,0 @@
<script>
import Logos from '$lib/language-logos/Logos.svelte';
import EmptyCard from './cards/EmptyCard.svelte';
import ProjectCard from './cards/ProjectCard.svelte';
async function getProjects() {
const res = await fetch('/projects/all');
const json = await res.json();
console.log(json);
return json;
}
</script>
{#await getProjects()}
<EmptyCard>
<p class="message">Fetching Projects...</p>
</EmptyCard>
{:then projects}
{#each projects as project}
<ProjectCard {project} />
{/each}
{:catch}
<EmptyCard>
<p class="message">Unable to fetch projects</p>
</EmptyCard>
{/await}
<style>
.message {
color: var(--island-txt-color);
}
</style>

View File

@ -1,36 +0,0 @@
<script lang="ts">
import type { ArticleSummary } from '$lib/posts/types';
import EmptyCard from './EmptyCard.svelte';
import PostTag from '$lib/posts/PostTag.svelte';
export let post: ArticleSummary;
</script>
<a href="/posts/{post.slug}">
<EmptyCard>
<h1 class="post-title">{post.title}</h1>
<h2 class="post-date">{new Date(post.date).toLocaleDateString()}</h2>
<br />
<p class="post-summary">{post.summary}</p>
<br />
<div class="tag-container">
{#each post.tags as tag}
<PostTag {tag} />
{/each}
</div>
</EmptyCard>
</a>
<style>
a {
text-decoration: none;
color: var(--island-txt-color);
}
.tag-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
</style>

View File

@ -1,21 +0,0 @@
<script lang="ts">
import Logos from '$lib/language-logos/Logos.svelte';
import EmptyCard from './EmptyCard.svelte';
export let project;
</script>
<a href="/posts/tag/{project.name.toLowerCase()}">
<EmptyCard>
<h1>{project.name}</h1>
<Logos langs={project.langs} plats={project.plats} />
<p>{project.description}</p>
</EmptyCard>
</a>
<style>
a {
text-decoration: none;
color: var(--island-txt-color);
}
</style>

View File

@ -1,47 +0,0 @@
<script lang="ts">
import PostTag from '$lib/posts/PostTag.svelte';
import EmptyCard from './EmptyCard.svelte';
async function fetchTags() {
const tags: string[] = [];
const endpoint = '/posts/tag/all';
const res = await fetch(endpoint);
const json = await res.json();
if (Array.isArray(json)) {
for (const item of json) {
tags.push(item);
}
}
return tags;
}
</script>
<EmptyCard>
<div class="tag-box">
{#await fetchTags()}
<p class="message">Loading Tags...</p>
{:then tags}
{#each tags as tag}
<div class="tag-link">
<PostTag {tag} />
</div>
{/each}
{:catch}
<p class="message">Unable to load tags</p>
{/await}
</div>
</EmptyCard>
<style>
.message {
color: var(--island-txt-color);
}
.tag-box {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: baseline;
row-gap: 15px;
}
</style>

View File

@ -1,20 +0,0 @@
<section>
<div>
<slot />
</div>
</section>
<style>
section {
width: 100%;
background-color: var(--main-text-color);
color: rgb(46, 46, 46);
margin: 0;
margin-bottom: 10px;
padding: 0;
}
div {
width: 90%;
margin: auto;
}
</style>

View File

@ -1,12 +0,0 @@
import { MongoClient } from 'mongodb';
const MongoUri = 'mongodb://owl:twittwoo@localhost:27017/';
let dbClient: MongoClient | null = null;
export async function mongoConnect() {
if (!dbClient) {
dbClient = await MongoClient.connect(MongoUri);
}
return dbClient;
}

View File

@ -11,4 +11,10 @@ export interface PixelfedFeed {
updated: string | null; updated: string | null;
imgUrl: string | null; imgUrl: string | null;
pixelfedUrl: string | null; pixelfedUrl: string | null;
}
export interface GitFeed {
title: string | null;
text: string | null;
url: string | null;
} }

View File

@ -1,14 +0,0 @@
<span>
<slot />
</span>
<style>
span {
background-color: green;
color: white;
border-top-right-radius: 5px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 2px;
border-top-left-radius: 2px;
}
</style>

View File

@ -1,25 +0,0 @@
<script lang="ts">
export let tag: string;
</script>
<a class="tag-link" href="/posts/tag/{tag}">
{tag}
</a>
<style>
.tag-link {
text-decoration: none;
color: var(--island-txt-color);
padding: 3px 5px 3px 5px;
margin: 10px;
background-color: var(--island-link-color);
border-radius: 5px;
box-shadow: 1px 1px 2px rgba(0,0,0,0.19);
}
.tag-link:hover,
.tag-link:active {
/*background-color: var(--accent-rollover);*/
box-shadow: 1px 1px 1px rgba(0,0,0,0.19) inset;
}
</style>

View File

@ -1,40 +0,0 @@
<script lang="ts">
import type { ArticleSummary } from './types';
import FullWidthContent from '$lib/content-boxes/FullWidthContent.svelte';
export let article: ArticleSummary;
</script>
<FullWidthContent>
<a href="/posts/{article.slug}">
<article>
<h1>{article.title}</h1>
<p>{article.summary}</p>
</article>
</a>
</FullWidthContent>
<style>
a {
text-decoration: none;
color: black;
}
article {
height: auto;
width: 100%;
margin: auto;
padding-top: 1px;
padding-bottom: 5px;
}
h1 {
margin-left: 10px;
margin-right: 10px;
font-family: shadowsintolight;
}
p {
margin-left: 10px;
margin-right: 10px;
}
</style>

View File

@ -1,20 +0,0 @@
export interface ArticleSummary {
title: string;
author: string;
tags: string[];
pusblished: boolean;
date: Date;
summary: string;
slug: string;
}
export interface Article {
title: string;
author: string;
tags: string[];
pusblished: boolean;
date: Date;
summary: string;
slug: string;
content: string;
}

View File

@ -1,30 +0,0 @@
<script lang="ts">
import type { Project } from './types';
import Logos from '$lib/language-logos/Logos.svelte';
export let project: Project;
</script>
<article>
<a href="/posts/tag/{project.tag}"><h1>{project.name}</h1></a>
<Logos langs={project.lang || []} plats={project.plat || []} />
<p>{project.summary}</p>
</article>
<style>
article {
height: auto;
width: 100%;
margin: auto;
}
h1 {
margin-left: 10px;
margin-right: 10px;
}
p {
margin-left: 10px;
margin-right: 10px;
}
</style>

View File

@ -1,8 +0,0 @@
export interface Project {
name: string;
tag: string;
imagePath: string;
summary: string;
lang: string[];
plat: string[];
}

View File

@ -1,17 +1,11 @@
<script lang="ts"> <script lang="ts">
import Latest from '$lib/posts/PostsSummary.svelte';
import Header from '$lib/header.svelte'; import Header from '$lib/header.svelte';
import Emphasis from '$lib/highlights/emphasis.svelte';
import LatestPosts from '$lib/card-collections/LatestPosts.svelte';
import TagsCard from '$lib/card-collections/cards/TagsCard.svelte';
import Projects from '$lib/card-collections/Projects.svelte';
import Pixelfed from "$lib/feeds/pixelfed.svelte"; import Pixelfed from "$lib/feeds/pixelfed.svelte";
import type { PageData } from "../$types"; import type { PageData } from "../$types";
export let data: PageData; export let data: PageData;
const title: string = "Hi, I'm Fred"; const title: string = "Hi, I'm Fred";
const columnLength = 7;
</script> </script>
<Header {title} /> <Header {title} />
@ -37,12 +31,10 @@
<Pixelfed pixelfedFeed={data.xml} /> <Pixelfed pixelfedFeed={data.xml} />
</div> </div>
<div id="posts" class="col"> <div id="posts" class="col">
<h1>Posts</h1> <p>I do lots of things, this is a central place you can check it all out.</p>
<LatestPosts length={columnLength} />
</div> </div>
<div id="tags" class="col"> <div id="git" class="col">
<h1>Tags</h1> <h1>Git</h1>
<TagsCard />
</div> </div>
</section> </section>

View File

@ -1,11 +0,0 @@
<script lang="ts">
import LatestPosts from '$lib/card-collections/LatestPosts.svelte';
import PostCard from '$lib/card-collections/cards/PostCard.svelte';
import Header from '$lib/header.svelte';
const title = "Things I've Written";
</script>
<Header {title} />
<LatestPosts number={20} />

View File

@ -1,55 +0,0 @@
import { mongoConnect } from '$lib/database/mongo.server';
import { marked } from 'marked';
import * as path from 'path';
import sanitizeHtml from 'sanitize-html';
import type { Article } from '$lib/posts/types';
import type { _Renderer } from 'Renderer';
export async function load({ params }) {
const slug = params.slug;
const db = await mongoConnect();
const query = {
slug: slug
};
const col = db.db('fredboniface').collection('posts');
const res = await col.findOne(query);
if (!res) {
throw new Error('Post Not Found');
}
const renderer = new marked.Renderer();
renderer.image = function (href, title, text) {
const imgPath = path.join('/images/posts', res.slug, href);
return `<figure>
<img class="post-inline-image-546543" src="${imgPath}" alt="${text}" title="${title}">
<figcaption>${title}</figcaption>
</figure>`;
};
const post: Article = {
title: res.title,
author: res.author,
pusblished: res.published,
summary: res.summary,
content: renderMarkdown(res.content, renderer),
slug: res.slug,
tags: res.tags,
date: res.date
};
return { data: post };
}
function renderMarkdown(md: string, renderer: _Renderer): string {
const rawHtml = marked(md, { renderer });
const sanitizedHtml = sanitizeHtml(rawHtml, {
allowedTags: ['a', 'br', 'code', 'figcaption', 'figure', 'img', 'p', 'pre'],
allowedAttributes: {
a: ['href'],
img: ['alt', 'class', 'src', 'title']
}
});
return sanitizedHtml;
}

View File

@ -1,124 +0,0 @@
<script lang="ts">
import LatestPosts from '$lib/card-collections/LatestPosts.svelte';
import Projects from '$lib/card-collections/Projects.svelte';
import Header from '$lib/header.svelte';
import PostTag from '$lib/posts/PostTag.svelte';
import type { Article } from '$lib/posts/types';
import { afterUpdate } from 'svelte';
export let data: any;
let post: Article;
$: post = data.data;
afterUpdate(() => {
const codeBlocks = document.querySelectorAll('article pre');
codeBlocks.forEach((codeBlock) => {
const copyButton = document.createElement('button');
copyButton.textContent = '📋 Copy code';
copyButton.classList.add('article-code-copy-button-32984456');
copyButton.addEventListener('click', () => {
const codeText = codeBlock.textContent || '';
const trimmedCodeText = codeText.replace(copyButton.textContent || '', '');
navigator.clipboard
.writeText(trimmedCodeText)
.then(() => {
console.log('Copied code to clipboard');
})
.catch((error) => {
console.error(
'Error copying code to clipboard, this may be due to privacy settings in your browser',
error
);
});
});
codeBlock.appendChild(copyButton);
});
});
</script>
<Header title={post.title} />
<div class="column-container">
<div class="main-column">
<article>
<p>
{#each post.tags as tag}
<PostTag {tag} />
{/each}<br /><br />
Published: {post.date.toLocaleDateString()}<br />
Author: {post.author}
</p>
<content>
{@html post.content}
</content>
</article>
</div>
<div class="side-column">
<h2>Projects</h2>
<LatestPosts />
</div>
</div>
<style>
.column-container {
display: flex;
flex-direction: column;
gap: 20px;
}
.main-column {
margin-left: 10px;
margin-right: 10px;
}
@media (min-width: 768px) {
.column-container {
flex-direction: row; /* Switch to row layout for larger screens */
}
.main-column {
flex: 2; /* Take up 2/3 of the available width */
}
.side-column {
flex: 1; /* Take up 1/3 of the available width */
padding-top: 70px;
}
}
:global(article pre) {
position: relative;
text-align: left;
background-color: rgb(46, 46, 46);
color: white;
padding: 15px;
padding-top: 30px;
padding-bottom: 30px;
font-family: 'Courier New', Courier, monospace;
border-radius: 8px;
width: 90%;
max-width: 800px;
margin: auto;
white-space: pre;
overflow: auto;
}
:global(.article-code-copy-button-32984456) {
position: absolute;
top: 10px;
right: 15px;
color: white;
background: none;
border: none;
cursor: pointer;
}
:global(.post-inline-image-546543) {
max-width: 100%;
}
</style>

View File

@ -1,15 +0,0 @@
import { json } from '@sveltejs/kit';
import { mongoConnect } from '$lib/database/mongo.server';
import type { ArticleSummary } from '$lib/posts/types';
const length = 8; // Number of posts to return
export async function GET({ url }) {
const db = await mongoConnect();
const col = db.db('fredboniface').collection('posts');
const res = await col.find().sort({ _id: -1 }).limit(length).toArray();
return json(res);
}
// The CONTENT field should be ommitted from the DB response

View File

@ -1,19 +0,0 @@
---
title: map-dots
author: Frederick Boniface
date: '2023-08-16'
---
[map-dots Repo](https://git.fjla.uk/fred.boniface/map-dots) [map-dots-fetch Repo](https://git.fjla.uk/fred.boniface/map-dots-fetch)
I'm someone who likes to gather data a bit of a data hoarder. But truth be told, having the data doesn't mean I always know what to do with it.
You know those monthly emails from Google that break down your location history? I used to find them fascinating. But, handing over all that info to Google didn't sit right with me. So, I took matters into my own hands and set up a Traccar instance at home, connecting my mobile devices to it.
Now, my location history is kept under my own roof. I even turned off Google's location history feature.
However, the downside was losing those monthly reports. You see, Traccar isn't exactly built for that; it's more focused on fleet tracking.
That's when "map-dots" came into play. It's a Go-based application that can be run through the command line or as an API server. While it's still a work in progress, it's got potential. Currently, it can take in HTTP requests, connect to a Traccar server, retrieve location history data, and turn it into an image.
To keep things ticking, I created the "map-dots-fetch" script in Python. It fetches a new image at regular intervals, and I've set that image as the wallpaper on my devices.

View File

@ -1,9 +0,0 @@
---
title: Not Found
date: '2023-08-16'
author: Frederick Boniface
---
**404 - The post you requested cannot be found**
If you came here from a search engine, maybe the post has been removed or renamed. If you got here from a link on my website then there may be a server error.

View File

@ -1,25 +0,0 @@
---
title: OwlBoard
author: Frederick Boniface
date: '2023-08-16'
---
[Git Organisation](https://git.fjla.uk/owlboard) [Live Website](https://owlboard.info)
OwlBoard came about because I was sick of dealing with clunky tools that were slow, outdated, and not user-friendly.
I had a clear goal in mind: make something smoother, faster, and more modern to shake up the tool landscape.
I decided to take control of the data side of things and built a Python-based db-manager app. It works on a schedule to handle database collections, polish data from different sources, and neatly store it all in the database.
db-manager eventually grew to pull data from Network Rail's CORPUS and TIMETABLE feeds, as well as downloading PIS and Reason Code data from a git repository.
OwlBoard started with a simple idea: real-time station departure boards. I used an Express backend alongside a basic HTML/CSS/JS frontend PWA. But as I added more features, it became obvious that a sturdier framework was needed. Both users and developers were struggling with more menus and messier code.
Enter Svelte, especially SvelteKit. I wasn't just hopping on a trend I liked that it allowed me to work with plain JS, HTML, and CSS in components. This made my learning curve easier and sped up improvements for users.
When API responses got lengthy, I turned to TypeScript. It was like flipping a switch, helping me understand what's happening behind the scenes and reducing how much I relied on console.log.
Later on, I integrated VSTP data from Network Rail using Go. I set up a message handler, subscribed to the VSTP feed using a STOMP library, and processed messages like the db-manager does. This ensured that the database's timetable collection was always up to date, thanks to how I managed transactions.
Looking ahead, I'm focused on fine-tuning the interactions between the backend and frontend. I want to make things smoother by sending less data, especially important when dealing with shaky data connections.

View File

@ -1,16 +0,0 @@
import { mongoConnect } from '$lib/database/mongo.server';
export async function load({ params }) {
const tag = params.tag;
const db = await mongoConnect();
const query = {
tags: {
$in: [tag]
}
};
const col = db.db('fredboniface').collection('posts');
const res = col.find(query);
const posts = await res.toArray();
return { data: JSON.stringify(posts), tag: tag };
}

View File

@ -1,18 +0,0 @@
<script lang="ts">
import PostCard from '$lib/card-collections/cards/PostCard.svelte';
import Header from '$lib/header.svelte';
import type { ArticleSummary } from '$lib/posts/types.js';
export let data;
let posts: ArticleSummary[];
$: posts = JSON.parse(data.data);
let title: string;
$: title = `tag: ${data.tag}`;
</script>
<Header {title} />
{#each posts as post}
<PostCard {post} />
{/each}

View File

@ -1,12 +0,0 @@
// Fetches all tags and returns a JSON Array of the tags ordered in their frequency of use
import { json } from '@sveltejs/kit';
import { mongoConnect } from '$lib/database/mongo.server';
export async function GET({ url }) {
const db = await mongoConnect();
const col = db.db('fredboniface').collection('posts');
const res = await col.distinct('tags');
return json(res);
}

View File

@ -1,22 +0,0 @@
<script lang="ts">
import ProjectCard from '$lib/card-collections/cards/ProjectCard.svelte';
import Header from '$lib/header.svelte';
const title: string = "Stuff I've Done";
async function getProjects() {
return await (await fetch('/projects/all')).json();
}
</script>
<Header {title} />
{#await getProjects()}
<p class="messages">Fetching projects</p>
{:then projects}
{#each projects as project}
<ProjectCard {project} />
{/each}
{:catch}
<p class="messages">Error fetching projects</p>
{/await}

View File

@ -1,12 +0,0 @@
// Fetches all tags and returns a JSON Array of the tags ordered in their frequency of use
import { json } from '@sveltejs/kit';
import { mongoConnect } from '$lib/database/mongo.server';
export async function GET({ url }) {
const db = await mongoConnect();
const col = db.db('fredboniface').collection('projects');
const res = await col.find().toArray();
return json(res);
}

View File

@ -1,11 +0,0 @@
import type { PageServerLoad } from "./$types";
export const load: PageServerLoad = async () => {
try {
const res = await fetch("https://pixelfed.scot/users/fbface.atom")
const xml = await res.text();
return {xml: xml}
} catch (err) {
console.error("Error in load function", err)
}
}

View File

@ -1,8 +0,0 @@
<script lang="ts">
import Pixelfed from "$lib/feeds/pixelfed.svelte";
import type { PageData } from "../$types";
export let data: PageData;
</script>
<Pixelfed pixelfedFeed={data.xml} />