Skip to content

Commit

Permalink
fix(Feed): pull to refresh on mobile
Browse files Browse the repository at this point in the history
  • Loading branch information
netchampfaris committed Feb 24, 2023
1 parent ef38697 commit b4c5631
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 4 deletions.
38 changes: 34 additions & 4 deletions frontend/src/pages/Feed.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<template>
<header class="sticky top-0 z-10 border-b bg-white py-3 px-4 sm:px-5">
<header
class="fixed top-0 z-10 h-14 w-full border-b bg-white py-3 px-4 sm:sticky sm:px-5"
>
<div class="flex items-center justify-between">
<div class="ml-3 flex">
<h1 class="mr-4 text-2xl font-semibold">Home</h1>
Expand Down Expand Up @@ -29,7 +31,13 @@
</button>
</div>
</header>
<div class="mt-1">
<div
class="fixed top-14 flex w-full justify-center py-2 text-gray-600"
v-if="swipeLoading"
>
<LoadingIndicator class="h-4 w-4" />
</div>
<div class="mt-14 pt-1 sm:mt-0">
<div
class="mx-auto -mt-1 flex max-w-4xl items-center justify-between px-2 pt-2 pb-2 sm:px-0 sm:px-5"
v-if="feedType === 'following'"
Expand Down Expand Up @@ -132,21 +140,24 @@ import Breadcrumbs from '@/components/Breadcrumbs.vue'
import DiscussionList from '@/components/DiscussionList.vue'
import { activeTeams } from '@/data/teams'
import { getTeamProjects } from '@/data/projects'
import { Autocomplete } from 'frappe-ui'
import { Autocomplete, LoadingIndicator } from 'frappe-ui'
import { getPlatform } from '@/utils'
import { showCommandPalette } from '@/components/CommandPalette.vue'
import { useSwipe } from '@/utils/composables'
import { getScrollContainer } from '@/utils/scrollContainer'
let projectFollowId = {}
export default {
name: 'Home',
props: ['feedType'],
components: { Breadcrumbs, DiscussionList, Autocomplete },
components: { Breadcrumbs, DiscussionList, Autocomplete, LoadingIndicator },
data() {
return {
followProjectsDialog: false,
projects: [],
selectedProject: null,
swipeLoading: false,
feedOptions: [
{
label: 'Recent',
Expand All @@ -163,6 +174,10 @@ export default {
],
}
},
setup() {
const swipe = useSwipe()
return { swipe }
},
watch: {
selectedProject(value) {
if (!value) return
Expand All @@ -171,6 +186,21 @@ export default {
}
this.selectedProject = null
},
swipe: {
handler(d) {
if (
getScrollContainer().scrollTop === 0 &&
d.direction == 'down' &&
d.diffY < -200
) {
this.swipeLoading = true
this.$refs.discussionList.discussions.reload().then(() => {
this.swipeLoading = false
})
}
},
deep: true,
},
},
resources: {
followedProjects() {
Expand Down
66 changes: 66 additions & 0 deletions frontend/src/utils/composables.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,72 @@ export function useScreenSize() {

return size
}
// write a composable for detecting swipe gestures in mobile devices
export function useSwipe() {
const swipe = reactive({
initialX: null,
initialY: null,
currentX: null,
currentY: null,
diffX: null,
diffY: null,
absDiffX: null,
absDiffY: null,
direction: null,
})

const onTouchStart = (e) => {
swipe.initialX = e.touches[0].clientX
swipe.initialY = e.touches[0].clientY
swipe.direction = null
swipe.diffX = null
swipe.diffY = null
swipe.absDiffX = null
swipe.absDiffY = null
}

const onTouchMove = (e) => {
swipe.currentX = e.touches[0].clientX
swipe.currentY = e.touches[0].clientY

swipe.diffX = swipe.initialX - swipe.currentX
swipe.diffY = swipe.initialY - swipe.currentY

swipe.absDiffX = Math.abs(swipe.diffX)
swipe.absDiffY = Math.abs(swipe.diffY)
}

const onTouchEnd = (e) => {
let { diffX, diffY, absDiffX, absDiffY } = swipe
if (absDiffX > absDiffY) {
if (diffX > 0) {
swipe.direction = 'left'
} else {
swipe.direction = 'right'
}
} else {
if (diffY > 0) {
swipe.direction = 'up'
} else {
swipe.direction = 'down'
}
}
}

onMounted(() => {
window.addEventListener('touchstart', onTouchStart)
window.addEventListener('touchend', onTouchEnd)
window.addEventListener('touchmove', onTouchMove)
})

onUnmounted(() => {
window.removeEventListener('touchstart', onTouchStart)
window.removeEventListener('touchend', onTouchEnd)
window.removeEventListener('touchmove', onTouchMove)
})

return swipe
}

export function useLocalStorage(key, initialValue) {
let value = ref(null)
Expand Down

0 comments on commit b4c5631

Please sign in to comment.