Skip to content
Draft
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
44 changes: 44 additions & 0 deletions TODOs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# TODOs

<!-- TODO: A todo within the TODOs!!! This is a temporary file to track work since there are so many of us mucking about on this! REMOVE BEFORE FINALIZING THE PR!!!! -->

---

## In Flight

- Blog list UI - fix posts width
- Blog post UI - (Started - needs more polish)
- OAuth
- Standard site push - Mock PDS push for now
- constellation - bsky API
- Docs Run them locally with `pnpm dev:docs`.

---

## On Deck

- automatic pulls or pushes from an action runner
- records walkers
- bsky posts stuff - Bluesky comments
- How does i18n deal with dynamic values? $t('blog.post.title'),
- blog publishing for https://bsky.app/profile/npmx.dev - cli/actions pipeline
- site.standard.publication lexicon - decales it's a blog on atproto can be manual setup
- site.standard.document - publishes everytime there's a new blog entry.
- Proposed: the pipeline takes login pds, handle, and app_password as secrets. Checks to see if one has already been published for that blog post. If so does not push it. If it hasn't then it creates the atproto record when deploying/building by logging in. check if an article has been created by parsing the createdate of the blog post to a TID, do a getRecord. if it's there dont publish the new one. If it isnt send it up. I wrote about tid concept here
https://marvins-guide.leaflet.pub/3mckm76mfws2h
- Proposed: nuxt module with a build hook. e.g. in standard-site-sync.ts we use a hook that triggers after the file is parsed and create the site.standard.document or not if it already exists.
- Update styling for blog posts.
- BlogWrapper Component or should it be a Blog Layout?
- Organize markdown files in blog post folder?
- I18n of blog posts.
- TBD

---

## Landed

- [x] Lexicons
- [x] Prose-styling using unocss typography
- [x] anthony's alternative markdown solution for now and Nuxt content integration for later

---
6 changes: 6 additions & 0 deletions app/components/AppFooter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
>
{{ $t('footer.about') }}
</NuxtLink>
<NuxtLink
to="/blog"
class="link-subtle font-mono text-xs min-h-8 sm:min-h-11 flex items-center"
>
{{ $t('footer.blog') }}
</NuxtLink>
<a
href="https://docs.npmx.dev"
target="_blank"
Expand Down
9 changes: 9 additions & 0 deletions app/components/AppHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ onKeyStroke(',', e => {
e.preventDefault()
router.push('/settings')
})
onKeyStroke('.', e => {
const target = e.target as HTMLElement
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {
return
}
e.preventDefault()
router.push('/blog')
})
</script>

<template>
Expand Down
26 changes: 26 additions & 0 deletions app/components/BlogPost.server.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script setup lang="ts">
const props = defineProps<{ title: string; htmlContent: string; date: string }>()
</script>
<template>
<main class="container">
<h1 class="text-4xl font-bold text-gray-900 dark:text-white mb-2">
{{ title }}
</h1>

<DateTime
:datetime="date"
year="numeric"
month="short"
day="numeric"
class="text-xs text-fg-subtle"
/>

<div class="" v-html="htmlContent" />
</main>
</template>

<style>
.container {
background: var(--bg-blue);
}
</style>
80 changes: 80 additions & 0 deletions app/components/BlogPostListCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<script setup lang="ts">
defineProps<{
/** First and last name - Potentially Multiple? i.e. co-authors */
author: string
/** Blog Title */
title: string
/** Tags such as OpenSource, Architecture, Community, etc. */
topics: string[]
/** Brief line from the text. */
excerpt: string
/** The datetime value (ISO string or Date) */
published: string
/** Path/Slug of the post */
path: string
/** For keyboard nav scaffold */
index: number
}>()
const emit = defineEmits<{
focus: [index: number]
}>()
</script>

<template>
<article
class="group card-interactive relative focus-within:outline-none focus-within:ring-2 focus-within:ring-offset-bg focus-within:ring-offset-2 focus-within:ring-fg/50"
>
<NuxtLink
:to="`/blog/${path}`"
:data-suggestion-index="index"
class="flex items-center gap-4 focus-visible:outline-none after:content-[''] after:absolute after:inset-0"
@focus="index != null && emit('focus', index)"
@mouseenter="index != null && emit('focus', index)"
>
<!-- Avatar placeholder -->
<div
class="w-10 h-10 shrink-0 flex items-center justify-center border border-border rounded-full bg-bg-muted"
aria-hidden="true"
>
<span class="text-lg text-fg-subtle font-mono">
{{
author
.split(' ')
.map(n => n[0])
.join('')
.toUpperCase()
}}
</span>
</div>

<!-- Text Content -->
<div class="flex-1 min-w-0 text-left">
<h2
class="font-mono text-base font-medium text-fg group-hover:text-primary transition-colors hover:underline"
>
{{ title }}
</h2>

<div class="flex items-center gap-2 text-xs text-fg-muted font-mono">
<span>{{ author }}</span>
<span>•</span>
<span>{{ published }}</span>
</div>

<p v-if="excerpt" class="text-sm text-muted-foreground mt-2 line-clamp-2 no-underline">
{{ excerpt }}
</p>
</div>

<span
class="i-carbon-arrow-right w-4 h-4 text-fg-subtle group-hover:text-fg transition-colors shrink-0"
aria-hidden="true"
/>
</NuxtLink>
</article>
</template>
<!-- :class="{
'bg-bg-muted border-border-hover': selected,
'border-accent/30 bg-accent/5': isExactMatch,
}" -->
22 changes: 22 additions & 0 deletions app/components/BlogPostWrapper.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script setup lang="ts">
import type { BlogPostFrontmatter } from '#shared/schemas/blog'
const props = defineProps<{
frontmatter?: BlogPostFrontmatter
}>()
useSeoMeta({
title: props.frontmatter?.title,
description: props.frontmatter?.description || props.frontmatter?.excerpt,
ogTitle: props.frontmatter?.title,
ogDescription: props.frontmatter?.description || props.frontmatter?.excerpt,
ogType: 'article',
})
</script>
<template>
<main class="container w-full py-8">
<article class="prose dark:prose-invert mx-auto">
<slot />
</article>
</main>
</template>
14 changes: 14 additions & 0 deletions app/pages/blog/atproto.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
author: 'Daniel Roe'
title: 'ATProto'
tags: ['OpenSource', 'Nuxt']
excerpt: 'ATProto is very cool'
date: '2026-01-28'
slug: 'atproto'
description: 'ATProto Adjacency Agenda'
draft: false
---

# Atmosphere Apps

All the cool kids are doing Software Decentralization.
Loading
Loading