Merge remote-tracking branch 'origin/develop' into notifications-thru-sw

This commit is contained in:
Henry Jameson 2023-11-13 17:26:53 +02:00
commit c059f4a7ee
57 changed files with 1296 additions and 86 deletions

View File

@ -3,6 +3,31 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## 2.6.0
### Added
- add the initial i18n translation file for Taiwanese (Hokkien), and modify some related files.
- Implemented a very basic instance administration screen
- Implement quoting
### Fixed
- Keep aspect ratio of custom emoji reaction in notification
- Fix openSettingsModalTab so that it correctly opens Settings modal instead of Admin modal
- Add alt text to emoji picker buttons
- Use export-subst gitattribute to allow tarball builds
- fix reports now showing reason/content
- Fix HTML attribute parsing, discard attributes not strating with a letter
- Make MentionsLine aware of line breaking by non-br elements
- Fix a bug where mentioning a user twice will not fill the mention into the textarea
- Fix parsing non-ascii tags
- Fix OAuth2 token lingering after revocation
- fix regex issue in HTML parser/renderer
- don't display quoted status twice
- fix typo in code that prevented cards from showing at all
- Fix react button not working if reaction accounts are not loaded
- Fix react button misalignment on safari ios
- Fix pinned statuses gone when reloading user timeline
- Fix scrolling emoji selector in modal in safari ios
## 2.5.1 ## 2.5.1
### Fixed ### Fixed
- Checkboxes in settings can now work with screenreaders - Checkboxes in settings can now work with screenreaders

View File

@ -1 +0,0 @@
add the initial i18n translation file for Taiwanese (Hokkien), and modify some related files.

View File

@ -1 +0,0 @@
Implemented a very basic instance administration screen

View File

@ -1 +0,0 @@
Keep aspect ratio of custom emoji reaction in notification

View File

@ -1 +0,0 @@
Fix openSettingsModalTab so that it correctly opens Settings modal instead of Admin modal

View File

@ -1 +0,0 @@
Add alt text to emoji picker buttons

View File

@ -1 +0,0 @@
Use export-subst gitattribute to allow tarball builds

View File

@ -0,0 +1 @@
Support showing extra notifications in the notifications column

View File

@ -0,0 +1 @@
Fix frontend admin tab crashing when no primary frontend is set

View File

@ -1 +0,0 @@
Fix HTML attribute parsing, discard attributes not strating with a letter

View File

@ -1 +0,0 @@
Fix a bug where mentioning a user twice will not fill the mention into the textarea

View File

@ -1 +0,0 @@
Make MentionsLine aware of line breaking by non-br elements

View File

@ -1 +0,0 @@
Fix parsing non-ascii tags

View File

@ -1 +0,0 @@
Fix OAuth2 token lingering after revocation

View File

@ -1 +0,0 @@
fix regex issue in HTML parser/renderer

View File

@ -1 +0,0 @@
fix typo in code that prevented cards from showing at all

View File

@ -1 +0,0 @@
don't display quoted status twice

View File

@ -1 +0,0 @@
Implement quoting

View File

@ -1 +0,0 @@
Fix react button misalignment on safari ios

View File

@ -1 +0,0 @@
Fix react button not working if reaction accounts are not loaded

View File

@ -0,0 +1 @@
Add aria attributes to react and extra buttons

View File

@ -1 +0,0 @@
Fix pinned statuses gone when reloading user timeline

View File

@ -1 +0,0 @@
Fix scrolling emoji selector in modal in safari ios

View File

@ -0,0 +1 @@
Shows the most recent scrobble under each post when available

View File

