Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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: 37 additions & 7 deletions app/components/BlueskyComment.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,17 @@ function getHostname(uri: string): string {
</script>

<template>
<div :class="depth === 0 ? 'flex gap-3' : 'flex gap-3 mt-3'">
<!-- Avatar -->
<!--
Depth 0: classic avatar-column layout (all screens)
Depth 1+: Medium-style inline avatar on mobile, avatar-column on desktop
-->
<div :class="depth === 0 ? 'flex gap-3' : 'sm:flex sm:gap-3'">
<!-- Column avatar: always shown at depth 0, desktop-only at depth 1+ -->
<a
:href="`https://bsky.app/profile/${comment.author.handle}`"
target="_blank"
rel="noopener noreferrer"
class="shrink-0"
:class="['shrink-0', depth > 0 ? 'hidden sm:block' : '']"
Comment thread
Adebesin-Cell marked this conversation as resolved.
Outdated
>
<img
v-if="comment.author.avatar"
Expand All @@ -71,16 +75,39 @@ function getHostname(uri: string): string {

<div class="flex-1 min-w-0">
<!-- Author info + timestamp -->
<div class="flex flex-wrap items-baseline gap-x-2 gap-y-0">
<div class="flex flex-wrap items-center gap-x-2 gap-y-0">
<!-- Inline avatar: mobile-only for nested comments -->
<a
v-if="depth > 0"
:href="`https://bsky.app/profile/${comment.author.handle}`"
target="_blank"
rel="noopener noreferrer"
class="font-medium text-fg hover:underline"
class="shrink-0 sm:hidden"
>
<img
v-if="comment.author.avatar"
:src="comment.author.avatar"
:alt="comment.author.displayName || comment.author.handle"
class="w-6 h-6 rounded-full"
width="24"
height="24"
loading="lazy"
/>
<div
v-else
class="w-6 h-6 rounded-full bg-border flex items-center justify-center text-fg-muted text-xs"
>
{{ (comment.author.displayName || comment.author.handle).charAt(0).toUpperCase() }}
Comment thread
ghostdevv marked this conversation as resolved.
Outdated
</div>
</a>
<a
:href="`https://bsky.app/profile/${comment.author.handle}`"
target="_blank"
rel="noopener noreferrer"
:class="['font-medium text-fg hover:underline', depth > 0 ? 'text-sm' : '']"
>
{{ comment.author.displayName || comment.author.handle }}
</a>
<span class="text-fg-subtle text-sm">@{{ comment.author.handle }}</span>
<span class="text-fg-subtle text-sm">·</span>
<a
:href="getCommentUrl(props.comment)"
Expand Down Expand Up @@ -174,7 +201,10 @@ function getHostname(uri: string): string {

<!-- Nested replies -->
<template v-if="comment.replies.length > 0">
<div v-if="depth < MaxDepth" class="mt-2 ps-2 border-is-2 border-border flex flex-col">
<div
v-if="depth < MaxDepth"
class="mt-3 ps-3 border-is-2 border-border flex flex-col gap-3"
>
<BlueskyComment
v-for="reply in comment.replies"
:key="reply.uri"
Expand Down
2 changes: 1 addition & 1 deletion app/components/Link/Base.vue
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ const keyboardShortcutsEnabled = useKeyboardShortcuts()
'text-xs px-2 py-0.5': isButtonSmall,
'bg-transparent text-fg hover:(bg-fg/10 text-accent) focus-visible:(bg-fg/10 text-accent) aria-[current=true]:(bg-fg/10 text-accent border-fg/20 hover:enabled:(bg-fg/20 text-fg/50))':
variant === 'button-secondary',
'text-bg bg-fg hover:(bg-fg/50 text-accent) focus-visible:(bg-fg/50) aria-current:(bg-fg text-bg border-fg hover:enabled:(text-bg/50))':
'text-bg bg-fg hover:(bg-fg/80 text-bg) focus-visible:(bg-fg/80 text-bg) aria-current:(bg-fg text-bg border-fg hover:enabled:(text-bg/50))':
variant === 'button-primary',
Comment thread
Adebesin-Cell marked this conversation as resolved.
Outdated
}"
:to="to"
Expand Down
4 changes: 2 additions & 2 deletions app/components/global/BlogPostFederatedArticles.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const federatedArticles = computed(() => {
</script>

<template>
<aside class="px-4 sm:-mx-6 sm:px-6 sm:-my-3 sm:py-3 sm:rounded-md">
<aside class="sm:-mx-6 sm:px-6 sm:-my-3 sm:py-3 sm:rounded-md">
<h2 class="font-mono text-xl font-medium text-fg mt-0">
{{ headline }}
</h2>
Expand All @@ -55,7 +55,7 @@ const federatedArticles = computed(() => {
rel="noopener noreferrer"
v-for="article in federatedArticles"
:key="article.url"
class="grid grid-cols-[auto_1fr] gap-x-5 no-underline hover:no-underline rounded-lg border border-border p-4 transition-shadow hover:shadow-lg hover:shadow-gray-500/50"
class="grid grid-cols-[auto_1fr] gap-x-5 no-underline hover:no-underline rounded-lg border border-border p-4 transition-all hover:shadow-md hover:shadow-black/5 dark:hover:shadow-white/5 hover:border-border-hover"
Comment thread
Adebesin-Cell marked this conversation as resolved.
Outdated
>
<AuthorAvatar v-if="article.author" :author="article.author" size="md" class="row-span-2" />
<div class="flex flex-col">
Expand Down
17 changes: 16 additions & 1 deletion app/components/global/BlogPostWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const blueskyPostUri = computed(() => blueskyLink.value?.postUri ?? null)
<AuthorList :authors="post.authors" variant="expanded" />
</div>
</div>
<article class="max-w-prose mx-auto p-2 prose dark:prose-invert">
<article class="max-w-prose mx-auto prose dark:prose-invert">
<div class="text-sm text-fg-muted font-mono mb-4">
<DateTime :datetime="frontmatter.date" year="numeric" month="short" day="numeric" />
</div>
Expand All @@ -77,4 +77,19 @@ const blueskyPostUri = computed(() => blueskyLink.value?.postUri ?? null)
:deep(.markdown-body) {
@apply prose dark:prose-invert;
}

:deep(.prose a:not(.not-prose a)) {
text-decoration: underline;
text-underline-offset: 0.2rem;
text-decoration-thickness: 1px;
text-decoration-color: var(--fg-subtle);
transition:
text-decoration-color 0.2s,
color 0.2s;
}
Comment thread
Adebesin-Cell marked this conversation as resolved.
Outdated

:deep(.prose a:not(.not-prose a):hover) {
text-decoration-color: var(--fg);
color: var(--fg);
}
</style>
14 changes: 8 additions & 6 deletions app/components/global/BlueskyPostEmbed.client.vue
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,16 @@ const postUrl = computed(() => {
:href="postUrl ?? '#'"
target="_blank"
rel="noopener noreferrer"
class="not-prose block rounded-lg border border-border bg-bg-subtle p-4 sm:p-5 no-underline hover:border-border-hover transition-colors duration-200"
class="not-prose block rounded-lg border border-border bg-bg-subtle p-4 sm:p-5 no-underline hover:border-border-hover transition-colors duration-200 relative"
>
<!-- Bluesky icon -->
<span
class="i-simple-icons:bluesky w-5 h-5 text-fg-subtle absolute top-4 end-4 sm:top-5 sm:end-5"
aria-hidden="true"
/>
Comment thread
Adebesin-Cell marked this conversation as resolved.
Outdated

<!-- Author row -->
<div class="flex items-center gap-3 mb-3">
<div class="flex items-center gap-3 mb-3 pe-7">
<img
v-if="post.author.avatar"
:src="`${post.author.avatar}?size=48`"
Expand All @@ -126,10 +132,6 @@ const postUrl = computed(() => {
</div>
<div class="text-sm text-fg-subtle truncate">@{{ post.author.handle }}</div>
</div>
<span
class="i-simple-icons:bluesky w-5 h-5 text-fg-subtle ms-auto shrink-0"
aria-hidden="true"
/>
</div>

<!-- Post text -->
Expand Down
2 changes: 1 addition & 1 deletion i18n/locales/az-AZ.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
"reply_count": "{count} cavab",
"like_count": "{count} bəyənmə",
"repost_count": "{count} yenidən paylaşım",
"more_replies": "{count} cavab daha..."
"more_replies": "daha {count} cavab... | daha {count} cavab..."
}
},
"settings": {
Expand Down
2 changes: 1 addition & 1 deletion i18n/locales/cs-CZ.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
"reply_count": "{count} odpověď | {count} odpovědi | {count} odpovědí",
"like_count": "{count} lajk | {count} lajky | {count} lajků",
"repost_count": "{count} repost | {count} reposty | {count} repostů",
"more_replies": "{count} další odpověď ... | {count} další odpovědi ... | {count} dalších odpovědí ..."
"more_replies": "ještě {count} odpověď… | ještě {count} odpovědi… | ještě {count} odpovědí"
}
},
"settings": {
Expand Down
2 changes: 1 addition & 1 deletion i18n/locales/de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
"reply_count": "{count} Antwort | {count} Antworten",
"like_count": "{count} Like | {count} Likes",
"repost_count": "{count} Repost | {count} Reposts",
"more_replies": "{count} weitere Antwort anzeigen | {count} weitere Antworten anzeigen"
"more_replies": "noch {count} Antwort… | noch {count} Antworten"
}
},
"settings": {
Expand Down
2 changes: 1 addition & 1 deletion i18n/locales/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
"reply_count": "{count} réponse | {count} réponses",
"like_count": "{count} j'aime | {count} j'aime",
"repost_count": "{count} repartage | {count} repartages",
"more_replies": "{count} réponse de plus... | {count} réponses de plus..."
"more_replies": "{count} réponse supplémentaire... | {count} réponses supplémentaires..."
}
},
"settings": {
Expand Down
2 changes: 1 addition & 1 deletion i18n/locales/id-ID.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
"reply_count": "{count} balasan | {count} balasan",
"like_count": "{count} suka | {count} suka",
"repost_count": "{count} repost | {count} repost",
"more_replies": "{count} balasan lainnya... | {count} balasan lainnya..."
"more_replies": "{count} balasan lagi... | {count} balasan lagi..."
}
},
"settings": {
Expand Down
2 changes: 1 addition & 1 deletion i18n/locales/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
"reply_count": "{count} 件の返信",
"like_count": "{count} 件のいいね",
"repost_count": "{count} 件のリポスト",
"more_replies": "さらに {count} 件のリプライを表示..."
"more_replies": "さらに{count}件の返信…"
}
},
"settings": {
Expand Down
2 changes: 1 addition & 1 deletion i18n/locales/pl-PL.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
"reply_count": "{count} odpowiedzi | {count} odpowiedź | {count} odpowiedzi | {count} odpowiedzi | {count} odpowiedzi",
"like_count": "{count} polubień | {count} polubienie | {count} polubienia | {count} polubień | {count} polubień",
"repost_count": "{count} udostępnień | {count} udostępnienie | {count} udostępnienia | {count} udostępnień | {count} udostępnień",
"more_replies": "{count} odpowiedzi więcej... | {count} odpowiedź więcej... | {count} odpowiedzi więcej... | {count} odpowiedzi więcej... | {count} odpowiedzi więcej..."
"more_replies": "jeszcze {count} odpowiedź… | jeszcze {count} odpowiedzi… | jeszcze {count} odpowiedzi"
}
},
"settings": {
Expand Down
76 changes: 76 additions & 0 deletions i18n/locales/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -1347,5 +1347,81 @@
"selection": "0 selecionados | 1 selecionado | {count} selecionados",
"shortcut": "Pressione \"{key}\" para focar nas ações",
"button_close_aria_label": "Fechar barra de ações"
},
"blog": {
"title": "Blog",
"meta_description": "Insights e atualizações da comunidade npmx",
"heading": "blog",
"draft_banner": "Este é um rascunho não publicado. Pode estar incompleto ou conter imprecisões.",
"atproto": {
"comments": "Comentários",
"could_not_load_comments": "Não foi possível carregar comentários.",
"like_count": "{count} curtida | {count} curtidas",
"like_or_reply_on_bluesky": "Curta esta postagem ou adicione seu comentário no Bluesky",
"likes_on_bluesky": "Curtidas no Bluesky",
"loading_comments": "Carregando comentários...",
"no_comments_yet": "Nenhum comentário ainda.",
"reply_count": "{count} resposta | {count} respostas",
"reply_on_bluesky": "Responder no Bluesky",
"repost_count": "{count} repostagem | {count} repostagens",
"updating": "Atualizando...",
"view_on_bluesky": "Ver no Bluesky"
},
"author": {
"view_profile": "Veja o perfil de {name} no Bluesky"
},
"draft_badge": "Rascunho"
},
"error": {
"401": "Não autorizado",
"404": "Página não encontrada",
"500": "Erro do Servidor Interno",
"503": "Serviço não disponível",
"default": "Algo deu errado"
},
"profile": {
"description": "Descrição",
"display_name": "Nome visível",
"invite": {
"compose_text": "Olá, {'@'}{handle}! Você já conferiu npmx.dev? É um navegador para o registro npm rápido, moderno e de código aberto.\nhttps://npmx.dev",
"message": "Parece que eles ainda não estão usando o npmx. Quer contar a eles sobre isso?",
"share_button": "Compartilhar no Bluesky"
},
"likes": "Curtidas",
"no_description": "Sem descrição",
"not_found": "Perfil não encontrado",
"not_found_message": "O perfil de {handle} não foi encontrado.",
"seo_description": "Perfil npmx de {handle}",
"seo_title": "{handle} - npmx",
"website": "Site",
"website_placeholder": "https://example.com"
},
"pds": {
"community": {
"description": "Algumas das {count} contas que já estão chamando npmx.social sua casa:",
"empty": "Nenhum membro da comunidade para exibir.",
"error": "Falha ao carregar a comunidade PDS.",
"loading": "Carregando comunidade PDS...",
"new_accounts": "...e mais {count} que são novos na atmosfera",
"title": "Quem está aqui",
"view_profile": "Veja o perfil de {handle}"
},
"join": {
"description": "Esteja você criando sua primeira conta na atmosfera ou migrando uma já existente, você pertence aqui. Você pode migrar sua conta atual sem perder seu controle, suas postagens ou seus seguidores.",
"migrate": "Migrar com PDS MOOver",
"title": "Junte-se à comunidade"
},
"meta_description": "O AT Protocol Personal Data Server (PDS) oficial para a comunidade npmx.",
"server": {
"infrastructure_label": "Infraestrutura:",
"infrastructure_value": "Hospedado em Hetzner",
"learn_more": "Aprenda como o npmx usa a atmosfera",
"location_label": "Localização:",
"location_value": "Nuremberga, Alemanha",
"privacy_label": "Privacidade:",
"privacy_value": "Sujeito às rigorosas leis de proteção de dados da UE",
"title": "Detalhes do servidor"
},
"title": "npmx.social"
}
Comment thread
Adebesin-Cell marked this conversation as resolved.
Outdated
}
2 changes: 1 addition & 1 deletion i18n/locales/ru-RU.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
"reply_count": "{count} ответ | {count} ответа | {count} ответов",
"like_count": "{count} лайк | {count} лайка | {count} лайков",
"repost_count": "{count} репост | {count} репоста | {count} репостов",
"more_replies": "Ещё {count} ответ | Ещё {count} ответа | Ещё {count} ответов"
"more_replies": "ещё {count} ответ... | ещё {count} ответа... | ещё {count} ответов..."
}
},
"settings": {
Expand Down
2 changes: 1 addition & 1 deletion i18n/locales/tr-TR.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
"reply_count": "{count} yanıt",
"like_count": "{count} beğeni",
"repost_count": "{count} yeniden paylaşım",
"more_replies": "{count} yanıt daha..."
"more_replies": "{count} yanıt daha... | {count} yanıt daha..."
}
},
"settings": {
Expand Down
2 changes: 1 addition & 1 deletion i18n/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
"reply_count": "{count} 条回复 | {count} 条回复",
"like_count": "{count} 个赞 | {count} 个赞",
"repost_count": "{count} 次转发 | {count} 次转发",
"more_replies": "还有 {count} 条回复... | 还有 {count} 条回复..."
"more_replies": "还有 {count} 条回复..."
}
},
"settings": {
Expand Down
Loading