WIP preserve scroll position during posting form resize, attachment upload, window resize, disable auto-focus for mobile

This commit is contained in:
eugenijm 2020-05-22 00:49:02 +03:00
parent 5f7494f134
commit 93049e9d52
6 changed files with 72 additions and 10 deletions

View File

@ -12,7 +12,7 @@ import MobilePostStatusButton from './components/mobile_post_status_button/mobil
import MobileNav from './components/mobile_nav/mobile_nav.vue'
import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
import { windowWidth } from './services/window_utils/window_utils'
import { windowWidth, windowHeight } from './services/window_utils/window_utils'
export default {
name: 'app',
@ -120,10 +120,12 @@ export default {
},
updateMobileState () {
const mobileLayout = windowWidth() <= 800
const layoutHeight = windowHeight()
const changed = mobileLayout !== this.isMobileLayout
if (changed) {
this.$store.dispatch('setMobileLayout', mobileLayout)
}
this.$store.dispatch('setLayoutHeight', layoutHeight)
}
},
watch: {

View File

@ -24,7 +24,8 @@ const Chat = {
mobileLayout: this.$store.state.interface.mobileLayout,
recipientId: this.$route.params.recipient_id,
hoveredSequenceId: undefined,
newMessageCount: this.currentChatMessageService && this.currentChatMessageService.newMessageCount
newMessageCount: this.currentChatMessageService && this.currentChatMessageService.newMessageCount,
lastPosition: undefined
}
},
created () {
@ -38,6 +39,7 @@ const Chat = {
window.addEventListener('scroll', this.handleScroll)
}
this.updateSize()
this.handleResize()
})
if (this.isMobileLayout) {
this.setMobileChatLayout()
@ -47,11 +49,19 @@ const Chat = {
document.addEventListener('visibilitychange', this.handleVisibilityChange, false)
this.$store.commit('setChatFocused', !document.hidden)
}
let body = document.querySelector('body')
if (body) {
body.style.overscrollBehavior = 'none'
}
},
destroyed () {
window.removeEventListener('scroll', this.handleScroll)
window.removeEventListener('resize', this.handleLayoutChange)
this.unsetMobileChatLayout()
let body = document.querySelector('body')
if (body) {
body.style.overscrollBehavior = 'unset'
}
if (typeof document.hidden !== 'undefined') document.removeEventListener('visibilitychange', this.handleVisibilityChange, false)
this.$store.dispatch('clearCurrentChat')
},
@ -86,7 +96,8 @@ const Chat = {
backendInteractor: state => state.api.backendInteractor,
currentUser: state => state.users.currentUser,
isMobileLayout: state => state.interface.mobileLayout,
openedChats: state => state.chats.openedChats
openedChats: state => state.chats.openedChats,
windowHeight: state => state.interface.layoutHeight
})
},
watch: {
@ -102,6 +113,9 @@ const Chat = {
'$route': function (prev, next) {
this.recipientId = this.$route.params.recipient_id
this.startFetching()
},
windowHeight () {
this.handleResize({ expand: true })
}
},
methods: {
@ -159,7 +173,6 @@ const Chat = {
let body = document.querySelector('body')
if (body) {
body.style.height = '100%'
body.style.overscrollBehavior = 'none'
}
let app = document.getElementById('app')
@ -201,7 +214,6 @@ const Chat = {
let body = document.querySelector('body')
if (body) {
body.style.height = 'unset'
body.style.overscrollBehavior = 'unset'
}
let app = document.getElementById('app')
@ -229,8 +241,37 @@ const Chat = {
content.style.overflow = 'unset'
}
},
handleResize (newHeight) {
this.updateSize(newHeight)
handleResize (opts) {
this.$nextTick(() => {
this.updateSize()
let prevOffsetHeight
if (this.lastPosition) {
prevOffsetHeight = this.lastPosition.offsetHeight
}
this.lastPosition = {
scrollTop: this.$refs.scrollable.scrollTop,
totalHeight: this.$refs.scrollable.scrollHeight,
offsetHeight: this.$refs.scrollable.offsetHeight
}
if (this.lastPosition) {
const diff = this.lastPosition.offsetHeight - prevOffsetHeight
const bottomedOut = this.bottomedOut()
if (diff < 0 || (!bottomedOut && opts && opts.expand)) {
this.$nextTick(() => {
this.updateSize()
this.$nextTick(() => {
this.$refs.scrollable.scrollTo({
top: this.$refs.scrollable.scrollTop - diff,
left: 0
})
})
})
}
}
})
},
updateSize (newHeight, _diff) {
let h = this.$refs.header

View File

@ -66,9 +66,9 @@
:disable-notice="true"
:disable-polls="true"
:poster="poster"
:preserve-focus="true"
:preserve-focus="!isMobileLayout"
:polls-available="false"
:auto-focus="true"
:auto-focus="!isMobileLayout"
:placeholder="formPlaceholder"
:file-limit="1"
max-height="160"

View File

@ -238,12 +238,19 @@ const PostStatusForm = {
})
},
addMediaFile (fileInfo) {
this.$emit('resize')
this.newStatus.files.push(fileInfo)
this.enableSubmit()
// TODO: use fixed dimensions instead so relying on timeout
setTimeout(() => {
this.$emit('resize')
}, 150)
},
removeMediaFile (fileInfo) {
this.$emit('resize')
let index = this.newStatus.files.indexOf(fileInfo)
this.newStatus.files.splice(index, 1)
this.$emit('resize')
},
uploadFailed (errString, templateArgs) {
templateArgs = templateArgs || {}

View File

@ -12,7 +12,8 @@ const defaultState = {
window.CSS.supports('-webkit-filter', 'drop-shadow(0 0)')
)
},
mobileLayout: false
mobileLayout: false,
layoutHeight: 0
}
const interfaceMod = {
@ -35,6 +36,9 @@ const interfaceMod = {
},
setMobileLayout (state, value) {
state.mobileLayout = value
},
setLayoutHeight (state, value) {
state.layoutHeight = value
}
},
actions: {
@ -49,6 +53,9 @@ const interfaceMod = {
},
setMobileLayout ({ commit }, value) {
commit('setMobileLayout', value)
},
setLayoutHeight ({ commit }, value) {
commit('setLayoutHeight', value)
}
}
}

View File

@ -3,3 +3,8 @@ export const windowWidth = () =>
window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth
export const windowHeight = () =>
window.innerHeight ||
document.documentElement.clientHeight ||
document.body.clientHeight