@ -1,6 +1,6 @@
{ {
"name": "pleroma_fe", "name": "pleroma_fe",
"version": "2.5.0", "version": "2.6.0",
"description": "Pleroma frontend, the default frontend of Pleroma social network server", "description": "Pleroma frontend, the default frontend of Pleroma social network server",
"author": "Pleroma contributors <https://git.pleroma.social/pleroma/pleroma-fe/-/blob/develop/CONTRIBUTORS.md>", "author": "Pleroma contributors <https://git.pleroma.social/pleroma/pleroma-fe/-/blob/develop/CONTRIBUTORS.md>",
"private": false, "private": false,

View File

@ -1,4 +1,5 @@
import Completion from '../../services/completion/completion.js' import Completion from '../../services/completion/completion.js'
import genRandomSeed from '../../services/random_seed/random_seed.service.js'
import EmojiPicker from '../emoji_picker/emoji_picker.vue' import EmojiPicker from '../emoji_picker/emoji_picker.vue'
import Popover from 'src/components/popover/popover.vue' import Popover from 'src/components/popover/popover.vue'
import ScreenReaderNotice from 'src/components/screen_reader_notice/screen_reader_notice.vue' import ScreenReaderNotice from 'src/components/screen_reader_notice/screen_reader_notice.vue'
@ -110,7 +111,7 @@ const EmojiInput = {
}, },
data () { data () {
return { return {
randomSeed: `${Math.random()}`.replace('.', '-'), randomSeed: genRandomSeed(),
input: undefined, input: undefined,
caretEl: undefined, caretEl: undefined,
highlighted: -1, highlighted: -1,

View File

@ -3,7 +3,7 @@
ref="popover" ref="popover"
trigger="click" trigger="click"
popover-class="emoji-picker popover-default" popover-class="emoji-picker popover-default"
:trigger-attrs="{ 'aria-hidden': true }" :trigger-attrs="{ 'aria-hidden': true, tabindex: -1 }"
@show="onPopoverShown" @show="onPopoverShown"
@close="onPopoverClosed" @close="onPopoverClosed"
> >

View File

@ -1,4 +1,5 @@
import Popover from '../popover/popover.vue' import Popover from '../popover/popover.vue'
import genRandomSeed from '../../services/random_seed/random_seed.service.js'
import ConfirmModal from '../confirm_modal/confirm_modal.vue' import ConfirmModal from '../confirm_modal/confirm_modal.vue'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { import {
@ -40,7 +41,8 @@ const ExtraButtons = {
data () { data () {
return { return {
expanded: false, expanded: false,
showingDeleteDialog: false showingDeleteDialog: false,
randomSeed: genRandomSeed()
} }
}, },
methods: { methods: {
@ -152,6 +154,15 @@ const ExtraButtons = {
editingAvailable () { return this.$store.state.instance.editingAvailable }, editingAvailable () { return this.$store.state.instance.editingAvailable },
shouldConfirmDelete () { shouldConfirmDelete () {
return this.$store.getters.mergedConfig.modalOnDelete return this.$store.getters.mergedConfig.modalOnDelete
},
triggerAttrs () {
return {
title: this.$t('status.more_actions'),
id: `popup-trigger-${this.randomSeed}`,
'aria-controls': `popup-menu-${this.randomSeed}`,
'aria-expanded': this.expanded,
'aria-haspopup': 'menu'
}
} }
} }
} }

View File

@ -2,6 +2,7 @@
<Popover <Popover
class="ExtraButtons" class="ExtraButtons"
trigger="click" trigger="click"
:trigger-attrs="triggerAttrs"
placement="top" placement="top"
:offset="{ y: 5 }" :offset="{ y: 5 }"
:bound-to="{ x: 'container' }" :bound-to="{ x: 'container' }"
@ -10,10 +11,15 @@
@close="onClose" @close="onClose"
> >
<template #content="{close}"> <template #content="{close}">
<div class="dropdown-menu"> <div
class="dropdown-menu"
role="menu"
:id="`popup-menu-${randomSeed}`"
>
<button <button
v-if="canMute && !status.thread_muted" v-if="canMute && !status.thread_muted"
class="button-default dropdown-item dropdown-item-icon" class="button-default dropdown-item dropdown-item-icon"
role="menuitem"
@click.prevent="muteConversation" @click.prevent="muteConversation"
> >
<FAIcon <FAIcon
@ -24,6 +30,7 @@
<button <button
v-if="canMute && status.thread_muted" v-if="canMute && status.thread_muted"
class="button-default dropdown-item dropdown-item-icon" class="button-default dropdown-item dropdown-item-icon"
role="menuitem"
@click.prevent="unmuteConversation" @click.prevent="unmuteConversation"
> >
<FAIcon <FAIcon
@ -34,6 +41,7 @@
<button <button
v-if="!status.pinned && canPin" v-if="!status.pinned && canPin"
class="button-default dropdown-item dropdown-item-icon" class="button-default dropdown-item dropdown-item-icon"
role="menuitem"
@click.prevent="pinStatus" @click.prevent="pinStatus"
@click="close" @click="close"
> >
@ -45,6 +53,7 @@
<button <button
v-if="status.pinned && canPin" v-if="status.pinned && canPin"
class="button-default dropdown-item dropdown-item-icon" class="button-default dropdown-item dropdown-item-icon"
role="menuitem"
@click.prevent="unpinStatus" @click.prevent="unpinStatus"
@click="close" @click="close"
> >
@ -57,6 +66,7 @@
<button <button
v-if="!status.bookmarked" v-if="!status.bookmarked"
class="button-default dropdown-item dropdown-item-icon" class="button-default dropdown-item dropdown-item-icon"
role="menuitem"
@click.prevent="bookmarkStatus" @click.prevent="bookmarkStatus"
@click="close" @click="close"
> >
@ -68,6 +78,7 @@
<button <button
v-if="status.bookmarked" v-if="status.bookmarked"
class="button-default dropdown-item dropdown-item-icon" class="button-default dropdown-item dropdown-item-icon"
role="menuitem"
@click.prevent="unbookmarkStatus" @click.prevent="unbookmarkStatus"
@click="close" @click="close"
> >
@ -80,6 +91,7 @@
<button <button
v-if="ownStatus && editingAvailable" v-if="ownStatus && editingAvailable"
class="button-default dropdown-item dropdown-item-icon" class="button-default dropdown-item dropdown-item-icon"
role="menuitem"
@click.prevent="editStatus" @click.prevent="editStatus"
@click="close" @click="close"
> >
@ -91,6 +103,7 @@
<button <button
v-if="isEdited && editingAvailable" v-if="isEdited && editingAvailable"
class="button-default dropdown-item dropdown-item-icon" class="button-default dropdown-item dropdown-item-icon"
role="menuitem"
@click.prevent="showStatusHistory" @click.prevent="showStatusHistory"
@click="close" @click="close"
> >
@ -102,6 +115,7 @@
<button <button
v-if="canDelete" v-if="canDelete"
class="button-default dropdown-item dropdown-item-icon" class="button-default dropdown-item dropdown-item-icon"
role="menuitem"
@click.prevent="deleteStatus" @click.prevent="deleteStatus"
@click="close" @click="close"
> >
@ -112,6 +126,7 @@
</button> </button>
<button <button
class="button-default dropdown-item dropdown-item-icon" class="button-default dropdown-item dropdown-item-icon"
role="menuitem"
@click.prevent="copyLink" @click.prevent="copyLink"
@click="close" @click="close"
> >
@ -123,6 +138,7 @@
<a <a
v-if="!status.is_local" v-if="!status.is_local"
class="button-default dropdown-item dropdown-item-icon" class="button-default dropdown-item dropdown-item-icon"
role="menuitem"
title="Source" title="Source"
:href="status.external_url" :href="status.external_url"
target="_blank" target="_blank"
@ -134,6 +150,7 @@
</a> </a>
<button <button
class="button-default dropdown-item dropdown-item-icon" class="button-default dropdown-item dropdown-item-icon"
role="menuitem"
@click.prevent="reportStatus" @click.prevent="reportStatus"
@click="close" @click="close"
> >

View File

@ -0,0 +1,48 @@
import { mapGetters } from 'vuex'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faUserPlus,
faComments,
faBullhorn
} from '@fortawesome/free-solid-svg-icons'
library.add(
faUserPlus,
faComments,
faBullhorn
)
const ExtraNotifications = {
computed: {
shouldShowChats () {
return this.mergedConfig.showExtraNotifications && this.mergedConfig.showChatsInExtraNotifications && this.unreadChatCount
},
shouldShowAnnouncements () {
return this.mergedConfig.showExtraNotifications && this.mergedConfig.showAnnouncementsInExtraNotifications && this.unreadAnnouncementCount
},
shouldShowFollowRequests () {
return this.mergedConfig.showExtraNotifications && this.mergedConfig.showFollowRequestsInExtraNotifications && this.followRequestCount
},
hasAnythingToShow () {
return this.shouldShowChats || this.shouldShowAnnouncements || this.shouldShowFollowRequests
},
shouldShowCustomizationTip () {
return this.mergedConfig.showExtraNotificationsTip && this.hasAnythingToShow
},
currentUser () {
return this.$store.state.users.currentUser
},
...mapGetters(['unreadChatCount', 'unreadAnnouncementCount', 'followRequestCount', 'mergedConfig'])
},
methods: {
openNotificationSettings () {
return this.$store.dispatch('openSettingsModalTab', 'notifications')
},
dismissConfigurationTip () {
return this.$store.dispatch('setOption', { name: 'showExtraNotificationsTip', value: false })
}
}
}
export default ExtraNotifications

View File

@ -0,0 +1,113 @@
<template>
<div class="ExtraNotifications">
<div
v-if="shouldShowChats"
class="notification unseen"
>
<div class="notification-overlay" />
<router-link
class="button-unstyled -link extra-notification"
:to="{ name: 'chats', params: { username: currentUser.screen_name } }"
>
<FAIcon
fixed-width
class="fa-scale-110 icon"
icon="comments"
/>
{{ $tc('notifications.unread_chats', unreadChatCount, { num: unreadChatCount }) }}
</router-link>
</div>
<div
v-if="shouldShowAnnouncements"
class="notification unseen"
>
<div class="notification-overlay" />
<router-link
class="button-unstyled -link extra-notification"
:to="{ name: 'announcements' }"
>
<FAIcon
fixed-width
class="fa-scale-110 icon"
icon="bullhorn"
/>
{{ $tc('notifications.unread_announcements', unreadAnnouncementCount, { num: unreadAnnouncementCount }) }}
</router-link>
</div>
<div
v-if="shouldShowFollowRequests"
class="notification unseen"
>
<div class="notification-overlay" />
<router-link
class="button-unstyled -link extra-notification"
:to="{ name: 'friend-requests' }"
>
<FAIcon
fixed-width
class="fa-scale-110 icon"
icon="user-plus"
/>
{{ $tc('notifications.unread_follow_requests', followRequestCount, { num: followRequestCount }) }}
</router-link>
</div>
<i18n-t
v-if="shouldShowCustomizationTip"
tag="span"
class="notification tip extra-notification"
keypath="notifications.configuration_tip"
>
<template #theSettings>
<button
class="button-unstyled -link"
@click="openNotificationSettings"
>
{{ $t('notifications.configuration_tip_settings') }}
</button>
</template>
<template #dismiss>
<button
class="button-unstyled -link"
@click="dismissConfigurationTip"
>
{{ $t('notifications.configuration_tip_dismiss') }}
</button>
</template>
</i18n-t>
</div>
</template>
<script src="./extra_notifications.js" />
<style lang="scss">
@import "../../variables";
.ExtraNotifications {
width: 100%;
display: flex;
flex-direction: column;
align-items: stretch;
.notification {
width: 100%;
border-bottom: 1px solid;
border-color: $fallback--border;
border-color: var(--border, $fallback--border);
display: flex;
flex-direction: column;
align-items: stretch;
}
.extra-notification {
padding: 1em;
}
.icon {
margin-right: 0.5em;
}
.tip {
display: inline;
}
}
</style>

View File

@ -39,6 +39,7 @@
<Notifications <Notifications
ref="notifications" ref="notifications"
:no-heading="true" :no-heading="true"
:no-extra="true"
:minimal-mode="true" :minimal-mode="true"
:filter-mode="filterMode" :filter-mode="filterMode"
/> />

View File

@ -1,7 +1,10 @@
import SideDrawer from '../side_drawer/side_drawer.vue' import SideDrawer from '../side_drawer/side_drawer.vue'
import Notifications from '../notifications/notifications.vue' import Notifications from '../notifications/notifications.vue'
import ConfirmModal from '../confirm_modal/confirm_modal.vue' import ConfirmModal from '../confirm_modal/confirm_modal.vue'
import { unseenNotificationsFromStore } from '../../services/notification_utils/notification_utils' import {
unseenNotificationsFromStore,
countExtraNotifications
} from '../../services/notification_utils/notification_utils'
import GestureService from '../../services/gesture_service/gesture_service' import GestureService from '../../services/gesture_service/gesture_service'
import NavigationPins from 'src/components/navigation/navigation_pins.vue' import NavigationPins from 'src/components/navigation/navigation_pins.vue'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
@ -50,7 +53,7 @@ const MobileNav = {
return unseenNotificationsFromStore(this.$store) return unseenNotificationsFromStore(this.$store)
}, },
unseenNotificationsCount () { unseenNotificationsCount () {
return this.unseenNotifications.length return this.unseenNotifications.length + countExtraNotifications(this.$store)
}, },
hideSitename () { return this.$store.state.instance.hideSitename }, hideSitename () { return this.$store.state.instance.hideSitename },
sitename () { return this.$store.state.instance.name }, sitename () { return this.$store.state.instance.name },

View File

@ -1,12 +1,14 @@
import { computed } from 'vue' import { computed } from 'vue'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import Notification from '../notification/notification.vue' import Notification from '../notification/notification.vue'
import ExtraNotifications from '../extra_notifications/extra_notifications.vue'
import NotificationFilters from './notification_filters.vue' import NotificationFilters from './notification_filters.vue'
import notificationsFetcher from '../../services/notifications_fetcher/notifications_fetcher.service.js' import notificationsFetcher from '../../services/notifications_fetcher/notifications_fetcher.service.js'
import { import {
notificationsFromStore, notificationsFromStore,
filteredNotificationsFromStore, filteredNotificationsFromStore,
unseenNotificationsFromStore unseenNotificationsFromStore,
countExtraNotifications
} from '../../services/notification_utils/notification_utils.js' } from '../../services/notification_utils/notification_utils.js'
import FaviconService from '../../services/favicon_service/favicon_service.js' import FaviconService from '../../services/favicon_service/favicon_service.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
@ -23,7 +25,8 @@ const DEFAULT_SEEN_TO_DISPLAY_COUNT = 30
const Notifications = { const Notifications = {
components: { components: {
Notification, Notification,
NotificationFilters NotificationFilters,
ExtraNotifications
}, },
props: { props: {
// Disables panel styles, unread mark, potentially other notification-related actions // Disables panel styles, unread mark, potentially other notification-related actions
@ -31,6 +34,11 @@ const Notifications = {
minimalMode: Boolean, minimalMode: Boolean,
// Custom filter mode, an array of strings, possible values 'mention', 'repeat', 'like', 'follow', used to override global filter for use in "Interactions" timeline // Custom filter mode, an array of strings, possible values 'mention', 'repeat', 'like', 'follow', used to override global filter for use in "Interactions" timeline
filterMode: Array, filterMode: Array,
// Do not show extra notifications
noExtra: {
type: Boolean,
default: false
},
// Disable teleporting (i.e. for /users/user/notifications) // Disable teleporting (i.e. for /users/user/notifications)
disableTeleport: Boolean disableTeleport: Boolean
}, },
@ -65,11 +73,17 @@ const Notifications = {
filteredNotifications () { filteredNotifications () {
return filteredNotificationsFromStore(this.$store, this.filterMode) return filteredNotificationsFromStore(this.$store, this.filterMode)
}, },
unseenCountBadgeText () {
return `${this.unseenCount ? this.unseenCount : ''}${this.extraNotificationsCount ? '*' : ''}`
},
unseenCount () { unseenCount () {
return this.unseenNotifications.length return this.unseenNotifications.length
}, },
extraNotificationsCount () {
return countExtraNotifications(this.$store)
},
unseenCountTitle () { unseenCountTitle () {
return this.unseenCount + (this.unreadChatCount) + this.unreadAnnouncementCount return this.unseenNotifications.length + (this.unreadChatCount) + this.unreadAnnouncementCount
}, },
loading () { loading () {
return this.$store.state.statuses.notifications.loading return this.$store.state.statuses.notifications.loading
@ -94,6 +108,9 @@ const Notifications = {
return this.filteredNotifications.slice(0, this.unseenCount + this.seenToDisplayCount) return this.filteredNotifications.slice(0, this.unseenCount + this.seenToDisplayCount)
}, },
noSticky () { return this.$store.getters.mergedConfig.disableStickyHeaders }, noSticky () { return this.$store.getters.mergedConfig.disableStickyHeaders },
showExtraNotifications () {
return !this.noExtra
},
...mapGetters(['unreadChatCount', 'unreadAnnouncementCount']) ...mapGetters(['unreadChatCount', 'unreadAnnouncementCount'])
}, },
mounted () { mounted () {

View File

@ -17,9 +17,9 @@
<div class="title"> <div class="title">
{{ $t('notifications.notifications') }} {{ $t('notifications.notifications') }}
<span <span
v-if="unseenCount" v-if="unseenCountBadgeText"
class="badge badge-notification unseen-count" class="badge badge-notification unseen-count"
>{{ unseenCount }}</span> >{{ unseenCountBadgeText }}</span>
</div> </div>
<div <div
v-if="showScrollTop" v-if="showScrollTop"
@ -54,6 +54,13 @@
class="panel-body" class="panel-body"
role="feed" role="feed"
> >
<div
v-if="showExtraNotifications"
role="listitem"
class="notification"
>
<extra-notifications />
</div>
<div <div
v-for="notification in notificationsToDisplay" v-for="notification in notificationsToDisplay"
:key="notification.id" :key="notification.id"

View File

@ -1,4 +1,5 @@
import Timeago from 'components/timeago/timeago.vue' import Timeago from 'components/timeago/timeago.vue'
import genRandomSeed from '../../services/random_seed/random_seed.service.js'
import RichContent from 'components/rich_content/rich_content.jsx' import RichContent from 'components/rich_content/rich_content.jsx'
import { forEach, map } from 'lodash' import { forEach, map } from 'lodash'
@ -13,7 +14,7 @@ export default {
return { return {
loading: false, loading: false,
choices: [], choices: [],
randomSeed: `${Math.random()}`.replace('.', '-') randomSeed: genRandomSeed()
} }
}, },
created () { created () {

View File

@ -1,4 +1,5 @@
import statusPoster from '../../services/status_poster/status_poster.service.js' import statusPoster from '../../services/status_poster/status_poster.service.js'
import genRandomSeed from '../../services/random_seed/random_seed.service.js'
import MediaUpload from '../media_upload/media_upload.vue' import MediaUpload from '../media_upload/media_upload.vue'
import ScopeSelector from '../scope_selector/scope_selector.vue' import ScopeSelector from '../scope_selector/scope_selector.vue'
import EmojiInput from '../emoji_input/emoji_input.vue' import EmojiInput from '../emoji_input/emoji_input.vue'
@ -162,7 +163,7 @@ const PostStatusForm = {
} }
return { return {
randomSeed: `${Math.random()}`.replace('.', '-'), randomSeed: genRandomSeed(),
dropFiles: [], dropFiles: [],
uploadingFiles: false, uploadingFiles: false,
error: null, error: null,

View File

@ -11,6 +11,8 @@
/> />
<span <span
class="button-unstyled popover-trigger" class="button-unstyled popover-trigger"
role="button"
:tabindex="0"
:title="$t('tool_tip.add_reaction')" :title="$t('tool_tip.add_reaction')"
@click.stop.prevent="show" @click.stop.prevent="show"
> >

View File

@ -1,6 +1,7 @@
import Select from '../select/select.vue' import Select from '../select/select.vue'
import StatusContent from '../status_content/status_content.vue' import StatusContent from '../status_content/status_content.vue'
import Timeago from '../timeago/timeago.vue' import Timeago from '../timeago/timeago.vue'
import RichContent from 'src/components/rich_content/rich_content.jsx'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
const Report = { const Report = {
@ -10,10 +11,12 @@ const Report = {
components: { components: {
Select, Select,
StatusContent, StatusContent,
Timeago Timeago,
RichContent
}, },
computed: { computed: {
report () { report () {
console.log(this.$store.state.reports.reports[this.reportId] || {})
return this.$store.state.reports.reports[this.reportId] || {} return this.$store.state.reports.reports[this.reportId] || {}
}, },
state: { state: {

View File

@ -33,9 +33,9 @@
> >
<strong>{{ frontend.name }}</strong> <strong>{{ frontend.name }}</strong>
{{ ' ' }} {{ ' ' }}
<span v-if="adminDraft[':pleroma'][':frontends'][':primary'].name === frontend.name"> <span v-if="adminDraft[':pleroma'][':frontends'][':primary']?.name === frontend.name">
<i18n-t <i18n-t
v-if="adminDraft[':pleroma'][':frontends'][':primary'].ref === frontend.refs[0]" v-if="adminDraft[':pleroma'][':frontends'][':primary']?.ref === frontend.refs[0]"
keypath="admin_dash.frontend.is_default" keypath="admin_dash.frontend.is_default"
/> />
<i18n-t <i18n-t

View File

@ -91,6 +91,11 @@
{{ $t('settings.hide_attachments_in_convo') }} {{ $t('settings.hide_attachments_in_convo') }}
</BooleanSetting> </BooleanSetting>
</li> </li>
<li>
<BooleanSetting path="hideScrobbles">
{{ $t('settings.hide_scrobbles') }}
</BooleanSetting>
</li>
</ul> </ul>
</div> </div>
<div <div

View File

@ -51,6 +51,47 @@
</li> </li>
</ul> </ul>
</li> </li>
<li>
<BooleanSetting path="showExtraNotifications">
{{ $t('settings.notification_show_extra') }}
</BooleanSetting>
</li>
<li>
<ul class="setting-list suboptions">
<li>
<BooleanSetting
path="showChatsInExtraNotifications"
:disabled="!mergedConfig.showExtraNotifications"
>
{{ $t('settings.notification_extra_chats') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting
path="showAnnouncementsInExtraNotifications"
:disabled="!mergedConfig.showExtraNotifications"
>
{{ $t('settings.notification_extra_announcements') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting
path="showFollowRequestsInExtraNotifications"
:disabled="!mergedConfig.showExtraNotifications"
>
{{ $t('settings.notification_extra_follow_requests') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting
path="showExtraNotificationsTip"
:disabled="!mergedConfig.showExtraNotifications"
>
{{ $t('settings.notification_extra_tip') }}
</BooleanSetting>
</li>
</ul>
</li>
</ul> </ul>
</div> </div>

View File

@ -39,7 +39,8 @@ import {
faThumbtack, faThumbtack,
faChevronUp, faChevronUp,
faChevronDown, faChevronDown,
faAngleDoubleRight faAngleDoubleRight,
faPlay
} from '@fortawesome/free-solid-svg-icons' } from '@fortawesome/free-solid-svg-icons'
library.add( library.add(
@ -59,7 +60,8 @@ library.add(
faThumbtack, faThumbtack,
faChevronUp, faChevronUp,
faChevronDown, faChevronDown,
faAngleDoubleRight faAngleDoubleRight,
faPlay
) )
const camelCase = name => name.charAt(0).toUpperCase() + name.slice(1) const camelCase = name => name.charAt(0).toUpperCase() + name.slice(1)
@ -415,6 +417,12 @@ const Status = {
}, },
shouldDisplayQuote () { shouldDisplayQuote () {
return this.quotedStatus && this.displayQuote return this.quotedStatus && this.displayQuote
},
scrobblePresent () {
return !this.mergedConfig.hideScrobbles && this.status.user.latestScrobble && this.status.user.latestScrobble.artist
},
scrobble () {
return this.status.user.latestScrobble
} }
}, },
methods: { methods: {

View File

@ -249,6 +249,24 @@
</button> </button>
</span> </span>
</div> </div>
<div class="status-rich-presence" v-if="scrobblePresent">
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="music"
/>
{{ scrobble.artist }} {{ scrobble.title }}
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="play"
/>
<span class="status-rich-presence-time">
<Timeago
template-key="time.in_past"
:time="scrobble.created_at"
:auto-update="60"
/>
</span>
</div>
<div <div
v-if="isReply || hasMentionsLine" v-if="isReply || hasMentionsLine"
class="heading-reply-row" class="heading-reply-row"

View File

@ -205,7 +205,13 @@
"migrated_to": "migrated to", "migrated_to": "migrated to",
"reacted_with": "reacted with {0}", "reacted_with": "reacted with {0}",
"submitted_report": "submitted a report", "submitted_report": "submitted a report",
"poll_ended": "poll has ended" "poll_ended": "poll has ended",
"unread_announcements": "{num} unread announcement | {num} unread announcements",
"unread_chats": "{num} unread chat | {num} unread chats",
"unread_follow_requests": "{num} new follow request | {num} new follow requests",
"configuration_tip": "You can customize what to display here in {theSettings}. {dismiss}",
"configuration_tip_settings": "the settings",
"configuration_tip_dismiss": "Do not show again"
}, },
"polls": { "polls": {
"add_poll": "Add poll", "add_poll": "Add poll",
@ -489,6 +495,7 @@
"hide_muted_posts": "Hide posts of muted users", "hide_muted_posts": "Hide posts of muted users",
"mute_bot_posts": "Mute bot posts", "mute_bot_posts": "Mute bot posts",
"hide_bot_indication": "Hide bot indication in posts", "hide_bot_indication": "Hide bot indication in posts",
"hide_scrobbles": "Hide scrobbles",
"hide_all_muted_posts": "Hide muted posts", "hide_all_muted_posts": "Hide muted posts",
"max_thumbnails": "Maximum amount of thumbnails per post (empty = no limit)", "max_thumbnails": "Maximum amount of thumbnails per post (empty = no limit)",
"hide_isp": "Hide instance-specific panel", "hide_isp": "Hide instance-specific panel",
@ -561,6 +568,11 @@
"notification_visibility_moves": "User Migrates", "notification_visibility_moves": "User Migrates",
"notification_visibility_emoji_reactions": "Reactions", "notification_visibility_emoji_reactions": "Reactions",
"notification_visibility_polls": "Ends of polls you voted in", "notification_visibility_polls": "Ends of polls you voted in",
"notification_show_extra": "Show extra notifications in the notifications column",
"notification_extra_chats": "Show unread chats",
"notification_extra_announcements": "Show unread announcements",
"notification_extra_follow_requests": "Show new follow requests",
"notification_extra_tip": "Show the customization tip for extra notifications",
"no_rich_text_description": "Strip rich text formatting from all posts", "no_rich_text_description": "Strip rich text formatting from all posts",
"no_blocks": "No blocks", "no_blocks": "No blocks",
"no_mutes": "No mutes", "no_mutes": "No mutes",
@ -1033,7 +1045,8 @@
"reaction_count_label": "{num} person reacted | {num} people reacted", "reaction_count_label": "{num} person reacted | {num} people reacted",
"hide_quote": "Hide the quoted status", "hide_quote": "Hide the quoted status",
"display_quote": "Display the quoted status", "display_quote": "Display the quoted status",
"invisible_quote": "Quoted status unavailable: {link}" "invisible_quote": "Quoted status unavailable: {link}",
"more_actions": "More actions on this status"
}, },
"user_card": { "user_card": {
"approve": "Approve", "approve": "Approve",

View File

@ -172,12 +172,14 @@
"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_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.", "direct_warning_to_all": "Ĉi tiu afiŝo estos videbla al ĉiuj menciitaj uzantoj.",
"media_description": "Priskribo de vidaŭdaĵo", "media_description": "Priskribo de vidaŭdaĵo",
"post": "Afiŝo", "post": "Afiŝi",
"edit_remote_warning": "Aliaj foraj nodoj eble ne subtenas redaktadon, kaj ne povos ricevi pli novan version de via afiŝo.", "edit_remote_warning": "Aliaj foraj nodoj eble ne subtenas redaktadon, kaj ne povos ricevi pli novan version de via afiŝo.",
"edit_unsupported_warning": "Pleroma ne subtenas redaktadon de mencioj aŭ enketoj.", "edit_unsupported_warning": "Pleroma ne subtenas redaktadon de mencioj aŭ enketoj.",
"edit_status": "Redakti afiŝon", "edit_status": "Redakti afiŝon",
"content_type_selection": "Formo de afiŝo", "content_type_selection": "Formo de afiŝo",
"scope_notice_dismiss": "Fermi ĉi tiun avizon" "scope_notice_dismiss": "Fermi ĉi tiun avizon",
"reply_option": "Respondi al ĉi tiu afiŝo",
"quote_option": "Citi ĉi tiun afiŝon"
}, },
"registration": { "registration": {
"bio": "Priskribo", "bio": "Priskribo",
@ -873,7 +875,8 @@
"symbols": "Simboloj", "symbols": "Simboloj",
"travel-and-places": "Vojaĝoj kaj lokoj" "travel-and-places": "Vojaĝoj kaj lokoj"
}, },
"regional_indicator": "Regiona marko {letter}" "regional_indicator": "Regiona marko {letter}",
"unpacked": "Malpakitaj bildosignoj"
}, },
"polls": { "polls": {
"not_enough_options": "Tro malmultaj unikaj elektebloj en la enketo", "not_enough_options": "Tro malmultaj unikaj elektebloj en la enketo",

View File

@ -558,7 +558,7 @@
"discoverable": "검색 결과나 다른 서비스들에서 이 계정을 찾을 수 있도록 허용", "discoverable": "검색 결과나 다른 서비스들에서 이 계정을 찾을 수 있도록 허용",
"pad_emoji": "에모지를 선택창에서 고를 때 띄어쓰기를 집어넣기", "pad_emoji": "에모지를 선택창에서 고를 때 띄어쓰기를 집어넣기",
"wordfilter": "단어 필터", "wordfilter": "단어 필터",
"word_filter_and_more": "단어 필터 그리고 더보기...", "word_filter_and_more": "단어 필터 및 기타 설정...",
"accent": "강조", "accent": "강조",
"hide_media_previews": "미디어 미리보기 숨기기", "hide_media_previews": "미디어 미리보기 숨기기",
"max_thumbnails": "게시물 하나 당 최대로 보여질 섬네일 개수 (비워두면 제한을 두지 않습니다)", "max_thumbnails": "게시물 하나 당 최대로 보여질 섬네일 개수 (비워두면 제한을 두지 않습니다)",
@ -686,7 +686,15 @@
"remove_language": "삭제", "remove_language": "삭제",
"primary_language": "주 언어:", "primary_language": "주 언어:",
"fallback_language": "보조 언어 {index}:", "fallback_language": "보조 언어 {index}:",
"confirm_dialogs_logout": "로그아웃" "confirm_dialogs_logout": "로그아웃",
"url": "URL",
"preview": "미리보기",
"commit_value": "저장",
"commit_value_tooltip": "값이 저장되지 않았습니다, 버튼을 눌러 변경사항을 반영하세요",
"reset_value": "초기화",
"reset_value_tooltip": "변경사항 초기화",
"hard_reset_value": "완전 초기화",
"hard_reset_value_tooltip": "스토리지에서 설정을 제거하고, 기본값을 사용하도록 강제합니다"
}, },
"timeline": { "timeline": {
"collapse": "접기", "collapse": "접기",
@ -703,7 +711,8 @@
"no_more_statuses": "새 게시물 없음", "no_more_statuses": "새 게시물 없음",
"socket_reconnected": "실시간 연결 됨", "socket_reconnected": "실시간 연결 됨",
"socket_broke": "실시간 연결이 끊어짐: CloseEvent 코드 {0}", "socket_broke": "실시간 연결이 끊어짐: CloseEvent 코드 {0}",
"quick_filter_settings": "빠른 필터 설정" "quick_filter_settings": "빠른 필터 설정",
"quick_view_settings": "빠른 뷰 설정"
}, },
"user_card": { "user_card": {
"approve": "승인", "approve": "승인",
@ -774,7 +783,33 @@
"approve_confirm_accept_button": "승인", "approve_confirm_accept_button": "승인",
"approve_confirm_cancel_button": "승인 안 함", "approve_confirm_cancel_button": "승인 안 함",
"approve_confirm": "{user}의 팔로우 요청을 승인할까요?", "approve_confirm": "{user}의 팔로우 요청을 승인할까요?",
"block_confirm_title": "차단 확인" "block_confirm_title": "차단 확인",
"note": "노트",
"unfollow_confirm": "정말 {user}를 팔로우 해제하시겠습니까?",
"unfollow_confirm_accept_button": "팔로우 해제",
"unfollow_confirm_cancel_button": "취소",
"remove_follower_confirm_title": "팔로워 삭제 확인",
"remove_follower_confirm_cancel_button": "냅두기",
"remove_follower_confirm_accept_button": "치우기",
"edit_note_cancel": "취소",
"birthday": "{birthday}에 태어남",
"edit_note": "노트 수정",
"edit_note_apply": "적용",
"deny_confirm_cancel_button": "취소",
"unfollow_confirm_title": "팔로우 해제 확인",
"mute_confirm_accept_button": "뮤트",
"remove_follower_confirm": "정말 {user}를 팔로워에서 치울까요?",
"deny_confirm_accept_button": "거절",
"mute_confirm_title": "뮤트 확인",
"mute_confirm": "정말 {user}를 뮤트할까요?",
"block_confirm_cancel_button": "취소",
"deny_confirm_title": "거절 확인",
"block_confirm": "정말 {user}를 차단할까요?",
"block_confirm_accept_button": "차단",
"mute_confirm_cancel_button": "취소",
"mute_duration_prompt": "이 사용자를 뮤트할 시간 (0으로 두면 무한히):",
"deny_confirm": "{user}의 팔로 요청을 거절할까요?",
"note_blank": "(없음)"
}, },
"user_profile": { "user_profile": {
"timeline_title": "사용자 타임라인", "timeline_title": "사용자 타임라인",
@ -794,7 +829,10 @@
"add_reaction": "반응 추가", "add_reaction": "반응 추가",
"accept_follow_request": "팔로우 요청 승인", "accept_follow_request": "팔로우 요청 승인",
"reject_follow_request": "팔로우 요청 거절", "reject_follow_request": "팔로우 요청 거절",
"bookmark": "북마크" "bookmark": "북마크",
"autocomplete_available": "{number}개의 결과가 있습니다. 위 또는 아래 화살표 키로 탐색할 수 있습니다. | {number}개의 결과가 있습니다. 위 또는 아래 화살표 키로 탐색할 수 있습니다.",
"toggle_expand": "알림을 펼치거나 접어서 전체 게시물을 보기",
"toggle_mute": "알림을 펼치거나 접어서 뮤트한 내용 보기"
}, },
"upload": { "upload": {
"error": { "error": {
@ -840,7 +878,8 @@
"symbols": "기호" "symbols": "기호"
}, },
"keep_open": "열린 채로 두기", "keep_open": "열린 채로 두기",
"regional_indicator": "지역 표시기 {letter}" "regional_indicator": "지역 표시기 {letter}",
"unpacked": "미분류 에모지"
}, },
"polls": { "polls": {
"add_poll": "투표를 추가", "add_poll": "투표를 추가",
@ -1049,7 +1088,8 @@
"update_changelog_here": "변경 내역", "update_changelog_here": "변경 내역",
"update_changelog": "무엇이 바뀌었는지 자세히 알아보시려면, {theFullChangelog}을 참조하세요.", "update_changelog": "무엇이 바뀌었는지 자세히 알아보시려면, {theFullChangelog}을 참조하세요.",
"big_update_content": "저희가 한동안 릴리즈를 안 해서, 익숙하셨던 생김새나 경험과 많이 달라졌을 수 있습니다.", "big_update_content": "저희가 한동안 릴리즈를 안 해서, 익숙하셨던 생김새나 경험과 많이 달라졌을 수 있습니다.",
"update_bugs": "저희가 비록 테스트를 많이 하고 직접 개발 버전을 쓰기도 하지만, 많이 바꾸기도 했고, 몇몇 가지 놓친 점들이 있을 터이니, 사용하면서 불편한 점이나 문제는 {pleromaGitlab}에 제보해주시면 감사하겠습니다. 저희는 겪으신 문제점이나 Pleroma와 Pleroma-FE에 대한 피드백과 제안을 환영합니다." "update_bugs": "저희가 비록 테스트를 많이 하고 직접 개발 버전을 쓰기도 하지만, 많이 바꾸기도 했고, 몇몇 가지 놓친 점들이 있을 터이니, 사용하면서 불편한 점이나 문제는 {pleromaGitlab}에 제보해주시면 감사하겠습니다. 저희는 겪으신 문제점이나 Pleroma와 Pleroma-FE에 대한 피드백과 제안을 환영합니다.",
"art_by": "{linkToArtist} 그림"
}, },
"unicode_domain_indicator": { "unicode_domain_indicator": {
"tooltip": "이 도메인은 아스키 문자가 아닌 문자를 포함하고 있습니다." "tooltip": "이 도메인은 아스키 문자가 아닌 문자를 포함하고 있습니다."
@ -1115,7 +1155,9 @@
"repeat_confirm_cancel_button": "리핏 안 함", "repeat_confirm_cancel_button": "리핏 안 함",
"delete_confirm_title": "삭제 확인", "delete_confirm_title": "삭제 확인",
"delete_confirm_accept_button": "삭제", "delete_confirm_accept_button": "삭제",
"delete_confirm_cancel_button": "냅두기" "delete_confirm_cancel_button": "냅두기",
"delete_error": "게시물 삭제 에러: {0}",
"reaction_count_label": "{num}명이 반응함 | {num}명이 반응함"
}, },
"errors": { "errors": {
"storage_unavailable": "Pleroma가 브라우저 저장소에 접근할 수 없습니다. 로그인이 풀리거나 로컬 설정이 초기화 되는 등 예상치 못한 문제를 겪을 수 있습니다. 쿠키를 활성화 해보세요." "storage_unavailable": "Pleroma가 브라우저 저장소에 접근할 수 없습니다. 로그인이 풀리거나 로컬 설정이 초기화 되는 등 예상치 못한 문제를 겪을 수 있습니다. 쿠키를 활성화 해보세요."
@ -1159,5 +1201,91 @@
"submit_edit_action": "수정본 반영", "submit_edit_action": "수정본 반영",
"cancel_edit_action": "취소", "cancel_edit_action": "취소",
"inactive_message": "이 공지사항은 비활성화 되었습니다" "inactive_message": "이 공지사항은 비활성화 되었습니다"
},
"admin_dash": {
"window_title": "관리",
"wip_notice": "이 관리자 대시보드는 실험적이며 개발 중에 있습니다, {adminFeLink}.",
"old_ui_link": "대신 구 관리자 UI를 사용할 수 있습니다",
"reset_all": "전부 초기화",
"commit_all": "전부 저장",
"tabs": {
"nodb": "DB 설정 불가",
"instance": "인스턴스",
"frontends": "프론트엔드",
"limits": "제한"
},
"nodb": {
"heading": "데이터베이스 설정 기능이 비활성화 되어 있습니다",
"documentation": "관련 문서",
"text2": "대부분의 설정을 건드릴 수 없습니다.",
"text": "백엔드 설정 파일에서 {property}를 {value}로 바꿔야 합니다, {documentation}를 참고하세요."
},
"captcha": {
"kocaptcha": "KoCaptcha",
"native": "내장"
},
"instance": {
"registrations": "유저 가입",
"captcha_header": "캡차",
"kocaptcha": "KoCaptcha 설정",
"access": "인스턴스 접근",
"restrict": {
"timelines": "타임라인 접근",
"profiles": "사용자 프로필 접근",
"activities": "게시물/활동 접근",
"header": "로그인하지 않은 방문자의 접근을 제한",
"description": "특정 API의 접근을 허용할지 말지에 대한 세부 설정입니다. 기본적으로(애매한 체크 표시) 인스턴스가 비공개이면 접근을 차단합니다, 체크 표시는 인스턴스가 공개여도 차단함을 의미합니다, 체크 해제는 인스턴스가 비공개여도 접근을 허용함을 의미합니다. 설정을 바꾸면 예기치 않은 동작이 일어날 수 있음을 유의하세요, 예로 프로필 접근이 차단되면 프로필 정보 없이 게시물이 보여집니다."
},
"instance": "인스턴스 정보"
},
"limits": {
"arbitrary_limits": "임의 제한",
"posts": "게시물 제한",
"uploads": "첨부파일 제한",
"users": "사용자 프로필 제한",
"profile_fields": "프로필 필드 제한",
"user_uploads": "프로필 미디어 제한"
},
"frontend": {
"repository": "리포지토리 링크",
"versions": "사용 가능한 버전",
"build_url": "빌드 URL",
"reinstall": "재설치",
"is_default": "(기본)",
"is_default_custom": "(기본, 버전: {version})",
"install": "설치",
"install_version": "설치된 버전 {version}",
"more_install_options": "설치 옵션 더 보기",
"more_default_options": "기본 설정 옵션 더 보기",
"set_default": "기본으로 설정",
"set_default_version": "버전 {version}을 기본으로 설정",
"wip_notice": "이 부분은 프론트엔드 관리에 대한 백엔드 구현이 미완성이기 때문에 개발 중이고 몇몇 기능이 빠져 있습니다.",
"default_frontend": "기본 프론트엔드",
"default_frontend_tip2": "개발 중: 아직 Pleroma 백엔드가 모든 설치된 프론트엔드 목록을 알려주지 않기 때문에 이름과 ref을 직접 입력해야 합니다. 아래에 있는 목록은 여기 값을 입력하기 위한 단축 버튼입니다.",
"available_frontends": "설치 가능",
"default_frontend_tip": "기본 프론트엔드는 모든 유저에게 보입니다. 현재로썬 유저가 개인적으로 프론트엔드를 선택할 수 있진 않습니다. PleromaFE에서 벗어난다면 저희가 완전히 대체할 때까지는 인스턴스 설정을 위해서 아마도 낡고 버그투성이인 AdminFE를 쓰셔야 할 겁니다."
},
"temp_overrides": {
":pleroma": {
":instance": {
":public": {
"label": "인스턴스를 공개",
"description": "이것을 끄면 모든 API가 로그인한 유저만 사용 가능하게 되며, 로그인하지 않은 사용자에겐 공개와 연합 타임라인이 보이지 않게 됩니다."
},
":limit_to_local_content": {
"label": "로컬 컨텐츠만 검색하도록 제한",
"description": "로그인하지 않은 사람 (기본값), 모두 또는 없음에게 전역 검색을 비활성화합니다"
},
":description_limit": {
"label": "글자수 제한",
"description": "첨부파일 설명문의 글자수 제한"
},
":background_image": {
"label": "배경 이미지",
"description": "배경 이미지 (주로 PleromaFE에서 쓰임)"
}
}
}
}
} }
} }

View File

@ -248,12 +248,12 @@
"regional_indicator": "地區指引 {letter}" "regional_indicator": "地區指引 {letter}"
}, },
"errors": { "errors": {
"storage_unavailable": "Pleroma buē-tàng the̍h 著瀏覽器儲存 ê。Lí ê 登入狀態抑是局部設定 buē 儲存mā 凡勢 tú 著意料外 ê 問題。拍開 cookie 看。" "storage_unavailable": "Pleroma buē-tàng the̍h 著瀏覽器儲存 ê。Lí ê 登入狀態抑是局部設定 buē 儲存mā 凡勢 tú 著意料外 ê 問題。拍開 cookie 看māi。"
}, },
"interactions": { "interactions": {
"favs_repeats": "轉送 kap kah 意", "favs_repeats": "轉送 kap kah 意",
"follows": "最近綴 lí ê", "follows": "最近綴 lí ê",
"emoji_reactions": "繪文字 ê 應", "emoji_reactions": "繪文字 ê 應",
"reports": "檢舉", "reports": "檢舉",
"moves": "用者 ê 移民", "moves": "用者 ê 移民",
"load_older": "載入 koh khah 早 ê 互動" "load_older": "載入 koh khah 早 ê 互動"
@ -275,11 +275,11 @@
"content_warning": "主旨(毋是必要)", "content_warning": "主旨(毋是必要)",
"default": "Tú正kàu高雄ah。", "default": "Tú正kàu高雄ah。",
"direct_warning_to_all": "Tsit ê PO 文通 hōo 逐 ê 提起 ê 用者看見。", "direct_warning_to_all": "Tsit ê PO 文通 hōo 逐 ê 提起 ê 用者看見。",
"direct_warning_to_first_only": "Tsit ê PO 文kan-ta 短信 tú 開始提起 ê 用者tsiah 通看見。", "direct_warning_to_first_only": "Tsit ê PO 文kan-ta佇短phue tú開始提起ê用者tsiah通看見。",
"edit_remote_warning": "別 ê 站臺可能無支援編輯,無法度收著 PO 文上新 ê 版本。", "edit_remote_warning": "別 ê 站臺可能無支援編輯,無法度收著 PO 文上新 ê 版本。",
"edit_unsupported_warning": "Pleroma 無支持編輯 the̍h 起 hām 投票。", "edit_unsupported_warning": "Pleroma 無支持編輯 the̍h 起 hām 投票。",
"posting": "PO 文", "posting": "PO 文",
"preview": "Sing 看覓", "preview": "Sing看māi",
"preview_empty": "空 ê", "preview_empty": "空 ê",
"empty_status_error": "無法度 PO 無檔案 koh 空 ê 狀態", "empty_status_error": "無法度 PO 無檔案 koh 空 ê 狀態",
"media_description_error": "更新媒體失敗,請 koh 試一 kái", "media_description_error": "更新媒體失敗,請 koh 試一 kái",
@ -295,7 +295,9 @@
"public": "公開 - PO kàu 公開時間線", "public": "公開 - PO kàu 公開時間線",
"unlisted": "Mài 列出來 - Mài PO tī 公開時間線" "unlisted": "Mài 列出來 - Mài PO tī 公開時間線"
}, },
"post": "PO 上去" "post": "PO 上去",
"reply_option": "應tsit ê狀態",
"quote_option": "引用tsit ê狀態"
}, },
"registration": { "registration": {
"bio_optional": "介紹(毋是必要)", "bio_optional": "介紹(毋是必要)",
@ -360,7 +362,16 @@
"color": "色彩", "color": "色彩",
"opacity": "無透明度", "opacity": "無透明度",
"contrast": { "contrast": {
"hint": "色彩ê對比率:{ratio}。{level}、 {context}" "hint": "色彩ê對比率:{ratio}。{level}、 {context}",
"level": {
"aa": "合AA級ê準則上kē ê)",
"aaa": "合AAA級ê準則建議ê",
"bad": "無合半ê無障礙準則"
},
"context": {
"18pt": "大18pt 以上)ê文字",
"text": "文字"
}
} }
}, },
"switcher": { "switcher": {
@ -370,7 +381,7 @@
"keep_roundness": "保留邊á角ê khà-buh", "keep_roundness": "保留邊á角ê khà-buh",
"keep_fonts": "保持字型", "keep_fonts": "保持字型",
"reset": "重頭設定", "reset": "重頭設定",
"clear_all": "清掉", "clear_all": "Lóng清掉",
"clear_opacity": "清掉無透明度", "clear_opacity": "清掉無透明度",
"load_theme": "載入主題", "load_theme": "載入主題",
"keep_as_is": "Mài振動", "keep_as_is": "Mài振動",
@ -380,8 +391,116 @@
"upgraded_from_v2": "PleromaFE升級ah主題huân-sè kap lí知影ê無kâng。", "upgraded_from_v2": "PleromaFE升級ah主題huân-sè kap lí知影ê無kâng。",
"v2_imported": "Lí輸入ê檔案是舊版本ê前端用ê。Guán盡量予版本相通毋過可能有所在buē-tàng。", "v2_imported": "Lí輸入ê檔案是舊版本ê前端用ê。Guán盡量予版本相通毋過可能有所在buē-tàng。",
"older_version_imported": "Lí輸入ê檔案是予舊ê前端用ê。", "older_version_imported": "Lí輸入ê檔案是予舊ê前端用ê。",
"future_version_imported": "Lí輸入ê檔案是新ê前端所用ê。" "future_version_imported": "Lí輸入ê檔案是新ê前端所用ê。",
"snapshot_missing": "無主題ê快相佇檔案內所以伊看起來凡勢kap原來預料ê無kâng。",
"snapshot_present": "主題ê快相有載入所以逐ê值lóng khàm過去ah。Lí 通改載入主題實際ê資料。",
"fe_upgraded": "版本更新了後Pleroma前端ê ia̋n-jín 升級ah。",
"fe_downgraded": "Pleroma ê前端滾tńg去ah。",
"migration_snapshot_ok": "為著保險主題快相載入去ah。Lí ē當試載入主題資料。",
"migration_napshot_gone": "快相因故無去ahtsi̍t-kuá所在看起來可能hām lí所想ê無kâng。",
"snapshot_source_mismatch": "版本tshia̋ng-póng上可能因為前端滾轉去koh更新ah若因為用舊版本ê前端主題tsiah改變lí有可能beh用舊ê版本。無著用新ê。"
},
"save_load_hint": "佇揀iah是載入主題ê時「保存」選項保留現tsú時設定ê選項mā佇輸出主題ê時tsūn儲存頭拄á講ê選項。若是逐ê選擇框á無設定逐項設定就ē khǹg佇輸出ê主題。"
},
"common_colors": {
"_tab_label": "一般",
"main": "一般ê色彩",
"foreground_hint": "請看「進階」分頁來調整khah幼ê所在",
"rgbo": "標頭、強調、徽章"
},
"advanced_colors": {
"_tab_label": "進階",
"alert": "警告ê背景",
"alert_error": "錯誤",
"alert_warning": "警告",
"alert_neutral": "其他ê",
"post": "PO文用者紹介",
"badge": "徽章ê背景",
"popover": "提示、目錄、跳出來ê",
"badge_notification": "通知",
"panel_header": "面枋ê標題",
"top_bar": "頂 liâu-á",
"borders": "框á邊",
"buttons": "鈕仔",
"inputs": "輸入框á",
"faint_text": "淺ê文字",
"underlay": "Tshū-á",
"wallpaper": "壁紙",
"poll": "投票數ê圖",
"icons": "標á",
"highlight": "強調ê要素",
"pressed": "Tshi̍h ê 時",
"selectedPost": "選擇ê PO文",
"selectedMenu": "選擇ê目錄項目",
"disabled": "關ê",
"toggled": "切換ê時",
"tabs": "分頁",
"chat": {
"incoming": "收著ê",
"outgoing": "送出ê",
"border": "框á邊"
} }
},
"radii": {
"_tab_label": "邊á角ê khà-buh"
},
"shadows": {
"_tab_label": "影kap光",
"override": "Khàm掉",
"shadow_id": "影 #{value}",
"blur": "予n̄g-n̄g",
"spread": "Hōo 闊",
"inset": "內pîng",
"filter_hint": {
"always_drop_shadow": "警告tsit ê 影一直用 {0}若是瀏覽器支援tsē。",
"drop_shadow_syntax": "{0} 無支援參數 {1} kap 關鍵字 {2}。",
"avatar_inset": "請注意結合內pîng kap外pîng ê影佇標頭,可能佇透明ê標頭現無預料ê結果。",
"spread_zero": "若是「hōo 闊」ê值比0較大影ê顯示ē kap hōo 闊設做0 kâng款",
"inset_classic": "內pîng ê影ē用{0}"
},
"component": "部件",
"hintV3": "針對影lí mā ē當用 {0} 標示法,來用其他ê色彩 khang (slot)。",
"components": {
"panelHeader": "面枋ê標題",
"topBar": "頂 liâu-á",
"avatar": "用者ê標頭(佇個人資料欄位)",
"popup": "跳出來ê kap提醒",
"button": "鈕仔",
"buttonHover": "鈕仔滑鼠ê指標khǹg佇面頂",
"panel": "面枋",
"avatarStatus": "用者ê標頭佇PO文ê顯示",
"buttonPressedHover": "鈕仔滑鼠指標leh khǹg 佇頂懸koh tshi̍h ê時)",
"buttonPressed": "鈕仔leh tshi̍h ê時)",
"input": "輸入框á"
}
},
"fonts": {
"_tab_label": "字型",
"components": {
"interface": "界面",
"input": "輸入框á",
"post": "PO文",
"postCode": "RTF ê PO文ê平闊文字"
},
"family": "字型ê名",
"help": "揀界面元件所用ê字型。若是揀「家己指定」lí著輸入系統內ê字型正確ê名。",
"size": "Sài-suh單位畫素",
"weight": "字ê重(粗度)",
"custom": "家己指定"
},
"preview": {
"header": "先看māi",
"content": "內容",
"error": "錯誤ê例",
"button": "鈕á",
"text": "Tsē是{0}kap{1} ê例",
"mono": "內容",
"input": "Tú正kàu高雄ah。",
"faint_link": "有幫tsān ê手冊",
"fine_print": "讀guán ê {0},毋過學無有路用ê!",
"header_faint": "Tsē OK",
"checkbox": "我有讀過使用條款",
"link": "好ê細ê連結"
} }
}, },
"upload": { "upload": {
@ -598,7 +717,7 @@
"navbar_column_stretch": "伸導覽liâukah 欄平闊", "navbar_column_stretch": "伸導覽liâukah 欄平闊",
"always_show_post_button": "一直顯示「新ê PO文」ê鈕仔", "always_show_post_button": "一直顯示「新ê PO文」ê鈕仔",
"hide_wallpaper": "Khàm站臺ê壁紙", "hide_wallpaper": "Khàm站臺ê壁紙",
"use_one_click_nsfw": "Tshi̍h 一ê就會當拍開敏感內容", "use_one_click_nsfw": "Tshi̍h chi̍t 下就ē當拍開敏感內容",
"hide_post_stats": "Khàm PO文ê統計數據比如kah 意ê額數)", "hide_post_stats": "Khàm PO文ê統計數據比如kah 意ê額數)",
"hide_filtered_statuses": "Khàm 逐ê過濾掉êPO文", "hide_filtered_statuses": "Khàm 逐ê過濾掉êPO文",
"hide_wordfiltered_statuses": "Khàm詞語過濾掉ê狀態", "hide_wordfiltered_statuses": "Khàm詞語過濾掉ê狀態",
@ -627,7 +746,7 @@
"mute_bot_posts": "Kā 機器lâng ê PO文消音", "mute_bot_posts": "Kā 機器lâng ê PO文消音",
"hide_shoutbox": "Khàm 站臺ê留話pang", "hide_shoutbox": "Khàm 站臺ê留話pang",
"account_backup_description": "Tse 予 lí ē當 kā lín 口座 ê 資訊 kap PO 文載落來,毋過 in 猶無法度輸入kàu Pleroma口座 ê 內底。", "account_backup_description": "Tse 予 lí ē當 kā lín 口座 ê 資訊 kap PO 文載落來,毋過 in 猶無法度輸入kàu Pleroma口座 ê 內底。",
"theme_help_v2_1": "拍開選擇框á就 ē 當改掉一寡組件ê色彩kap無透明度。Ji̍h「清掉所有ê」,ē 恢復原來ê款。", "theme_help_v2_1": "拍開選擇框á就 ē 當改掉一寡組件ê色彩kap無透明度。Ji̍h「Lóng清掉」,ē 恢復原來ê款。",
"preload_images": "Kā 圖片先載入", "preload_images": "Kā 圖片先載入",
"hide_user_stats": "Khàm 掉用者ê統計數據(比如:綴ê lâng額", "hide_user_stats": "Khàm 掉用者ê統計數據(比如:綴ê lâng額",
"interfaceLanguage": "界面ê語言", "interfaceLanguage": "界面ê語言",
@ -678,7 +797,7 @@
"notification_visibility_mentions": "提起", "notification_visibility_mentions": "提起",
"notification_visibility_repeats": "轉送", "notification_visibility_repeats": "轉送",
"notification_visibility_moves": "用者suá位", "notification_visibility_moves": "用者suá位",
"notification_visibility_emoji_reactions": "應", "notification_visibility_emoji_reactions": "應",
"notification_visibility_polls": "Lí參與ê選舉辦suah佇", "notification_visibility_polls": "Lí參與ê選舉辦suah佇",
"no_rich_text_description": "Po文mài用RTF格式", "no_rich_text_description": "Po文mài用RTF格式",
"no_blocks": "無封鎖", "no_blocks": "無封鎖",
@ -690,7 +809,7 @@
"show_moderator_badge": "佇我ê個人資料顯示「管理員」證章", "show_moderator_badge": "佇我ê個人資料顯示「管理員」證章",
"nsfw_clickthrough": "Khàm掉敏感ê媒體內容", "nsfw_clickthrough": "Khàm掉敏感ê媒體內容",
"oauth_tokens": "OAuth token", "oauth_tokens": "OAuth token",
"refresh_token": "頭the̍h token", "refresh_token": "頭the̍h token",
"valid_until": "到期佇", "valid_until": "到期佇",
"revoke_token": "撤回", "revoke_token": "撤回",
"panelRadius": "面pang", "panelRadius": "面pang",
@ -716,12 +835,12 @@
"set_new_avatar": "設定新ê標頭", "set_new_avatar": "設定新ê標頭",
"set_new_profile_background": "設定新ê個人資料ê背景", "set_new_profile_background": "設定新ê個人資料ê背景",
"set_new_profile_banner": "設定新ê個人資料ê條á", "set_new_profile_banner": "設定新ê個人資料ê條á",
"reset_avatar": "Tuì頭設定標頭", "reset_avatar": "頭設定標頭",
"reset_profile_background": "Tuì頭設個人資料ê背景", "reset_profile_background": "頭設個人資料ê背景",
"reset_profile_banner": "Tuì頭設個人資料ê條á", "reset_profile_banner": "頭設個人資料ê條á",
"reset_avatar_confirm": "Lí敢確實beh tuì頭設定標頭?", "reset_avatar_confirm": "Lí敢確實beh 頭設定標頭?",
"reset_banner_confirm": "Lí敢確實beh tuì頭設定條á?", "reset_banner_confirm": "Lí敢確實beh 頭設定條á?",
"reset_background_confirm": "Lí敢確實beh tuì頭設定背景?", "reset_background_confirm": "Lí敢確實beh 頭設定背景?",
"settings": "設定", "settings": "設定",
"subject_input_always_show": "一直顯示主旨ê格á", "subject_input_always_show": "一直顯示主旨ê格á",
"subject_line_behavior": "回應ê時khóo-pih主旨", "subject_line_behavior": "回應ê時khóo-pih主旨",
@ -792,15 +911,430 @@
"notification_mutes": "若tsún無愛收tuì指定用者來ê通知著用消音。", "notification_mutes": "若tsún無愛收tuì指定用者來ê通知著用消音。",
"notification_blocks": "封鎖用者ē停止所有i hia來ê通知mā取消訂伊。", "notification_blocks": "封鎖用者ē停止所有i hia來ê通知mā取消訂伊。",
"enable_web_push_notifications": "拍開網頁sak通知ê功能", "enable_web_push_notifications": "拍開網頁sak通知ê功能",
"more_settings": "Koh較tsē ê設定" "more_settings": "Koh較tsē ê設定",
"version": {
"title": "版本",
"backend_version": "後端ê版本",
"frontend_version": "前端ê版本"
},
"commit_value": "儲存",
"commit_value_tooltip": "值無儲存tshi̍h tsit ê 鈕仔來送出你改變ê",
"hard_reset_value": "硬ê重頭設",
"hard_reset_value_tooltip": "Suá掉儲存內底ê設定強制用預設ê值",
"reset_value": "重頭設",
"reset_value_tooltip": "重頭設草稿"
}, },
"status": { "status": {
"favorites": "收藏" "favorites": "收藏",
"repeat_confirm_cancel_button": "Mài轉送",
"delete_confirm_title": "Thâi掉ê確認",
"edit": "編輯狀態",
"edited_at": "頂kái編輯佇{time}",
"pin": "釘佇個人資料",
"unpin": "Tuì個人資料拆掉",
"pinned": "釘入去ê",
"bookmark": "加入冊籤",
"unbookmark": "Tuì冊籤the̍h掉",
"delete_confirm": "Lí kám真ê beh thâi掉tsit ê狀態?",
"delete_confirm_accept_button": "Thâi掉",
"delete_confirm_cancel_button": "保留",
"reply_to": "回應",
"replies_list": "回應:",
"repeats": "轉送",
"repeat_confirm_accept_button": "轉送",
"repeat_confirm_title": "轉送ê確認",
"repeat_confirm": "Lí kám真ê beh轉送tsit ê狀態?",
"delete": "Thâi掉身份",
"delete_error": "Thâi狀態ê時出tshê{0}",
"mentions": "提起",
"move_down": "Kā附件suá kàu正pîng",
"thread_show_full": "展示tsit 條討論線ê所有lóng總有{numStatus}ê狀態,深度上限:{depth}",
"thread_follow": "看討論線tshūn ê部份lóng總有{numStatus}ê狀態)",
"replies_list_with_others": "回應(+其他{numReplies}ê):",
"mute_conversation": "Kā會話消音",
"unmute_conversation": "Kā會話取消消音",
"status_unavailable": "狀態bē當用",
"copy_link": "Khóo-pih 狀態ê連結",
"external_source": "外口ê來源",
"thread_muted": "討論線消音ah",
"thread_muted_and_words": ",有詞語:",
"hide_full_subject": "Khàm掉主題ê全文",
"show_full_subject": "顯示標題ê全文",
"show_content": "顯示內容",
"hide_content": "Khàm掉內容",
"status_deleted": "Tsit篇PO文thâi掉ah",
"nsfw": "敏感ê內容",
"expand": "Thián開",
"you": "",
"plus_more": "Koh有{number}ê",
"many_attachments": "PO文有{number}ê附件",
"collapse_attachments": "Kā附件tshàng起來",
"show_all_attachments": "顯示逐ê附件",
"show_attachment_in_modal": "佇媒體模式顯示",
"show_attachment_description": "Kā敘述先看māi拍開附件會當看kui ê敘述)",
"hide_attachment": "Khàm掉附件",
"attachment_stop_flash": "停止Flash ê播放器",
"remove_attachment": "Kā附件suá走",
"move_up": "Kā附件suá kàu倒pîng",
"open_gallery": "拍開畫廊",
"thread_hide": "Khàm掉討論線",
"thread_show": "顯示討論線",
"thread_show_full_with_icon": "{icon} {text}",
"thread_follow_with_icon": "{icon} {text}",
"ancestor_follow": "看其他{numReplies}ê佇tsit ê狀態ê回應",
"ancestor_follow_with_icon": "{icon} {text}",
"show_all_conversation_with_icon": "{icon} {text}",
"show_all_conversation": "看kui ê會話(有其他{numStatus}ê狀態)",
"show_only_conversation_under_this": "Kan-ta顯示tsit ê狀態ê回應",
"status_history": "狀態ê歷史",
"reaction_count_label": "{num}ê lâng用表情反應",
"hide_quote": "Khàm條引用ê狀態",
"display_quote": "顯示引用ê狀態",
"invisible_quote": "引用ê狀態bē當用{link}"
}, },
"user_card": { "user_card": {
"favorites": "收藏" "favorites": "收藏",
"show_repeats": "顯示轉送",
"hide_repeats": "Khàm掉轉送",
"remove_follower_confirm": "Lí kám真正想beh kā {user} tuì lí所跟綴ê suá走",
"statuses": "狀態",
"admin_menu": {
"activate_account": "啟動口座",
"deactivate_account": "予口座失效",
"delete_account": "Thâi掉口座",
"force_nsfw": "Kā逐ê PO文標做敏感內容",
"strip_media": "Tuì PO文thâi掉媒體",
"force_unlisted": "強制PO文mài列佇公共時間線",
"disable_remote_subscription": "Mài允准tuì其他站臺跟tuè用者",
"sandbox": "強制PO文kan-ta予跟tuè ê看",
"disable_any_subscription": "Mài允准跟tuè任何用者",
"quarantine": "Tuì聯邦禁止用者ê PO文",
"delete_user": "Thâi掉用者ê口座",
"delete_user_data_and_deactivate_confirmation": "Án-ne ē永永thâi掉tsit ê口座ê資料兼hōo失效。Lí kám完全確定",
"grant_admin": "授與行政員ê權",
"revoke_admin": "撤掉行政員ê權",
"moderation": "仲裁",
"grant_moderator": "授與仲裁員ê權",
"revoke_moderator": "撤掉仲裁員ê權"
},
"highlight": {
"disabled": "Mài強調",
"side": "邊á ê花tsuā",
"solid": "孤色ê背景",
"striped": "花tsuā ê背景"
},
"note": "筆記",
"note_blank": "(無)",
"edit_note": "編輯筆記",
"edit_note_apply": "適用",
"approve": "核准",
"approve_confirm_title": "核准ê確認",
"approve_confirm_accept_button": "核准",
"approve_confirm_cancel_button": "Mài核准",
"block": "封鎖",
"blocked": "封鎖ah",
"block_confirm_title": "封鎖ê確認",
"approve_confirm": "Lí kám想beh核准{user}ê跟tuè請求",
"block_confirm": "Lí kám 真正想beh封鎖{user}?",
"block_confirm_accept_button": "封鎖",
"block_confirm_cancel_button": "Mài封鎖",
"deactivated": "停止使用ah",
"deny": "拒絕",
"deny_confirm_title": "拒絕ê確認",
"deny_confirm_accept_button": "拒絕",
"deny_confirm_cancel_button": "Mài拒絕",
"deny_confirm": "Lí kám想beh拒絕{user}ê跟tuè請求",
"edit_profile": "編輯個人資料",
"follow": "跟tuè",
"follow_cancel": "取消請求",
"follow_sent": "請求送ah",
"follow_progress": "Teh請求……",
"follow_unfollow": "無愛跟tuè",
"unfollow_confirm_title": "無愛跟tuè ê確認",
"unfollow_confirm": "lí kám真正無beh跟tuè {user}?",
"unfollow_confirm_accept_button": "無愛跟綴",
"unfollow_confirm_cancel_button": "繼續跟tuè",
"followees": "Teh跟綴",
"followers": "跟綴ê",
"following": "Teh跟tuè",
"follows_you": "跟tuè lí",
"hidden": "Tshàng起來ê",
"its_you": "Tse是lí",
"media": "媒體",
"mention": "提起",
"message": "短phue",
"mute": "消音",
"muted": "消音ê",
"mute_confirm_title": "消音ê確認",
"mute_confirm": "Lí確定想beh kā {user}消音?",
"mute_confirm_accept_button": "消音",
"mute_confirm_cancel_button": "Mài消音",
"mute_duration_prompt": "消音tsit ê用戶ê期限0表示永遠",
"per_day": "/kang",
"remote_follow": "遠距離ê關注",
"remove_follower": "Suá走跟綴ê",
"remove_follower_confirm_title": "Suá走跟tuè者ê確認",
"remove_follower_confirm_accept_button": "Suá走",
"remove_follower_confirm_cancel_button": "保留",
"report": "檢舉",
"subscribe": "注文",
"unsubscribe": "取消注文",
"unblock": "Mài封鎖",
"unblock_progress": "Teh取消封鎖……",
"block_progress": "Leh封鎖……",
"unmute": "Mài消音",
"mute_progress": "Leh消音……",
"unmute_progress": "Leh取消消音……",
"bot": "機器lâng",
"birthday": "出世佇{birthday}",
"edit_note_cancel": "取消"
}, },
"tool_tip": { "tool_tip": {
"favorite": "收藏" "favorite": "收藏",
"repeat": "轉送",
"media_upload": "Kā媒體傳起去",
"reply": "回應",
"add_reaction": "加反應",
"user_settings": "用者ê設定",
"accept_follow_request": "允准跟tuè ê請求",
"reject_follow_request": "拒絕跟tuè ê請求",
"bookmark": "冊籤",
"toggle_expand": "Thián開á是tshàng通知顯示kui篇PO文",
"toggle_mute": "Thián開á是tshàng通知顯露消音ê內容",
"autocomplete_available": "{number} ê結果通用。用頂kap下ê key來看結果。"
},
"password_reset": {
"instruction": "輸入你ê email地址iah是用者ê名。阮ē寄予lí連結通重頭設你ê密碼。",
"password_reset_disabled": "密碼重頭設ê功能無開放。請聯絡lín站臺ê行政員。",
"password_reset_required_but_mailer_is_disabled": "Lí著重設密碼M̄-koh重頭設密碼ê功能無開放。請聯絡lín站臺ê行政員。",
"forgot_password": "Buē記得密碼",
"password_reset": "密碼重頭設",
"placeholder": "你ê email iah是用者ê名",
"check_email": "檢查你ê電子phue箱有重頭設密碼ê連結ê phue無。",
"return_home": "Tńg去頭頁",
"too_many_requests": "Lí已經kàu 試ê回數限制 ah小等leh koh試。",
"password_reset_required": "Lí著重設密碼tsiah通登入。"
},
"admin_dash": {
"window_title": "行政員",
"reset_all": "Kui ê重頭設",
"wip_notice": "Tsit ê 管理 la-jí-báng (dashboard) 是試驗êkoh teh 起做,{adminFeLink}.",
"old_ui_link": "舊ê管理界面佇tsia",
"commit_all": "Lóng總儲存",
"tabs": {
"nodb": "無資料庫ê設置",
"instance": "站臺",
"limits": "限制",
"frontends": "前端"
},
"nodb": {
"heading": "資料庫設置無開放",
"text": "Lí需要改後端ê設置檔案tsiah ē當kā{property}設做{value},請佇{documentation}了解詳細。",
"documentation": "文件",
"text2": "大部份ê設定ē無開放。"
},
"limits": {
"user_uploads": "個人資料ê媒體限制",
"arbitrary_limits": "任何限制",
"posts": "PO文ê限制",
"uploads": "附件ê限制",
"users": "用者個人資料ê限制",
"profile_fields": "個人資料欄位ê限制"
},
"captcha": {
"native": "在來ê",
"kocaptcha": "KoCaptcha"
},
"instance": {
"instance": "站臺ê資訊",
"registrations": "用者ê註冊",
"kocaptcha": "KoCaptcha ê設定",
"restrict": {
"header": "管制無落名ê訪客使用",
"timelines": "讀取時間線",
"profiles": "讀取用者ê個人資料",
"activities": "讀取狀態/活動",
"description": "允准一kuá方面ê API the̍h取資源ê詳細設定。預設無定ê狀態若是站臺毋是公開êē無允准the̍h取選擇框á若勾就算站臺是公開êiáu是無允准the̍h取若無勾就算站臺是私人êmā是允准the̍h取。請注意若是設一kuá設定無預料ê行為可能產生。比如講若是the̍h取個人資料無開放PO文buē顯示個人資料。"
},
"access": "讀取實體",
"captcha_header": "CAPTCHA"
},
"frontend": {
"repository": "原始碼庫ê連結",
"versions": "通用ê版本",
"build_url": "起做URL",
"reinstall": "重頭安裝",
"is_default": "(預設)",
"is_default_custom": "(預設,版本:{version}",
"install": "安裝",
"install_version": "安裝ê版本:{version}",
"more_install_options": "其他ê安裝選項",
"more_default_options": "其他ê預設設定ê選項",
"set_default": "設做預設ê",
"set_default_version": "Kā版本{version}設做預設ê",
"default_frontend_tip": "預設ê前端ē展示予逐ê用者。現在用者無法度揀個人ê前端。若是lí變換無beh用PleromaFE上有可能ē用舊koh問題tsē ê AdminFE 做站臺ê設置佇阮iáu-bē kā伊取代以前。",
"wip_notice": "請注意tsit ê段落iáu teh起做欠缺一寡特點因為後端tuì前端管理ê實做無齊備。",
"default_frontend": "預設ê前端",
"default_frontend_tip2": "Teh起做因為Pleroma後端無適當列出逐ê安裝ê前端lí著手動輸入名字kap引用。下kha ê列單提供寫tsiah-ê 值ê近路。",
"available_frontends": "Ē當安裝"
},
"temp_overrides": {
":pleroma": {
":instance": {
":public": {
"description": "無開放tseē 控制逐êAPI干焦予登入ê用者用mā ē予公開kap聯邦ê時間線buē當予無落名ê訪客the̍h著。",
"label": "站臺是公開ê"
},
":limit_to_local_content": {
"label": "Kan-ta會當tshuē在地ê內容",
"description": "無開放無認證ê用者、逐儂猶是lóng總開放tshuē全球ê網路"
},
":description_limit": {
"label": "限制",
"description": "附件說明ê字元限制"
},
":background_image": {
"label": "背景ê影像",
"description": "背景ê影像主要予PleromaFE用"
}
}
}
}
},
"timeline": {
"up_to_date": "是上新ê",
"collapse": "疊起來",
"conversation": "會話",
"error": "佇the̍h時間線ê時出tshê{0}",
"load_older": "載入舊ê狀態",
"repeated": "轉送ah",
"no_retweet_hint": "PO文hőng標做限定跟綴êá是私人phue無法度轉送",
"show_new": "看新ê",
"reload": "重新載入",
"no_more_statuses": "無其他ê狀態",
"no_statuses": "無狀態",
"socket_reconnected": "實時ê連結成立ah",
"socket_broke": "實時連結拍m̄見ahCloseEvent代碼{0}",
"quick_view_settings": "快速 view ê設定",
"quick_filter_settings": "快速過濾器ê設定"
},
"time": {
"unit": {
"days": "{0}工",
"days_short": "{0}工",
"hours": "{0}點鐘",
"hours_short": "{0}點鐘",
"minutes": "{0}分鐘",
"minutes_short": "{0}分",
"months": "{0}個月",
"months_short": "{0}個月",
"seconds": "{0}秒鐘",
"seconds_short": "{0}秒",
"weeks": "{0}禮拜",
"weeks_short": "{0}週",
"years": "{0}年",
"years_short": "{0}年"
},
"in_future": "koh有{0}",
"in_past": "{0}進前",
"now": "tú正",
"now_short": "tsit-má"
},
"user_reporting": {
"title": "檢舉 {0}",
"forward_description": "Tsit ê口座是別ê站臺ê。Mā kám beh寄報告ê khóo-pih kàu hit ê站?",
"add_comment_description": "本檢舉ē 寄kàu你ê站臺ê仲裁員。Lí會當佇下kha解說檢舉tsit ê口座ê原因:",
"additional_comments": "其他ê意見",
"forward_to": "轉送kàu{0}",
"submit": "送出",
"generic_error": "佇處理lí ê請求ê時出tshê。"
},
"lists": {
"really_delete": "Kám真正 beh thâi列單",
"search": "Tshiau-tshuē用者",
"create": "建立",
"save": "保存改變",
"delete": "Thâi列單",
"lists": "列單",
"new": "新ê列單",
"title": "列單ê標題",
"following_only": "限制佇跟tuè ê",
"manage_lists": "管理列單",
"manage_members": "管理列單ê成員",
"add_members": "Tshiau-tshuē其他ê用者",
"remove_from_list": "Tuì列單suá走",
"add_to_list": "Ke-thinn kàu列單",
"is_in_list": "已經佇列單內底",
"editing_list": "編輯列單 {listTitle}",
"creating_list": "開新ê列單",
"update_title": "保存標題",
"error": "佇操作列單ê時出tshê{0}"
},
"update": {
"update_bugs": "請報告任何問題kap錯誤佇 {pleromaGitlab}因為已經改變真tsē。雖bóng guán徹底試過ka-kī mā用開發版iáu是有可能有無注意ê所在。Guán歡迎lí tuì所tú tio̍h ê問題提出意見kap建議或者是改進Pleroma kap Pleroma-FE ê方法。",
"big_update_title": "請sió等tsi̍t ê",
"update_bugs_gitlab": "Pleroma GitLab",
"big_update_content": "Guán已經有tsi̍t段時間無推出發行所以外觀kap感覺kap lí所慣勢ê凡勢無kâng。",
"update_changelog": "Beh知影改變ê詳細請看{theFullChangelog}。",
"update_changelog_here": "Changelog全文",
"art_by": "美術製作:{linkToArtist}"
},
"user_profile": {
"timeline_title": "用者ê時間線",
"profile_does_not_exist": "Pháinn勢tsit ê個人資料無佇leh。",
"profile_loading_error": "Pháinn勢佇載入tsit ê個人資料ê時出tshê。"
},
"who_to_follow": {
"more": "詳情",
"who_to_follow": "Siáng通tuè"
},
"upload": {
"error": {
"base": "傳起去ê時失敗。",
"message": "傳起去ê時失敗:{0}",
"file_too_big": "檔案siūnn大[{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]",
"default": "Koh試tsi̍t kái"
},
"file_size_units": {
"B": "B",
"KiB": "KiB",
"MiB": "MiB",
"GiB": "GiB",
"TiB": "TiB"
}
},
"search": {
"people": "Lâng",
"hashtags": "井字ê標籤",
"person_talking": "{count}ê lâng teh開講",
"people_talking": "{count}ê lâng teh開講",
"no_results": "無結果",
"no_more_results": "無其他結果",
"load_more": "載入其他結果"
},
"chats": {
"you": "Lí",
"message_user": "送短phue予{nickname}",
"delete": "Thâi掉",
"chats": "開講",
"new": "新ê開講",
"empty_message_error": "Bē當PO空ê短phue",
"more": "其他",
"delete_confirm": "Lí kám真正beh thâi tsit ê短phue",
"error_loading_chat": "佇載入開講ê時出問題。",
"error_sending_message": "佇送短phue ê時出問題。",
"empty_chat_list_placeholder": "Lí iáu buē開講過。開始開講"
},
"file_type": {
"audio": "聲音",
"video": "影片",
"image": "影像",
"file": "檔案"
},
"display_date": {
"today": "今á日"
},
"unicode_domain_indicator": {
"tooltip": "Tsit ê域名含m̄是ascii ê字元。"
} }
} }

View File

@ -121,7 +121,8 @@
"placeholder": "напр. stepan", "placeholder": "напр. stepan",
"logout_confirm": "Ви дійсно хочете вийти?", "logout_confirm": "Ви дійсно хочете вийти?",
"logout_confirm_accept_button": "Вийти", "logout_confirm_accept_button": "Вийти",
"logout_confirm_cancel_button": "Ні, хочу назад!" "logout_confirm_cancel_button": "Ні, хочу назад!",
"logout_confirm_title": "Вихід"
}, },
"importer": { "importer": {
"error": "Під час імпортування файлу сталася помилка.", "error": "Під час імпортування файлу сталася помилка.",
@ -164,7 +165,13 @@
"broken_favorite": "Невідомий допис, шукаю його…", "broken_favorite": "Невідомий допис, шукаю його…",
"error": "Помилка при оновленні сповіщень: {0}", "error": "Помилка при оновленні сповіщень: {0}",
"poll_ended": "опитування закінчено", "poll_ended": "опитування закінчено",
"submitted_report": "подав скаргу" "submitted_report": "подав скаргу",
"unread_announcements": "{num} непрочитане оголошення | {num} непрочитаних оголошень",
"unread_chats": "{num} непрочитаний чат | {num} непрочитаних чатів",
"unread_follow_requests": "{num} новий запит на підписку | {num} нових запитів на підписку",
"configuration_tip": "Ви можете налаштувати, що відображати тут у {theSettings}. {dismiss}",
"configuration_tip_settings": "налаштування",
"configuration_tip_dismiss": "Не показувати знову"
}, },
"nav": { "nav": {
"chats": "Чати", "chats": "Чати",
@ -267,7 +274,8 @@
"activities": "Активності", "activities": "Активності",
"symbols": "Символи", "symbols": "Символи",
"travel-and-places": "Подорожі та Місця" "travel-and-places": "Подорожі та Місця"
} },
"unpacked": "Розпаковані емоджі"
}, },
"post_status": { "post_status": {
"content_type": { "content_type": {
@ -304,7 +312,11 @@
"post": "Опублікувати", "post": "Опублікувати",
"edit_unsupported_warning": "Pleroma не підтримує редагування згадувань чи голосувань.", "edit_unsupported_warning": "Pleroma не підтримує редагування згадувань чи голосувань.",
"edit_status": "Редагувати допис", "edit_status": "Редагувати допис",
"edit_remote_warning": "Інші віддалені інстанси можуть не підтримувати редагування та вони можуть не отримати актуальну версію допису." "edit_remote_warning": "Інші віддалені інстанси можуть не підтримувати редагування та вони можуть не отримати актуальну версію допису.",
"content_type_selection": "Форматування допису",
"scope_notice_dismiss": "Закрити це сповіщення",
"reply_option": "Відповісти на цей допис",
"quote_option": "Процитувати допис"
}, },
"settings": { "settings": {
"blocks_imported": "Блокування імпортовані! Їх обробка триватиме певний час.", "blocks_imported": "Блокування імпортовані! Їх обробка триватиме певний час.",
@ -730,7 +742,7 @@
"conversation_display_tree_quick": "Вигляд дерева", "conversation_display_tree_quick": "Вигляд дерева",
"disable_sticky_headers": "Не закріплювати заголовок колонки зверху на сторінці", "disable_sticky_headers": "Не закріплювати заголовок колонки зверху на сторінці",
"third_column_mode_none": "Не показувати третю колонку взагалі", "third_column_mode_none": "Не показувати третю колонку взагалі",
"third_column_mode_notifications": "Колонка сповіщень", "third_column_mode_notifications": "Колонку сповіщень",
"columns": "Колонки", "columns": "Колонки",
"auto_update": "Автоматично показувати нові дописи", "auto_update": "Автоматично показувати нові дописи",
"use_websockets": "Використовувати вебсокети (Оновлення в реальному часі)", "use_websockets": "Використовувати вебсокети (Оновлення в реальному часі)",
@ -743,7 +755,38 @@
"wordfilter": "Фільтр слів", "wordfilter": "Фільтр слів",
"mention_links": "Посилання для згадування", "mention_links": "Посилання для згадування",
"user_profiles": "Профілі користувачів", "user_profiles": "Профілі користувачів",
"notification_visibility_polls": "Закінчення опитувань, в яких ви проголосували" "notification_visibility_polls": "Закінчення опитувань, в яких ви проголосували",
"remove_language": "Вилучити",
"primary_language": "Основна мова:",
"fallback_language": "Резервна мова {index}:",
"confirm_dialogs_deny_follow": "тим, як відмовити у запиті на підписку",
"confirm_dialogs_remove_follower": "видаленням підписника",
"notification_show_extra": "Показувати додаткові сповіщення в панелі сповіщень",
"notification_extra_chats": "Показувати непрочитані чати",
"notification_extra_announcements": "Показувати непрочитані оголошення",
"notification_extra_follow_requests": "Показувати нові запити на підписку",
"third_column_mode_postform": "Форму відправки повідомлень та панель навігації",
"notification_extra_tip": "Показати пораду з налаштувань для додаткових сповіщень",
"backup_running": "Резервне копіювання триває, оброблено {number} записи. | Резервне копіювання триває, оброблено {number} записів.",
"backup_failed": "Резервне копіювання не вдалося.",
"preview": "Попередній перегляд",
"url": "URL",
"birthday": {
"label": "День народження",
"show_birthday": "Показувати мій день народження"
},
"confirm_dialogs": "Запитувати підтвердження перед",
"confirm_dialogs_repeat": "поширенням допису",
"confirm_dialogs_unfollow": "скасуванням підписки",
"confirm_dialogs_block": "блокуванням користувача",
"confirm_dialogs_mute": "тим, як заглушити користувача",
"show_scrollbars": "Показувати смугу прокрутки на бічних панелях",
"column_sizes": "Розміри панелей",
"column_sizes_sidebar": "Бічна панель",
"add_language": "Додати резервну мову",
"confirm_dialogs_delete": "видаленням допису",
"confirm_dialogs_logout": "виходом із системи",
"confirm_dialogs_approve_follow": "схваленням запиту на підписку"
}, },
"selectable_list": { "selectable_list": {
"select_all": "Вибрати все" "select_all": "Вибрати все"
@ -760,7 +803,8 @@
"password_required": "не може бути порожнім", "password_required": "не може бути порожнім",
"email_required": "не може бути порожнім", "email_required": "не може бути порожнім",
"fullname_required": "не може бути порожнім", "fullname_required": "не може бути порожнім",
"username_required": "не може бути порожнім" "username_required": "не може бути порожнім",
"birthday_required": "не може бути пустим"
}, },
"bio_placeholder": "напр.\nНаш народ завжди прагне волі для себе і бажає її для інших народів. Він боровся і бореться за правду і справедливість. Ми хочемо жити у згоді і взаємному шануванні з усіми народами доброї волі. Такі самі права визнаємо за іншими народами, за які боремося для себе.", "bio_placeholder": "напр.\nНаш народ завжди прагне волі для себе і бажає її для інших народів. Він боровся і бореться за правду і справедливість. Ми хочемо жити у згоді і взаємному шануванні з усіми народами доброї волі. Такі самі права визнаємо за іншими народами, за які боремося для себе.",
"fullname_placeholder": "напр. Степан Бандера", "fullname_placeholder": "напр. Степан Бандера",
@ -778,7 +822,9 @@
"reason": "Причина реєстрації", "reason": "Причина реєстрації",
"bio_optional": "Біографія (необов'язково)", "bio_optional": "Біографія (необов'язково)",
"email_language": "Якою мовою ви бажаєте отримувати електронні листи від сервера?", "email_language": "Якою мовою ви бажаєте отримувати електронні листи від сервера?",
"email_optional": "Ел. пошта (необов'язково)" "email_optional": "Ел. пошта (необов'язково)",
"birthday": "День народження:",
"birthday_optional": "День народження (необов'язково):"
}, },
"who_to_follow": { "who_to_follow": {
"who_to_follow": "На кого підписатися", "who_to_follow": "На кого підписатися",
@ -890,7 +936,8 @@
"grant_moderator": "Надати права модератора", "grant_moderator": "Надати права модератора",
"revoke_admin": "Позбавити прав адміністратора", "revoke_admin": "Позбавити прав адміністратора",
"grant_admin": "Надати права адміністратора", "grant_admin": "Надати права адміністратора",
"quarantine": "Не розповсюджувати дописи на інших інстансах" "quarantine": "Не розповсюджувати дописи на інших інстансах",
"delete_user_data_and_deactivate_confirmation": "Це назовсім видалить дані обліковки й вимкне її. Точно продовжити?"
}, },
"deny": "Відмовити", "deny": "Відмовити",
"block": "Заблокувати", "block": "Заблокувати",
@ -929,7 +976,32 @@
"bot": "Бот", "bot": "Бот",
"edit_profile": "Редагувати профіль", "edit_profile": "Редагувати профіль",
"deactivated": "Деактивований", "deactivated": "Деактивований",
"follow_cancel": "Скасувати запит" "follow_cancel": "Скасувати запит",
"block_confirm_title": "Блокування",
"block_confirm": "Точно заблокувати {user}?",
"mute_confirm_cancel_button": "Ні, не приглушувати",
"note_blank": "(Пусто)",
"edit_note_apply": "Застосувати",
"edit_note_cancel": "Скасувати",
"block_confirm_accept_button": "Так, заблокувати",
"block_confirm_cancel_button": "Ні, не блокувати",
"deny_confirm_title": "Відхилити запит на підписку",
"mute_confirm_accept_button": "Так, приглушити",
"mute_confirm": "Точно приглушити {user}?",
"edit_note": "Редагувати нотатку",
"mute_confirm_title": "Приглушення",
"mute_duration_prompt": "Приглушити користувача на (0 якщо назавжди):",
"approve_confirm_title": "Дозвіл підписатись",
"approve_confirm_accept_button": "Так, дозволити",
"approve_confirm_cancel_button": "Ні, скасувати",
"deny_confirm_accept_button": "Так, відхилити",
"deny_confirm_cancel_button": "Ні, скасувати",
"deny_confirm": "Ви точно хочете відхилити запит на підписку від {user}?",
"unfollow_confirm_title": "Відписка",
"unfollow_confirm": "Точно відписатись від {user}?",
"unfollow_confirm_accept_button": "Так, відписатись",
"unfollow_confirm_cancel_button": "Ні, не відписуватись",
"note": "Приватна нотатка"
}, },
"status": { "status": {
"copy_link": "Скопіювати посилання на допис", "copy_link": "Скопіювати посилання на допис",
@ -965,7 +1037,38 @@
"plus_more": "+{number} більше", "plus_more": "+{number} більше",
"thread_show_full_with_icon": "{icon} {text}", "thread_show_full_with_icon": "{icon} {text}",
"show_only_conversation_under_this": "Показати всі відповіді на цей допис", "show_only_conversation_under_this": "Показати всі відповіді на цей допис",
"status_history": "Історія змін" "status_history": "Історія змін",
"thread_hide": "Сховати гілку",
"open_gallery": "Відкрити галерею",
"repeat_confirm": "Точно поширити допис?",
"repeat_confirm_title": "Підтвердьте поширення",
"repeat_confirm_accept_button": "Так, поширити",
"repeat_confirm_cancel_button": "Ні, не поширювати",
"delete_error": "Помилка при видаленні допису: {0}",
"delete_confirm_accept_button": "Так, видалити",
"delete_confirm_cancel_button": "Ні, лишити",
"delete_confirm_title": "Підтвердьте видалення",
"you": "(ви)",
"collapse_attachments": "Згорнути вкладення",
"show_all_attachments": "Показати всі вкладення",
"hide_attachment": "Сховати вкладення",
"many_attachments": "Вкладень: {number} | Вкладень: {number}",
"attachment_stop_flash": "Зупинити Flash-плеєр",
"thread_follow": "Ще відповідей: {numStatus} | Ще відповідей: {numStatus}",
"remove_attachment": "Видалити вкладення",
"ancestor_follow": "Переглянути ще {numReplies} під цим дописом | Переглянути ще {numReplies} під цим дописом",
"show_all_conversation": "Показати всю розмову (ще дописів: {numStatus}) | Показати всю розмову (ще дописів: {numStatus})",
"move_up": "Посунути вкладення ліворуч",
"move_down": "Посунути вкладення праворуч",
"thread_show": "Показати гілку",
"mentions": "Згадки",
"thread_show_full": "Показати відповіді: {numStatus} | Показати відповіді: {numStatus}",
"hide_quote": "Сховати процитований допис",
"display_quote": "Показати процитований допис",
"invisible_quote": "Процитований допис недоступний: {link}",
"replies_list_with_others": "Ще відповідей: {numReplies} | Ще відповідей: {numReplies}:",
"show_attachment_in_modal": "Показати вкладення у вікні",
"show_attachment_description": "Переглянути опис (натисніть саме вкладення, якщо опис не вміщається)"
}, },
"timeline": { "timeline": {
"no_more_statuses": "Більше немає дописів", "no_more_statuses": "Більше немає дописів",
@ -980,7 +1083,8 @@
"repeated": "поширив(-ла)", "repeated": "поширив(-ла)",
"no_retweet_hint": "Запис, позначено як \"тільки для підписників\" або \"особисте\" і тому не може бути поширений", "no_retweet_hint": "Запис, позначено як \"тільки для підписників\" або \"особисте\" і тому не може бути поширений",
"socket_broke": "Втрачено з'єднання у реальному часі: код {0}", "socket_broke": "Втрачено з'єднання у реальному часі: код {0}",
"socket_reconnected": "Встановлено з'єднання у реальному часі" "socket_reconnected": "Встановлено з'єднання у реальному часі",
"quick_view_settings": "Налаштування швидкого перегляду"
}, },
"user_reporting": { "user_reporting": {
"submit": "Відправити", "submit": "Відправити",
@ -1026,5 +1130,35 @@
"submit_edit_action": "Надіслати", "submit_edit_action": "Надіслати",
"cancel_edit_action": "Скасувати", "cancel_edit_action": "Скасувати",
"inactive_message": "Це оголошення неактивне" "inactive_message": "Це оголошення неактивне"
},
"lists": {
"really_delete": "Дійсно видалити список?",
"error": "Помилка при роботі зі списками: {0}",
"is_in_list": "Вже є у списку",
"editing_list": "Редагування списку {listTitle}",
"creating_list": "Створення нового списку",
"search": "Знайти користувачів",
"create": "Створити",
"save": "Зберегти зміни",
"manage_members": "Керувати учасниками списку",
"new": "Новий список",
"title": "Назва списку",
"delete": "Видалити список",
"following_only": "Лише за ким ви стежите",
"lists": "Списки",
"manage_lists": "Керувати списками",
"remove_from_list": "Видалити зі списку",
"add_to_list": "Додати до списку"
},
"update": {
"update_changelog": "Щоб дізнатись більше інформації, дивіться {theFullChangelog}.",
"update_bugs": "Будь ласка, повідомляйте про будь-які проблеми та помилки на {pleromaGitlab}, оскільки ми внесли багато змін, і навіть після ретельно проведених перевірок, ми можемо щось пропустити. Ми заздалегідь вдячні за ваші відгуки щодо проблем, з якими ви можете зіткнутися, а також пропозиції щодо вдосконалення Pleroma та Pleroma-FE.",
"update_changelog_here": "повний список змін",
"big_update_title": "Хвилинку уваги",
"update_bugs_gitlab": "Pleroma GitLab",
"big_update_content": "У нас не було оновлень протягом тривалого часу, тому речі можуть мати інакший вигляд, аніж ви звикли."
},
"unicode_domain_indicator": {
"tooltip": "Цей домен містить не-ASCII символи."
} }
} }

