diff --git a/CHANGELOG.md b/CHANGELOG.md index 99f601a50..1257cd75f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Fixed chats list not updating its order when new messages come in - Fixed chat messages sometimes getting lost when you receive a message at the same time - Fixed clicking NSFW hider through status popover +- Fixed chat-view back button being hard to click +- Fixed fresh chat notifications being cleared immediately while leaving the chat view and not having time to actually see the messages + +### Changed +- Clicking immediately when timeline shifts is now blocked to prevent misclicks ### Added - Import/export a muted users diff --git a/src/components/chat/chat.js b/src/components/chat/chat.js index 083f850ff..c0c9ad6cf 100644 --- a/src/components/chat/chat.js +++ b/src/components/chat/chat.js @@ -21,6 +21,7 @@ library.add( const BOTTOMED_OUT_OFFSET = 10 const JUMP_TO_BOTTOM_BUTTON_VISIBILITY_OFFSET = 150 const SAFE_RESIZE_TIME_OFFSET = 100 +const MARK_AS_READ_DELAY = 1500 const Chat = { components: { @@ -104,7 +105,7 @@ const Chat = { const bottomedOutBeforeUpdate = this.bottomedOut(BOTTOMED_OUT_OFFSET) this.$nextTick(() => { if (bottomedOutBeforeUpdate) { - this.scrollDown({ forceRead: !document.hidden }) + this.scrollDown() } }) }, @@ -210,7 +211,7 @@ const Chat = { this.$nextTick(() => { scrollable.scrollTo({ top: scrollable.scrollHeight, left: 0, behavior }) }) - if (forceRead || this.newMessageCount > 0) { + if (forceRead) { this.readChat() } }, @@ -235,12 +236,18 @@ const Chat = { } else if (this.bottomedOut(JUMP_TO_BOTTOM_BUTTON_VISIBILITY_OFFSET)) { this.jumpToBottomButtonVisible = false if (this.newMessageCount > 0) { - this.readChat() + // Use a delay before marking as read to prevent situation where new messages + // arrive just as you're leaving the view and messages that you didn't actually + // get to see get marked as read. + window.setTimeout(() => { + // Don't mark as read if the element doesn't exist, user has left chat view + if (this.$el) this.readChat() + }, MARK_AS_READ_DELAY) } } else { this.jumpToBottomButtonVisible = true } - }, 100), + }, 200), handleScrollUp (positionBeforeLoading) { const positionAfterLoading = getScrollPosition(this.$refs.scrollable) this.$refs.scrollable.scrollTo({ diff --git a/src/components/chat/chat.scss b/src/components/chat/chat.scss index b7b0d3777..787514c8b 100644 --- a/src/components/chat/chat.scss +++ b/src/components/chat/chat.scss @@ -25,7 +25,7 @@ min-height: 100%; margin: 0 0 0 0; border-radius: 10px 10px 0 0; - border-radius: var(--panelRadius, 10px) var(--panelRadius, 10px) 0 0 ; + border-radius: var(--panelRadius, 10px) var(--panelRadius, 10px) 0 0; &::after { border-radius: 0; @@ -58,8 +58,10 @@ .go-back-button { cursor: pointer; - margin-right: 1.7em; - margin-left: 0.3em; + width: 28px; + text-align: center; + padding: 0.6em; + margin: -0.6em 0.6em -0.6em -0.6em; } .jump-to-bottom-button { @@ -74,7 +76,7 @@ display: flex; justify-content: center; align-items: center; - box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.3), 0px 2px 4px rgba(0, 0, 0, 0.3); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3), 0 2px 4px rgba(0, 0, 0, 0.3); z-index: 10; transition: 0.35s all; transition-timing-function: cubic-bezier(0, 1, 0.5, 1); diff --git a/src/components/chat_new/chat_new.scss b/src/components/chat_new/chat_new.scss index 716172b05..5506143d4 100644 --- a/src/components/chat_new/chat_new.scss +++ b/src/components/chat_new/chat_new.scss @@ -23,7 +23,9 @@ .go-back-button { cursor: pointer; - margin-right: 1.7em; - margin-left: 0.3em; + width: 28px; + text-align: center; + padding: 0.6em; + margin: -0.6em 0.6em -0.6em -0.6em; } } diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js index a443340ff..368ee81be 100644 --- a/src/components/timeline/timeline.js +++ b/src/components/timeline/timeline.js @@ -2,7 +2,7 @@ import Status from '../status/status.vue' import timelineFetcher from '../../services/timeline_fetcher/timeline_fetcher.service.js' import Conversation from '../conversation/conversation.vue' import TimelineMenu from '../timeline_menu/timeline_menu.vue' -import { throttle, keyBy } from 'lodash' +import { debounce, throttle, keyBy } from 'lodash' import { library } from '@fortawesome/fontawesome-svg-core' import { faCircleNotch } from '@fortawesome/free-solid-svg-icons' @@ -40,7 +40,8 @@ const Timeline = { paused: false, unfocused: false, bottomedOut: false, - virtualScrollIndex: 0 + virtualScrollIndex: 0, + blockingClicks: false } }, components: { @@ -70,8 +71,10 @@ const Timeline = { } }, classes () { + let rootClasses = !this.embedded ? ['panel', 'panel-default'] : [] + if (this.blockingClicks) rootClasses = rootClasses.concat(['-blocked']) return { - root: ['timeline'].concat(!this.embedded ? ['panel', 'panel-default'] : []), + root: rootClasses, header: ['timeline-heading'].concat(!this.embedded ? ['panel-heading'] : []), body: ['timeline-body'].concat(!this.embedded ? ['panel-body'] : []), footer: ['timeline-footer'].concat(!this.embedded ? ['panel-footer'] : []) @@ -130,6 +133,15 @@ const Timeline = { this.$store.commit('setLoading', { timeline: this.timelineName, value: false }) }, methods: { + stopBlockingClicks: debounce(function () { + this.blockingClicks = false + }, 1000), + blockClicksTemporarily () { + if (!this.blockingClicks) { + this.blockingClicks = true + } + this.stopBlockingClicks() + }, handleShortKey (e) { // Ignore when input fields are focused if (['textarea', 'input'].includes(e.target.tagName.toLowerCase())) return @@ -141,6 +153,7 @@ const Timeline = { this.$store.commit('queueFlush', { timeline: this.timelineName, id: 0 }) this.fetchOlderStatuses() } else { + this.blockClicksTemporarily() this.$store.commit('showNewStatuses', { timeline: this.timelineName }) this.paused = false } diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue index aaf0349cb..373b946f2 100644 --- a/src/components/timeline/timeline.vue +++ b/src/components/timeline/timeline.vue @@ -1,5 +1,5 @@