aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md3
-rw-r--r--src/App.js3
-rw-r--r--src/components/interface_language_switcher/interface_language_switcher.vue3
-rw-r--r--src/components/media_upload/media_upload.js39
-rw-r--r--src/components/media_upload/media_upload.vue7
-rw-r--r--src/components/post_status_form/post_status_form.js22
-rw-r--r--src/components/post_status_form/post_status_form.vue46
-rw-r--r--src/i18n/it.json39
-rw-r--r--src/i18n/messages.js67
-rw-r--r--src/i18n/ru.json4
-rw-r--r--src/main.js6
-rw-r--r--src/modules/config.js5
12 files changed, 173 insertions, 71 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 11f539da..ad03c760 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Removed the use of with_move parameters when fetching notifications
### Fixed
+- Weird bug related to post being sent seemingly after pasting with keyboard (hopefully)
- Multiple issues with muted statuses/notifications
## [Unreleased patch]
@@ -20,12 +21,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Change heart to thumbs up in reaction picker
- Close the media modal on navigation events
- Add colons to the emoji alt text, to make them copyable
+- Add better visual indication for drag-and-drop for files
### Fixed
- Status ellipsis menu closes properly when selecting certain options
- Cropped images look correct in Chrome
- Newlines in the muted words settings work again
- Clicking on non-latin hashtags won't open a new window
+- Uploading and drag-dropping multiple files works correctly now.
## [2.0.3] - 2020-05-02
### Fixed
diff --git a/src/App.js b/src/App.js
index 6445335a..040138c9 100644
--- a/src/App.js
+++ b/src/App.js
@@ -47,7 +47,8 @@ export default {
}),
created () {
// Load the locale from the storage
- this.$i18n.locale = this.$store.getters.mergedConfig.interfaceLanguage
+ const val = this.$store.getters.mergedConfig.interfaceLanguage
+ this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
window.addEventListener('resize', this.updateMobileState)
},
destroyed () {
diff --git a/src/components/interface_language_switcher/interface_language_switcher.vue b/src/components/interface_language_switcher/interface_language_switcher.vue
index f5ace0cc..dd6800a3 100644
--- a/src/components/interface_language_switcher/interface_language_switcher.vue
+++ b/src/components/interface_language_switcher/interface_language_switcher.vue
@@ -32,7 +32,7 @@ import _ from 'lodash'
export default {
computed: {
languageCodes () {
- return Object.keys(languagesObject)
+ return languagesObject.languages
},
languageNames () {
@@ -43,7 +43,6 @@ export default {
get: function () { return this.$store.getters.mergedConfig.interfaceLanguage },
set: function (val) {
this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
- this.$i18n.locale = val
}
}
},
diff --git a/src/components/media_upload/media_upload.js b/src/components/media_upload/media_upload.js
index f457d022..fbb2d03d 100644
--- a/src/components/media_upload/media_upload.js
+++ b/src/components/media_upload/media_upload.js
@@ -5,10 +5,15 @@ import fileSizeFormatService from '../../services/file_size_format/file_size_for
const mediaUpload = {
data () {
return {
- uploading: false,
+ uploadCount: 0,
uploadReady: true
}
},
+ computed: {
+ uploading () {
+ return this.uploadCount > 0
+ }
+ },
methods: {
uploadFile (file) {
const self = this
@@ -23,29 +28,21 @@ const mediaUpload = {
formData.append('file', file)
self.$emit('uploading')
- self.uploading = true
+ self.uploadCount++
statusPosterService.uploadMedia({ store, formData })
.then((fileData) => {
self.$emit('uploaded', fileData)
- self.uploading = false
+ self.decreaseUploadCount()
}, (error) => { // eslint-disable-line handle-callback-err
self.$emit('upload-failed', 'default')
- self.uploading = false
+ self.decreaseUploadCount()
})
},
- fileDrop (e) {
- if (e.dataTransfer.files.length > 0) {
- e.preventDefault() // allow dropping text like before
- this.uploadFile(e.dataTransfer.files[0])
- }
- },
- fileDrag (e) {
- let types = e.dataTransfer.types
- if (types.contains('Files')) {
- e.dataTransfer.dropEffect = 'copy'
- } else {
- e.dataTransfer.dropEffect = 'none'
+ decreaseUploadCount () {
+ this.uploadCount--
+ if (this.uploadCount === 0) {
+ this.$emit('all-uploaded')
}
},
clearFile () {
@@ -54,11 +51,13 @@ const mediaUpload = {
this.uploadReady = true
})
},
- change ({ target }) {
- for (var i = 0; i < target.files.length; i++) {
- let file = target.files[i]
+ multiUpload (files) {
+ for (const file of files) {
this.uploadFile(file)
}
+ },
+ change ({ target }) {
+ this.multiUpload(target.files)
}
},
props: [
@@ -67,7 +66,7 @@ const mediaUpload = {
watch: {
'dropFiles': function (fileInfos) {
if (!this.uploading) {
- this.uploadFile(fileInfos[0])
+ this.multiUpload(fileInfos)
}
}
}
diff --git a/src/components/media_upload/media_upload.vue b/src/components/media_upload/media_upload.vue
index 0fc305ac..5e31730b 100644
--- a/src/components/media_upload/media_upload.vue
+++ b/src/components/media_upload/media_upload.vue
@@ -1,10 +1,5 @@
<template>
- <div
- class="media-upload"
- @drop.prevent
- @dragover.prevent="fileDrag"
- @drop="fileDrop"
- >
+ <div class="media-upload">
<label
class="label"
:title="$t('tool_tip.media_upload')"
diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
index a98e1e31..9027566f 100644
--- a/src/components/post_status_form/post_status_form.js
+++ b/src/components/post_status_form/post_status_form.js
@@ -82,7 +82,9 @@ const PostStatusForm = {
contentType
},
caret: 0,
- pollFormVisible: false
+ pollFormVisible: false,
+ showDropIcon: 'hide',
+ dropStopTimeout: null
}
},
computed: {
@@ -218,7 +220,6 @@ const PostStatusForm = {
},
addMediaFile (fileInfo) {
this.newStatus.files.push(fileInfo)
- this.enableSubmit()
},
removeMediaFile (fileInfo) {
let index = this.newStatus.files.indexOf(fileInfo)
@@ -227,7 +228,6 @@ const PostStatusForm = {
uploadFailed (errString, templateArgs) {
templateArgs = templateArgs || {}
this.error = this.$t('upload.error.base') + ' ' + this.$t('upload.error.' + errString, templateArgs)
- this.enableSubmit()
},
disableSubmit () {
this.submitDisabled = true
@@ -250,13 +250,27 @@ const PostStatusForm = {
}
},
fileDrop (e) {
- if (e.dataTransfer.files.length > 0) {
+ if (e.dataTransfer && e.dataTransfer.types.includes('Files')) {
e.preventDefault() // allow dropping text like before
this.dropFiles = e.dataTransfer.files
+ clearTimeout(this.dropStopTimeout)
+ this.showDropIcon = 'hide'
}
},
+ fileDragStop (e) {
+ // The false-setting is done with delay because just using leave-events
+ // directly caused unwanted flickering, this is not perfect either but
+ // much less noticable.
+ clearTimeout(this.dropStopTimeout)
+ this.showDropIcon = 'fade'
+ this.dropStopTimeout = setTimeout(() => (this.showDropIcon = 'hide'), 500)
+ },
fileDrag (e) {
e.dataTransfer.dropEffect = 'copy'
+ if (e.dataTransfer && e.dataTransfer.types.includes('Files')) {
+ clearTimeout(this.dropStopTimeout)
+ this.showDropIcon = 'show'
+ }
},
onEmojiInputInput (e) {
this.$nextTick(() => {
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index 9789a481..c4d7f7e2 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -6,7 +6,15 @@
<form
autocomplete="off"
@submit.prevent="postStatus(newStatus)"
+ @dragover.prevent="fileDrag"
>
+ <div
+ v-show="showDropIcon !== 'hide'"
+ :style="{ animation: showDropIcon === 'show' ? 'fade-in 0.25s' : 'fade-out 0.5s' }"
+ class="drop-indicator icon-upload"
+ @dragleave="fileDragStop"
+ @drop.stop="fileDrop"
+ />
<div class="form-group">
<i18n
v-if="!$store.state.users.currentUser.locked && newStatus.visibility == 'private'"
@@ -96,9 +104,7 @@
:disabled="posting"
class="form-post-body"
@keydown.meta.enter="postStatus(newStatus)"
- @keyup.ctrl.enter="postStatus(newStatus)"
- @drop="fileDrop"
- @dragover.prevent="fileDrag"
+ @keydown.ctrl.enter="postStatus(newStatus)"
@input="resize"
@compositionupdate="resize"
@paste="paste"
@@ -172,6 +178,7 @@
@uploading="disableSubmit"
@uploaded="addMediaFile"
@upload-failed="uploadFailed"
+ @all-uploaded="enableSubmit"
/>
<div
class="emoji-icon"
@@ -446,7 +453,8 @@
form {
display: flex;
flex-direction: column;
- padding: 0.6em;
+ margin: 0.6em;
+ position: relative;
}
.form-group {
@@ -504,5 +512,35 @@
cursor: pointer;
z-index: 4;
}
+
+ @keyframes fade-in {
+ from { opacity: 0; }
+ to { opacity: 0.6; }
+ }
+
+ @keyframes fade-out {
+ from { opacity: 0.6; }
+ to { opacity: 0; }
+ }
+
+ .drop-indicator {
+ position: absolute;
+ z-index: 1;
+ width: 100%;
+ height: 100%;
+ font-size: 5em;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ opacity: 0.6;
+ color: $fallback--text;
+ color: var(--text, $fallback--text);
+ background-color: $fallback--bg;
+ background-color: var(--bg, $fallback--bg);
+ border-radius: $fallback--tooltipRadius;
+ border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
+ border: 2px dashed $fallback--text;
+ border: 2px dashed var(--text, $fallback--text);
+ }
}
</style>
diff --git a/src/i18n/it.json b/src/i18n/it.json
index 360c72aa..101e1dd3 100644
--- a/src/i18n/it.json
+++ b/src/i18n/it.json
@@ -12,7 +12,12 @@
"disable": "Disabilita",
"enable": "Abilita",
"confirm": "Conferma",
- "verify": "Verifica"
+ "verify": "Verifica",
+ "peek": "Anteprima",
+ "close": "Chiudi",
+ "retry": "Riprova",
+ "error_retry": "Per favore, riprova",
+ "loading": "Carico…"
},
"nav": {
"mentions": "Menzioni",
@@ -212,7 +217,34 @@
},
"common": {
"opacity": "Opacità",
- "color": "Colore"
+ "color": "Colore",
+ "contrast": {
+ "context": {
+ "text": "per il testo",
+ "18pt": "per il testo grande (oltre 17pt)"
+ },
+ "level": {
+ "bad": "non soddisfa le linee guida di alcun livello",
+ "aaa": "soddisfa le linee guida di livello AAA (ottimo)",
+ "aa": "soddisfa le linee guida di livello AA (sufficiente)"
+ },
+ "hint": "Il rapporto di contrasto è {ratio}, e {level} {context}"
+ }
+ },
+ "advanced_colors": {
+ "badge": "Sfondo medaglie",
+ "post": "Messaggi / Biografie",
+ "alert_neutral": "Neutro",
+ "alert_warning": "Attenzione",
+ "alert_error": "Errore",
+ "alert": "Sfondo degli avvertimenti",
+ "_tab_label": "Avanzate"
+ },
+ "common_colors": {
+ "rgbo": "Icone, accenti, medaglie",
+ "foreground_hint": "Seleziona l'etichetta \"Avanzate\" per controlli più fini",
+ "main": "Colori comuni",
+ "_tab_label": "Comuni"
}
},
"enable_web_push_notifications": "Abilita notifiche web push",
@@ -273,7 +305,8 @@
"accent": "Accento",
"emoji_reactions_on_timeline": "Mostra emoji di reazione sulle sequenze",
"pad_emoji": "Affianca spazi agli emoji inseriti tramite selettore",
- "notification_blocks": "Bloccando un utente non riceverai più le sue notifiche né lo seguirai più."
+ "notification_blocks": "Bloccando un utente non riceverai più le sue notifiche né lo seguirai più.",
+ "mutes_and_blocks": "Zittiti e bloccati"
},
"timeline": {
"error_fetching": "Errore nell'aggiornamento",
diff --git a/src/i18n/messages.js b/src/i18n/messages.js
index c56ae205..c3195f10 100644
--- a/src/i18n/messages.js
+++ b/src/i18n/messages.js
@@ -7,34 +7,47 @@
// sed -i -e "s/'//gm" -e 's/"/\\"/gm' -re 's/^( +)(.+?): ((.+?))?(,?)(\{?)$/\1"\2": "\4"/gm' -e 's/\"\{\"/{/g' -e 's/,"$/",/g' file.json
// There's only problem that apostrophe character ' gets replaced by \\ so you have to fix it manually, sorry.
+const loaders = {
+ ar: () => import('./ar.json'),
+ ca: () => import('./ca.json'),
+ cs: () => import('./cs.json'),
+ de: () => import('./de.json'),
+ eo: () => import('./eo.json'),
+ es: () => import('./es.json'),
+ et: () => import('./et.json'),
+ eu: () => import('./eu.json'),
+ fi: () => import('./fi.json'),
+ fr: () => import('./fr.json'),
+ ga: () => import('./ga.json'),
+ he: () => import('./he.json'),
+ hu: () => import('./hu.json'),
+ it: () => import('./it.json'),
+ ja: () => import('./ja_pedantic.json'),
+ ja_easy: () => import('./ja_easy.json'),
+ ko: () => import('./ko.json'),
+ nb: () => import('./nb.json'),
+ nl: () => import('./nl.json'),
+ oc: () => import('./oc.json'),
+ pl: () => import('./pl.json'),
+ pt: () => import('./pt.json'),
+ ro: () => import('./ro.json'),
+ ru: () => import('./ru.json'),
+ te: () => import('./te.json'),
+ zh: () => import('./zh.json')
+}
+
const messages = {
- ar: require('./ar.json'),
- ca: require('./ca.json'),
- cs: require('./cs.json'),
- de: require('./de.json'),
- en: require('./en.json'),
- eo: require('./eo.json'),
- es: require('./es.json'),
- et: require('./et.json'),
- eu: require('./eu.json'),
- fi: require('./fi.json'),
- fr: require('./fr.json'),
- ga: require('./ga.json'),
- he: require('./he.json'),
- hu: require('./hu.json'),
- it: require('./it.json'),
- ja: require('./ja_pedantic.json'),
- ja_easy: require('./ja_easy.json'),
- ko: require('./ko.json'),
- nb: require('./nb.json'),
- nl: require('./nl.json'),
- oc: require('./oc.json'),
- pl: require('./pl.json'),
- pt: require('./pt.json'),
- ro: require('./ro.json'),
- ru: require('./ru.json'),
- te: require('./te.json'),
- zh: require('./zh.json')
+ languages: ['en', ...Object.keys(loaders)],
+ default: {
+ en: require('./en.json')
+ },
+ setLanguage: async (i18n, language) => {
+ if (loaders[language]) {
+ let messages = await loaders[language]()
+ i18n.setLocaleMessage(language, messages)
+ }
+ i18n.locale = language
+ }
}
export default messages
diff --git a/src/i18n/ru.json b/src/i18n/ru.json
index 69b22618..f9a72954 100644
--- a/src/i18n/ru.json
+++ b/src/i18n/ru.json
@@ -456,9 +456,9 @@
},
"domain_mute_card": {
"mute": "Игнорировать",
- "mute_progress": "В процессе...",
+ "mute_progress": "В процессе…",
"unmute": "Прекратить игнорирование",
- "unmute_progress": "В процессе..."
+ "unmute_progress": "В процессе…"
},
"exporter": {
"export": "Экспорт",
diff --git a/src/main.js b/src/main.js
index be4213fa..9a201e4f 100644
--- a/src/main.js
+++ b/src/main.js
@@ -46,11 +46,13 @@ Vue.use(VBodyScrollLock)
const i18n = new VueI18n({
// By default, use the browser locale, we will update it if neccessary
- locale: currentLocale,
+ locale: 'en',
fallbackLocale: 'en',
- messages
+ messages: messages.default
})
+messages.setLanguage(i18n, currentLocale)
+
const persistedStateOptions = {
paths: [
'config',
diff --git a/src/modules/config.js b/src/modules/config.js
index b6b1b241..47b24d77 100644
--- a/src/modules/config.js
+++ b/src/modules/config.js
@@ -1,5 +1,6 @@
import { set, delete as del } from 'vue'
import { setPreset, applyTheme } from '../services/style_setter/style_setter.js'
+import messages from '../i18n/messages'
const browserLocale = (window.navigator.language || 'en').split('-')[0]
@@ -115,6 +116,10 @@ const config = {
case 'customTheme':
case 'customThemeSource':
applyTheme(value)
+ break
+ case 'interfaceLanguage':
+ messages.setLanguage(this.getters.i18n, value)
+ break
}
}
}