aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/announcement/announcement.js3
-rw-r--r--src/components/announcement/announcement.vue4
-rw-r--r--src/components/announcements_page/announcements_page.js3
-rw-r--r--src/components/announcements_page/announcements_page.vue2
-rw-r--r--src/components/emoji_picker/emoji_picker.js6
-rw-r--r--src/components/lists_edit/lists_edit.js4
-rw-r--r--src/components/rich_content/rich_content.scss6
-rw-r--r--src/components/settings_modal/tabs/data_import_export_tab.vue10
-rw-r--r--src/i18n/en.json3
-rw-r--r--src/i18n/uk.json32
-rw-r--r--src/modules/announcements.js2
-rw-r--r--src/modules/instance.js36
12 files changed, 95 insertions, 16 deletions
diff --git a/src/components/announcement/announcement.js b/src/components/announcement/announcement.js
index c10c7d90..30254926 100644
--- a/src/components/announcement/announcement.js
+++ b/src/components/announcement/announcement.js
@@ -27,6 +27,9 @@ const Announcement = {
...mapState({
currentUser: state => state.users.currentUser
}),
+ canEditAnnouncement () {
+ return this.currentUser && this.currentUser.privileges.includes('announcements_manage_announcements')
+ },
content () {
return this.announcement.content
},
diff --git a/src/components/announcement/announcement.vue b/src/components/announcement/announcement.vue
index 5f64232a..c1b35981 100644
--- a/src/components/announcement/announcement.vue
+++ b/src/components/announcement/announcement.vue
@@ -45,14 +45,14 @@
{{ $t('announcements.mark_as_read_action') }}
</button>
<button
- v-if="currentUser && currentUser.role === 'admin'"
+ v-if="canEditAnnouncement"
class="btn button-default"
@click="enterEditMode"
>
{{ $t('announcements.edit_action') }}
</button>
<button
- v-if="currentUser && currentUser.role === 'admin'"
+ v-if="canEditAnnouncement"
class="btn button-default"
@click="deleteAnnouncement"
>
diff --git a/src/components/announcements_page/announcements_page.js b/src/components/announcements_page/announcements_page.js
index 0bb4892e..8d1204d4 100644
--- a/src/components/announcements_page/announcements_page.js
+++ b/src/components/announcements_page/announcements_page.js
@@ -28,6 +28,9 @@ const AnnouncementsPage = {
}),
announcements () {
return this.$store.state.announcements.announcements
+ },
+ canPostAnnouncement () {
+ return this.currentUser && this.currentUser.privileges.includes('announcements_manage_announcements')
}
},
methods: {
diff --git a/src/components/announcements_page/announcements_page.vue b/src/components/announcements_page/announcements_page.vue
index b1489dec..59ed283d 100644
--- a/src/components/announcements_page/announcements_page.vue
+++ b/src/components/announcements_page/announcements_page.vue
@@ -7,7 +7,7 @@
</div>
<div class="panel-body">
<section
- v-if="currentUser && currentUser.role === 'admin'"
+ v-if="canPostAnnouncement"
>
<div class="post-form">
<div class="heading">
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index dd5e5217..2838e102 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -287,7 +287,11 @@ const EmojiPicker = {
return 0
},
allCustomGroups () {
- return this.$store.getters.groupedCustomEmojis
+ const emojis = this.$store.getters.groupedCustomEmojis
+ if (emojis.unpacked) {
+ emojis.unpacked.text = this.$t('emoji.unpacked')
+ }
+ return emojis
},
defaultGroup () {
return Object.keys(this.allCustomGroups)[0]
diff --git a/src/components/lists_edit/lists_edit.js b/src/components/lists_edit/lists_edit.js
index c22d1323..c33659df 100644
--- a/src/components/lists_edit/lists_edit.js
+++ b/src/components/lists_edit/lists_edit.js
@@ -95,10 +95,10 @@ const ListsNew = {
return this.addedUserIds.has(user.id)
},
addUser (user) {
- this.$store.dispatch('addListAccount', { accountId: this.user.id, listId: this.id })
+ this.$store.dispatch('addListAccount', { accountId: user.id, listId: this.id })
},
removeUser (userId) {
- this.$store.dispatch('removeListAccount', { accountId: this.user.id, listId: this.id })
+ this.$store.dispatch('removeListAccount', { accountId: userId, listId: this.id })
},
onSearchLoading (results) {
this.searchLoading = true
diff --git a/src/components/rich_content/rich_content.scss b/src/components/rich_content/rich_content.scss
index db08ef1e..52042314 100644
--- a/src/components/rich_content/rich_content.scss
+++ b/src/components/rich_content/rich_content.scss
@@ -1,7 +1,11 @@
+@import '../../variables';
+
.RichContent {
blockquote {
- margin: 0.2em 0 0.2em 2em;
+ margin: 0.2em 0 0.2em 0.2em;
font-style: italic;
+ border-left: 0.2em solid var(--faint, $fallback--faint);
+ padding-left: 1em;
}
pre {
diff --git a/src/components/settings_modal/tabs/data_import_export_tab.vue b/src/components/settings_modal/tabs/data_import_export_tab.vue
index e3b7f407..48356c9b 100644
--- a/src/components/settings_modal/tabs/data_import_export_tab.vue
+++ b/src/components/settings_modal/tabs/data_import_export_tab.vue
@@ -78,6 +78,16 @@
{{ $t('settings.download_backup') }}
</a>
<span
+ v-else-if="backup.state === 'running'"
+ >
+ {{ $tc('settings.backup_running', backup.processed_number, { number: backup.processed_number }) }}
+ </span>
+ <span
+ v-else-if="backup.state === 'failed'"
+ >
+ {{ $t('settings.backup_failed') }}
+ </span>
+ <span
v-else
>
{{ $t('settings.backup_not_ready') }}
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 59ee1c17..1ee1147a 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -225,6 +225,7 @@
"search_emoji": "Search for an emoji",
"add_emoji": "Insert emoji",
"custom": "Custom emoji",
+ "unpacked": "Unpacked emoji",
"unicode": "Unicode emoji",
"unicode_groups": {
"activities": "Activities",
@@ -390,6 +391,8 @@
"account_backup_table_head": "Backup",
"download_backup": "Download",
"backup_not_ready": "This backup is not ready yet.",
+ "backup_running": "This backup is in progress, processed {number} record. | This backup is in progress, processed {number} records.",
+ "backup_failed": "This backup has failed.",
"remove_backup": "Remove",
"list_backups_error": "Error fetching backup list: {error}",
"add_backup": "Create a new backup",
diff --git a/src/i18n/uk.json b/src/i18n/uk.json
index 99b49868..c781b1f6 100644
--- a/src/i18n/uk.json
+++ b/src/i18n/uk.json
@@ -188,7 +188,8 @@
"mobile_sidebar": "Ввімкнути бокову панель",
"mobile_notifications": "Відкрити сповіщення (є непрочитані)",
"mobile_notifications_close": "Закрити сповіщення",
- "edit_nav_mobile": "Редагувати панель навігації"
+ "edit_nav_mobile": "Редагувати панель навігації",
+ "announcements": "Анонси"
},
"media_modal": {
"next": "Наступна",
@@ -735,7 +736,10 @@
"hide_favorites_description": "Не показувати список моїх вподобань (люди все одно отримують сповіщення)",
"third_column_mode": "Коли достатньо місця, показувати третю колонку, що містить",
"user_popover_avatar_action_open": "Відкрити профіль",
- "wordfilter": "Фільтр слів"
+ "wordfilter": "Фільтр слів",
+ "mention_links": "Посилання для згадування",
+ "user_profiles": "Профілі користувачів",
+ "notification_visibility_polls": "Закінчення опитувань, в яких ви проголосували"
},
"selectable_list": {
"select_all": "Вибрати все"
@@ -956,7 +960,8 @@
"show_all_conversation_with_icon": "{icon} {text}",
"plus_more": "+{number} більше",
"thread_show_full_with_icon": "{icon} {text}",
- "show_only_conversation_under_this": "Показати всі відповіді на цей допис"
+ "show_only_conversation_under_this": "Показати всі відповіді на цей допис",
+ "status_history": "Історія змін"
},
"timeline": {
"no_more_statuses": "Більше немає дописів",
@@ -996,5 +1001,26 @@
"reported_statuses": "Дописи, на які подано скаргу:",
"reporter": "Позивач:",
"reported_user": "Відповідач:"
+ },
+ "announcements": {
+ "delete_action": "Видалити",
+ "page_header": "Анонси",
+ "title": "Анонси",
+ "mark_as_read_action": "Позначити як прочитане",
+ "post_form_header": "Розмістити оголошення",
+ "post_placeholder": "Введіть текст вашого оголошення тут...",
+ "post_action": "Пост",
+ "post_error": "Помилка: {error}",
+ "close_error": "Закрити",
+ "start_time_prompt": "Початок: ",
+ "end_time_prompt": "Кінець: ",
+ "all_day_prompt": "Це захід на цілий день",
+ "published_time_display": "Опубліковано в {time}",
+ "start_time_display": "Початок о {time}",
+ "end_time_display": "Кінець о {time}",
+ "edit_action": "Редагувати",
+ "submit_edit_action": "Надіслати",
+ "cancel_edit_action": "Скасувати",
+ "inactive_message": "Це оголошення неактивне"
}
}
diff --git a/src/modules/announcements.js b/src/modules/announcements.js
index e4d2d2b0..4504263b 100644
--- a/src/modules/announcements.js
+++ b/src/modules/announcements.js
@@ -49,7 +49,7 @@ const announcements = {
}
const currentUser = store.rootState.users.currentUser
- const isAdmin = currentUser && currentUser.role === 'admin'
+ const isAdmin = currentUser && currentUser.privileges.includes('announcements_manage_announcements')
const getAnnouncements = async () => {
if (!isAdmin) {
diff --git a/src/modules/instance.js b/src/modules/instance.js
index 3b15e62e..8e8d13d3 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -181,15 +181,28 @@ const instance = {
},
groupedCustomEmojis (state) {
const packsOf = emoji => {
- return emoji.tags
+ const packs = emoji.tags
.filter(k => k.startsWith('pack:'))
- .map(k => k.slice(5)) // remove 'pack:' prefix
+ .map(k => {
+ const packName = k.slice(5) // remove 'pack:' prefix
+ return {
+ id: `custom-${packName}`,
+ text: packName
+ }
+ })
+
+ if (!packs.length) {
+ return [{
+ id: 'unpacked'
+ }]
+ } else {
+ return packs
+ }
}
return state.customEmoji
.reduce((res, emoji) => {
- packsOf(emoji).forEach(packName => {
- const packId = `custom-${packName}`
+ packsOf(emoji).forEach(({ id: packId, text: packName }) => {
if (!res[packId]) {
res[packId] = ({
id: packId,
@@ -290,9 +303,22 @@ const instance = {
const lb = b.toLowerCase()
return la > lb ? 1 : (la < lb ? -1 : 0)
}
+ const noPackLast = (a, b) => {
+ const aNull = a === ''
+ const bNull = b === ''
+ if (aNull === bNull) {
+ return 0
+ } else if (aNull && !bNull) {
+ return 1
+ } else {
+ return -1
+ }
+ }
const byPackThenByName = (a, b) => {
const packOf = emoji => (emoji.tags.filter(k => k.startsWith('pack:'))[0] || '').slice(5)
- return caseInsensitiveStrCmp(packOf(a), packOf(b)) || caseInsensitiveStrCmp(a.displayText, b.displayText)
+ const packOfA = packOf(a)
+ const packOfB = packOf(b)
+ return noPackLast(packOfA, packOfB) || caseInsensitiveStrCmp(packOfA, packOfB) || caseInsensitiveStrCmp(a.displayText, b.displayText)
}
const emoji = Object.entries(values).map(([key, value]) => {