forked from AkkomaGang/akkoma-fe
WIP preserve scroll position during posting form resize, attachment upload, window resize, disable auto-focus for mobile
This commit is contained in:
parent
5f7494f134
commit
93049e9d52
6 changed files with 72 additions and 10 deletions
|
@ -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: {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 || {}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue