Skip to content

Commit 04e330c

Browse files
authored
Merge branch 'main' into fix/i18n-turkish-missing-translations
2 parents 6887ed9 + 51ecbc7 commit 04e330c

13 files changed

Lines changed: 288 additions & 50 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ test-results/
4040
# generated files
4141
shared/types/lexicons
4242
file-tree-sprite.svg
43+
public/blog/avatar
4344

4445
**/__screenshots__/**
4546

app/components/AuthorList.vue

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
<script setup lang="ts">
2-
import type { Author } from '#shared/schemas/blog'
2+
import type { ResolvedAuthor } from '#shared/schemas/blog'
33
4-
const props = defineProps<{
5-
authors: Author[]
4+
defineProps<{
5+
authors: ResolvedAuthor[]
66
variant?: 'compact' | 'expanded'
77
}>()
8-
9-
const { resolvedAuthors } = useBlueskyAuthorProfiles(props.authors)
108
</script>
119

1210
<template>
1311
<!-- Expanded variant: vertical list with larger avatars -->
1412
<div v-if="variant === 'expanded'" class="flex flex-wrap items-center gap-4">
15-
<div v-for="author in resolvedAuthors" :key="author.name" class="flex items-center gap-2">
13+
<div v-for="author in authors" :key="author.name" class="flex items-center gap-2">
1614
<AuthorAvatar :author="author" size="md" disable-link />
1715
<div class="flex flex-col">
1816
<span class="text-sm font-medium text-fg">{{ author.name }}</span>
@@ -34,7 +32,7 @@ const { resolvedAuthors } = useBlueskyAuthorProfiles(props.authors)
3432
<div v-else class="flex items-center gap-2 min-w-0">
3533
<div class="flex items-center">
3634
<AuthorAvatar
37-
v-for="(author, index) in resolvedAuthors"
35+
v-for="(author, index) in authors"
3836
:key="author.name"
3937
:author="author"
4038
size="md"
@@ -43,7 +41,7 @@ const { resolvedAuthors } = useBlueskyAuthorProfiles(props.authors)
4341
/>
4442
</div>
4543
<span class="text-xs text-fg-muted font-mono truncate">
46-
{{ resolvedAuthors.map(a => a.name).join(', ') }}
44+
{{ authors.map(a => a.name).join(', ') }}
4745
</span>
4846
</div>
4947
</template>

app/components/BlogPostListCard.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<script setup lang="ts">
2-
import type { Author } from '#shared/schemas/blog'
2+
import type { ResolvedAuthor } from '#shared/schemas/blog'
33
44
defineProps<{
55
/** Authors of the blog post */
6-
authors: Author[]
6+
authors: ResolvedAuthor[]
77
/** Blog Title */
88
title: string
99
/** Tags such as OpenSource, Architecture, Community, etc. */

