aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/desktop_nav/desktop_nav.scss4
-rw-r--r--src/components/emoji_picker/emoji_picker.js5
-rw-r--r--src/components/emoji_picker/emoji_picker.vue1
-rw-r--r--src/components/notifications/notifications.js4
-rw-r--r--src/components/notifications/notifications.vue2
-rw-r--r--src/components/react_button/react_button.js3
-rw-r--r--src/components/react_button/react_button.vue1
-rw-r--r--src/components/settings_modal/tabs/data_import_export_tab.js29
-rw-r--r--src/components/settings_modal/tabs/data_import_export_tab.vue61
-rw-r--r--src/components/settings_modal/tabs/security_tab/security_tab.js55
-rw-r--r--src/components/settings_modal/tabs/security_tab/security_tab.vue108
-rw-r--r--src/components/timeago/timeago.vue2
-rw-r--r--src/components/timeline/timeline.scss2
13 files changed, 268 insertions, 9 deletions
diff --git a/src/components/desktop_nav/desktop_nav.scss b/src/components/desktop_nav/desktop_nav.scss
index 0ca9802e..eddd9707 100644
--- a/src/components/desktop_nav/desktop_nav.scss
+++ b/src/components/desktop_nav/desktop_nav.scss
@@ -3,6 +3,10 @@
.DesktopNav {
width: 100%;
+ input {
+ color: var(--inputTopbarText, var(--inputText));
+ }
+
a {
color: var(--topBarLink, $fallback--link);
}
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index 6b589079..bd5c2e39 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -6,6 +6,7 @@ import {
faStickyNote,
faSmileBeam
} from '@fortawesome/free-solid-svg-icons'
+import { trim } from 'lodash'
library.add(
faBoxOpen,
@@ -176,7 +177,7 @@ const EmojiPicker = {
filteredEmoji () {
return filterByKeyword(
this.$store.state.instance.customEmoji || [],
- this.keyword
+ trim(this.keyword)
)
},
customEmojiBuffer () {
@@ -197,7 +198,7 @@ const EmojiPicker = {
id: 'standard',
text: this.$t('emoji.unicode'),
icon: 'box-open',
- emojis: filterByKeyword(standardEmojis, this.keyword)
+ emojis: filterByKeyword(standardEmojis, trim(this.keyword))
}
]
},
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index 3262a3d9..a7269120 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -47,6 +47,7 @@
type="text"
class="form-control"
:placeholder="$t('emoji.search_emoji')"
+ @input="$event.target.composing = false"
>
</div>
<div
diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js
index fb2579a5..82aa1489 100644
--- a/src/components/notifications/notifications.js
+++ b/src/components/notifications/notifications.js
@@ -27,7 +27,9 @@ const Notifications = {
// meant for "Interactions" timeline
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
- filterMode: Array
+ filterMode: Array,
+ // Disable teleporting (i.e. for /users/user/notifications)
+ disableTeleport: Boolean
},
data () {
return {
diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue
index 794ef51d..b46c06aa 100644
--- a/src/components/notifications/notifications.vue
+++ b/src/components/notifications/notifications.vue
@@ -1,5 +1,5 @@
<template>
- <teleport :disabled="minimalMode" :to="teleportTarget">
+ <teleport :disabled="minimalMode || disableTeleport" :to="teleportTarget">
<div
:class="{ minimal: minimalMode }"
class="Notifications"
diff --git a/src/components/react_button/react_button.js b/src/components/react_button/react_button.js
index ce82c90d..e6f9dbff 100644
--- a/src/components/react_button/react_button.js
+++ b/src/components/react_button/react_button.js
@@ -1,6 +1,7 @@
import Popover from '../popover/popover.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faSmileBeam } from '@fortawesome/free-regular-svg-icons'
+import { trim } from 'lodash'
library.add(faSmileBeam)
@@ -43,7 +44,7 @@ const ReactButton = {
},
emojis () {
if (this.filterWord !== '') {
- const filterWordLowercase = this.filterWord.toLowerCase()
+ const filterWordLowercase = trim(this.filterWord.toLowerCase())
let orderedEmojiList = []
for (const emoji of this.$store.state.instance.emoji) {
if (emoji.replacement === this.filterWord) return [emoji]
diff --git a/src/components/react_button/react_button.vue b/src/components/react_button/react_button.vue
index 7f35b7b5..8a4b4d3b 100644
--- a/src/components/react_button/react_button.vue
+++ b/src/components/react_button/react_button.vue
@@ -12,6 +12,7 @@
<div class="reaction-picker-filter">
<input
v-model="filterWord"
+ @input="$event.target.composing = false"
size="1"
:placeholder="$t('emoji.search_emoji')"
>
diff --git a/src/components/settings_modal/tabs/data_import_export_tab.js b/src/components/settings_modal/tabs/data_import_export_tab.js
index f4b736d2..4895733c 100644
--- a/src/components/settings_modal/tabs/data_import_export_tab.js
+++ b/src/components/settings_modal/tabs/data_import_export_tab.js
@@ -7,11 +7,16 @@ const DataImportExportTab = {
data () {
return {
activeTab: 'profile',
- newDomainToMute: ''
+ newDomainToMute: '',
+ listBackupsError: false,
+ addBackupError: false,
+ addedBackup: false,
+ backups: []
}
},
created () {
this.$store.dispatch('fetchTokens')
+ this.fetchBackups()
},
components: {
Importer,
@@ -72,6 +77,28 @@ const DataImportExportTab = {
}
return user.screen_name
}).join('\n')
+ },
+ addBackup () {
+ this.$store.state.api.backendInteractor.addBackup()
+ .then((res) => {
+ this.addedBackup = true
+ this.addBackupError = false
+ })
+ .catch((error) => {
+ this.addedBackup = false
+ this.addBackupError = error
+ })
+ .then(() => this.fetchBackups())
+ },
+ fetchBackups () {
+ this.$store.state.api.backendInteractor.listBackups()
+ .then((res) => {
+ this.backups = res
+ this.listBackupsError = false
+ })
+ .catch((error) => {
+ this.listBackupsError = error.error
+ })
}
}
}
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 a406077d..e3b7f407 100644
--- a/src/components/settings_modal/tabs/data_import_export_tab.vue
+++ b/src/components/settings_modal/tabs/data_import_export_tab.vue
@@ -53,6 +53,67 @@
:export-button-label="$t('settings.mute_export_button')"
/>
</div>
+ <div class="setting-item">
+ <h2>{{ $t('settings.account_backup') }}</h2>
+ <p>{{ $t('settings.account_backup_description') }}</p>
+ <table>
+ <thead>
+ <tr>
+ <th>{{ $t('settings.account_backup_table_head') }}</th>
+ <th />
+ </tr>
+ </thead>
+ <tbody>
+ <tr
+ v-for="backup in backups"
+ :key="backup.id"
+ >
+ <td>{{ backup.inserted_at }}</td>
+ <td class="actions">
+ <a
+ v-if="backup.processed"
+ target="_blank"
+ :href="backup.url"
+ >
+ {{ $t('settings.download_backup') }}
+ </a>
+ <span
+ v-else
+ >
+ {{ $t('settings.backup_not_ready') }}
+ </span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <div
+ v-if="listBackupsError"
+ class="alert error"
+ >
+ {{ $t('settings.list_backups_error', { error }) }}
+ <button
+ :title="$t('settings.hide_list_backups_error_action')"
+ @click="listBackupsError = false"
+ >
+ <FAIcon
+ class="fa-scale-110 fa-old-padding"
+ icon="times"
+ />
+ </button>
+ </div>
+ <button
+ class="btn button-default"
+ @click="addBackup"
+ >
+ {{ $t('settings.add_backup') }}
+ </button>
+ <p v-if="addedBackup">
+ {{ $t('settings.added_backup') }}
+ </p>
+ <template v-if="addBackupError !== false">
+ <p>{{ $t('settings.add_backup_error', { error: addBackupError }) }}</p>
+ </template>
+ </div>
</div>
</template>
diff --git a/src/components/settings_modal/tabs/security_tab/security_tab.js b/src/components/settings_modal/tabs/security_tab/security_tab.js
index 65d20fc0..fc732936 100644
--- a/src/components/settings_modal/tabs/security_tab/security_tab.js
+++ b/src/components/settings_modal/tabs/security_tab/security_tab.js
@@ -15,11 +15,21 @@ const SecurityTab = {
deleteAccountError: false,
changePasswordInputs: [ '', '', '' ],
changedPassword: false,
- changePasswordError: false
+ changePasswordError: false,
+ moveAccountTarget: '',
+ moveAccountPassword: '',
+ movedAccount: false,
+ moveAccountError: false,
+ aliases: [],
+ listAliasesError: false,
+ addAliasTarget: '',
+ addedAlias: false,
+ addAliasError: false
}
},
created () {
this.$store.dispatch('fetchTokens')
+ this.fetchAliases()
},
components: {
ProgressButton,
@@ -92,6 +102,49 @@ const SecurityTab = {
}
})
},
+ moveAccount () {
+ const params = {
+ targetAccount: this.moveAccountTarget,
+ password: this.moveAccountPassword
+ }
+ this.$store.state.api.backendInteractor.moveAccount(params)
+ .then((res) => {
+ if (res.status === 'success') {
+ this.movedAccount = true
+ this.moveAccountError = false
+ } else {
+ this.movedAccount = false
+ this.moveAccountError = res.error
+ }
+ })
+ },
+ removeAlias (alias) {
+ this.$store.state.api.backendInteractor.deleteAlias({ alias })
+ .then(() => this.fetchAliases())
+ },
+ addAlias () {
+ this.$store.state.api.backendInteractor.addAlias({ alias: this.addAliasTarget })
+ .then((res) => {
+ this.addedAlias = true
+ this.addAliasError = false
+ this.addAliasTarget = ''
+ })
+ .catch((error) => {
+ this.addedAlias = false
+ this.addAliasError = error
+ })
+ .then(() => this.fetchAliases())
+ },
+ fetchAliases () {
+ this.$store.state.api.backendInteractor.listAliases()
+ .then((res) => {
+ this.aliases = res.aliases
+ this.listAliasesError = false
+ })
+ .catch((error) => {
+ this.listAliasesError = error.error
+ })
+ },
logout () {
this.$store.dispatch('logout')
this.$router.replace('/')
diff --git a/src/components/settings_modal/tabs/security_tab/security_tab.vue b/src/components/settings_modal/tabs/security_tab/security_tab.vue
index 275d4616..c74a0c67 100644
--- a/src/components/settings_modal/tabs/security_tab/security_tab.vue
+++ b/src/components/settings_modal/tabs/security_tab/security_tab.vue
@@ -103,6 +103,114 @@
</table>
</div>
<mfa />
+
+ <div class="setting-item">
+ <h2>{{ $t('settings.account_alias') }}</h2>
+ <table>
+ <thead>
+ <tr>
+ <th>{{ $t('settings.account_alias_table_head') }}</th>
+ <th />
+ </tr>
+ </thead>
+ <tbody>
+ <tr
+ v-for="alias in aliases"
+ :key="alias"
+ >
+ <td>{{ alias }}</td>
+ <td class="actions">
+ <button
+ class="btn button-default"
+ @click="removeAlias(alias)"
+ >
+ {{ $t('settings.remove_alias') }}
+ </button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <div
+ v-if="listAliasesError"
+ class="alert error"
+ >
+ {{ $t('settings.list_aliases_error', { error }) }}
+ <FAIcon
+ class="fa-scale-110 fa-old-padding"
+ icon="times"
+ :title="$t('settings.hide_list_aliases_error_action')"
+ @click="listAliasesError = false"
+ />
+ </div>
+ <div>
+ <i18n
+ path="settings.new_alias_target"
+ tag="p"
+ >
+ <code
+ place="example"
+ >
+ foo@example.org
+ </code>
+ </i18n>
+ <input
+ v-model="addAliasTarget"
+ >
+ </div>
+ <button
+ class="btn button-default"
+ @click="addAlias"
+ >
+ {{ $t('settings.save') }}
+ </button>
+ <p v-if="addedAlias">
+ {{ $t('settings.added_alias') }}
+ </p>
+ <template v-if="addAliasError !== false">
+ <p>{{ $t('settings.add_alias_error', { error: addAliasError }) }}</p>
+ </template>
+ </div>
+
+ <div class="setting-item">
+ <h2>{{ $t('settings.move_account') }}</h2>
+ <p>{{ $t('settings.move_account_notes') }}</p>
+ <div>
+ <i18n
+ path="settings.move_account_target"
+ tag="p"
+ >
+ <code
+ place="example"
+ >
+ foo@example.org
+ </code>
+ </i18n>
+ <input
+ v-model="moveAccountTarget"
+ >
+ </div>
+ <div>
+ <p>{{ $t('settings.current_password') }}</p>
+ <input
+ v-model="moveAccountPassword"
+ type="password"
+ autocomplete="current-password"
+ >
+ </div>
+ <button
+ class="btn button-default"
+ @click="moveAccount"
+ >
+ {{ $t('settings.save') }}
+ </button>
+ <p v-if="movedAccount">
+ {{ $t('settings.moved_account') }}
+ </p>
+ <template v-if="moveAccountError !== false">
+ <p>{{ $t('settings.move_account_error', { error: moveAccountError }) }}</p>
+ </template>
+ </div>
+
<div class="setting-item">
<h2>{{ $t('settings.delete_account') }}</h2>
<p v-if="!deletingAccount">
diff --git a/src/components/timeago/timeago.vue b/src/components/timeago/timeago.vue
index bed29020..2b487dfd 100644
--- a/src/components/timeago/timeago.vue
+++ b/src/components/timeago/timeago.vue
@@ -3,7 +3,7 @@
:datetime="time"
:title="localeDateString"
>
- {{ $t(relativeTime.key, [relativeTime.num]) }}
+ {{ $tc(relativeTime.key, relativeTime.num, [relativeTime.num]) }}
</time>
</template>
diff --git a/src/components/timeline/timeline.scss b/src/components/timeline/timeline.scss
index c7ea0dff..9e009fd3 100644
--- a/src/components/timeline/timeline.scss
+++ b/src/components/timeline/timeline.scss
@@ -11,7 +11,7 @@
.conversation-heading {
top: calc(var(--__panel-heading-height) * var(--currentPanelStack, 2));
- z-index: 1;
+ z-index: 2;
}
&.-nonpanel {