diff options
| -rw-r--r-- | CHANGELOG.md | 3 | ||||
| -rw-r--r-- | src/App.js | 3 | ||||
| -rw-r--r-- | src/components/interface_language_switcher/interface_language_switcher.vue | 3 | ||||
| -rw-r--r-- | src/components/media_upload/media_upload.js | 39 | ||||
| -rw-r--r-- | src/components/media_upload/media_upload.vue | 7 | ||||
| -rw-r--r-- | src/components/post_status_form/post_status_form.js | 22 | ||||
| -rw-r--r-- | src/components/post_status_form/post_status_form.vue | 46 | ||||
| -rw-r--r-- | src/i18n/it.json | 39 | ||||
| -rw-r--r-- | src/i18n/messages.js | 67 | ||||
| -rw-r--r-- | src/i18n/ru.json | 4 | ||||
| -rw-r--r-- | src/main.js | 6 | ||||
| -rw-r--r-- | src/modules/config.js | 5 |
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 @@ -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 } } } |
