diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 00000000..b3a52671
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1 @@
+*.css
diff --git a/components/common/CommonPaginator.vue b/components/common/CommonPaginator.vue
index 20a8315b..bb742a2f 100644
--- a/components/common/CommonPaginator.vue
+++ b/components/common/CommonPaginator.vue
@@ -51,7 +51,7 @@ const { items, prevItems, update, state, endAnchor, error } = usePaginator(pagin
-
Loading...
+
{{ $t('state.loading') }}
diff --git a/components/nav/NavTitle.vue b/components/nav/NavTitle.vue
index 6efc5647..acb8d9cc 100644
--- a/components/nav/NavTitle.vue
+++ b/components/nav/NavTitle.vue
@@ -7,7 +7,7 @@ const sub = process.dev ? 'dev' : window.location.hostname.includes('deploy-prev
- Elk {{ sub }}
+ {{ $t('app_name') }} {{ sub }}
diff --git a/components/publish/PublishWidget.vue b/components/publish/PublishWidget.vue
index c3893251..342f2872 100644
--- a/components/publish/PublishWidget.vue
+++ b/components/publish/PublishWidget.vue
@@ -245,9 +245,9 @@ const { isOverDropZone } = useDropZone(dropZoneRef, onDrop)
:checked="visibility.value === draft.params.visibility"
@click="chooseVisibility(visibility.value)"
>
- {{ visibility.label }}
+ {{ $t(`visibility.${visibility.value}`) }}
- {{ visibility.description }}
+ {{ $t(`visibility.${visibility.value}_desc`) }}
diff --git a/components/status/StatusActions.vue b/components/status/StatusActions.vue
index 14f4db22..56e9c515 100644
--- a/components/status/StatusActions.vue
+++ b/components/status/StatusActions.vue
@@ -133,7 +133,7 @@ function editStatus() {
@@ -193,7 +193,7 @@ function editStatus() {
@@ -210,7 +210,7 @@ function editStatus() {
STATUS_VISIBILITIES.find(v => v.value === sta
:status="status"
:inline="false"
>
- (Edited)
+ {{ $t('state.edited') }}
·
-
+
diff --git a/components/user/UserSwitcher.vue b/components/user/UserSwitcher.vue
index 0fe22e95..12365410 100644
--- a/components/user/UserSwitcher.vue
+++ b/components/user/UserSwitcher.vue
@@ -33,17 +33,17 @@ const switchUser = (user: UserLogin) => {
-
-
+
-
- Sign out {{ getFullHandle(currentUser.account) }}
-
+ />
diff --git a/composables/masto.ts b/composables/masto.ts
index b415dd24..d1797d18 100644
--- a/composables/masto.ts
+++ b/composables/masto.ts
@@ -6,27 +6,19 @@ import { withoutProtocol } from 'ufo'
export const STATUS_VISIBILITIES = [
{
value: 'public',
- label: 'Public',
icon: 'i-ri:global-line',
- description: 'Visible for all',
},
{
value: 'unlisted',
- label: 'Unlisted',
icon: 'i-ri:lock-unlock-line',
- description: 'Visible for all, but opted-out of discovery features',
},
{
value: 'private',
- label: 'Followers only',
icon: 'i-ri:lock-line',
- description: 'Visible for followers only',
},
{
value: 'direct',
- label: 'Mentioned people only',
icon: 'i-ri:at-line',
- description: 'Visible for mentioned users only',
},
] as const
diff --git a/composables/statusDrafts.ts b/composables/statusDrafts.ts
index f6ab9a5a..923fba07 100644
--- a/composables/statusDrafts.ts
+++ b/composables/statusDrafts.ts
@@ -24,11 +24,12 @@ export const currentUserDrafts = computed(() => {
})
export function getDefaultDraft(options: Partial> = {}): Draft {
+ const { t } = useI18n()
const {
status = '',
inReplyToId,
visibility = 'public',
- placeholder = 'What is on your mind?',
+ placeholder = t('placeholder.default_1'),
attachments = [],
} = options
return {
@@ -52,11 +53,12 @@ export function getDraftFromStatus(status: Status, text?: null | string): Draft
}
export function getReplyDraft(status: Status) {
+ const { t } = useI18n()
return {
key: `reply-${status.id}`,
draft: () => getDefaultDraft({
inReplyToId: status!.id,
- placeholder: `Reply to ${status?.account ? getDisplayName(status.account) : 'this thread'}`,
+ placeholder: t('placeholder.reply_to_account', [status?.account ? getDisplayName(status.account) : t('placeholder.the_thread')]),
visibility: status.visibility,
}),
}
diff --git a/composables/time.ts b/composables/time.ts
index ce059cf3..d0097033 100644
--- a/composables/time.ts
+++ b/composables/time.ts
@@ -4,7 +4,8 @@ export const useFormattedDateTime = (
value: MaybeComputedRef,
options: Intl.DateTimeFormatOptions = { dateStyle: 'long', timeStyle: 'medium' },
) => {
- const formatter = Intl.DateTimeFormat(undefined, options)
+ const { locale } = useI18n()
+ const formatter = Intl.DateTimeFormat(locale.value, options)
return computed(() => {
const v = resolveUnref(value)
return v ? formatter.format(new Date(v)) : ''
diff --git a/locales/en-US.json b/locales/en-US.json
index 731bfae9..d866c4aa 100644
--- a/locales/en-US.json
+++ b/locales/en-US.json
@@ -15,12 +15,18 @@
"unfollow": "Unfollow"
},
"action": {
+ "bookmark": "Bookmark",
+ "boost": "Boost",
"compose": "Compose",
"enter_app": "Enter App",
+ "favourite": "Favourite",
+ "more": "More",
"publish": "Publish!",
+ "reply": "Reply",
"save_changes": "Save changes",
"sign_in": "Sign in"
},
+ "app_name": "Elk",
"command": {
"activate": "Activate",
"complete": "Complete"
@@ -39,13 +45,21 @@
"menu": {
"block_account": "Block {0}",
"block_domain": "Block domain {0}",
+ "copy_link_to_post": "Copy link to this post",
+ "delete": "Delete",
+ "delete_and_redraft": "Delete & re-draft",
"direct_message_account": "Direct message {0}",
+ "edit": "Edit",
"mention_account": "Mention {0}",
"mute_account": "Mute {0}",
"open_in_original_site": "Open in original site",
+ "pin_on_profile": "Pin on profile",
+ "show_untranslated": "Show untranslated",
+ "translate_post": "Translate post",
"unblock_account": "Unblock {0}",
"unblock_domain": "Unblock domain {0}",
- "unmute_account": "Unmute {0}"
+ "unmute_account": "Unmute {0}",
+ "unpin_on_profile": "Unpin on profile"
},
"nav_footer": {
"select_feature_flags": "Toggle Feature Flags",
@@ -75,12 +89,21 @@
"request_to_follow": "requested to follow you",
"update_status": "updated their status"
},
+ "placeholder": {
+ "default_1": "What is on your mind?",
+ "reply_to_account": "Reply to {0}",
+ "the_thread": "the thread"
+ },
"state": {
+ "edited": "(Edited)",
"editing": "Editing",
+ "loading": "Loading...",
"uploading": "Uploading..."
},
"tab": {
"media": "Media",
+ "notifications_all": "All",
+ "notifications_mention": "Mention",
"posts": "Posts",
"posts_with_replies": "Posts & Replies"
},
@@ -96,5 +119,19 @@
"add_media": "Add images, a video or an audio file",
"change_content_visibility": "Change content visibility",
"toggle_code_block": "Toggle code block"
+ },
+ "user": {
+ "add_existing": "Add an existing account",
+ "sign_out_account": "Sign out {0}"
+ },
+ "visibility": {
+ "direct": "Direct",
+ "direct_desc": "Visible for mentioned users only",
+ "private": "Followers only",
+ "private_desc": "Visible for followers only",
+ "public": "Public",
+ "public_desc": "Visible for all",
+ "unlisted": "Unlisted",
+ "unlisted_desc": "Visible for all, but opted-out of discovery features"
}
}
diff --git a/locales/es-ES.json b/locales/es-ES.json
index 6a634f2c..cf1114de 100644
--- a/locales/es-ES.json
+++ b/locales/es-ES.json
@@ -1,94 +1,93 @@
{
- "account": {
- "blocked_domains": "Dominios bloqueados",
- "blocked_users": "Usuarios bloqueados",
- "favourites": "Favoritos",
- "follow": "Seguir",
- "follow_back": "Seguir de vuelta",
- "follow_requested": "Enviado",
- "followers_count": "{0} Seguidores",
- "following_count": "{0} Siguiendo",
- "follows_you": "Te sigue",
- "muted_users": "Usuarios silenciados",
- "pinned": "Pinned",
- "posts_count": "{0} Posts",
- "unfollow": "Dejar de seguir"
- },
- "action": {
- "compose": "Componer",
- "enter_app": "Entrar",
- "publish": "¡Publicar!",
- "save_changes": "Guardar",
- "sign_in": "Iniciar sesión"
- },
- "common": {
- "end_of_list": "Final",
- "error": "ERROR",
- "not_found": "404 No Encontrado"
- },
- "feature_flag": {
- "virtual_scroll": "Virtual Scrolling"
- },
- "menu": {
- "block_account": "Bloqueados {0}",
- "block_domain": "Dominios bloqueado/s {0}",
- "direct_message_account": "Mensaje Directo {0}",
- "mention_account": "Mención {0}",
- "mute_account": "Silenciados {0}",
- "open_in_original_site": "Abrir original",
- "unblock_account": "Desbloqueado/s {0}",
- "unblock_domain": "Dominios desbloqueados {0}",
- "unmute_account": "No silenciados {0}"
- },
- "nav_footer": {
- "select_feature_flags": "Cambiar Feature Flags",
- "select_language": "Seleccionar Lenguaje",
- "toggle_theme": "Cambiar Tema",
- "zen_mode": "Modo Zen"
- },
- "nav_side": {
- "bookmarks": "Bookmarks",
- "conversations": "Conversaciones",
- "explore": "Explorar",
- "favourites": "Favoritos",
- "federated": "Federados",
- "home": "Home",
- "local": "Local",
- "notifications": "Notificaciones",
- "profile": "Perfil"
- },
- "nav_user": {
- "sign_in_desc": "Inicia sesión para seguir perfiles o hashtags, marcar como favorito, compartir and responder a publicaciones, or interactuar desde tu usuario con un servidor diferente."
- },
- "notification": {
- "favourited_post": "tu post fue marcado como favorito",
- "followed_you": "te ha seguido",
- "missing_type": "MISSING notification.type:",
- "reblogged_post": "reblogged your post",
- "request_to_follow": "ha solicitado seguirte",
- "update_status": "ha actualizado su estado"
- },
- "state": {
- "editing": "Editando",
- "uploading": "Subiendo..."
- },
- "tab": {
- "media": "Media",
- "posts": "Publicaciones",
- "posts_with_replies": "Publicaciones y respuestas"
- },
- "timeline": {
- "show_new_items": "Muestra {0} nuevos artículos"
- },
- "title": {
- "federated_timeline": "Timeline Federada",
- "local_timeline": "Timeline Local"
- },
- "tooltip": {
- "add_content_warning": "Añadir advertencia",
- "add_media": "Añadir imágenes, arhivos de video o audio",
- "change_content_visibility": "Cambiar visibilidad",
- "toggle_code_block": "Toggle code block"
- }
+ "account": {
+ "blocked_domains": "Dominios bloqueados",
+ "blocked_users": "Usuarios bloqueados",
+ "favourites": "Favoritos",
+ "follow": "Seguir",
+ "follow_back": "Seguir de vuelta",
+ "follow_requested": "Enviado",
+ "followers_count": "{0} Seguidores",
+ "following_count": "{0} Siguiendo",
+ "follows_you": "Te sigue",
+ "muted_users": "Usuarios silenciados",
+ "pinned": "Pinned",
+ "posts_count": "{0} Posts",
+ "unfollow": "Dejar de seguir"
+ },
+ "action": {
+ "compose": "Componer",
+ "enter_app": "Entrar",
+ "publish": "¡Publicar!",
+ "save_changes": "Guardar",
+ "sign_in": "Iniciar sesión"
+ },
+ "common": {
+ "end_of_list": "Final",
+ "error": "ERROR",
+ "not_found": "404 No Encontrado"
+ },
+ "feature_flag": {
+ "virtual_scroll": "Virtual Scrolling"
+ },
+ "menu": {
+ "block_account": "Bloqueados {0}",
+ "block_domain": "Dominios bloqueado/s {0}",
+ "direct_message_account": "Mensaje Directo {0}",
+ "mention_account": "Mención {0}",
+ "mute_account": "Silenciados {0}",
+ "open_in_original_site": "Abrir original",
+ "unblock_account": "Desbloqueado/s {0}",
+ "unblock_domain": "Dominios desbloqueados {0}",
+ "unmute_account": "No silenciados {0}"
+ },
+ "nav_footer": {
+ "select_feature_flags": "Cambiar Feature Flags",
+ "select_language": "Seleccionar Lenguaje",
+ "toggle_theme": "Cambiar Tema",
+ "zen_mode": "Modo Zen"
+ },
+ "nav_side": {
+ "bookmarks": "Bookmarks",
+ "conversations": "Conversaciones",
+ "explore": "Explorar",
+ "favourites": "Favoritos",
+ "federated": "Federados",
+ "home": "Home",
+ "local": "Local",
+ "notifications": "Notificaciones",
+ "profile": "Perfil"
+ },
+ "nav_user": {
+ "sign_in_desc": "Inicia sesión para seguir perfiles o hashtags, marcar como favorito, compartir and responder a publicaciones, or interactuar desde tu usuario con un servidor diferente."
+ },
+ "notification": {
+ "favourited_post": "tu post fue marcado como favorito",
+ "followed_you": "te ha seguido",
+ "missing_type": "MISSING notification.type:",
+ "reblogged_post": "reblogged your post",
+ "request_to_follow": "ha solicitado seguirte",
+ "update_status": "ha actualizado su estado"
+ },
+ "state": {
+ "editing": "Editando",
+ "uploading": "Subiendo..."
+ },
+ "tab": {
+ "media": "Media",
+ "posts": "Publicaciones",
+ "posts_with_replies": "Publicaciones y respuestas"
+ },
+ "timeline": {
+ "show_new_items": "Muestra {0} nuevos artículos"
+ },
+ "title": {
+ "federated_timeline": "Timeline Federada",
+ "local_timeline": "Timeline Local"
+ },
+ "tooltip": {
+ "add_content_warning": "Añadir advertencia",
+ "add_media": "Añadir imágenes, arhivos de video o audio",
+ "change_content_visibility": "Cambiar visibilidad",
+ "toggle_code_block": "Toggle code block"
}
-
\ No newline at end of file
+}
diff --git a/locales/ja-JP.json b/locales/ja-JP.json
index caef5903..17739dec 100644
--- a/locales/ja-JP.json
+++ b/locales/ja-JP.json
@@ -78,12 +78,11 @@
"posts_with_replies": "投稿と返信"
},
"timeline": {
- "name": "タイムライン",
"show_new_items": "{0}件の新しい投稿"
},
"title": {
- "federated_timeline": "@:nav_side.federated @:timeline.name",
- "local_timeline": "@:nav_side.local @:timeline.name"
+ "federated_timeline": "連合タイムライン",
+ "local_timeline": "ローカルタイムライン"
},
"tooltip": {
"add_content_warning": "警告を追加",
diff --git a/locales/zh-CN.json b/locales/zh-CN.json
index 0409ba64..46473311 100644
--- a/locales/zh-CN.json
+++ b/locales/zh-CN.json
@@ -15,30 +15,51 @@
"unfollow": "取消关注"
},
"action": {
+ "bookmark": "收藏",
+ "boost": "转发",
"compose": "撰写",
"enter_app": "进入应用",
+ "favourite": "喜欢",
+ "more": "更多",
"publish": "发布!",
+ "reply": "回复",
"save_changes": "保存更改",
"sign_in": "登录"
},
+ "app_name": "鹿鸣",
+ "command": {
+ "activate": "执行",
+ "complete": "完成"
+ },
"common": {
"end_of_list": "列表到底啦",
"error": "错误",
"not_found": "无法找到相关内容"
},
+ "error": {
+ "account_not_found": "未找到用户 {0}"
+ },
"feature_flag": {
"virtual_scroll": "虚拟滚动"
},
"menu": {
"block_account": "拉黑 {0}",
"block_domain": "拉黑域名 {0}",
+ "copy_link_to_post": "复制这篇文章的链接",
+ "delete": "删除",
+ "delete_and_redraft": "删除并重新编辑",
"direct_message_account": "私信 {0}",
+ "edit": "编辑",
"mention_account": "提及 {0}",
"mute_account": "屏蔽 {0}",
"open_in_original_site": "从源站打开",
+ "pin_on_profile": "钉选在个人资料上",
+ "show_untranslated": "显示原文",
+ "translate_post": "翻译帖子",
"unblock_account": "解除拉黑 {0}",
"unblock_domain": "解除拉黑域名 {0}",
- "unmute_account": "解除屏蔽 {0}"
+ "unmute_account": "解除屏蔽 {0}",
+ "unpin_on_profile": "取消钉选"
},
"nav_footer": {
"select_feature_flags": "功能开关",
@@ -68,12 +89,21 @@
"request_to_follow": "请求关注你",
"update_status": "更新了他们的状态"
},
+ "placeholder": {
+ "default_1": "在想些什么?",
+ "reply_to_account": "回复 {0}",
+ "the_thread": "这个帖子"
+ },
"state": {
+ "edited": "(已编辑)",
"editing": "编辑中",
+ "loading": "加载中...",
"uploading": "上传中..."
},
"tab": {
"media": "媒体",
+ "notifications_all": "全部",
+ "notifications_mention": "提及",
"posts": "帖文",
"posts_with_replies": "帖文与留言"
},
@@ -89,5 +119,19 @@
"add_media": "添加图片、视频或者音频文件",
"change_content_visibility": "修改内容是否可见",
"toggle_code_block": "切换代码块"
+ },
+ "user": {
+ "add_existing": "添加现有帐户",
+ "sign_out_account": "登出 {0}"
+ },
+ "visibility": {
+ "direct": "私信",
+ "direct_desc": "仅对提及的用户可见",
+ "private": "仅限关注者",
+ "private_desc": "仅关注者可见",
+ "public": "公开",
+ "public_desc": "所有人可见",
+ "unlisted": "不列出",
+ "unlisted_desc": "对所有人可见,但不出现在公共时间线上"
}
}
diff --git a/pages/notifications.vue b/pages/notifications.vue
index d8ab90b6..ff1476f8 100644
--- a/pages/notifications.vue
+++ b/pages/notifications.vue
@@ -7,12 +7,25 @@ definePageMeta({
const { t } = useI18n()
-const tabNames = ['All', 'Mentions'] as const
-const tab = $(useLocalStorage(STORAGE_KEY_NOTIFY_TAB, 'All'))
+const paginatorAll = useMasto().notifications.getIterator()
+const paginatorMention = useMasto().notifications.getIterator({ types: ['mention'] })
-const paginator = $computed(() => {
- return useMasto().notifications.getIterator(tab === 'All' ? undefined : { types: ['mention'] })
-})
+const tabs = $computed(() => [
+ {
+ name: 'all',
+ display: t('tab.notifications_all'),
+ paginator: paginatorAll,
+ },
+ {
+ name: 'mention',
+ display: t('tab.notifications_mention'),
+ paginator: paginatorMention,
+ },
+] as const)
+
+// Don't use local storage because it is better to default to Posts every time you visit a user's profile.
+const tab = $ref(tabs[0].name)
+const paginator = $computed(() => tabs.find(t => t.name === tab)!.paginator)
useHeadFixed({
title: () => t('nav_side.notifications'),
@@ -29,7 +42,7 @@ useHeadFixed({
-
+