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
|
@ -12,7 +12,7 @@ import MobilePostStatusButton from './components/mobile_post_status_button/mobil
|
||||||
import MobileNav from './components/mobile_nav/mobile_nav.vue'
|
import MobileNav from './components/mobile_nav/mobile_nav.vue'
|
||||||
import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
|
import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
|
||||||
import PostStatusModal from './components/post_status_modal/post_status_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 {
|
export default {
|
||||||
name: 'app',
|
name: 'app',
|
||||||
|
@ -120,10 +120,12 @@ export default {
|
||||||
},
|
},
|
||||||
updateMobileState () {
|
updateMobileState () {
|
||||||
const mobileLayout = windowWidth() <= 800
|
const mobileLayout = windowWidth() <= 800
|
||||||
|
const layoutHeight = windowHeight()
|
||||||
const changed = mobileLayout !== this.isMobileLayout
|
const changed = mobileLayout !== this.isMobileLayout
|
||||||
if (changed) {
|
if (changed) {
|
||||||
this.$store.dispatch('setMobileLayout', mobileLayout)
|
this.$store.dispatch('setMobileLayout', mobileLayout)
|
||||||
}
|
}
|
||||||
|
this.$store.dispatch('setLayoutHeight', layoutHeight)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|
|
@ -24,7 +24,8 @@ const Chat = {
|
||||||
mobileLayout: this.$store.state.interface.mobileLayout,
|
mobileLayout: this.$store.state.interface.mobileLayout,
|
||||||
recipientId: this.$route.params.recipient_id,
|
recipientId: this.$route.params.recipient_id,
|
||||||
hoveredSequenceId: undefined,
|
hoveredSequenceId: undefined,
|
||||||
newMessageCount: this.currentChatMessageService && this.currentChatMessageService.newMessageCount
|
newMessageCount: this.currentChatMessageService && this.currentChatMessageService.newMessageCount,
|
||||||
|
lastPosition: undefined
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
|
@ -38,6 +39,7 @@ const Chat = {
|
||||||
window.addEventListener('scroll', this.handleScroll)
|
window.addEventListener('scroll', this.handleScroll)
|
||||||
}
|
}
|
||||||
this.updateSize()
|
this.updateSize()
|
||||||
|
this.handleResize()
|
||||||
})
|
})
|
||||||
if (this.isMobileLayout) {
|
if (this.isMobileLayout) {
|
||||||
this.setMobileChatLayout()
|
this.setMobileChatLayout()
|
||||||
|
@ -47,11 +49,19 @@ const Chat = {
|
||||||
document.addEventListener('visibilitychange', this.handleVisibilityChange, false)
|
document.addEventListener('visibilitychange', this.handleVisibilityChange, false)
|
||||||
this.$store.commit('setChatFocused', !document.hidden)
|
this.$store.commit('setChatFocused', !document.hidden)
|
||||||
}
|
}
|
||||||
|
let body = document.querySelector('body')
|
||||||
|
if (body) {
|
||||||
|
body.style.overscrollBehavior = 'none'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
destroyed () {
|
destroyed () {
|
||||||
window.removeEventListener('scroll', this.handleScroll)
|
window.removeEventListener('scroll', this.handleScroll)
|
||||||
window.removeEventListener('resize', this.handleLayoutChange)
|
window.removeEventListener('resize', this.handleLayoutChange)
|
||||||
this.unsetMobileChatLayout()
|
this.unsetMobileChatLayout()
|
||||||
|
let body = document.querySelector('body')
|
||||||
|
if (body) {
|
||||||
|
body.style.overscrollBehavior = 'unset'
|
||||||
|
}
|
||||||
if (typeof document.hidden !== 'undefined') document.removeEventListener('visibilitychange', this.handleVisibilityChange, false)
|
if (typeof document.hidden !== 'undefined') document.removeEventListener('visibilitychange', this.handleVisibilityChange, false)
|
||||||
this.$store.dispatch('clearCurrentChat')
|
this.$store.dispatch('clearCurrentChat')
|
||||||
},
|
},
|
||||||
|
@ -86,7 +96,8 @@ const Chat = {
|
||||||
backendInteractor: state => state.api.backendInteractor,
|
backendInteractor: state => state.api.backendInteractor,
|
||||||
currentUser: state => state.users.currentUser,
|
currentUser: state => state.users.currentUser,
|
||||||
isMobileLayout: state => state.interface.mobileLayout,
|
isMobileLayout: state => state.interface.mobileLayout,
|
||||||
openedChats: state => state.chats.openedChats
|
openedChats: state => state.chats.openedChats,
|
||||||
|
windowHeight: state => state.interface.layoutHeight
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -102,6 +113,9 @@ const Chat = {
|
||||||
'$route': function (prev, next) {
|
'$route': function (prev, next) {
|
||||||
this.recipientId = this.$route.params.recipient_id
|
this.recipientId = this.$route.params.recipient_id
|
||||||
this.startFetching()
|
this.startFetching()
|
||||||
|
},
|
||||||
|
windowHeight () {
|
||||||
|
this.handleResize({ expand: true })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -159,7 +173,6 @@ const Chat = {
|
||||||
let body = document.querySelector('body')
|
let body = document.querySelector('body')
|
||||||
if (body) {
|
if (body) {
|
||||||
body.style.height = '100%'
|
body.style.height = '100%'
|
||||||
body.style.overscrollBehavior = 'none'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let app = document.getElementById('app')
|
let app = document.getElementById('app')
|
||||||
|
@ -201,7 +214,6 @@ const Chat = {
|
||||||
let body = document.querySelector('body')
|
let body = document.querySelector('body')
|
||||||
if (body) {
|
if (body) {
|
||||||
body.style.height = 'unset'
|
body.style.height = 'unset'
|
||||||
body.style.overscrollBehavior = 'unset'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let app = document.getElementById('app')
|
let app = document.getElementById('app')
|
||||||
|
@ -229,8 +241,37 @@ const Chat = {
|
||||||
content.style.overflow = 'unset'
|
content.style.overflow = 'unset'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleResize (newHeight) {
|
handleResize (opts) {
|
||||||
this.updateSize(newHeight)
|
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) {
|
updateSize (newHeight, _diff) {
|
||||||
let h = this.$refs.header
|
let h = this.$refs.header
|
||||||
|
|
|
@ -66,9 +66,9 @@
|
||||||
:disable-notice="true"
|
:disable-notice="true"
|
||||||
:disable-polls="true"
|
:disable-polls="true"
|
||||||
:poster="poster"
|
:poster="poster"
|
||||||
:preserve-focus="true"
|
:preserve-focus="!isMobileLayout"
|
||||||
:polls-available="false"
|
:polls-available="false"
|
||||||
:auto-focus="true"
|
:auto-focus="!isMobileLayout"
|
||||||
:placeholder="formPlaceholder"
|
:placeholder="formPlaceholder"
|
||||||
:file-limit="1"
|
:file-limit="1"
|
||||||
max-height="160"
|
max-height="160"
|
||||||
|
|
|
@ -238,12 +238,19 @@ const PostStatusForm = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
addMediaFile (fileInfo) {
|
addMediaFile (fileInfo) {
|
||||||
|
this.$emit('resize')
|
||||||
this.newStatus.files.push(fileInfo)
|
this.newStatus.files.push(fileInfo)
|
||||||
this.enableSubmit()
|
this.enableSubmit()
|
||||||
|
// TODO: use fixed dimensions instead so relying on timeout
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$emit('resize')
|
||||||
|
}, 150)
|
||||||
},
|
},
|
||||||
removeMediaFile (fileInfo) {
|
removeMediaFile (fileInfo) {
|
||||||
|
this.$emit('resize')
|
||||||
let index = this.newStatus.files.indexOf(fileInfo)
|
let index = this.newStatus.files.indexOf(fileInfo)
|
||||||
this.newStatus.files.splice(index, 1)
|
this.newStatus.files.splice(index, 1)
|
||||||
|
this.$emit('resize')
|
||||||
},
|
},
|
||||||
uploadFailed (errString, templateArgs) {
|
uploadFailed (errString, templateArgs) {
|
||||||
templateArgs = templateArgs || {}
|
templateArgs = templateArgs || {}
|
||||||
|
|
|
@ -12,7 +12,8 @@ const defaultState = {
|
||||||
window.CSS.supports('-webkit-filter', 'drop-shadow(0 0)')
|
window.CSS.supports('-webkit-filter', 'drop-shadow(0 0)')
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
mobileLayout: false
|
mobileLayout: false,
|
||||||
|
layoutHeight: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const interfaceMod = {
|
const interfaceMod = {
|
||||||
|
@ -35,6 +36,9 @@ const interfaceMod = {
|
||||||
},
|
},
|
||||||
setMobileLayout (state, value) {
|
setMobileLayout (state, value) {
|
||||||
state.mobileLayout = value
|
state.mobileLayout = value
|
||||||
|
},
|
||||||
|
setLayoutHeight (state, value) {
|
||||||
|
state.layoutHeight = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -49,6 +53,9 @@ const interfaceMod = {
|
||||||
},
|
},
|
||||||
setMobileLayout ({ commit }, value) {
|
setMobileLayout ({ commit }, value) {
|
||||||
commit('setMobileLayout', value)
|
commit('setMobileLayout', value)
|
||||||
|
},
|
||||||
|
setLayoutHeight ({ commit }, value) {
|
||||||
|
commit('setLayoutHeight', value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,3 +3,8 @@ export const windowWidth = () =>
|
||||||
window.innerWidth ||
|
window.innerWidth ||
|
||||||
document.documentElement.clientWidth ||
|
document.documentElement.clientWidth ||
|
||||||
document.body.clientWidth
|
document.body.clientWidth
|
||||||
|
|
||||||
|
export const windowHeight = () =>
|
||||||
|
window.innerHeight ||
|
||||||
|
document.documentElement.clientHeight ||
|
||||||
|
document.body.clientHeight
|
||||||
|
|
Loading…
Reference in a new issue