diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ed1c186..3fb72931 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,34 @@ 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/). +## 2.5.1 +### Fixed +- Checkboxes in settings can now work with screenreaders +- Autocomplete in edit boxes can now work with screenreaders +- Status interact buttons now have focus indicator for anonymous users +- Top bar buttons now correctly have text labels +- It is now possible to register if the site admin requires birthday to register +- User cards from search results will correctly popup +- Fix notification attachment icon overflow +- Editing mute words is less laggy +- Repeater's name will no longer mess up with the directionality of the text sitting on the same line +- Unauthenticated access will give better error messages +- It is now easier to close the media viewer with a mouse when there is only one image +- Deleting profile fields can work properly +- Clicking the react button will correctly focus the search box +- Clicking buttons on the top-bar will no longer bring you to the top of the page +- Emoji picker is much faster to load +- `blockquote`s have a better display style +- Announcements posting and editing are now available to everyone with such a privilege, not just admins +- Adding or removing list members will actually work +- Emojis without a pack are now correctly displayed in emoji picker +- Changing notification settings will actually work + +### Added +- You can now set and see birthdays +- Optional confirmation dialogs when performing various actions +- You can now set fallback languages + ## 2.5.0 - 23.12.2022 ### Fixed - UI no longer lags when switching between mobile and desktop mode diff --git a/package.json b/package.json index 557672ea..9c5b638a 100644 --- a/package.json +++ b/package.json @@ -16,12 +16,12 @@ "lint-fix": "eslint --fix --ext .js,.vue src test/unit/specs test/e2e/specs" }, "dependencies": { - "@babel/runtime": "7.20.7", + "@babel/runtime": "7.21.0", "@chenfengyuan/vue-qrcode": "2.0.0", - "@fortawesome/fontawesome-svg-core": "6.2.1", - "@fortawesome/free-regular-svg-icons": "6.2.1", - "@fortawesome/free-solid-svg-icons": "6.2.1", - "@fortawesome/vue-fontawesome": "3.0.2", + "@fortawesome/fontawesome-svg-core": "6.3.0", + "@fortawesome/free-regular-svg-icons": "6.3.0", + "@fortawesome/free-solid-svg-icons": "6.3.0", + "@fortawesome/vue-fontawesome": "3.0.3", "@kazvmoe-infra/pinch-zoom-element": "1.2.0", "@kazvmoe-infra/unicode-emoji-json": "0.4.0", "@ruffle-rs/ruffle": "0.1.0-nightly.2022.7.12", @@ -36,7 +36,7 @@ "localforage": "1.10.0", "parse-link-header": "2.0.0", "phoenix": "1.6.2", - "punycode.js": "2.1.0", + "punycode.js": "2.3.0", "qrcode": "1.5.0", "querystring-es3": "0.2.1", "url": "0.11.0", @@ -49,19 +49,19 @@ "vuex": "4.1.0" }, "devDependencies": { - "@babel/core": "7.20.7", + "@babel/core": "7.21.0", "@babel/eslint-parser": "7.19.1", - "@babel/plugin-transform-runtime": "7.19.6", + "@babel/plugin-transform-runtime": "7.21.0", "@babel/preset-env": "7.20.2", - "@babel/register": "7.18.9", + "@babel/register": "7.21.0", "@intlify/vue-i18n-loader": "5.0.0", "@ungap/event-target": "0.2.3", "@vue/babel-helper-vue-jsx-merge-props": "1.4.0", "@vue/babel-plugin-jsx": "1.1.1", "@vue/compiler-sfc": "3.2.45", - "@vue/test-utils": "2.2.7", + "@vue/test-utils": "2.2.8", "autoprefixer": "10.4.13", - "babel-loader": "9.1.0", + "babel-loader": "9.1.2", "babel-plugin-lodash": "3.3.4", "chai": "4.3.7", "chalk": "1.1.3", @@ -72,7 +72,7 @@ "css-loader": "6.7.3", "css-minimizer-webpack-plugin": "4.2.2", "custom-event-polyfill": "1.0.7", - "eslint": "8.32.0", + "eslint": "8.33.0", "eslint-config-standard": "17.0.0", "eslint-formatter-friendly": "7.0.0", "eslint-plugin-import": "2.27.5", @@ -99,7 +99,7 @@ "lodash": "4.17.21", "mini-css-extract-plugin": "2.7.2", "mocha": "10.2.0", - "nightwatch": "2.6.10", + "nightwatch": "2.6.11", "opn": "5.5.0", "ora": "0.4.1", "postcss": "8.4.20", diff --git a/src/App.scss b/src/App.scss index 1c4c8941..3f352e8d 100644 --- a/src/App.scss +++ b/src/App.scss @@ -580,8 +580,6 @@ textarea, } &[type="checkbox"] { - display: none; - &:checked + label::before { color: $fallback--text; color: var(--inputText, $fallback--text); @@ -887,3 +885,15 @@ option { opacity: 0; } /* stylelint-enable no-descending-specificity */ + +.visible-for-screenreader-only { + display: block; + width: 1px; + height: 1px; + margin: -1px; + overflow: hidden; + visibility: visible; + clip: rect(0 0 0 0); + padding: 0; + position: absolute; +} diff --git a/src/boot/after_store.js b/src/boot/after_store.js index d2e7f488..9c1f007b 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -253,6 +253,7 @@ const getNodeInfo = async ({ store }) => { store.dispatch('setInstanceOption', { name: 'safeDM', value: features.includes('safe_dm_mentions') }) store.dispatch('setInstanceOption', { name: 'shoutAvailable', value: features.includes('chat') }) store.dispatch('setInstanceOption', { name: 'pleromaChatMessagesAvailable', value: features.includes('pleroma_chat_messages') }) + store.dispatch('setInstanceOption', { name: 'pleromaCustomEmojiReactionsAvailable', value: features.includes('pleroma_custom_emoji_reactions') }) store.dispatch('setInstanceOption', { name: 'gopherAvailable', value: features.includes('gopher') }) store.dispatch('setInstanceOption', { name: 'pollsAvailable', value: features.includes('polls') }) store.dispatch('setInstanceOption', { name: 'editingAvailable', value: features.includes('editing') }) diff --git a/src/components/checkbox/checkbox.vue b/src/components/checkbox/checkbox.vue index 7139d4fc..42f89be9 100644 --- a/src/components/checkbox/checkbox.vue +++ b/src/components/checkbox/checkbox.vue @@ -5,12 +5,16 @@ > - + @import "../../variables"; +@import "../../mixins"; .checkbox { position: relative; @@ -81,8 +86,6 @@ export default { } input[type="checkbox"] { - display: none; - &:checked + .checkbox-indicator::before { color: $fallback--text; color: var(--inputText, $fallback--text); diff --git a/src/components/desktop_nav/desktop_nav.vue b/src/components/desktop_nav/desktop_nav.vue index 92622cf9..dc8bbfd3 100644 --- a/src/components/desktop_nav/desktop_nav.vue +++ b/src/components/desktop_nav/desktop_nav.vue @@ -20,6 +20,7 @@ class="logo" :to="{ name: 'root' }" :style="logoBgStyle" + :title="sitename" > diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js index ba5f7552..68654f69 100644 --- a/src/components/emoji_input/emoji_input.js +++ b/src/components/emoji_input/emoji_input.js @@ -1,6 +1,7 @@ import Completion from '../../services/completion/completion.js' import EmojiPicker from '../emoji_picker/emoji_picker.vue' import Popover from 'src/components/popover/popover.vue' +import ScreenReaderNotice from 'src/components/screen_reader_notice/screen_reader_notice.vue' import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue' import { take } from 'lodash' import { findOffset } from '../../services/offset_finder/offset_finder.service.js' @@ -109,9 +110,10 @@ const EmojiInput = { }, data () { return { + randomSeed: `${Math.random()}`.replace('.', '-'), input: undefined, caretEl: undefined, - highlighted: 0, + highlighted: -1, caret: 0, focused: false, blurTimeout: null, @@ -125,12 +127,16 @@ const EmojiInput = { components: { Popover, EmojiPicker, - UnicodeDomainIndicator + UnicodeDomainIndicator, + ScreenReaderNotice }, computed: { padEmoji () { return this.$store.getters.mergedConfig.padEmoji }, + defaultCandidateIndex () { + return this.$store.getters.mergedConfig.autocompleteSelect ? 0 : -1 + }, preText () { return this.modelValue.slice(0, this.caret) }, @@ -203,6 +209,12 @@ const EmojiInput = { top: this.input.scrollTop, left: this.input.scrollLeft }) + }, + suggestionListId () { + return `suggestions-${this.randomSeed}` + }, + suggestionItemId () { + return (index) => `suggestion-item-${index}-${this.randomSeed}` } }, mounted () { @@ -278,6 +290,11 @@ const EmojiInput = { ...rest, img: imageUrl || '' })) + this.highlighted = this.defaultCandidateIndex + this.$refs.screenReaderNotice.announce( + this.$tc('tool_tip.autocomplete_available', + this.suggestions.length, + { number: this.suggestions.length })) } }, methods: { @@ -374,26 +391,27 @@ const EmojiInput = { }, cycleBackward (e) { const len = this.suggestions.length || 0 - if (len > 1) { - this.highlighted -= 1 - if (this.highlighted < 0) { - this.highlighted = this.suggestions.length - 1 - } + + this.highlighted -= 1 + if (this.highlighted === -1) { + this.input.focus() + } else if (this.highlighted < -1) { + this.highlighted = len - 1 + } + if (len > 0) { e.preventDefault() - } else { - this.highlighted = 0 } }, cycleForward (e) { const len = this.suggestions.length || 0 - if (len > 1) { - this.highlighted += 1 - if (this.highlighted >= len) { - this.highlighted = 0 - } + + this.highlighted += 1 + if (this.highlighted >= len) { + this.highlighted = -1 + this.input.focus() + } + if (len > 0) { e.preventDefault() - } else { - this.highlighted = 0 } }, scrollIntoView () { @@ -540,6 +558,13 @@ const EmojiInput = { }) }, resize () { + }, + autoCompleteItemLabel (suggestion) { + if (suggestion.user) { + return suggestion.displayText + ' ' + suggestion.detailText + } else { + return this.maybeLocalizedEmojiName(suggestion) + } } } } diff --git a/src/components/emoji_input/emoji_input.vue b/src/components/emoji_input/emoji_input.vue index ccba0393..7f9ecc99 100644 --- a/src/components/emoji_input/emoji_input.vue +++ b/src/components/emoji_input/emoji_input.vue @@ -4,12 +4,19 @@ class="emoji-input" :class="{ 'with-picker': !hideEmojiButton }" > - +
{{ preText }} x {{ postText }}
+