aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/emoji_reactions/emoji_reactions.js4
-rw-r--r--src/components/emoji_reactions/emoji_reactions.vue65
-rw-r--r--src/components/post_status_form/post_status_form.js22
-rw-r--r--src/components/react_button/react_button.js5
-rw-r--r--src/components/settings_modal/tabs/notifications_tab.vue34
-rw-r--r--src/components/status/status.js30
-rw-r--r--src/components/status/status.vue59
-rw-r--r--src/components/user_card/user_card.vue1
-rw-r--r--src/components/user_list_popover/user_list_popover.js18
-rw-r--r--src/components/user_list_popover/user_list_popover.vue71
-rw-r--r--src/i18n/ca.json8
-rw-r--r--src/i18n/cs.json5
-rw-r--r--src/i18n/de.json22
-rw-r--r--src/i18n/en.json8
-rw-r--r--src/i18n/eo.json306
-rw-r--r--src/i18n/es.json5
-rw-r--r--src/i18n/et.json5
-rw-r--r--src/i18n/eu.json33
-rw-r--r--src/i18n/fi.json5
-rw-r--r--src/i18n/fr.json10
-rw-r--r--src/i18n/ga.json6
-rw-r--r--src/i18n/he.json18
-rw-r--r--src/i18n/it.json12
-rw-r--r--src/i18n/ja_easy.json79
-rw-r--r--src/i18n/ja_pedantic.json5
-rw-r--r--src/i18n/nb.json5
-rw-r--r--src/i18n/nl.json5
-rw-r--r--src/i18n/oc.json7
-rw-r--r--src/i18n/pl.json45
-rw-r--r--src/i18n/ru.json6
-rw-r--r--src/i18n/zh.json5
-rw-r--r--src/modules/api.js2
-rw-r--r--src/modules/chats.js15
-rw-r--r--src/modules/statuses.js47
-rw-r--r--src/services/chat_utils/chat_utils.js19
-rw-r--r--src/services/desktop_notification_utils/desktop_notification_utils.js9
-rw-r--r--src/services/entity_normalizer/entity_normalizer.service.js1
-rw-r--r--src/services/notification_utils/notification_utils.js40
-rw-r--r--src/services/notifications_fetcher/notifications_fetcher.service.js2
-rw-r--r--src/services/timeline_fetcher/timeline_fetcher.service.js4
40 files changed, 644 insertions, 404 deletions
diff --git a/src/components/emoji_reactions/emoji_reactions.js b/src/components/emoji_reactions/emoji_reactions.js
index ae7f53be..bb11b840 100644
--- a/src/components/emoji_reactions/emoji_reactions.js
+++ b/src/components/emoji_reactions/emoji_reactions.js
@@ -1,5 +1,5 @@
import UserAvatar from '../user_avatar/user_avatar.vue'
-import Popover from '../popover/popover.vue'
+import UserListPopover from '../user_list_popover/user_list_popover.vue'
const EMOJI_REACTION_COUNT_CUTOFF = 12
@@ -7,7 +7,7 @@ const EmojiReactions = {
name: 'EmojiReactions',
components: {
UserAvatar,
- Popover
+ UserListPopover
},
props: ['status'],
data: () => ({
diff --git a/src/components/emoji_reactions/emoji_reactions.vue b/src/components/emoji_reactions/emoji_reactions.vue
index bac4c605..2f14b5b2 100644
--- a/src/components/emoji_reactions/emoji_reactions.vue
+++ b/src/components/emoji_reactions/emoji_reactions.vue
@@ -1,44 +1,11 @@
<template>
<div class="emoji-reactions">
- <Popover
+ <UserListPopover
v-for="(reaction) in emojiReactions"
:key="reaction.name"
- trigger="hover"
- placement="top"
- :offset="{ y: 5 }"
+ :users="accountsForEmoji[reaction.name]"
>
- <div
- slot="content"
- class="reacted-users"
- >
- <div v-if="accountsForEmoji[reaction.name].length">
- <div
- v-for="(account) in accountsForEmoji[reaction.name]"
- :key="account.id"
- class="reacted-user"
- >
- <UserAvatar
- :user="account"
- class="avatar-small"
- :compact="true"
- />
- <div class="reacted-user-names">
- <!-- eslint-disable vue/no-v-html -->
- <span
- class="reacted-user-name"
- v-html="account.name_html"
- />
- <!-- eslint-enable vue/no-v-html -->
- <span class="reacted-user-screen-name">{{ account.screen_name }}</span>
- </div>
- </div>
- </div>
- <div v-else>
- <i class="icon-spin4 animate-spin" />
- </div>
- </div>
<button
- slot="trigger"
class="emoji-reaction btn btn-default"
:class="{ 'picked-reaction': reactedWith(reaction.name), 'not-clickable': !loggedIn }"
@click="emojiOnClick(reaction.name, $event)"
@@ -47,7 +14,7 @@
<span class="reaction-emoji">{{ reaction.name }}</span>
<span>{{ reaction.count }}</span>
</button>
- </Popover>
+ </UserListPopover>
<a
v-if="tooManyReactions"
class="emoji-reaction-expand faint"
@@ -69,32 +36,6 @@
flex-wrap: wrap;
}
-.reacted-users {
- padding: 0.5em;
-}
-
-.reacted-user {
- padding: 0.25em;
- display: flex;
- flex-direction: row;
-
- .reacted-user-names {
- display: flex;
- flex-direction: column;
- margin-left: 0.5em;
- min-width: 5em;
-
- img {
- width: 1em;
- height: 1em;
- }
- }
-
- .reacted-user-screen-name {
- font-size: 9px;
- }
-}
-
.emoji-reaction {
padding: 0 0.5em;
margin-right: 0.5em;
diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
index c70c2232..e7094bec 100644
--- a/src/components/post_status_form/post_status_form.js
+++ b/src/components/post_status_form/post_status_form.js
@@ -27,6 +27,11 @@ const buildMentionsString = ({ user, attentions = [] }, currentUser) => {
return mentions.length > 0 ? mentions.join(' ') + ' ' : ''
}
+// Converts a string with px to a number like '2px' -> 2
+const pxStringToNumber = (str) => {
+ return Number(str.substring(0, str.length - 2))
+}
+
const PostStatusForm = {
props: [
'replyTo',
@@ -433,7 +438,7 @@ const PostStatusForm = {
* scroll is different for `Window` and `Element`s
*/
const bottomBottomPaddingStr = window.getComputedStyle(bottomRef)['padding-bottom']
- const bottomBottomPadding = Number(bottomBottomPaddingStr.substring(0, bottomBottomPaddingStr.length - 2))
+ const bottomBottomPadding = pxStringToNumber(bottomBottomPaddingStr)
const scrollerRef = this.$el.closest('.sidebar-scroller') ||
this.$el.closest('.post-form-modal-view') ||
@@ -442,10 +447,12 @@ const PostStatusForm = {
// Getting info about padding we have to account for, removing 'px' part
const topPaddingStr = window.getComputedStyle(target)['padding-top']
const bottomPaddingStr = window.getComputedStyle(target)['padding-bottom']
- const topPadding = Number(topPaddingStr.substring(0, topPaddingStr.length - 2))
- const bottomPadding = Number(bottomPaddingStr.substring(0, bottomPaddingStr.length - 2))
+ const topPadding = pxStringToNumber(topPaddingStr)
+ const bottomPadding = pxStringToNumber(bottomPaddingStr)
const vertPadding = topPadding + bottomPadding
+ const oldHeight = pxStringToNumber(target.style.height)
+
/* Explanation:
*
* https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight
@@ -474,8 +481,13 @@ const PostStatusForm = {
// BEGIN content size update
target.style.height = 'auto'
- const heightWithoutPadding = target.scrollHeight - vertPadding
- const newHeight = this.maxHeight ? Math.min(heightWithoutPadding, this.maxHeight) : heightWithoutPadding
+ const heightWithoutPadding = Math.floor(target.scrollHeight - vertPadding)
+ let newHeight = this.maxHeight ? Math.min(heightWithoutPadding, this.maxHeight) : heightWithoutPadding
+ // This is a bit of a hack to combat target.scrollHeight being different on every other input
+ // on some browsers for whatever reason. Don't change the height if difference is 1px or less.
+ if (Math.abs(newHeight - oldHeight) <= 1) {
+ newHeight = oldHeight
+ }
target.style.height = `${newHeight}px`
this.$emit('resize', newHeight)
// END content size update
diff --git a/src/components/react_button/react_button.js b/src/components/react_button/react_button.js
index f0931446..abcf0455 100644
--- a/src/components/react_button/react_button.js
+++ b/src/components/react_button/react_button.js
@@ -28,7 +28,10 @@ const ReactButton = {
},
emojis () {
if (this.filterWord !== '') {
- return this.$store.state.instance.emoji.filter(emoji => emoji.displayText.includes(this.filterWord))
+ const filterWordLowercase = this.filterWord.toLowerCase()
+ return this.$store.state.instance.emoji.filter(emoji =>
+ emoji.displayText.toLowerCase().includes(filterWordLowercase)
+ )
}
return this.$store.state.instance.emoji || []
},
diff --git a/src/components/settings_modal/tabs/notifications_tab.vue b/src/components/settings_modal/tabs/notifications_tab.vue
index b7a3cb37..86eed3f5 100644
--- a/src/components/settings_modal/tabs/notifications_tab.vue
+++ b/src/components/settings_modal/tabs/notifications_tab.vue
@@ -2,38 +2,18 @@
<div :label="$t('settings.notifications')">
<div class="setting-item">
<h2>{{ $t('settings.notification_setting_filters') }}</h2>
- <div class="select-multiple">
- <span class="label">{{ $t('settings.notification_setting') }}</span>
- <ul class="option-list">
- <li>
- <Checkbox v-model="notificationSettings.follows">
- {{ $t('settings.notification_setting_follows') }}
- </Checkbox>
- </li>
- <li>
- <Checkbox v-model="notificationSettings.followers">
- {{ $t('settings.notification_setting_followers') }}
- </Checkbox>
- </li>
- <li>
- <Checkbox v-model="notificationSettings.non_follows">
- {{ $t('settings.notification_setting_non_follows') }}
- </Checkbox>
- </li>
- <li>
- <Checkbox v-model="notificationSettings.non_followers">
- {{ $t('settings.notification_setting_non_followers') }}
- </Checkbox>
- </li>
- </ul>
- </div>
+ <p>
+ <Checkbox v-model="notificationSettings.block_from_strangers">
+ {{ $t('settings.notification_setting_block_from_strangers') }}
+ </Checkbox>
+ </p>
</div>
<div class="setting-item">
<h2>{{ $t('settings.notification_setting_privacy') }}</h2>
<p>
- <Checkbox v-model="notificationSettings.privacy_option">
- {{ $t('settings.notification_setting_privacy_option') }}
+ <Checkbox v-model="notificationSettings.hide_notification_contents">
+ {{ $t('settings.notification_setting_hide_notification_contents') }}
</Checkbox>
</p>
</div>
diff --git a/src/components/status/status.js b/src/components/status/status.js
index ad0b72a9..d263da68 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -9,6 +9,7 @@ import AvatarList from '../avatar_list/avatar_list.vue'
import Timeago from '../timeago/timeago.vue'
import StatusContent from '../status_content/status_content.vue'
import StatusPopover from '../status_popover/status_popover.vue'
+import UserListPopover from '../user_list_popover/user_list_popover.vue'
import EmojiReactions from '../emoji_reactions/emoji_reactions.vue'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
@@ -18,6 +19,21 @@ import { mapGetters, mapState } from 'vuex'
const Status = {
name: 'Status',
+ components: {
+ FavoriteButton,
+ ReactButton,
+ RetweetButton,
+ ExtraButtons,
+ PostStatusForm,
+ UserCard,
+ UserAvatar,
+ AvatarList,
+ Timeago,
+ StatusPopover,
+ UserListPopover,
+ EmojiReactions,
+ StatusContent
+ },
props: [
'statusoid',
'expandable',
@@ -197,20 +213,6 @@ const Status = {
currentUser: state => state.users.currentUser
})
},
- components: {
- FavoriteButton,
- ReactButton,
- RetweetButton,
- ExtraButtons,
- PostStatusForm,
- UserCard,
- UserAvatar,
- AvatarList,
- Timeago,
- StatusPopover,
- EmojiReactions,
- StatusContent
- },
methods: {
visibilityIcon (visibility) {
switch (visibility) {
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index f6b5dd6f..e1e56ec9 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -72,7 +72,10 @@
:user="statusoid.user"
/>
<div class="media-body faint">
- <span class="user-name">
+ <span
+ class="user-name"
+ :title="retweeter"
+ >
<router-link
v-if="retweeterHtml"
:to="retweeterProfileLink"
@@ -129,20 +132,28 @@
<h4
v-if="status.user.name_html"
class="user-name"
+ :title="status.user.name"
v-html="status.user.name_html"
/>
<h4
v-else
class="user-name"
+ :title="status.user.name"
>
{{ status.user.name }}
</h4>
<router-link
class="account-name"
+ :title="status.user.screen_name"
:to="userProfileLink"
>
{{ status.user.screen_name }}
</router-link>
+ <img
+ class="status-favicon"
+ v-if="!!(status.user && status.user.favicon)"
+ :src="status.user.favicon"
+ >
</div>
<span class="heading-right">
@@ -222,7 +233,10 @@
>
<span class="reply-to-text">{{ $t('status.reply_to') }}</span>
</span>
- <router-link :to="replyProfileLink">
+ <router-link
+ :title="replyToName"
+ :to="replyProfileLink"
+ >
{{ replyToName }}
</router-link>
<span
@@ -265,24 +279,30 @@
class="favs-repeated-users"
>
<div class="stats">
- <div
+ <UserListPopover
v-if="statusFromGlobalRepository.rebloggedBy && statusFromGlobalRepository.rebloggedBy.length > 0"
- class="stat-count"
+ :users="statusFromGlobalRepository.rebloggedBy"
>
- <a class="stat-title">{{ $t('status.repeats') }}</a>
- <div class="stat-number">
- {{ statusFromGlobalRepository.rebloggedBy.length }}
+ <div class="stat-count">
+ <a class="stat-title">{{ $t('status.repeats') }}</a>
+ <div class="stat-number">
+ {{ statusFromGlobalRepository.rebloggedBy.length }}
+ </div>
</div>
- </div>
- <div
+ </UserListPopover>
+ <UserListPopover
v-if="statusFromGlobalRepository.favoritedBy && statusFromGlobalRepository.favoritedBy.length > 0"
- class="stat-count"
+ :users="statusFromGlobalRepository.favoritedBy"
>
- <a class="stat-title">{{ $t('status.favorites') }}</a>
- <div class="stat-number">
- {{ statusFromGlobalRepository.favoritedBy.length }}
+ <div
+ class="stat-count"
+ >
+ <a class="stat-title">{{ $t('status.favorites') }}</a>
+ <div class="stat-number">
+ {{ statusFromGlobalRepository.favoritedBy.length }}
+ </div>
</div>
- </div>
+ </UserListPopover>
<div class="avatar-row">
<AvatarList :users="combinedFavsAndRepeatsUsers" />
</div>
@@ -428,6 +448,12 @@ $status-margin: 0.75em;
}
}
+ .status-favicon {
+ height: 18px;
+ width: 18px;
+ margin-right: 0.4em;
+ }
+
.media-heading {
padding: 0;
vertical-align: bottom;
@@ -722,6 +748,11 @@ $status-margin: 0.75em;
.stat-count {
margin-right: $status-margin;
+ user-select: none;
+
+ &:hover .stat-title {
+ text-decoration: underline;
+ }
.stat-title {
color: var(--faint, $fallback--faint);
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 9529d7f6..75db5db1 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -66,6 +66,7 @@
<div class="bottom-line">
<router-link
class="user-screen-name"
+ :title="user.screen_name"
:to="userProfileLink(user)"
>
@{{ user.screen_name }}
diff --git a/src/components/user_list_popover/user_list_popover.js b/src/components/user_list_popover/user_list_popover.js
new file mode 100644
index 00000000..b60f2c4c
--- /dev/null
+++ b/src/components/user_list_popover/user_list_popover.js
@@ -0,0 +1,18 @@
+
+const UserListPopover = {
+ name: 'UserListPopover',
+ props: [
+ 'users'
+ ],
+ components: {
+ Popover: () => import('../popover/popover.vue'),
+ UserAvatar: () => import('../user_avatar/user_avatar.vue')
+ },
+ computed: {
+ usersCapped () {
+ return this.users.slice(0, 16)
+ }
+ }
+}
+
+export default UserListPopover
diff --git a/src/components/user_list_popover/user_list_popover.vue b/src/components/user_list_popover/user_list_popover.vue
new file mode 100644
index 00000000..185c73ca
--- /dev/null
+++ b/src/components/user_list_popover/user_list_popover.vue
@@ -0,0 +1,71 @@
+<template>
+ <Popover
+ trigger="hover"
+ placement="top"
+ :offset="{ y: 5 }"
+ >
+ <template slot="trigger">
+ <slot />
+ </template>
+ <div
+ slot="content"
+ class="user-list-popover"
+ >
+ <div v-if="users.length">
+ <div
+ v-for="(user) in usersCapped"
+ :key="user.id"
+ class="user-list-row"
+ >
+ <UserAvatar
+ :user="user"
+ class="avatar-small"
+ :compact="true"
+ />
+ <div class="user-list-names">
+ <!-- eslint-disable vue/no-v-html -->
+ <span v-html="user.name_html" />
+ <!-- eslint-enable vue/no-v-html -->
+ <span class="user-list-screen-name">{{ user.screen_name }}</span>
+ </div>
+ </div>
+ </div>
+ <div v-else>
+ <i class="icon-spin4 animate-spin" />
+ </div>
+ </div>
+ </Popover>
+</template>
+
+<script src="./user_list_popover.js" ></script>
+
+<style lang="scss">
+@import '../../_variables.scss';
+
+.user-list-popover {
+ padding: 0.5em;
+
+ .user-list-row {
+ padding: 0.25em;
+ display: flex;
+ flex-direction: row;
+
+ .user-list-names {
+ display: flex;
+ flex-direction: column;
+ margin-left: 0.5em;
+ min-width: 5em;
+
+ img {
+ width: 1em;
+ height: 1em;
+ }
+ }
+
+ .user-list-screen-name {
+ font-size: 9px;
+ }
+ }
+}
+
+</style>
diff --git a/src/i18n/ca.json b/src/i18n/ca.json
index c91fc073..f2bcdd06 100644
--- a/src/i18n/ca.json
+++ b/src/i18n/ca.json
@@ -95,8 +95,8 @@
"default_vis": "Abast per defecte de les entrades",
"delete_account": "Esborra el compte",
"delete_account_description": "Esborra permanentment el teu compte i tots els missatges",
- "delete_account_error": "No s'ha pogut esborrar el compte. Si continua el problema, contacta amb l'administració del node",
- "delete_account_instructions": "Confirma que vols esborrar el compte escrivint la teva contrasenya aquí sota",
+ "delete_account_error": "No s'ha pogut esborrar el compte. Si continua el problema, contacta amb l'administració del node.",
+ "delete_account_instructions": "Confirma que vols esborrar el compte escrivint la teva contrasenya aquí sota.",
"export_theme": "Desa el tema",
"filtering": "Filtres",
"filtering_explanation": "Es silenciaran totes les entrades que continguin aquestes paraules. Separa-les per línies",
@@ -118,7 +118,7 @@
"invalid_theme_imported": "No s'ha entès l'arxiu carregat perquè no és un tema vàlid de Pleroma. No s'ha fet cap canvi als temes actuals.",
"limited_availability": "No està disponible en aquest navegador",
"links": "Enllaços",
- "lock_account_description": "Restringeix el teu compte només a seguidores aprovades.",
+ "lock_account_description": "Restringeix el teu compte només a seguidores aprovades",
"loop_video": "Reprodueix els vídeos en bucle",
"loop_video_silent_only": "Reprodueix en bucles només els vídeos sense so (com els \"GIF\" de Mastodon)",
"name": "Nom",
@@ -158,7 +158,7 @@
"streaming": "Carrega automàticament entrades noves quan estigui a dalt de tot",
"text": "Text",
"theme": "Tema",
- "theme_help": "Personalitza els colors del tema. Escriu-los en format RGB hexadecimal (#rrggbb)",
+ "theme_help": "Personalitza els colors del tema. Escriu-los en format RGB hexadecimal (#rrggbb).",
"tooltipRadius": "Missatges sobreposats",
"user_settings": "Configuració personal",
"values": {
diff --git a/src/i18n/cs.json b/src/i18n/cs.json
index 4e8cbcda..d9aed34a 100644
--- a/src/i18n/cs.json
+++ b/src/i18n/cs.json
@@ -256,7 +256,7 @@
"contrast": {
"hint": "Poměr kontrastu je {ratio}, {level} {context}",
"level": {
- "aa": "splňuje směrnici úrovně AA (minimální)",
+ "aa": "splňuje směrnici úrovně AA (minimální)",
"aaa": "splňuje směrnici úrovně AAA (doporučováno)",
"bad": "nesplňuje žádné směrnice přístupnosti"
},
@@ -398,7 +398,6 @@
"reply_to": "Odpověď uživateli",
"replies_list": "Odpovědi:"
},
-
"user_card": {
"approve": "Schválit",
"block": "Blokovat",
@@ -444,7 +443,7 @@
"favorite": "Oblíbit",
"user_settings": "Uživatelské nastavení"
},
- "upload":{
+ "upload": {
"error": {
"base": "Nahrávání selhalo.",
"file_too_big": "Soubor je příliš velký [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
diff --git a/src/i18n/de.json b/src/i18n/de.json
index 4deea07e..413b9bfc 100644
--- a/src/i18n/de.json
+++ b/src/i18n/de.json
@@ -66,7 +66,7 @@
"who_to_follow": "Wem folgen"
},
"notifications": {
- "broken_favorite": "Unbekannte Nachricht, suche danach...",
+ "broken_favorite": "Unbekannte Nachricht, suche danach…",
"favorited_you": "favorisierte deine Nachricht",
"followed_you": "folgt dir",
"load_older": "Ältere Benachrichtigungen laden",
@@ -115,7 +115,7 @@
"registration": "Registrierung",
"token": "Einladungsschlüssel",
"captcha": "CAPTCHA",
- "new_captcha": "Zum Erstellen eines neuen Captcha auf das Bild klicken.",
+ "new_captcha": "Zum Erstellen eines neuen Captcha auf das Bild klicken",
"validations": {
"username_required": "darf nicht leer sein",
"fullname_required": "darf nicht leer sein",
@@ -161,7 +161,7 @@
"pad_emoji": "Emojis mit Leerzeichen umrahmen",
"export_theme": "Farbschema speichern",
"filtering": "Filtern",
- "filtering_explanation": "Alle Beiträge, welche diese Wörter enthalten, werden ausgeblendet. Ein Wort pro Zeile.",
+ "filtering_explanation": "Alle Beiträge, welche diese Wörter enthalten, werden ausgeblendet. Ein Wort pro Zeile",
"follow_export": "Follower exportieren",
"follow_export_button": "Exportiere deine Follows in eine csv-Datei",
"follow_export_processing": "In Bearbeitung. Die Liste steht gleich zum herunterladen bereit.",
@@ -247,7 +247,7 @@
"streaming": "Aktiviere automatisches Laden (Streaming) von neuen Beiträgen",
"text": "Text",
"theme": "Farbschema",
- "theme_help": "Benutze HTML-Farbcodes (#rrggbb) um dein Farbschema anzupassen",
+ "theme_help": "Benutze HTML-Farbcodes (#rrggbb) um dein Farbschema anzupassen.",
"theme_help_v2_1": "Du kannst auch die Farben und die Deckkraft bestimmter Komponenten überschreiben, indem du das Kontrollkästchen umschaltest. Verwende die Schaltfläche \"Alle löschen\", um alle Überschreibungen zurückzusetzen.",
"theme_help_v2_2": "Unter einigen Einträgen befinden sich Symbole für Hintergrund-/Textkontrastindikatoren, für detaillierte Informationen fahre mit der Maus darüber. Bitte beachte, dass bei der Verwendung von Transparenz Kontrastindikatoren den schlechtest möglichen Fall darstellen.",
"tooltipRadius": "Tooltips/Warnungen",
@@ -321,7 +321,7 @@
"always_drop_shadow": "Achtung, dieser Schatten verwendet immer {0}, wenn der Browser dies unterstützt.",
"drop_shadow_syntax": "{0} unterstützt Parameter {1} und Schlüsselwort {2} nicht.",
"avatar_inset": "Bitte beachte, dass die Kombination von eingesetzten und nicht eingesetzten Schatten auf Avataren zu unerwarteten Ergebnissen bei transparenten Avataren führen kann.",
- "spread_zero": "Schatten mit einer Streuung > 0 erscheinen so, als ob sie auf Null gesetzt wären.",
+ "spread_zero": "Schatten mit einer Streuung > 0 erscheinen so, als ob sie auf Null gesetzt wären",
"inset_classic": "Eingesetzte Schatten werden mit {0} verwendet"
},
"components": {
@@ -375,7 +375,7 @@
"warning_of_generate_new_codes": "Wenn du neue Wiederherstellungs-Codes generierst, werden die alten Codes nicht mehr funktionieren.",
"generate_new_recovery_codes": "Generiere neue Wiederherstellungs-Codes",
"title": "Zwei-Faktor Authentifizierung",
- "waiting_a_recovery_codes": "Erhalte Wiederherstellungscodes...",
+ "waiting_a_recovery_codes": "Erhalte Wiederherstellungscodes…",
"authentication_methods": "Authentifizierungsmethoden",
"scan": {
"title": "Scan",
@@ -399,8 +399,6 @@
"changed_email": "Email Adresse erfolgreich geändert!",
"change_email_error": "Es trat ein Problem auf beim Versuch, deine Email Adresse zu ändern.",
"change_email": "Ändere Email",
- "notification_setting_non_followers": "Nutzer, die dir nicht folgen",
- "notification_setting_followers": "Nutzer, die dir folgen",
"import_blocks_from_a_csv_file": "Importiere Blocks von einer CSV Datei",
"accent": "Akzent"
},
@@ -409,7 +407,7 @@
"conversation": "Unterhaltung",
"error_fetching": "Fehler beim Laden",
"load_older": "Lade ältere Beiträge",
- "no_retweet_hint": "Der Beitrag ist als nur-für-Follower oder als Direktnachricht markiert und kann nicht wiederholt werden.",
+ "no_retweet_hint": "Der Beitrag ist als nur-für-Follower oder als Direktnachricht markiert und kann nicht wiederholt werden",
"repeated": "wiederholte",
"show_new": "Zeige Neuere",
"up_to_date": "Aktuell"
@@ -483,7 +481,7 @@
"not_found": "Benutzername/E-Mail-Adresse nicht gefunden. Vertippt?",
"too_many_requests": "Kurze Pause. Zu viele Versuche. Bitte, später nochmal probieren.",
"password_reset_disabled": "Passwortzurücksetzen deaktiviert. Bitte Administrator kontaktieren.",
- "password_reset_required": "Passwortzurücksetzen erforderlich",
+ "password_reset_required": "Passwortzurücksetzen erforderlich.",
"password_reset_required_but_mailer_is_disabled": "Passwortzurücksetzen wäre erforderlich, ist aber deaktiviert. Bitte Administrator kontaktieren."
},
"about": {
@@ -518,9 +516,9 @@
},
"domain_mute_card": {
"mute": "Stummschalten",
- "mute_progress": "Wird stummgeschaltet..",
+ "mute_progress": "Wird stummgeschaltet…",
"unmute": "Stummschaltung aufheben",
- "unmute_progress": "Stummschaltung wird aufgehoben.."
+ "unmute_progress": "Stummschaltung wird aufgehoben…"
},
"exporter": {
"export": "Exportieren",
diff --git a/src/i18n/en.json b/src/i18n/en.json
index f5c21b69..dc714bce 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -433,13 +433,9 @@
"greentext": "Meme arrows",
"notifications": "Notifications",
"notification_setting_filters": "Filters",
- "notification_setting": "Receive notifications from:",
- "notification_setting_follows": "Users you follow",
- "notification_setting_non_follows": "Users you do not follow",
- "notification_setting_followers": "Users who follow you",
- "notification_setting_non_followers": "Users who do not follow you",
+ "notification_setting_block_from_strangers": "Block notifications from users who you do not follow",
"notification_setting_privacy": "Privacy",
- "notification_setting_privacy_option": "Hide the sender and contents of push notifications",
+ "notification_setting_hide_notification_contents": "Hide the sender and contents of push notifications",
"notification_mutes": "To stop receiving notifications from a specific user, use a mute.",
"notification_blocks": "Blocking a user stops all notifications as well as unsubscribes them.",
"enable_web_push_notifications": "Enable web push notifications",
diff --git a/src/i18n/eo.json b/src/i18n/eo.json
index fb115872..195c0ed8 100644
--- a/src/i18n/eo.json
+++ b/src/i18n/eo.json
@@ -7,12 +7,13 @@
"gopher": "Gopher",
"media_proxy": "Aŭdvidaĵa prokurilo",
"scope_options": "Agordoj de amplekso",
- "text_limit": "Teksta limo",
+ "text_limit": "Limo de teksto",
"title": "Funkcioj",
- "who_to_follow": "Kiun aboni"
+ "who_to_follow": "Kiun aboni",
+ "pleroma_chat_messages": "Babilejo de Pleroma"
},
"finder": {
- "error_fetching_user": "Eraro alportante uzanton",
+ "error_fetching_user": "Eraris alporto de uzanto",
"find_user": "Trovi uzanton"
},
"general": {
@@ -20,12 +21,25 @@
"submit": "Sendi",
"more": "Pli",
"generic_error": "Eraro okazis",
- "optional": "Malnepra"
+ "optional": "malnepra",
+ "close": "Fermi",
+ "verify": "Kontroli",
+ "confirm": "Konfirmi",
+ "enable": "Ŝalti",
+ "disable": "Malŝalti",
+ "cancel": "Nuligi",
+ "dismiss": "Forlasi",
+ "show_less": "Montri malplion",
+ "show_more": "Montri plion",
+ "retry": "Reprovi",
+ "error_retry": "Bonvolu reprovi",
+ "loading": "Enlegante…"
},
"image_cropper": {
"crop_picture": "Tondi bildon",
"save": "Konservi",
- "cancel": "Nuligi"
+ "cancel": "Nuligi",
+ "save_without_cropping": "Konservi sen tondado"
},
"login": {
"login": "Saluti",
@@ -34,8 +48,16 @@
"password": "Pasvorto",
"placeholder": "ekz. lain",
"register": "Registriĝi",
- "username": "Salutnomo",
- "hint": "Salutu por partopreni la diskutadon"
+ "username": "Uzantonomo",
+ "hint": "Salutu por partopreni la diskutadon",
+ "heading": {
+ "recovery": "Rehavo de duobla aŭtentikigo",
+ "totp": "Duobla aŭtentikigo"
+ },
+ "recovery_code": "Rehava kodo",
+ "enter_two_factor_code": "Enigu kodon de duobla aŭtentikigo",
+ "enter_recovery_code": "Enigu rehavan kodon",
+ "authentication_code": "Aŭtentikiga kodo"
},
"media_modal": {
"previous": "Antaŭa",
@@ -45,7 +67,7 @@
"about": "Pri",
"back": "Reen",
"chat": "Loka babilejo",
- "friend_requests": "Abonaj petoj",
+ "friend_requests": "Petoj pri abono",
"mentions": "Mencioj",
"dms": "Rektaj mesaĝoj",
"public_tl": "Publika tempolinio",
@@ -53,7 +75,11 @@
"twkn": "La tuta konata reto",
"user_search": "Serĉi uzantojn",
"who_to_follow": "Kiun aboni",
- "preferences": "Agordoj"
+ "preferences": "Agordoj",
+ "chats": "Babiloj",
+ "search": "Serĉi",
+ "interactions": "Interagoj",
+ "administration": "Administrado"
},
"notifications": {
"broken_favorite": "Nekonata stato, serĉante ĝin…",
@@ -63,15 +89,21 @@
"notifications": "Sciigoj",
"read": "Legite!",
"repeated_you": "ripetis vian staton",
- "no_more_notifications": "Neniuj pliaj sciigoj"
+ "no_more_notifications": "Neniuj pliaj sciigoj",
+ "reacted_with": "reagis per {0}",
+ "migrated_to": "migris al",
+ "follow_request": "volas vin aboni"
},
"post_status": {
"new_status": "Afiŝi novan staton",
- "account_not_locked_warning": "Via konto ne estas {0}. Iu ajn povas vin aboni por vidi viajn afiŝoj nur por abonantoj.",
+ "account_not_locked_warning": "Via konto ne estas {0}. Iu ajn povas vin aboni por vidi eĉ viajn afiŝoj nur por abonantoj.",
"account_not_locked_warning_link": "ŝlosita",
- "attachments_sensitive": "Marki kunsendaĵojn kiel konsternajn",
+ "attachments_sensitive": "Marki kunsendaĵojn konsternaj",
"content_type": {
- "text/plain": "Plata teksto"
+ "text/plain": "Plata teksto",
+ "text/bbcode": "BBCode",
+ "text/markdown": "Markdown",
+ "text/html": "HTML"
},
"content_warning": "Temo (malnepra)",
"default": "Ĵus alvenis al la Universala Kongreso!",
@@ -82,7 +114,19 @@
"private": "Nur abonantoj – Afiŝi nur al abonantoj",
"public": "Publika – Afiŝi al publikaj tempolinioj",
"unlisted": "Nelistigita – Ne afiŝi al publikaj tempolinioj"
- }
+ },
+ "scope_notice": {
+ "unlisted": "Ĉi tiu afiŝo ne estos videbla en la Publika historio kaj La tuta konata reto",
+ "private": "Ĉi tiu afiŝo estos videbla nur al viaj abonantoj",
+ "public": "Ĉi tiu afiŝo estos videbla al ĉiuj"
+ },
+ "media_description_error": "Malsukcesis afiŝo de vidaŭdaĵoj; reprovu",
+ "empty_status_error": "Ne povas afiŝi malplenan staton sen dosieroj",
+ "preview_empty": "Malplena",
+ "preview": "Antaŭrigardo",
+ "direct_warning_to_first_only": "Ĉi tiu afiŝo estas nur videbla al uzantoj menciitaj je la komenco de la mesaĝo.",
+ "direct_warning_to_all": "Ĉi tiu afiŝo estos videbla al ĉiuj menciitaj uzantoj.",
+ "media_description": "Priskribo de vidaŭdaĵo"
},
"registration": {
"bio": "Priskribo",
@@ -92,10 +136,10 @@
"registration": "Registriĝo",
"token": "Invita ĵetono",
"captcha": "TESTO DE HOMECO",
- "new_captcha": "Alklaku la bildon por akiri novan teston",
+ "new_captcha": "Klaku la bildon por akiri novan teston",
"username_placeholder": "ekz. lain",
"fullname_placeholder": "ekz. Lain Iwakura",
- "bio_placeholder": "ekz.\nSaluton, mi estas Lain\nMi estas animea knabino vivante en Japanujo. Eble vi konas min de la retejo « Wired ».",
+ "bio_placeholder": "ekz.\nSaluton, mi estas Lain.\nMi estas animea knabino vivanta en Japanujo. Eble vi konas min pro la retejo « Wired ».",
"validations": {
"username_required": "ne povas resti malplena",
"fullname_required": "ne povas resti malplena",
@@ -114,47 +158,47 @@
"avatarRadius": "Profilbildoj",
"background": "Fono",
"bio": "Priskribo",
- "blocks_tab": "Baroj",
+ "blocks_tab": "Blokitoj",
"btnRadius": "Butonoj",
- "cBlue": "Blua (Respondo, abono)",
- "cGreen": "Verda (Kunhavigo)",
- "cOrange": "Oranĝa (Ŝato)",
- "cRed": "Ruĝa (Nuligo)",
+ "cBlue": "Blua (respondi, aboni)",
+ "cGreen": "Verda (kunhavigi)",
+ "cOrange": "Oranĝa (ŝati)",
+ "cRed": "Ruĝa (nuligi)",
"change_password": "Ŝanĝi pasvorton",
- "change_password_error": "Okazis eraro dum ŝanĝo de via pasvorto.",
+ "change_password_error": "Eraris ŝanĝo de via pasvorto.",
"changed_password": "Pasvorto sukcese ŝanĝiĝis!",
"collapse_subject": "Maletendi afiŝojn kun temoj",
- "composing": "Verkante",
+ "composing": "Verkado",
"confirm_new_password": "Konfirmu novan pasvorton",
"current_avatar": "Via nuna profilbildo",
"current_password": "Nuna pasvorto",
"current_profile_banner": "Via nuna profila rubando",
- "data_import_export_tab": "Enporto / Elporto de datenoj",
- "default_vis": "Implicita videbleca amplekso",
+ "data_import_export_tab": "Enporto / Elporto de datumoj",
+ "default_vis": "Implicita amplekso de vidibleco",
"delete_account": "Forigi konton",
- "delete_account_description": "Por ĉiam forigi vian konton kaj ĉiujn viajn mesaĝojn",
- "delete_account_error": "Okazis eraro dum forigo de via kanto. Se tio daŭre okazados, bonvolu kontakti la administranton de via nodo.",
+ "delete_account_description": "Por ĉiam forigi viajn datumojn kaj malaktivigi vian konton.",
+ "delete_account_error": "Eraris forigo de via kanto. Se tio daŭre ripetiĝos, bonvolu kontakti la administranton de via nodo.",
"delete_account_instructions": "Entajpu sube vian pasvorton por konfirmi forigon de konto.",
- "avatar_size_instruction": "La rekomendata malpleja grando de profilbildoj estas 150×150 bilderoj.",
+ "avatar_size_instruction": "La rekomendata minimuma grando de profilbildoj estas 150×150 bilderoj.",
"export_theme": "Konservi antaŭagordon",
"filtering": "Filtrado",
- "filtering_explanation": "Ĉiuj statoj kun tiuj ĉi vortoj silentiĝos, po unu linio",
- "follow_export": "Abona elporto",
+ "filtering_explanation": "Ĉiuj statoj kun tiuj ĉi vortoj silentiĝos; skribu po unu linie",
+ "follow_export": "Elporto de abonoj",
"follow_export_button": "Elporti viajn abonojn al CSV-dosiero",
"follow_export_processing": "Traktante; baldaŭ vi ricevos peton elŝuti la dosieron",
- "follow_import": "Abona enporto",
+ "follow_import": "Enporto de abonoj",
"follow_import_error": "Eraro enportante abonojn",
- "follows_imported": "Abonoj enportiĝis! Traktado daŭros iom.",
+ "follows_imported": "Abonoj enportiĝis! Traktado daŭros iom da tempo.",
"foreground": "Malfono",
"general": "Ĝenerala",
"hide_attachments_in_convo": "Kaŝi kunsendaĵojn en interparoloj",
"hide_attachments_in_tl": "Kaŝi kunsendaĵojn en tempolinio",
- "max_thumbnails": "Plej multa nombro da bildetoj po afiŝo",
- "hide_isp": "Kaŝi nodo-propran breton",
+ "max_thumbnails": "Maksimuma nombro da bildetoj en afiŝo",
+ "hide_isp": "Kaŝi breton propran al nodo",
"preload_images": "Antaŭ-enlegi bildojn",
"use_one_click_nsfw": "Malfermi konsternajn kunsendaĵojn per nur unu klako",
- "hide_post_stats": "Kaŝi statistikon de afiŝoj (ekz. nombron da ŝatoj)",
- "hide_user_stats": "Kaŝi statistikon de uzantoj (ekz. nombron da abonantoj)",
+ "hide_post_stats": "Kaŝi statistikon de afiŝoj (ekz. nombron de ŝatoj)",
+ "hide_user_stats": "Kaŝi statistikon de uzantoj (ekz. nombron de abonantoj)",
"hide_filtered_statuses": "Kaŝi filtritajn statojn",
"import_followers_from_a_csv_file": "Enporti abonojn el CSV-dosiero",
"import_theme": "Enlegi antaŭagordojn",
@@ -169,9 +213,9 @@
"links": "Ligiloj",
"lock_account_description": "Limigi vian konton al nur abonantoj aprobitaj",
"loop_video": "Ripetadi filmojn",
- "loop_video_silent_only": "Ripetadi nur filmojn sen sono (ekz. la \"GIF-ojn\" de Mastodon)",
+ "loop_video_silent_only": "Ripetadi nur filmojn sen sono (ekz. la «GIF-ojn» de Mastodon)",
"mutes_tab": "Silentigoj",
- "play_videos_in_modal": "Ludi filmojn rekte en la aŭdvidaĵa spektilo",
+ "play_videos_in_modal": "Ludi filmojn en ŝpruca kadro",
"use_contain_fit": "Ne tondi la kunsendaĵon en bildetoj",
"name": "Nomo",
"name_bio": "Nomo kaj priskribo",
@@ -182,50 +226,50 @@
"notification_visibility_mentions": "Mencioj",
"notification_visibility_repeats": "Ripetoj",
"no_rich_text_description": "Forigi riĉtekstajn formojn de ĉiuj afiŝoj",
- "no_blocks": "Neniuj baroj",
+ "no_blocks": "Neniuj blokitoj",
"no_mutes": "Neniuj silentigoj",
"hide_follows_description": "Ne montri kiun mi sekvas",
"hide_followers_description": "Ne montri kiu min sekvas",
"show_admin_badge": "Montri la insignon de administranto en mia profilo",
- "show_moderator_badge": "Montri la insignon de kontrolanto en mia profilo",
- "nsfw_clickthrough": "Ŝalti traklakan kaŝon de konsternaj kunsendaĵoj",
+ "show_moderator_badge": "Montri la insignon de reguligisto en mia profilo",
+ "nsfw_clickthrough": "Ŝalti traklakan kaŝadon de konsternaj kunsendaĵoj",
"oauth_tokens": "Ĵetonoj de OAuth",
"token": "Ĵetono",
- "refresh_token": "Ĵetono de novigo",
+ "refresh_token": "Ĵetono de aktualigo",
"valid_until": "Valida ĝis",
"revoke_token": "Senvalidigi",
"panelRadius": "Bretoj",
"pause_on_unfocused": "Paŭzigi elsendfluon kiam langeto ne estas fokusata",
"presets": "Antaŭagordoj",
- "profile_background": "Profila fono",
- "profile_banner": "Profila rubando",
+ "profile_background": "Fono de profilo",
+ "profile_banner": "Rubando de profilo",
"profile_tab": "Profilo",
"radii_help": "Agordi fasadan rondigon de randoj (bildere)",
"replies_in_timeline": "Respondoj en tempolinio",
"reply_visibility_all": "Montri ĉiujn respondojn",
"reply_visibility_following": "Montri nur respondojn por mi aŭ miaj abonatoj",
"reply_visibility_self": "Montri nur respondojn por mi",
- "saving_err": "Eraro dum konservo de agordoj",
+ "saving_err": "Eraris konservado de agordoj",
"saving_ok": "Agordoj konserviĝis",
"security_tab": "Sekureco",
"scope_copy": "Kopii amplekson por respondo (rektaj mesaĝoj ĉiam kopiiĝas)",
"set_new_avatar": "Agordi novan profilbildon",
- "set_new_profile_background": "Agordi novan profilan fonon",
- "set_new_profile_banner": "Agordi novan profilan rubandon",
+ "set_new_profile_background": "Agordi novan fonon de profilo",
+ "set_new_profile_banner": "Agordi novan rubandon de profilo",
"settings": "Agordoj",
- "subject_input_always_show": "Ĉiam montri teman kampon",
- "subject_line_behavior": "Kopii temon por respondo",
- "subject_line_email": "Kiel retpoŝto: \"re: temo\"",
+ "subject_input_always_show": "Ĉiam montri kampon de temo",
+ "subject_line_behavior": "Kopii temon dum respondado",
+ "subject_line_email": "Kiel retpoŝto: «re: temo»",
"subject_line_mastodon": "Kiel Mastodon: kopii senŝanĝe",
"subject_line_noop": "Ne kopii",
"post_status_content_type": "Afiŝi specon de la enhavo de la stato",
- "stop_gifs": "Movi GIF-bildojn dum musa ŝvebo",
- "streaming": "Ŝalti memfaran fluigon de novaj afiŝoj ĉe la supro de la paĝo",
+ "stop_gifs": "Movi GIF-bildojn dum ŝvebo de muso",
+ "streaming": "Ŝalti memagan fluigon de novaj afiŝoj kiam vi vidas la supron de la paĝo",
"text": "Teksto",
"theme": "Haŭto",
"theme_help": "Uzu deksesumajn kolorkodojn (#rrvvbb) por adapti vian koloran haŭton.",
- "theme_help_v2_1": "Vi ankaŭ povas superagordi la kolorojn kaj travideblecon de kelkaj eroj per marko de la markbutono; uzu la butonon \"Vakigi ĉion\" por forigi ĉîujn superagordojn.",
- "theme_help_v2_2": "Bildsimboloj sub kelkaj eroj estas indikiloj de kontrasto inter fono kaj teksto; muse ŝvebu por detalaj informoj. Bonvolu memori, ke la indikilo montras la plej malbonan okazeblon dum sia uzo.",
+ "theme_help_v2_1": "Vi ankaŭ povas superagordi la kolorojn kaj travideblecon de kelkaj eroj per marko de la markbutono; uzu la butonon «Vakigi ĉion» por forigi ĉîujn superagordojn.",
+ "theme_help_v2_2": "Bildsimboloj sub kelkaj eroj estas indikiloj de kontrasto inter fono kaj teksto; ŝvebigu muson por detalaj informoj. Bonvolu memori, ke la indikilo montras la plej malbonan okazeblon dum sia uzo.",
"tooltipRadius": "Ŝpruchelpiloj/avertoj",
"upload_a_photo": "Alŝuti foton",
"user_settings": "Agordoj de uzanto",
@@ -317,7 +361,7 @@
},
"fonts": {
"_tab_label": "Tiparoj",
- "help": "Elektu tiparon uzotan por eroj de la fasado. Por \"propra\" vi devas enigi la precizan nomon de tiparo tiel, kiel ĝi aperas en la sistemo",
+ "help": "Elektu tiparon uzotan por eroj de la fasado. Por \"propra\" vi devas enigi la precizan nomon de tiparo tiel, kiel ĝi aperas en la sistemo.",
"components": {
"interface": "Fasado",
"input": "Enigaj kampoj",
@@ -343,7 +387,70 @@
"checkbox": "Mi legetis la kondiĉojn de uzado",
"link": "bela eta ligil’"
}
- }
+ },
+ "discoverable": "Permesi trovon de ĉi tiu konto en serĉrezultoj kaj aliaj servoj",
+ "mutes_and_blocks": "Silentigitoj kaj blokitoj",
+ "chatMessageRadius": "Babileja mesaĝo",
+ "changed_email": "Retpoŝtadreso sukcese ŝanĝiĝis!",
+ "change_email_error": "Eraris ŝanĝo de via retpoŝtadreso.",
+ "change_email": "Ŝanĝi retpoŝtadreson",
+ "bot": "Ĉi tio estas robota konto",
+ "blocks_imported": "Blokitoj enportiĝis! Traktado daŭros iom da tempo.",
+ "block_import_error": "Eraris enporto de blokitoj",
+ "block_export": "Elporto de blokitoj",
+ "block_import": "Enporto de blokitoj",
+ "block_export_button": "Elporti viajn blokitojn al CSV-dosiero",
+ "allow_following_move": "Permesi memagan abonadon kiam abonata konto migras",
+ "mfa": {
+ "verify": {
+ "desc": "Por ŝalti duoblan aŭtentikigon, enigu la kodon el via aplikaĵo por duobla aŭtentikigo:"
+ },
+ "scan": {
+ "secret_code": "Ŝlosilo",
+ "desc": "Uzante vian aplikaĵon por duobla aŭtentikigo, skanu ĉi tiun rapidrespondan kodon aŭ enigu tekstan ŝlosilon:",
+ "title": "Skani"
+ },
+ "authentication_methods": "Metodoj de aŭtentikigo",
+ "recovery_codes_warning": "Notu la kodojn aŭ konservu ilin en sekura loko – alie vi ne revidos ilin. Se vi perdos aliron al via aplikaĵo por duobla aŭtentikigo kaj al la rehavaj kodoj, vi ne povos aliri vian konton.",
+ "waiting_a_recovery_codes": "Ricevante savkopiajn kodojn…",
+ "recovery_codes": "Rehavaj kodoj.",
+ "warning_of_generate_new_codes": "Kiam vi estigos novajn rehavajn kodojn, viaj malnovaj ne plu funkcios.",
+ "generate_new_recovery_codes": "Estigi novajn rehavajn kodojn",
+ "title": "Duobla aŭtentikigo"
+ },
+ "enter_current_password_to_confirm": "Enigu vian pasvorton por konfirmi vian identecon",
+ "security": "Sekureco",
+ "fun": "Amuzo",
+ "type_domains_to_mute": "Serĉu silentigotajn retnomojn",
+ "useStreamingApiWarning": "(Nerekomendate, eksperimente, povas preterpasi afiŝojn)",
+ "useStreamingApi": "Ricevi afiŝojn kaj sciigojn realtempe",
+ "user_mutes": "Uzantoj",
+ "reset_background_confirm": "Ĉu vi certe volas restarigi la fonon?",
+ "reset_banner_confirm": "Ĉu vi certe volas restarigi la rubandon?",
+ "reset_avatar_confirm": "Ĉu vi certe volas restarigi la profilbildon?",
+ "reset_profile_banner": "Restarigi rubandon de profilo",
+ "reset_profile_background": "Restarigi fonon de profilo",
+ "reset_avatar": "Restarigi profilbildon",
+ "minimal_scopes_mode": "Minimumigi elekteblojn pri amplekso de afiŝoj",
+ "search_user_to_block": "Serĉu, kiun vi volas bloki",
+ "search_user_to_mute": "Serĉu, kiun vi volas silentigi",
+ "autohide_floating_post_button": "Memage kaŝi la butonon por Nova afiŝo (poŝtelefone)",
+ "hide_followers_count_description": "Ne montri nombron de abonantoj",
+ "hide_follows_count_description": "Ne montri nombron de abonoj",
+ "notification_visibility_emoji_reactions": "Reagoj",
+ "notification_visibility_moves": "Migroj",
+ "new_email": "Nova retpoŝtadreso",
+ "profile_fields": {
+ "value": "Enhavo",
+ "name": "Etikedo",
+ "add_field": "Aldoni kampon",
+ "label": "Pridatumoj de profilo"
+ },
+ "import_blocks_from_a_csv_file": "Enporti blokitojn el CSV-dosiero",
+ "hide_muted_posts": "Kaŝi afiŝojn de silentigitaj uzantoj",
+ "emoji_reactions_on_timeline": "Montri bildosignajn reagojn en la tempolinio",
+ "pad_emoji": "Meti spacetojn ĉirkaŭ bildosigno post ties elekto",
+ "domain_mutes": "Retnomoj"
},
"timeline": {
"collapse": "Maletendi",
@@ -402,7 +509,7 @@
"favorite": "Ŝati",
"user_settings": "Agordoj de uzanto"
},
- "upload":{
+ "upload": {
"error": {
"base": "Alŝuto malsukcesis.",
"file_too_big": "Dosiero estas tro granda [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
@@ -415,5 +522,90 @@
"GiB": "GiB",
"TiB": "TiB"
}
+ },
+ "emoji": {
+ "search_emoji": "Serĉi bildosignon",
+ "keep_open": "Teni elektilon malfermita",
+ "emoji": "Bildsignoj",
+ "stickers": "Glumarkoj",
+ "add_emoji": "Enigi bildosignon",
+ "load_all": "Enlegante ĉiujn {emojiAmount} bildosignojn",
+ "load_all_hint": "Enlegis la {saneAmount} unuajn bildosignojn; enlego de ĉiuj povus kaŭzi problemojn pri efikeco.",
+ "unicode": "Unikoda bildosigno",
+ "custom": "Propra bildosigno"
+ },
+ "polls": {
+ "not_enough_options": "Tro malmultaj unikaj elektebloj en la enketo",
+ "expired": "Enketo finiĝis antaŭ {0}",
+ "expires_in": "Enketo finiĝas je {0}",
+ "expiry": "Aĝo de enketo",
+ "multiple_choices": "Pluraj elektoj",
+ "single_choice": "Unu elekto",
+ "type": "Speco de enketo",
+ "vote": "Voĉi",
+ "votes": "voĉoj",
+ "option": "Elekteblo",
+ "add_option": "Aldoni elekteblon",
+ "add_poll": "Aldoni enketon"
+ },
+ "importer": {
+ "error": "Eraris enporto de ĉi tiu dosiero.",
+ "success": "Enportita sukcese.",
+ "submit": "Sendi"
+ },
+ "exporter": {
+ "processing": "Traktante; baldaŭ vi ricevos peton elŝuti vian dosieron",
+ "export": "Elporti"
+ },
+ "domain_mute_card": {
+ "unmute_progress": "Malsilentigante…",
+ "unmute": "Malsilentigi",
+ "mute_progress": "Silentigante…",
+ "mute": "Silentigi"
+ },
+ "about": {
+ "staff": "Skipo",
+ "mrf": {
+ "simple": {
+ "media_nsfw_desc": "Ĉi tiu nodo devigas vidaŭdaĵojn esti markitaj kiel konsternaj en afiŝoj el la jenaj nodoj:",
+ "media_nsfw": "Devige marki vidaŭdaĵojn konsternaj",
+ "media_removal_desc": "Ĉi tiu nodo forigas vidaŭdaĵojn de afiŝoj el la jenaj nodoj:",
+ "media_removal": "Forigo de vidaŭdaĵoj",
+ "ftl_removal": "Forigo de la historio de «La tuta konata reto»",
+ "quarantine_desc": "Ĉi tiu nodo sendos nur publikajn afiŝojn al la jenaj nodoj:",
+ "quarantine": "Kvaranteno",
+ "reject_desc": "Ĉi tiu nodo ne akceptos mesaĝojn de la jenaj nodoj:",
+ "reject": "Rifuzi",
+ "accept_desc": "Ĉi tiu nodo nur akceptas mesaĝojn de la jenaj nodoj:",
+ "accept": "Akcepti",
+ "simple_policies": "Specialaj politikoj de la nodo"
+ },
+ "mrf_policies": "Ŝaltis politikon de MRF",
+ "keyword": {
+ "is_replaced_by": "→",
+ "replace": "Anstataŭigi",
+ "reject": "Rifuzi",
+ "ftl_removal": "Forigo de la historio de «La tuta konata reto»",
+ "keyword_policies": "Politiko pri ŝlosilvortoj"
+ },
+ "federation": "Federado"
+ }
+ },
+ "selectable_list": {
+ "select_all": "Elekti ĉion"
+ },
+ "remote_user_resolver": {
+ "error": "Netrovinte.",
+ "searching_for": "Serĉante",
+ "remote_user_resolver": "Trovilo de foraj uzantoj"
+ },
+ "interactions": {
+ "load_older": "Enlegi pli malnovajn interagojn",
+ "moves": "Migrado de uzantoj",
+ "follows": "Novaj abonoj",
+ "favs_repeats": "Ripetoj kaj ŝatoj"
+ },
+ "errors": {
+ "storage_unavailable": "Pleroma ne povis aliri deponejon de la foliumilo. Via saluto kaj viaj lokaj agordoj ne estos konservitaj, kaj vi eble renkontos neatenditajn problemojn. Provu permesi kuketojn."
}
}
diff --git a/src/i18n/es.json b/src/i18n/es.json
index 8151a799..3f313eb3 100644
--- a/src/i18n/es.json
+++ b/src/i18n/es.json
@@ -342,11 +342,6 @@
"true": "sí"
},
"notifications": "Notificaciones",
- "notification_setting": "Recibir notificaciones de:",
- "notification_setting_follows": "Usuarios que sigues",
- "notification_setting_non_follows": "Usuarios que no sigues",
- "notification_setting_followers": "Usuarios que te siguen",
- "notification_setting_non_followers": "Usuarios que no te siguen",
"notification_mutes": "Para dejar de recibir notificaciones de un usuario específico, siléncialo.",
"notification_blocks": "El bloqueo de un usuario detiene todas las notificaciones y también las cancela.",
"enable_web_push_notifications": "Habilitar las notificiaciones en el navegador",
diff --git a/src/i18n/et.json b/src/i18n/et.json
index 3368d169..97e835da 100644
--- a/src/i18n/et.json
+++ b/src/i18n/et.json
@@ -302,14 +302,9 @@
"enable_web_push_notifications": "Luba veebipõhised push-teated",
"notification_blocks": "Kasutaja blokeerimisel ei tule neilt enam teateid ning nendele teilt ka mitte.",
"notification_setting_privacy_option": "Peida saatja ning sisu push-teadetelt",
- "notification_setting": "Saa teateid nendelt:",
"notifications": "Teated",
"notification_mutes": "Kui soovid mõnelt kasutajalt mitte teateid saada, kasuta vaigistust.",
"notification_setting_privacy": "Privaatsus",
- "notification_setting_non_followers": "Kasutajatelt, kes sind ei jälgi",
- "notification_setting_followers": "Kasutajatelt, kes jälgivad sind",
- "notification_setting_non_follows": "Kasutajatelt, keda sa ei jälgi",
- "notification_setting_follows": "Kasutajatelt, keda jälgid",
"notification_setting_filters": "Filtrid",
"greentext": "Meemi nooled",
"fun": "Naljad",
diff --git a/src/i18n/eu.json b/src/i18n/eu.json
index 476f555d..f04203f0 100644
--- a/src/i18n/eu.json
+++ b/src/i18n/eu.json
@@ -84,7 +84,7 @@
"preferences": "Hobespenak"
},
"notifications": {
- "broken_favorite": "Egoera ezezaguna, bilatzen...",
+ "broken_favorite": "Egoera ezezaguna, bilatzen…",
"favorited_you": "zure mezua gogoko du",
"followed_you": "Zu jarraitzen zaitu",
"load_older": "Kargatu jakinarazpen zaharragoak",
@@ -128,7 +128,7 @@
"new_status": "Mezu berri bat idatzi",
"account_not_locked_warning": "Zure kontua ez dago {0}. Edozeinek jarraitzen hastearekin, zure mezuak irakur ditzake.",
"account_not_locked_warning_link": "Blokeatuta",
- "attachments_sensitive": "Nabarmendu eranskinak hunkigarri gisa ",
+ "attachments_sensitive": "Nabarmendu eranskinak hunkigarri gisa",
"content_type": {
"text/plain": "Testu arrunta",
"text/html": "HTML",
@@ -187,9 +187,9 @@
"confirm_and_enable": "Baieztatu eta gaitu OTP",
"title": "Bi-faktore autentifikazioa",
"generate_new_recovery_codes": "Sortu berreskuratze kode berriak",
- "warning_of_generate_new_codes": "Berreskuratze kode berriak sortzean, zure berreskuratze kode zaharrak ez dute balioko",
+ "warning_of_generate_new_codes": "Berreskuratze kode berriak sortzean, zure berreskuratze kode zaharrak ez dute balioko.",
"recovery_codes": "Berreskuratze kodea",
- "waiting_a_recovery_codes": "Babes-kopia kodeak jasotzen...",
+ "waiting_a_recovery_codes": "Babes-kopia kodeak jasotzen…",
"recovery_codes_warning": "Idatzi edo gorde kodeak leku seguruan - bestela ez dituzu berriro ikusiko. Zure 2FA aplikaziorako sarbidea eta berreskuratze kodeak galduz gero, zure kontutik blokeatuta egongo zara.",
"authentication_methods": "Autentifikazio metodoa",
"scan": {
@@ -198,7 +198,7 @@
"secret_code": "Giltza"
},
"verify": {
- "desc": "Bi-faktore autentifikazioa gaitzeko, sar ezazu bi-faktore kodea zure app-tik"
+ "desc": "Bi-faktore autentifikazioa gaitzeko, sar ezazu bi-faktore kodea zure app-tik:"
}
},
"attachmentRadius": "Eranskinak",
@@ -220,7 +220,7 @@
"cOrange": "Laranja (Gogokoa)",
"cRed": "Gorria (ezeztatu)",
"change_password": "Pasahitza aldatu",
- "change_password_error": "Arazao bat egon da zure pasahitza aldatzean",
+ "change_password_error": "Arazao bat egon da zure pasahitza aldatzean.",
"changed_password": "Pasahitza ondo aldatu da!",
"collapse_subject": "Bildu gaia daukaten mezuak",
"composing": "Idazten",
@@ -247,7 +247,7 @@
"follows_imported": "Jarraitzaileak inportatuta! Prozesatzeak denbora pixka bat iraungo du.",
"foreground": "Aurreko planoa",
"general": "Orokorra",
- "hide_attachments_in_convo": "Ezkutatu eranskinak elkarrizketatan ",
+ "hide_attachments_in_convo": "Ezkutatu eranskinak elkarrizketatan",
"hide_attachments_in_tl": "Ezkutatu eranskinak donbora-lerroan",
"hide_muted_posts": "Ezkutatu mutututako erabiltzaileen mezuak",
"max_thumbnails": "Mezu bakoitzeko argazki-miniatura kopuru maximoa",
@@ -342,11 +342,6 @@
"true": "bai"
},
"notifications": "Jakinarazpenak",
- "notification_setting": "Jaso pertsona honen jakinarazpenak:",
- "notification_setting_follows": "Jarraitutako erabiltzaileak",
- "notification_setting_non_follows": "Jarraitzen ez dituzun erabiltzaileak",
- "notification_setting_followers": "Zu jarraitzen zaituzten erabiltzaileak",
- "notification_setting_non_followers": "Zu jarraitzen ez zaituzten erabiltzaileak",
"notification_mutes": "Erabiltzaile jakin baten jakinarazpenak jasotzeari uzteko, isilarazi ezazu.",
"notification_blocks": "Erabiltzaile bat blokeatzeak jakinarazpen guztiak gelditzen ditu eta harpidetza ezeztatu.",
"enable_web_push_notifications": "Gaitu web jakinarazpenak",
@@ -432,7 +427,7 @@
},
"fonts": {
"_tab_label": "Letra-tipoak",
- "help": "Aukeratu letra-tipoak erabiltzailearen interfazean erabiltzeko. \"Pertsonalizatua\" letra-tipoan, sisteman agertzen den izen berdinarekin idatzi behar duzu.",
+ "help": "Aukeratu letra-tipoak erabiltzailearen interfazean erabiltzeko. \"Pertsonalizatua\" letra-tipoan, sisteman agertzen den izen berdinarekin idatzi behar duzu.",
"components": {
"interface": "Interfazea",
"input": "Sarrera eremuak",
@@ -532,7 +527,7 @@
"favorites": "Gogokoak",
"follow": "Jarraitu",
"follow_sent": "Eskaera bidalita!",
- "follow_progress": "Eskatzen...",
+ "follow_progress": "Eskatzen…",
"follow_again": "Eskaera berriro bidali?",
"follow_unfollow": "Jarraitzeari utzi",
"followees": "Jarraitzen",
@@ -551,11 +546,11 @@
"subscribe": "Harpidetu",
"unsubscribe": "Harpidetza ezeztatu",
"unblock": "Blokeoa kendu",
- "unblock_progress": "Blokeoa ezeztatzen...",
- "block_progress": "Blokeatzen...",
+ "unblock_progress": "Blokeoa ezeztatzen…",
+ "block_progress": "Blokeatzen…",
"unmute": "Isiltasuna kendu",
- "unmute_progress": "Isiltasuna kentzen...",
- "mute_progress": "Isiltzen...",
+ "unmute_progress": "Isiltasuna kentzen…",
+ "mute_progress": "Isiltzen…",
"hide_repeats": "Ezkutatu errepikapenak",
"show_repeats": "Erakutsi errpekiapenak",
"admin_menu": {
@@ -637,4 +632,4 @@
"password_reset_required": "Pasahitza berrezarri behar duzu saioa hasteko.",
"password_reset_required_but_mailer_is_disabled": "Pasahitza berrezarri behar duzu, baina pasahitza berrezartzeko aukera desgaituta dago. Mesedez, jarri harremanetan instantziaren administratzailearekin."
}
-} \ No newline at end of file
+}
diff --git a/src/i18n/fi.json b/src/i18n/fi.json
index 7ab9fe4a..6170303f 100644
--- a/src/i18n/fi.json
+++ b/src/i18n/fi.json
@@ -282,7 +282,6 @@
"show_moderator_badge": "Näytä Moderaattori-merkki profiilissani",
"useStreamingApi": "Vastaanota viestiejä ja ilmoituksia reaaliajassa",
"notification_setting_filters": "Suodattimet",
- "notification_setting": "Vastaanota ilmoituksia seuraavista:",
"notification_setting_privacy_option": "Piilota lähettäjä ja sisältö sovelluksen ulkopuolisista ilmoituksista",
"enable_web_push_notifications": "Ota käyttöön sovelluksen ulkopuoliset ilmoitukset",
"app_name": "Sovelluksen nimi",
@@ -488,10 +487,6 @@
"pad_emoji": "Välistä emojit välilyönneillä lisätessäsi niitä valitsimesta",
"mutes_tab": "Mykistykset",
"new_email": "Uusi sähköpostiosoite",
- "notification_setting_follows": "Käyttäjät joita seuraat",
- "notification_setting_non_follows": "Käyttäjät joita et seuraa",
- "notification_setting_followers": "Käyttäjät jotka seuraavat sinua",
- "notification_setting_non_followers": "Käyttäjät jotka eivät seuraa sinua",
"notification_setting_privacy": "Yksityisyys",
"notification_mutes": "Jos et halua ilmoituksia joltain käyttäjältä, käytä mykistystä.",
"notification_blocks": "Estäminen pysäyttää kaikki ilmoitukset käyttäjältä ja poistaa seurauksen.",
diff --git a/src/i18n/fr.json b/src/i18n/fr.json
index f41be424..794ed812 100644
--- a/src/i18n/fr.json
+++ b/src/i18n/fr.json
@@ -317,11 +317,6 @@
"true": "oui"
},
"notifications": "Notifications",
- "notification_setting": "Reçevoir les notifications de :",
- "notification_setting_follows": "Utilisateurs que vous suivez",
- "notification_setting_non_follows": "Utilisateurs que vous ne suivez pas",
- "notification_setting_followers": "Utilisateurs qui vous suivent",
- "notification_setting_non_followers": "Utilisateurs qui ne vous suivent pas",
"notification_mutes": "Pour stopper la récéption de notifications d'un utilisateur particulier, utilisez un masquage.",
"notification_blocks": "Bloquer un utilisateur stoppe toute notification et se désabonne de lui.",
"enable_web_push_notifications": "Activer les notifications de push web",
@@ -348,7 +343,8 @@
"migration_snapshot_ok": "Pour être sûr un instantanée du thème à été chargé. Vos pouvez essayer de charger ses données.",
"fe_downgraded": "Retour en arrière de la version de PleromaFE.",
"fe_upgraded": "Le moteur de thème PleromaFE à été mis à jour après un changement de version.",
- "snapshot_missing": "Aucun instantané du thème à été trouvé dans le fichier, il peut y avoir un rendu différent à la vision originelle."
+ "snapshot_missing": "Aucun instantané du thème à été trouvé dans le fichier, il peut y avoir un rendu différent à la vision originelle.",
+ "snapshot_present": "Un instantané du thème à été chargé, toutes les valeurs sont dont écrasées. Vous pouvez autrement charger le thème complètement."
},
"keep_as_is": "Garder tel-quel",
"use_source": "Nouvelle version"
@@ -624,7 +620,7 @@
"reject": "Rejeté",
"replace": "Remplacer",
"keyword_policies": "Politiques par mot-clés",
- "ftl_removal": "Suppression du flux \"Ensemble du réseau connu\"",
+ "ftl_removal": "Suppression du flux fédéré",
"is_replaced_by": "→"
},
"simple": {
diff --git a/src/i18n/ga.json b/src/i18n/ga.json
index 74a48bfc..3ec5d86b 100644
--- a/src/i18n/ga.json
+++ b/src/i18n/ga.json
@@ -36,7 +36,7 @@
"twkn": "An Líonra Iomlán"
},
"notifications": {
- "broken_favorite": "Post anaithnid. Cuardach dó...",
+ "broken_favorite": "Post anaithnid. Cuardach dó…",
"favorited_you": "toghadh le do phost",
"followed_you": "lean tú",
"load_older": "Luchtaigh fógraí aosta",
@@ -84,7 +84,7 @@
"cOrange": "Oráiste (Cosúil)",
"cRed": "Dearg (Cealaigh)",
"change_password": "Athraigh do pasfhocal",
- "change_password_error": "Bhí fadhb ann ag athrú do pasfhocail",
+ "change_password_error": "Bhí fadhb ann ag athrú do pasfhocail.",
"changed_password": "Athraigh an pasfhocal go rathúil!",
"collapse_subject": "Poist a chosc le teidil",
"confirm_new_password": "Deimhnigh do pasfhocal nua",
@@ -160,7 +160,7 @@
"streaming": "Cumasaigh post nua a shruthú uathoibríoch nuair a scrollaítear go barr an leathanaigh",
"text": "Téacs",
"theme": "Téama",
- "theme_help": "Úsáid cód daith hex (#rrggbb) chun do schéim a saincheapadh",
+ "theme_help": "Úsáid cód daith hex (#rrggbb) chun do schéim a saincheapadh.",
"tooltipRadius": "Bileoga eolais",
"user_settings": "Socruithe úsáideora",
"values": {
diff --git a/src/i18n/he.json b/src/i18n/he.json
index b1c9da69..7f2bf58f 100644
--- a/src/i18n/he.json
+++ b/src/i18n/he.json
@@ -70,9 +70,9 @@
"preferences": "העדפות"
},
"notifications": {
- "broken_favorite": "סטאטוס לא ידוע, מחפש...",
+ "broken_favorite": "סטאטוס לא ידוע, מחפש…",
"favorited_you": "אהב את הסטטוס שלך",
- "followed_you": "עקב אחריך!",
+ "followed_you": "עקב אחריך",
"load_older": "טען התראות ישנות",
"notifications": "התראות",
"read": "קרא!",
@@ -178,7 +178,7 @@
"follow_export": "יצוא עקיבות",
"follow_export_button": "ייצא את הנעקבים שלך לקובץ csv",
"follow_import": "יבוא עקיבות",
- "follow_import_error": "שגיאה בייבוא נעקבים.",
+ "follow_import_error": "שגיאה בייבוא נעקבים",
"follows_imported": "נעקבים יובאו! ייקח זמן מה לעבד אותם.",
"foreground": "חזית",
"general": "כללי",
@@ -311,7 +311,7 @@
"favorites": "מועדפים",
"follow": "עקוב",
"follow_sent": "בקשה נשלחה!",
- "follow_progress": "מבקש...",
+ "follow_progress": "מבקש…",
"follow_again": "שלח בקשה שוב?",
"follow_unfollow": "בטל עקיבה",
"followees": "נעקבים",
@@ -327,11 +327,11 @@
"report": "דווח",
"statuses": "סטטוסים",
"unblock": "הסר חסימה",
- "unblock_progress": "מסיר חסימה...",
- "block_progress": "חוסם...",
+ "unblock_progress": "מסיר חסימה…",
+ "block_progress": "חוסם…",
"unmute": "הסר השתקה",
- "unmute_progress": "מסיר השתקה...",
- "mute_progress": "משתיק...",
+ "unmute_progress": "מסיר השתקה…",
+ "mute_progress": "משתיק…",
"admin_menu": {
"moderation": "ניהול (צוות)",
"grant_admin": "הפוך למנהל",
@@ -377,7 +377,7 @@
"favorite": "מועדף",
"user_settings": "הגדרות משתמש"
},
- "upload":{
+ "upload": {
"error": {
"base": "העלאה נכשלה.",
"file_too_big": "קובץ גדול מדי [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
diff --git a/src/i18n/it.json b/src/i18n/it.json
index 7a8faf68..b27edd61 100644
--- a/src/i18n/it.json
+++ b/src/i18n/it.json
@@ -336,11 +336,6 @@
"notification_mutes": "Per non ricevere notifiche da uno specifico utente, zittiscilo.",
"notification_setting_privacy_option": "Nascondi mittente e contenuti delle notifiche push",
"notification_setting_privacy": "Privacy",
- "notification_setting_followers": "Utenti che ti seguono",
- "notification_setting_non_followers": "Utenti che non ti seguono",
- "notification_setting_non_follows": "Utenti che non segui",
- "notification_setting_follows": "Utenti che segui",
- "notification_setting": "Ricevi notifiche da:",
"notification_setting_filters": "Filtri",
"notifications": "Notifiche",
"greentext": "Frecce da meme",
@@ -409,7 +404,9 @@
"reset_avatar_confirm": "Vuoi veramente azzerare l'icona?",
"reset_banner_confirm": "Vuoi veramente azzerare lo stendardo?",
"reset_background_confirm": "Vuoi veramente azzerare lo sfondo?",
- "chatMessageRadius": "Messaggi istantanei"
+ "chatMessageRadius": "Messaggi istantanei",
+ "notification_setting_hide_notification_contents": "Nascondi mittente e contenuti delle notifiche push",
+ "notification_setting_block_from_strangers": "Blocca notifiche da utenti che non segui"
},
"timeline": {
"error_fetching": "Errore nell'aggiornamento",
@@ -806,6 +803,7 @@
"new": "Nuova conversazione",
"chats": "Conversazioni",
"delete": "Elimina",
- "message_user": "Contatta {nickname}"
+ "message_user": "Contatta {nickname}",
+ "you": "Tu:"
}
}
diff --git a/src/i18n/ja_easy.json b/src/i18n/ja_easy.json
index 194068ce..255648e7 100644
--- a/src/i18n/ja_easy.json
+++ b/src/i18n/ja_easy.json
@@ -27,7 +27,7 @@
},
"exporter": {
"export": "エクスポート",
- "processing": "おまちください。しばらくすると、あなたのファイルをダウンロードするように、メッセージがでます。"
+ "processing": "おまちください。しばらくすると、あなたのファイルをダウンロードするように、メッセージがでます"
},
"features_panel": {
"chat": "チャット",
@@ -39,7 +39,7 @@
"who_to_follow": "おすすめユーザー"
},
"finder": {
- "error_fetching_user": "ユーザーけんさくがエラーになりました。",
+ "error_fetching_user": "ユーザーけんさくがエラーになりました",
"find_user": "ユーザーをさがす"
},
"general": {
@@ -80,9 +80,9 @@
"enter_recovery_code": "リカバリーコードをいれてください",
"enter_two_factor_code": "2-ファクターコードをいれてください",
"recovery_code": "リカバリーコード",
- "heading" : {
- "totp" : "2-ファクターにんしょう",
- "recovery" : "2-ファクターリカバリー"
+ "heading": {
+ "totp": "2-ファクターにんしょう",
+ "recovery": "2-ファクターリカバリー"
}
},
"media_modal": {
@@ -107,7 +107,7 @@
"preferences": "せってい"
},
"notifications": {
- "broken_favorite": "ステータスがみつかりません。さがしています...",
+ "broken_favorite": "ステータスがみつかりません。さがしています…",
"favorited_you": "あなたのステータスがおきにいりされました",
"followed_you": "フォローされました",
"load_older": "ふるいつうちをみる",
@@ -172,10 +172,10 @@
"unlisted": "このとうこうは、パブリックタイムラインと、つながっているすべてのネットワークでは、みることができません"
},
"scope": {
- "direct": "ダイレクト: メンションされたユーザーのみにとどきます。",
- "private": "フォロワーげんてい: フォロワーのみにとどきます。",
- "public": "パブリック: パブリックタイムラインにとどきます。",
- "unlisted": "アンリステッド: パブリックタイムラインにとどきません。"
+ "direct": "ダイレクト: メンションされたユーザーのみにとどきます",
+ "private": "フォロワーげんてい: フォロワーのみにとどきます",
+ "public": "パブリック: パブリックタイムラインにとどきます",
+ "unlisted": "アンリステッド: パブリックタイムラインにとどきません"
}
},
"registration": {
@@ -212,17 +212,17 @@
"security": "セキュリティ",
"enter_current_password_to_confirm": "あなたのアイデンティティをたしかめるため、あなたのいまのパスワードをかいてください",
"mfa": {
- "otp" : "OTP",
- "setup_otp" : "OTPをつくる",
- "wait_pre_setup_otp" : "OTPをよういしています",
- "confirm_and_enable" : "OTPをたしかめて、ゆうこうにする",
+ "otp": "OTP",
+ "setup_otp": "OTPをつくる",
+ "wait_pre_setup_otp": "OTPをよういしています",
+ "confirm_and_enable": "OTPをたしかめて、ゆうこうにする",
"title": "2-ファクターにんしょう",
- "generate_new_recovery_codes" : "あたらしいリカバリーコードをつくる",
- "warning_of_generate_new_codes" : "あたらしいリカバリーコードをつくったら、ふるいコードはつかえなくなります。",
- "recovery_codes" : "リカバリーコード。",
- "waiting_a_recovery_codes": "バックアップコードをうけとっています...",
- "recovery_codes_warning" : "コードをかきうつすか、ひとにみられないところにセーブしてください。そうでなければ、あなたはこのコードをふたたびみることはできません。もしあなたが、2FAアプリのアクセスをうしなって、なおかつ、リカバリーコードもおもいだせないならば、あなたはあなたのアカウントから、しめだされます。",
- "authentication_methods" : "にんしょうメソッド",
+ "generate_new_recovery_codes": "あたらしいリカバリーコードをつくる",
+ "warning_of_generate_new_codes": "あたらしいリカバリーコードをつくったら、ふるいコードはつかえなくなります。",
+ "recovery_codes": "リカバリーコード。",
+ "waiting_a_recovery_codes": "バックアップコードをうけとっています…",
+ "recovery_codes_warning": "コードをかきうつすか、ひとにみられないところにセーブしてください。そうでなければ、あなたはこのコードをふたたびみることはできません。もしあなたが、2FAアプリのアクセスをうしなって、なおかつ、リカバリーコードもおもいだせないならば、あなたはあなたのアカウントから、しめだされます。",
+ "authentication_methods": "にんしょうメソッド",
"scan": {
"title": "スキャン",
"desc": "あなたの2-ファクターアプリをつかって、このQRコードをスキャンするか、テキストキーをうちこんでください:",
@@ -273,12 +273,12 @@
"pad_emoji": "えもじをピッカーでえらんだとき、えもじのまわりにスペースをいれる",
"export_theme": "セーブ",
"filtering": "フィルタリング",
- "filtering_explanation": "これらのことばをふくむすべてのものがミュートされます。1ぎょうに1つのことばをかいてください。",
+ "filtering_explanation": "これらのことばをふくむすべてのものがミュートされます。1ぎょうに1つのことばをかいてください",
"follow_export": "フォローのエクスポート",
"follow_export_button": "エクスポート",
"follow_export_processing": "おまちください。まもなくファイルをダウンロードできます。",
"follow_import": "フォローインポート",
- "follow_import_error": "フォローのインポートがエラーになりました。",
+ "follow_import_error": "フォローのインポートがエラーになりました",
"follows_imported": "フォローがインポートされました! すこしじかんがかかるかもしれません。",
"foreground": "フォアグラウンド",
"general": "ぜんぱん",
@@ -340,7 +340,7 @@
"profile_background": "プロフィールのバックグラウンド",
"profile_banner": "プロフィールバナー",
"profile_tab": "プロフィール",
- "radii_help": "インターフェースのまるさをせっていする。",
+ "radii_help": "インターフェースのまるさをせっていする",
"replies_in_timeline": "タイムラインのリプライ",
"reply_visibility_all": "すべてのリプライをみる",
"reply_visibility_following": "わたしにあてられたリプライと、フォローしているひとからのリプライをみる",
@@ -367,7 +367,7 @@
"streaming": "うえまでスクロールしたとき、じどうてきにストリーミングする",
"text": "もじ",
"theme": "テーマ",
- "theme_help": "カラーテーマをカスタマイズできます",
+ "theme_help": "カラーテーマをカスタマイズできます。",
"theme_help_v2_1": "チェックボックスをONにすると、コンポーネントごとに、いろと、とうめいどを、オーバーライドできます。「すべてクリア」ボタンをおすと、すべてのオーバーライドを、やめます。",
"theme_help_v2_2": "バックグラウンドとテキストのコントラストをあらわすアイコンがあります。マウスをホバーすると、くわしいせつめいがでます。とうめいないろをつかっているときは、もっともわるいばあいのコントラストがしめされます。",
"upload_a_photo": "がぞうをアップロード",
@@ -380,11 +380,6 @@
"fun": "おたのしみ",
"greentext": "ミームやじるし",
"notifications": "つうち",
- "notification_setting": "つうちをうけとる:",
- "notification_setting_follows": "あなたがフォローしているひとから",
- "notification_setting_non_follows": "あなたがフォローしていないひとから",
- "notification_setting_followers": "あなたをフォローしているひとから",
- "notification_setting_non_followers": "あなたをフォローしていないひとから",
"notification_mutes": "あるユーザーからのつうちをとめるには、ミュートしてください。",
"notification_blocks": "ブロックしているユーザーからのつうちは、すべてとまります。",
"enable_web_push_notifications": "ウェブプッシュつうちをゆるす",
@@ -407,8 +402,8 @@
"hint": "コントラストは {ratio} です。{level}。({context})",
"level": {
"aa": "AAレベルガイドライン (ミニマル) をみたします",
- "aaa": "AAAレベルガイドライン (レコメンデッド) をみたします。",
- "bad": "ガイドラインをみたしません。"
+ "aaa": "AAAレベルガイドライン (レコメンデッド) をみたします",
+ "bad": "ガイドラインをみたしません"
},
"context": {
"18pt": "おおきい (18ポイントいじょう) テキスト",
@@ -452,8 +447,8 @@
"always_drop_shadow": "ブラウザーがサポートしていれば、つねに {0} がつかわれます。",
"drop_shadow_syntax": "{0} は、{1} パラメーターと {2} キーワードをサポートしていません。",
"avatar_inset": "うちがわのかげと、そとがわのかげを、いっしょにつかうと、とうめいなアバターが、へんなみためになります。",
- "spread_zero": "ひろがりが 0 よりもおおきなかげは、0 とおなじです。",
- "inset_classic": "うちがわのかげは {0} をつかいます。"
+ "spread_zero": "ひろがりが 0 よりもおおきなかげは、0 とおなじです",
+ "inset_classic": "うちがわのかげは {0} をつかいます"
},
"components": {
"panel": "パネル",
@@ -488,7 +483,7 @@
"content": "ほんぶん",
"error": "エラーのれい",
"button": "ボタン",
- "text": "これは{0}と{1}のれいです。",
+ "text": "これは{0}と{1}のれいです",
"mono": "monospace",
"input": "はねだくうこうに、つきました。",
"faint_link": "とてもたすけになるマニュアル",
@@ -591,11 +586,11 @@
"subscribe": "サブスクライブ",
"unsubscribe": "サブスクライブをやめる",
"unblock": "ブロックをやめる",
- "unblock_progress": "ブロックをとりけしています...",
- "block_progress": "ブロックしています...",
+ "unblock_progress": "ブロックをとりけしています…",
+ "block_progress": "ブロックしています…",
"unmute": "ミュートをやめる",
- "unmute_progress": "ミュートをとりけしています...",
- "mute_progress": "ミュートしています...",
+ "unmute_progress": "ミュートをとりけしています…",
+ "mute_progress": "ミュートしています…",
"hide_repeats": "リピートをかくす",
"show_repeats": "リピートをみる",
"admin_menu": {
@@ -643,11 +638,11 @@
"favorite": "おきにいり",
"user_settings": "ユーザーせってい"
},
- "upload":{
+ "upload": {
"error": {
- "base": "アップロードにしっぱいしました。",
- "file_too_big": "ファイルがおおきすぎます [{filesize} {filesizeunit} / {allowedsize} {allowedsizeunit}]",
- "default": "しばらくしてから、ためしてください"
+ "base": "アップロードにしっぱいしました。",
+ "file_too_big": "ファイルがおおきすぎます [{filesize} {filesizeunit} / {allowedsize} {allowedsizeunit}]",
+ "default": "しばらくしてから、ためしてください"
},
"file_size_units": {
"B": "B",
diff --git a/src/i18n/ja_pedantic.json b/src/i18n/ja_pedantic.json
index 0acecf50..07fea45d 100644
--- a/src/i18n/ja_pedantic.json
+++ b/src/i18n/ja_pedantic.json
@@ -343,11 +343,6 @@
"true": "はい"
},
"notifications": "通知",
- "notification_setting": "通知を受け取る:",
- "notification_setting_follows": "あなたがフォローしているユーザーから",
- "notification_setting_non_follows": "あなたがフォローしていないユーザーから",
- "notification_setting_followers": "あなたをフォローしているユーザーから",
- "notification_setting_non_followers": "あなたをフォローしていないユーザーから",
"notification_mutes": "特定のユーザーからの通知を止めるには、ミュートしてください。",
"notification_blocks": "ブロックしているユーザーからの通知は、すべて止まります。",
"enable_web_push_notifications": "ウェブプッシュ通知を許可する",
diff --git a/src/i18n/nb.json b/src/i18n/nb.json
index af0f9a45..b9669a35 100644
--- a/src/i18n/nb.json
+++ b/src/i18n/nb.json
@@ -328,11 +328,6 @@
"true": "ja"
},
"notifications": "Varsler",
- "notification_setting": "Motta varsler i fra:",
- "notification_setting_follows": "Brukere du følger",
- "notification_setting_non_follows": "Brukere du ikke følger",
- "notification_setting_followers": "Brukere som følger deg",
- "notification_setting_non_followers": "Brukere som ikke følger deg",
"notification_mutes": "For å stoppe å motta varsler i fra en spesifikk bruker, kan du dempe dem.",
"notification_blocks": "Hvis du blokkerer en bruker vil det stoppe alle varsler og i tilleg få dem til å slutte å følge deg",
"enable_web_push_notifications": "Skru på pushnotifikasjoner i nettlesere",
diff --git a/src/i18n/nl.json b/src/i18n/nl.json
index 2f2a1786..e7509f12 100644
--- a/src/i18n/nl.json
+++ b/src/i18n/nl.json
@@ -388,9 +388,6 @@
"link": "een leuke kleine link"
}
},
- "notification_setting_follows": "Gebruikers die je volgt",
- "notification_setting_non_follows": "Gebruikers die je niet volgt",
- "notification_setting_followers": "Gebruikers die je volgen",
"notification_setting_privacy": "Privacy",
"notification_setting_privacy_option": "Verberg de afzender en inhoud van push meldingen",
"notification_mutes": "Om niet langer meldingen te ontvangen van een specifieke gebruiker, kun je deze negeren.",
@@ -458,7 +455,6 @@
"upload_a_photo": "Upload een foto",
"fun": "Plezier",
"greentext": "Meme pijlen",
- "notification_setting": "Ontvang meldingen van:",
"block_export_button": "Exporteer je geblokkeerde gebruikers naar een csv bestand",
"block_import_error": "Fout bij importeren blokkades",
"discoverable": "Sta toe dat dit account ontdekt kan worden in zoekresultaten en andere diensten",
@@ -467,7 +463,6 @@
"hide_follows_description": "Niet tonen wie ik volg",
"show_moderator_badge": "Moderators badge tonen in mijn profiel",
"notification_setting_filters": "Filters",
- "notification_setting_non_followers": "Gebruikers die je niet volgen",
"notification_blocks": "Door een gebruiker te blokkeren, ontvang je geen meldingen meer van de gebruiker en wordt je abonnement op de gebruiker opgeheven.",
"version": {
"frontend_version": "Frontend Versie",
diff --git a/src/i18n/oc.json b/src/i18n/oc.json
index 6606c7f2..24001d4a 100644
--- a/src/i18n/oc.json
+++ b/src/i18n/oc.json
@@ -286,11 +286,6 @@
"true": "òc"
},
"notifications": "Notificacions",
- "notification_setting": "Recebre las notificacions de :",
- "notification_setting_follows": "Utilizaires que seguissètz",
- "notification_setting_non_follows": "Utilizaires que seguissètz pas",
- "notification_setting_followers": "Utilizaires que vos seguisson",
- "notification_setting_non_followers": "Utilizaires que vos seguisson pas",
"notification_mutes": "Per recebre pas mai d’un utilizaire en particular, botatz-lo en silenci.",
"notification_blocks": "Blocar un utilizaire arrèsta totas las notificacions tan coma quitar de los seguir.",
"enable_web_push_notifications": "Activar las notificacions web push",
@@ -548,4 +543,4 @@
"people_talking": "{count} personas ne parlan",
"no_results": "Cap de resultats"
}
-} \ No newline at end of file
+}
diff --git a/src/i18n/pl.json b/src/i18n/pl.json
index ee583016..629e8a11 100644
--- a/src/i18n/pl.json
+++ b/src/i18n/pl.json
@@ -34,9 +34,9 @@
},
"domain_mute_card": {
"mute": "Wycisz",
- "mute_progress": "Wyciszam...",
+ "mute_progress": "Wyciszam…",
"unmute": "Odcisz",
- "unmute_progress": "Odciszam..."
+ "unmute_progress": "Odciszam…"
},
"exporter": {
"export": "Eksportuj",
@@ -68,7 +68,10 @@
"disable": "Wyłącz",
"enable": "Włącz",
"confirm": "Potwierdź",
- "verify": "Zweryfikuj"
+ "verify": "Zweryfikuj",
+ "close": "Zamknij",
+ "loading": "Ładowanie…",
+ "retry": "Spróbuj ponownie"
},
"image_cropper": {
"crop_picture": "Przytnij obrazek",
@@ -118,7 +121,8 @@
"user_search": "Wyszukiwanie użytkowników",
"search": "Wyszukiwanie",
"who_to_follow": "Sugestie obserwacji",
- "preferences": "Preferencje"
+ "preferences": "Preferencje",
+ "bookmarks": "Zakładki"
},
"notifications": {
"broken_favorite": "Nieznany status, szukam go…",
@@ -190,7 +194,9 @@
"private": "Tylko dla obserwujących – Umieść dla osób, które cię obserwują",
"public": "Publiczny – Umieść na publicznych osiach czasu",
"unlisted": "Niewidoczny – Nie umieszczaj na publicznych osiach czasu"
- }
+ },
+ "preview_empty": "Pusty",
+ "preview": "Podgląd"
},
"registration": {
"bio": "Bio",
@@ -234,7 +240,7 @@
"generate_new_recovery_codes": "Wygeneruj nowe kody zapasowe",
"warning_of_generate_new_codes": "Po tym gdy wygenerujesz nowe kody zapasowe, stare przestaną działać.",
"recovery_codes": "Kody zapasowe.",
- "waiting_a_recovery_codes": "Otrzymuję kody zapasowe...",
+ "waiting_a_recovery_codes": "Otrzymuję kody zapasowe…",
"recovery_codes_warning": "Spisz kody na kartce papieru, albo zapisz je w bezpiecznym miejscu - inaczej nie zobaczysz ich już nigdy. Jeśli stracisz dostęp do twojej aplikacji 2FA i kodów zapasowych, nie będziesz miał(-a) dostępu do swojego konta.",
"authentication_methods": "Metody weryfikacji",
"scan": {
@@ -403,11 +409,6 @@
"fun": "Zabawa",
"greentext": "Memiczne strzałki",
"notifications": "Powiadomienia",
- "notification_setting": "Otrzymuj powiadomienia od:",
- "notification_setting_follows": "Ludzi których obserwujesz",
- "notification_setting_non_follows": "Ludzi których nie obserwujesz",
- "notification_setting_followers": "Ludzi którzy obserwują ciebie",
- "notification_setting_non_followers": "Ludzi którzy nie obserwują ciebie",
"notification_mutes": "By przestać otrzymywać powiadomienia od jednego użytkownika, wycisz go.",
"notification_blocks": "Blokowanie uzytkownika zatrzymuje wszystkie powiadomienia i odsubskrybowuje go.",
"enable_web_push_notifications": "Włącz powiadomienia push",
@@ -558,7 +559,13 @@
},
"notification_setting_privacy": "Prywatność",
"notification_setting_filters": "Filtry",
- "notification_setting_privacy_option": "Ukryj nadawcę i zawartość powiadomień push"
+ "notification_setting_privacy_option": "Ukryj nadawcę i zawartość powiadomień push",
+ "reset_avatar": "Zresetuj awatar",
+ "profile_fields": {
+ "value": "Zawartość",
+ "label": "Metadane profilu"
+ },
+ "bot": "To konto jest prowadzone przez bota"
},
"time": {
"day": "{0} dzień",
@@ -604,7 +611,8 @@
"show_new": "Pokaż nowe",
"up_to_date": "Na bieżąco",
"no_more_statuses": "Brak kolejnych statusów",
- "no_statuses": "Brak statusów"
+ "no_statuses": "Brak statusów",
+ "reload": "Odśwież"
},
"status": {
"favorites": "Ulubione",
@@ -737,5 +745,16 @@
"password_reset_disabled": "Resetowanie hasła jest wyłączone. Proszę skontaktuj się z administratorem tej instancji.",
"password_reset_required": "Musisz zresetować hasło, by się zalogować.",
"password_reset_required_but_mailer_is_disabled": "Musisz zresetować hasło, ale resetowanie hasła jest wyłączone. Proszę skontaktuj się z administratorem tej instancji."
+ },
+ "file_type": {
+ "file": "Plik"
+ },
+ "chats": {
+ "more": "Więcej",
+ "delete": "Usuń",
+ "you": "Ty:"
+ },
+ "display_date": {
+ "today": "Dzisiaj"
}
}
diff --git a/src/i18n/ru.json b/src/i18n/ru.json
index a128d564..df172935 100644
--- a/src/i18n/ru.json
+++ b/src/i18n/ru.json
@@ -348,12 +348,8 @@
"link": "ссылка"
}
},
- "notification_setting_non_followers": "Не читающие вас",
"allow_following_move": "Разрешить автоматически читать новый аккаунт при перемещении на другой сервер",
- "hide_user_stats": "Не показывать статистику пользователей (например количество читателей)",
- "notification_setting_followers": "Читающие вас",
- "notification_setting_follows": "Читаемые вами",
- "notification_setting_non_follows": "Не читаемые вами"
+ "hide_user_stats": "Не показывать статистику пользователей (например количество читателей)"
},
"timeline": {
"collapse": "Свернуть",
diff --git a/src/i18n/zh.json b/src/i18n/zh.json
index 9c345a77..24b799df 100644
--- a/src/i18n/zh.json
+++ b/src/i18n/zh.json
@@ -334,11 +334,6 @@
"true": "是"
},
"notifications": "通知",
- "notification_setting": "通知来源:",
- "notification_setting_follows": "你所关注的用户",
- "notification_setting_non_follows": "你没有关注的用户",
- "notification_setting_followers": "关注你的用户",
- "notification_setting_non_followers": "没有关注你的用户",
"notification_mutes": "要停止收到某个指定的用户的通知,请使用隐藏功能。",
"notification_blocks": "拉黑一个用户会停掉所有他的通知,等同于取消关注。",
"enable_web_push_notifications": "启用 web 推送通知",
diff --git a/src/modules/api.js b/src/modules/api.js
index 68402602..5e213f0d 100644
--- a/src/modules/api.js
+++ b/src/modules/api.js
@@ -1,5 +1,6 @@
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
import { WSConnectionStatus } from '../services/api/api.service.js'
+import { maybeShowChatNotification } from '../services/chat_utils/chat_utils.js'
import { Socket } from 'phoenix'
const api = {
@@ -77,6 +78,7 @@ const api = {
messages: [message.chatUpdate.lastMessage]
})
dispatch('updateChat', { chat: message.chatUpdate })
+ maybeShowChatNotification(store, message.chatUpdate)
}
}
)
diff --git a/src/modules/chats.js b/src/modules/chats.js
index 228d6256..c7609018 100644
--- a/src/modules/chats.js
+++ b/src/modules/chats.js
@@ -2,6 +2,7 @@ import Vue from 'vue'
import { find, omitBy, orderBy, sumBy } from 'lodash'
import chatService from '../services/chat_service/chat_service.js'
import { parseChat, parseChatMessage } from '../services/entity_normalizer/entity_normalizer.service.js'
+import { maybeShowChatNotification } from '../services/chat_utils/chat_utils.js'
const emptyChatList = () => ({
data: [],
@@ -59,8 +60,12 @@ const chats = {
return chats
})
},
- addNewChats ({ rootState, commit, dispatch, rootGetters }, { chats }) {
- commit('addNewChats', { dispatch, chats, rootGetters })
+ addNewChats (store, { chats }) {
+ const { commit, dispatch, rootGetters } = store
+ const newChatMessageSideEffects = (chat) => {
+ maybeShowChatNotification(store, chat)
+ }
+ commit('addNewChats', { dispatch, chats, rootGetters, newChatMessageSideEffects })
},
updateChat ({ commit }, { chat }) {
commit('updateChat', { chat })
@@ -130,13 +135,17 @@ const chats = {
setCurrentChatId (state, { chatId }) {
state.currentChatId = chatId
},
- addNewChats (state, { _dispatch, chats, _rootGetters }) {
+ addNewChats (state, { chats, newChatMessageSideEffects }) {
chats.forEach((updatedChat) => {
const chat = getChatById(state, updatedChat.id)
if (chat) {
+ const isNewMessage = (chat.lastMessage && chat.lastMessage.id) !== (updatedChat.lastMessage && updatedChat.lastMessage.id)
chat.lastMessage = updatedChat.lastMessage
chat.unread = updatedChat.unread
+ if (isNewMessage && chat.unread) {
+ newChatMessageSideEffects(updatedChat)
+ }
} else {
state.chatList.data.push(updatedChat)
Vue.set(state.chatList.idStore, updatedChat.id, updatedChat)
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index 64f5b587..e108b2a7 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -13,9 +13,8 @@ import {
omitBy
} from 'lodash'
import { set } from 'vue'
-import { isStatusNotification, prepareNotificationObject } from '../services/notification_utils/notification_utils.js'
+import { isStatusNotification, maybeShowNotification } from '../services/notification_utils/notification_utils.js'
import apiService from '../services/api/api.service.js'
-import { muteWordHits } from '../services/status_parser/status_parser.js'
const emptyTl = (userId = 0) => ({
statuses: [],
@@ -77,17 +76,6 @@ export const prepareStatus = (status) => {
return status
}
-const visibleNotificationTypes = (rootState) => {
- return [
- rootState.config.notificationVisibility.likes && 'like',
- rootState.config.notificationVisibility.mentions && 'mention',
- rootState.config.notificationVisibility.repeats && 'repeat',
- rootState.config.notificationVisibility.follows && 'follow',
- rootState.config.notificationVisibility.moves && 'move',
- rootState.config.notificationVisibility.emojiReactions && 'pleroma:emoji_reactions'
- ].filter(_ => _)
-}
-
const mergeOrAdd = (arr, obj, item) => {
const oldItem = obj[item.id]
@@ -325,7 +313,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
}
}
-const addNewNotifications = (state, { dispatch, notifications, older, visibleNotificationTypes, rootGetters }) => {
+const addNewNotifications = (state, { dispatch, notifications, older, visibleNotificationTypes, rootGetters, newNotificationSideEffects }) => {
each(notifications, (notification) => {
if (isStatusNotification(notification.type)) {
notification.action = addStatusToGlobalStorage(state, notification.action).item
@@ -348,27 +336,7 @@ const addNewNotifications = (state, { dispatch, notifications, older, visibleNot
state.notifications.data.push(notification)
state.notifications.idStore[notification.id] = notification
- if ('Notification' in window && window.Notification.permission === 'granted') {
- const notifObj = prepareNotificationObject(notification, rootGetters.i18n)
-
- const reasonsToMuteNotif = (
- notification.seen ||
- state.notifications.desktopNotificationSilence ||
- !visibleNotificationTypes.includes(notification.type) ||
- (
- notification.type === 'mention' && status && (
- status.muted ||
- muteWordHits(status, rootGetters.mergedConfig.muteWords).length === 0
- )
- )
- )
- if (!reasonsToMuteNotif) {
- let desktopNotification = new window.Notification(notifObj.title, notifObj)
- // Chrome is known for not closing notifications automatically
- // according to MDN, anyway.
- setTimeout(desktopNotification.close.bind(desktopNotification), 5000)
- }
- }
+ newNotificationSideEffects(notification)
} else if (notification.seen) {
state.notifications.idStore[notification.id].seen = true
}
@@ -609,8 +577,13 @@ const statuses = {
addNewStatuses ({ rootState, commit }, { statuses, showImmediately = false, timeline = false, noIdUpdate = false, userId, pagination }) {
commit('addNewStatuses', { statuses, showImmediately, timeline, noIdUpdate, user: rootState.users.currentUser, userId, pagination })
},
- addNewNotifications ({ rootState, commit, dispatch, rootGetters }, { notifications, older }) {
- commit('addNewNotifications', { visibleNotificationTypes: visibleNotificationTypes(rootState), dispatch, notifications, older, rootGetters })
+ addNewNotifications (store, { notifications, older }) {
+ const { commit, dispatch, rootGetters } = store
+
+ const newNotificationSideEffects = (notification) => {
+ maybeShowNotification(store, notification)
+ }
+ commit('addNewNotifications', { dispatch, notifications, older, rootGetters, newNotificationSideEffects })
},
setError ({ rootState, commit }, { value }) {
commit('setError', { value })
diff --git a/src/services/chat_utils/chat_utils.js b/src/services/chat_utils/chat_utils.js
new file mode 100644
index 00000000..ab898ced
--- /dev/null
+++ b/src/services/chat_utils/chat_utils.js
@@ -0,0 +1,19 @@
+import { showDesktopNotification } from '../desktop_notification_utils/desktop_notification_utils.js'
+
+export const maybeShowChatNotification = (store, chat) => {
+ if (!chat.lastMessage) return
+ if (store.rootState.chats.currentChatId === chat.id && !document.hidden) return
+
+ const opts = {
+ tag: chat.lastMessage.id,
+ title: chat.account.name,
+ icon: chat.account.profile_image_url,
+ body: chat.lastMessage.content
+ }
+
+ if (chat.lastMessage.attachment && chat.lastMessage.attachment.type === 'image') {
+ opts.image = chat.lastMessage.attachment.preview_url
+ }
+
+ showDesktopNotification(store.rootState, opts)
+}
diff --git a/src/services/desktop_notification_utils/desktop_notification_utils.js b/src/services/desktop_notification_utils/desktop_notification_utils.js
new file mode 100644
index 00000000..b84a1f75
--- /dev/null
+++ b/src/services/desktop_notification_utils/desktop_notification_utils.js
@@ -0,0 +1,9 @@
+export const showDesktopNotification = (rootState, desktopNotificationOpts) => {
+ if (!('Notification' in window && window.Notification.permission === 'granted')) return
+ if (rootState.statuses.notifications.desktopNotificationSilence) { return }
+
+ const desktopNotification = new window.Notification(desktopNotificationOpts.title, desktopNotificationOpts)
+ // Chrome is known for not closing notifications automatically
+ // according to MDN, anyway.
+ setTimeout(desktopNotification.close.bind(desktopNotification), 5000)
+}
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index 7ea8a16c..c1bf8535 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -79,6 +79,7 @@ export const parseUser = (data) => {
const relationship = data.pleroma.relationship
output.background_image = data.pleroma.background_image
+ output.favicon = data.pleroma.favicon
output.token = data.pleroma.chat_token
if (relationship) {
diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js
index 5cc19215..d912d19f 100644
--- a/src/services/notification_utils/notification_utils.js
+++ b/src/services/notification_utils/notification_utils.js
@@ -1,16 +1,22 @@
import { filter, sortBy, includes } from 'lodash'
+import { muteWordHits } from '../status_parser/status_parser.js'
+import { showDesktopNotification } from '../desktop_notification_utils/desktop_notification_utils.js'
export const notificationsFromStore = store => store.state.statuses.notifications.data
-export const visibleTypes = store => ([
- store.state.config.notificationVisibility.likes && 'like',
- store.state.config.notificationVisibility.mentions && 'mention',
- store.state.config.notificationVisibility.repeats && 'repeat',
- store.state.config.notificationVisibility.follows && 'follow',
- store.state.config.notificationVisibility.followRequest && 'follow_request',
- store.state.config.notificationVisibility.moves && 'move',
- store.state.config.notificationVisibility.emojiReactions && 'pleroma:emoji_reaction'
-].filter(_ => _))
+export const visibleTypes = store => {
+ const rootState = store.rootState || store.state
+
+ return ([
+ rootState.config.notificationVisibility.likes && 'like',
+ rootState.config.notificationVisibility.mentions && 'mention',
+ rootState.config.notificationVisibility.repeats && 'repeat',
+ rootState.config.notificationVisibility.follows && 'follow',
+ rootState.config.notificationVisibility.followRequest && 'follow_request',
+ rootState.config.notificationVisibility.moves && 'move',
+ rootState.config.notificationVisibility.emojiReactions && 'pleroma:emoji_reaction'
+ ].filter(_ => _))
+}
const statusNotifications = ['like', 'mention', 'repeat', 'pleroma:emoji_reaction']
@@ -32,6 +38,22 @@ const sortById = (a, b) => {
}
}
+const isMutedNotification = (store, notification) => {
+ if (!notification.status) return
+ return notification.status.muted || muteWordHits(notification.status, store.rootGetters.mergedConfig.muteWords).length > 0
+}
+
+export const maybeShowNotification = (store, notification) => {
+ const rootState = store.rootState || store.state
+
+ if (notification.seen) return
+ if (!visibleTypes(store).includes(notification.type)) return
+ if (notification.type === 'mention' && isMutedNotification(store, notification)) return
+
+ const notificationObject = prepareNotificationObject(notification, store.rootGetters.i18n)
+ showDesktopNotification(rootState, notificationObject)
+}
+
export const filteredNotificationsFromStore = (store, types) => {
// map is just to clone the array since sort mutates it and it causes some issues
let sortedNotifications = notificationsFromStore(store).map(_ => _).sort(sortById)
diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js
index d282074a..80be02ca 100644
--- a/src/services/notifications_fetcher/notifications_fetcher.service.js
+++ b/src/services/notifications_fetcher/notifications_fetcher.service.js
@@ -35,7 +35,7 @@ const fetchAndUpdate = ({ store, credentials, older = false }) => {
const notifications = timelineData.data
const readNotifsIds = notifications.filter(n => n.seen).map(n => n.id)
const numUnseenNotifs = notifications.length - readNotifsIds.length
- if (numUnseenNotifs > 0) {
+ if (numUnseenNotifs > 0 && readNotifsIds.length > 0) {
args['since'] = Math.max(...readNotifsIds)
fetchNotifications({ store, args, older })
}
diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js
index 214294eb..d0cddf84 100644
--- a/src/services/timeline_fetcher/timeline_fetcher.service.js
+++ b/src/services/timeline_fetcher/timeline_fetcher.service.js
@@ -43,7 +43,9 @@ const fetchAndUpdate = ({
args['userId'] = userId
args['tag'] = tag
args['withMuted'] = !hideMutedPosts
- if (loggedIn) args['replyVisibility'] = replyVisibility
+ if (loggedIn && ['friends', 'public', 'publicAndExternal'].includes(timeline)) {
+ args['replyVisibility'] = replyVisibility
+ }
const numStatusesBeforeFetch = timelineData.statuses.length