View File

@ -40,6 +40,7 @@ export const defaultState = {
padEmoji: true, padEmoji: true,
hideAttachments: false, hideAttachments: false,
hideAttachmentsInConv: false, hideAttachmentsInConv: false,
hideScrobbles: false,
maxThumbnails: 16, maxThumbnails: 16,
hideNsfw: true, hideNsfw: true,
preloadImage: true, preloadImage: true,
@ -120,6 +121,11 @@ export const defaultState = {
conversationTreeAdvanced: undefined, // instance default conversationTreeAdvanced: undefined, // instance default
conversationOtherRepliesButton: undefined, // instance default conversationOtherRepliesButton: undefined, // instance default
conversationTreeFadeAncestors: undefined, // instance default conversationTreeFadeAncestors: undefined, // instance default
showExtraNotifications: undefined, // instance default
showExtraNotificationsTip: undefined, // instance default
showChatsInExtraNotifications: undefined, // instance default
showAnnouncementsInExtraNotifications: undefined, // instance default
showFollowRequestsInExtraNotifications: undefined, // instance default
maxDepthInThread: undefined, // instance default maxDepthInThread: undefined, // instance default
autocompleteSelect: undefined // instance default autocompleteSelect: undefined // instance default
} }

View File

@ -103,6 +103,11 @@ const defaultState = {
conversationTreeAdvanced: false, conversationTreeAdvanced: false,
conversationOtherRepliesButton: 'below', conversationOtherRepliesButton: 'below',
conversationTreeFadeAncestors: false, conversationTreeFadeAncestors: false,
showExtraNotifications: true,
showExtraNotificationsTip: true,
showChatsInExtraNotifications: true,
showAnnouncementsInExtraNotifications: true,
showFollowRequestsInExtraNotifications: true,
maxDepthInThread: 6, maxDepthInThread: 6,
autocompleteSelect: false, autocompleteSelect: false,

View File

@ -47,6 +47,7 @@ const emptyNotifications = () => ({
export const defaultState = () => ({ export const defaultState = () => ({
allStatuses: [], allStatuses: [],
scrobblesNextFetch: {},
allStatusesObject: {}, allStatusesObject: {},
conversationsObject: {}, conversationsObject: {},
maxId: 0, maxId: 0,
@ -120,8 +121,24 @@ const sortTimeline = (timeline) => {
return timeline return timeline
} }
const getLatestScrobble = (state, user) => {
if (state.scrobblesNextFetch[user.id] && state.scrobblesNextFetch[user.id] > Date.now()) {
return
}
state.scrobblesNextFetch[user.id] = Date.now() + 24 * 60 * 60 * 1000
apiService.fetchScrobbles({ accountId: user.id }).then((scrobbles) => {
if (scrobbles.length > 0) {
user.latestScrobble = scrobbles[0]
state.scrobblesNextFetch[user.id] = Date.now() + 60 * 1000
}
})
}
// Add status to the global storages (arrays and objects maintaining statuses) except timelines // Add status to the global storages (arrays and objects maintaining statuses) except timelines
const addStatusToGlobalStorage = (state, data) => { const addStatusToGlobalStorage = (state, data) => {
getLatestScrobble(state, data.user)
const result = mergeOrAdd(state.allStatuses, state.allStatusesObject, data) const result = mergeOrAdd(state.allStatuses, state.allStatusesObject, data)
if (result.new) { if (result.new) {
// Add to conversation // Add to conversation

View File

@ -107,6 +107,7 @@ const PLEROMA_ANNOUNCEMENTS_URL = '/api/v1/pleroma/admin/announcements'
const PLEROMA_POST_ANNOUNCEMENT_URL = '/api/v1/pleroma/admin/announcements' const PLEROMA_POST_ANNOUNCEMENT_URL = '/api/v1/pleroma/admin/announcements'
const PLEROMA_EDIT_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}` const PLEROMA_EDIT_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}`
const PLEROMA_DELETE_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}` const PLEROMA_DELETE_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}`
const PLEROMA_SCROBBLES_URL = id => `/api/v1/pleroma/accounts/${id}/scrobbles`
const PLEROMA_ADMIN_CONFIG_URL = '/api/pleroma/admin/config' const PLEROMA_ADMIN_CONFIG_URL = '/api/pleroma/admin/config'
const PLEROMA_ADMIN_DESCRIPTIONS_URL = '/api/pleroma/admin/config/descriptions' const PLEROMA_ADMIN_DESCRIPTIONS_URL = '/api/pleroma/admin/config/descriptions'
@ -1765,6 +1766,23 @@ const installFrontend = ({ credentials, payload }) => {
}) })
} }
const fetchScrobbles = ({ accountId, limit = 1 }) => {
let url = PLEROMA_SCROBBLES_URL(accountId)
const params = [['limit', limit]]
const queryString = map(params, (param) => `${param[0]}=${param[1]}`).join('&')
url += `?${queryString}`
return fetch(url, {})
.then((response) => {
if (response.ok) {
return response.json()
} else {
return {
error: response
}
}
})
}
const apiService = { const apiService = {
verifyCredentials, verifyCredentials,
fetchTimeline, fetchTimeline,
@ -1878,6 +1896,7 @@ const apiService = {
postAnnouncement, postAnnouncement,
editAnnouncement, editAnnouncement,
deleteAnnouncement, deleteAnnouncement,
fetchScrobbles,
adminFetchAnnouncements, adminFetchAnnouncements,
fetchInstanceDBConfig, fetchInstanceDBConfig,
fetchInstanceConfigDescriptions, fetchInstanceConfigDescriptions,

View File

@ -133,3 +133,17 @@ export const prepareNotificationObject = (notification, i18n) => {
return notifObj return notifObj
} }
export const countExtraNotifications = (store) => {
const mergedConfig = store.getters.mergedConfig
if (!mergedConfig.showExtraNotifications) {
return 0
}
return [
mergedConfig.showChatsInExtraNotifications ? store.getters.unreadChatCount : 0,
mergedConfig.showAnnouncementsInExtraNotifications ? store.getters.unreadAnnouncementCount : 0,
mergedConfig.showFollowRequestsInExtraNotifications ? store.getters.followRequestCount : 0
].reduce((a, c) => a + c, 0)
}

View File

@ -0,0 +1,3 @@
const genRandomSeed = () => `${Math.random()}`.replace('.', '-')
export default genRandomSeed

27
tools/collect-changelog Executable file
View File

@ -0,0 +1,27 @@
#!/bin/sh
collectType() {
local suffix="$1"
local header="$2"
local printed=0
for file in changelog.d/*."$suffix"; do
if [ '!' -f "$file" ]; then
continue
fi
if [ "$printed" = 0 ]; then
echo
echo "### $header"
printed=1
fi
# Normalize any trailing newlines/spaces, etc.
echo "- $(cat "$file")"
done
}
collectType security Security
collectType change Changed
collectType add Added
collectType fix Fixed
collectType remove Removed
rm changelog.d/*