app/components/OgImage/BlogPost.vue

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<script setup lang="ts">
2-
import type { Author } from '#shared/schemas/blog'
2+
import type { ResolvedAuthor } from '#shared/schemas/blog'
33
44
const props = withDefaults(
55
defineProps<{
66
title: string
7-
authors?: Author[]
7+
authors?: ResolvedAuthor[]
88
date?: string
99
primaryColor?: string
1010
}>(),
@@ -15,8 +15,6 @@ const props = withDefaults(
1515
},
1616
)
1717
18-
const { resolvedAuthors } = useBlueskyAuthorProfiles(props.authors)
19-
2018
const formattedDate = computed(() => {
2119
if (!props.date) return ''
2220
try {
@@ -41,17 +39,17 @@ const getInitials = (name: string) =>
4139
.slice(0, 2)
4240
4341
const visibleAuthors = computed(() => {
44-
if (resolvedAuthors.value.length <= 3) return resolvedAuthors.value
45-
return resolvedAuthors.value.slice(0, MAX_VISIBLE_AUTHORS)
42+
if (props.authors.length <= 3) return props.authors
43+
return props.authors.slice(0, MAX_VISIBLE_AUTHORS)
4644
})
4745
4846
const extraCount = computed(() => {
49-
if (resolvedAuthors.value.length <= 3) return 0
50-
return resolvedAuthors.value.length - MAX_VISIBLE_AUTHORS
47+
if (props.authors.length <= 3) return 0
48+
return props.authors.length - MAX_VISIBLE_AUTHORS
5149
})
5250
5351
const formattedAuthorNames = computed(() => {
54-
const allNames = resolvedAuthors.value.map(a => a.name)
52+
const allNames = props.authors.map(a => a.name)
5553
if (allNames.length === 0) return ''
5654
if (allNames.length === 1) return allNames[0]
5755
if (allNames.length === 2) return `${allNames[0]} and ${allNames[1]}`
@@ -96,7 +94,7 @@ const formattedAuthorNames = computed(() => {
9694

9795
<!-- Authors -->
9896
<div
99-
v-if="resolvedAuthors.length"
97+
v-if="authors.length"
10098
class="flex items-center gap-4 self-start justify-start flex-nowrap"
10199
style="font-family: 'Geist', sans-serif"
102100
>

app/components/Package/Dependencies.vue

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,8 @@ const numberFormatter = useNumberFormatter()
218218
:key="peer.name"
219219
class="flex items-center justify-between py-1 text-sm gap-1 min-w-0"
220220
>
221-
<div class="flex items-center gap-1 min-w-0 flex-1">
222-
<LinkBase :to="packageRoute(peer.name)" class="block truncate" dir="ltr">
221+
<div class="flex items-center gap-2 min-w-0 flex-1">
222+
<LinkBase :to="packageRoute(peer.name)" class="block max-w-[70%] break-words" dir="ltr">
223223
{{ peer.name }}
224224
</LinkBase>
225225
<TagStatic v-if="peer.optional" :title="$t('package.dependencies.optional')">
@@ -228,7 +228,7 @@ const numberFormatter = useNumberFormatter()
228228
</div>
229229
<LinkBase
230230
:to="packageRoute(peer.name, peer.version)"
231-
class="block truncate max-w-[40%]"
231+
class="block truncate max-w-[30%]"
232232
:title="peer.version"
233233
dir="ltr"
234234
>
@@ -278,9 +278,9 @@ const numberFormatter = useNumberFormatter()
278278
optionalDepsExpanded ? undefined : 10,
279279
)"
280280
:key="dep"
281-
class="flex items-center justify-between py-1 text-sm gap-2"
281+
class="flex items-baseline justify-between py-1 text-sm gap-2"
282282
>
283-
<LinkBase :to="packageRoute(dep)" class="block truncate" dir="ltr">
283+
<LinkBase :to="packageRoute(dep)" class="block max-w-[80%] break-words" dir="ltr">
284284
{{ dep }}
285285
</LinkBase>
286286
<LinkBase

app/components/Package/Playgrounds.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const providerIcons: Record<string, string> = {
2121
'svelte-playground': 'i-simple-icons:svelte',
2222
'tailwind-playground': 'i-simple-icons:tailwindcss',
2323
'storybook': 'i-simple-icons:storybook',
24+
'marko-playground': 'i-simple-icons:marko',
2425
}
2526
2627
// Map provider id to color class
@@ -39,6 +40,7 @@ const providerColors: Record<string, string> = {
3940
'svelte-playground': 'text-provider-svelte',
4041
'tailwind-playground': 'text-provider-tailwind',
4142
'storybook': 'text-provider-storybook',
43+
'marko-playground': 'text-provider-marko',
4244
}
4345
4446
function getIcon(provider: string): string {

app/components/global/BlogPostWrapper.vue

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
<script setup lang="ts">
2-
import type { BlogPostFrontmatter } from '#shared/schemas/blog'
2+
import type { RawBlogPostFrontmatter } from '#shared/schemas/blog'
33
import { generateBlogTID } from '#shared/utils/atproto'
4+
import { posts } from '#blog/posts'
45
56
const props = defineProps<{
6-
frontmatter: BlogPostFrontmatter
7+
frontmatter: RawBlogPostFrontmatter
78
}>()
89
10+
const post = computed(() => posts.find(p => p.slug === props.frontmatter.slug))
11+
912
useSeoMeta({
1013
title: props.frontmatter.title,
1114
description: props.frontmatter.description || props.frontmatter.excerpt,
@@ -26,7 +29,7 @@ useHead({
2629
2730
defineOgImageComponent('BlogPost', {
2831
title: props.frontmatter.title,
29-
authors: props.frontmatter.authors,
32+
authors: post.value?.authors ?? [],
3033
date: props.frontmatter.date,
3134
})
3235
@@ -50,9 +53,9 @@ const blueskyPostUri = computed(() => blueskyLink.value?.postUri ?? null)
5053
</span>
5154
</div>
5255
</div>
53-
<div v-if="frontmatter.authors" class="mb-12 max-w-prose mx-auto">
56+
<div v-if="post?.authors" class="mb-12 max-w-prose mx-auto">
5457
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
55-
<AuthorList :authors="frontmatter.authors" variant="expanded" />
58+
<AuthorList :authors="post.authors" variant="expanded" />
5659
</div>
5760
</div>
5861
<article class="max-w-prose mx-auto p-2 prose dark:prose-invert">

i18n/locales/uk-UA.json

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
"trademark_disclaimer": "npm є зареєстрованою торговою маркою npm, Inc. Цей сайт не пов'язаний з npm, Inc.",
1414
"footer": {
1515
"about": "про проект",
16+
"blog": "Блог",
1617
"docs": "документація",
1718
"source": "код",
1819
"social": "соціальні мережі",
1920
"chat": "чат",
21+
"builders_chat": "розробники",
2022
"keyboard_shortcuts": "гарячі клавіші"
2123
},
2224
"shortcuts": {
@@ -63,7 +65,13 @@
6365
"org": "організація",
6466
"view_user_packages": "Переглянути пакети цього користувача",
6567
"view_org_packages": "Переглянути пакети цієї організації"
66-
}
68+
},
69+
"instant_search": "Миттєвий пошук",
70+
"instant_search_on": "увімкнено",
71+
"instant_search_off": "вимкнено",
72+
"instant_search_turn_on": "увімкнути",
73+
"instant_search_turn_off": "вимкнути",
74+
"instant_search_advisory": "{label} {state} — {action}"
6775
},
6876
"nav": {
6977
"main_navigation": "Головна",
@@ -77,6 +85,31 @@
7785
"links": "Посилання",
7886
"tap_to_search": "Натисніть для пошуку"
7987
},
88+
"blog": {
89+
"title": "Блог",
90+
"heading": "блог",
91+
"meta_description": "Думки та оновлення від спільноти npmx",
92+
"author": {
93+
"view_profile": "Переглянути профіль {name} у Bluesky"
94+
},
95+
"draft_badge": "Чернетка",
96+
"draft_banner": "Це неопублікована чернетка. Вона може бути неповною або містити неточності.",
97+
"atproto": {
98+
"view_on_bluesky": "Переглянути у Bluesky",
99+
"reply_on_bluesky": "Відповісти у Bluesky",
100+
"likes_on_bluesky": "Вподобайки у Bluesky",
101+
"like_or_reply_on_bluesky": "Вподобайте цей пост або залиште коментар у Bluesky",
102+
"no_comments_yet": "Коментарів поки немає.",
103+
"could_not_load_comments": "Не вдалося завантажити коментарі.",
104+
"comments": "Коментарі",
105+
"loading_comments": "Завантаження коментарів...",
106+
"updating": "Оновлення...",
107+
"reply_count": "{count} відповідь | {count} відповіді | {count} відповідей",
108+
"like_count": "{count} вподобайка | {count} вподобайки | {count} вподобайок",
109+
"repost_count": "{count} репост | {count} репости | {count} репостів",
110+
"more_replies": "ще {count} відповідь... | ще {count} відповіді... | ще {count} відповідей..."
111+
}
112+
},
80113
"settings": {
81114
"title": "параметри",
82115
"tagline": "налаштуйте ваше середовище npmx",
@@ -96,6 +129,8 @@
96129
"algolia": "Algolia",
97130
"algolia_description": "Використовує Algolia для швидшого пошуку, сторінок організацій та користувачів."
98131
},
132+
"instant_search": "Миттєвий пошук",
133+
"instant_search_description": "Переходить на сторінку пошуку та оновлює результати під час введення.",
99134
"relative_dates": "Відносні дати",
100135
"include_types": "Включити {'@'}types у встановлення",
101136
"include_types_description": "Додавайте пакет {'@'}types до команд встановлення для пакетів без типів",
@@ -122,6 +157,13 @@
122157
"edit_on_github": "Редагувати на GitHub",
123158
"view_guide": "Керівництво з перекладу"
124159
},
160+
"error": {
161+
"401": "Не авторизовано",
162+
"404": "Сторінку не знайдено",
163+
"500": "Внутрішня помилка сервера",
164+
"503": "Сервіс недоступний",
165+
"default": "Щось пішло не так"
166+
},
125167
"common": {
126168
"loading": "Завантаження...",
127169
"loading_more": "Завантаження ще...",
@@ -399,6 +441,8 @@
399441
"download_file": "Завантажити {fileType}",
400442
"toggle_annotator": "Перемкнути анотатор",
401443
"toggle_stack_mode": "Перемкнути режим стека",
444+
"open_options": "Відкрити параметри",
445+
"close_options": "Закрити параметри",
402446
"legend_estimation": "Оцінка",
403447
"no_data": "Дані недоступні",
404448
"y_axis_label": "{granularity} {facet}",
@@ -918,6 +962,11 @@
918962
"description": "Спілкуйтеся в чаті, ставте питання та діліться ідеями.",
919963
"cta": "Приєднатися до спільноти Discord"
920964
},
965+
"builders": {
966+
"title": "Допоможіть розвивати npmx",
967+
"description": "Приєднайтесь до розробників, що формують майбутнє npmx.",
968+
"cta": "Приєднатися до Discord для розробників"
969+
},
921970
"follow": {
922971
"title": "Залишайтеся в курсі",
923972
"description": "Дізнайтеся останні новини про npmx.",
@@ -1099,6 +1148,7 @@
10991148
"file_too_large": "Файл завеликий для порівняння",
11001149
"file_size_warning": "{size} перевищує ліміт 250 КБ для порівняння",
11011150
"compare_versions": "різниця",
1151+
"compare_versions_title": "Порівняти з останньою версією",
11021152
"summary": "Підсумок",
11031153
"deps_count": "{count} залежн.",
11041154
"dependencies": "Залежності",
@@ -1126,6 +1176,34 @@
11261176
"close_files_panel": "Закрити панель файлів",
11271177
"filter_files_label": "Фільтрувати файли за типом зміни"
11281178
},
1179+
"pds": {
1180+
"title": "npmx.social",
1181+
"meta_description": "Офіційний сервер особистих даних AT Protocol (PDS) для спільноти npmx.",
1182+
"join": {
1183+
"title": "Приєднатися до спільноти",
1184+
"description": "Незалежно від того, чи ви створюєте свій перший акаунт в атмосфері, чи мігруєте наявний — ви тут на своєму місці. Ви можете перенести поточний акаунт, не втрачаючи нікнейм, пости або підписників.",
1185+
"migrate": "Мігрувати за допомогою PDS MOOver"
1186+
},
1187+
"server": {
1188+
"title": "Деталі сервера",
1189+
"location_label": "Розташування:",
1190+
"location_value": "Нюрнберг, Німеччина",
1191+
"infrastructure_label": "Інфраструктура:",
1192+
"infrastructure_value": "Розміщено на Hetzner",
1193+
"privacy_label": "Конфіденційність:",
1194+
"privacy_value": "Підпадає під суворе законодавство ЄС про захист даних",
1195+
"learn_more": "Дізнайтесь, як npmx використовує Атмосферу"
1196+
},
1197+
"community": {
1198+
"title": "Хто тут є",
1199+
"description": "Деякі з {count} акаунтів, що вже вважають npmx.social своїм домом:",
1200+
"loading": "Завантаження спільноти PDS...",
1201+
"error": "Не вдалося завантажити спільноту PDS.",
1202+
"empty": "Немає учасників спільноти для відображення.",
1203+
"view_profile": "Переглянути профіль {handle}",
1204+
"new_accounts": "...та ще {count} нових в атмосфері"
1205+
}
1206+
},
11291207
"privacy_policy": {
11301208
"title": "політика конфіденційності",
11311209
"last_updated": "Останнє оновлення: {date}",

0 commit comments

Comments
 (0)