Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 3 additions & 63 deletions src/components/VoteTable/VoteTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
-->

<script setup lang="ts">
import { n, t } from '@nextcloud/l10n'
import { t } from '@nextcloud/l10n'

import { usePollStore } from '../../stores/poll.ts'
import { useOptionsStore } from '../../stores/options.ts'
import { useVotesStore } from '../../stores/votes.ts'

import { NcButton } from '@nextcloud/vue'
import SortNameIcon from 'vue-material-design-icons/SortAlphabeticalDescending.vue'
import { computed, nextTick, ref } from 'vue'
import { computed, ref } from 'vue'
import { getCurrentUser } from '@nextcloud/auth'
import Counter from '../Options/Counter.vue'
import CalendarPeek from '../Calendar/CalendarPeek.vue'
Expand All @@ -23,17 +23,13 @@ import { usePreferencesStore } from '../../stores/preferences.ts'
import SortOptionIcon from 'vue-material-design-icons/SortBoolAscendingVariant.vue'
import VoteItem from './VoteItem.vue'
import VoteParticipant from './VoteParticipant.vue'
import IntersectionObserver from '../Base/modules/IntersectionObserver.vue'
import { showError } from '@nextcloud/dialogs'

const emit = defineEmits(['headerSticky', 'headerUnSticky'])

const pollStore = usePollStore()
const optionsStore = useOptionsStore()
const votesStore = useVotesStore()
const preferencesStore = usePreferencesStore()

const downPage = defineModel<boolean>('downPage', { default: false })
const { downPage = false } = defineProps<{ downPage: boolean }>()

const chunksLoading = ref(false)

Expand All @@ -48,32 +44,9 @@ const showCalendarPeek = computed(
&& getCurrentUser()
&& preferencesStore.user.calendarPeek,
)

/**
*
*/
function loadMore() {
try {
chunksLoading.value = true
nextTick(() => {
votesStore.addChunk()
})
nextTick(() => {
chunksLoading.value = false
})
} catch {
showError(t('polls', 'Error loading more participants'))
}
}
</script>

<template>
<IntersectionObserver
key="top-observer"
v-model="downPage"
@visible="emit('headerSticky')"
@invisible="emit('headerUnSticky')" />

<TransitionGroup
id="vote-table"
tag="div"
Expand Down Expand Up @@ -154,42 +127,9 @@ function loadMore() {
</div>
</template>
</TransitionGroup>
<div
v-if="
votesStore.countHiddenParticipants > 0
&& pollStore.viewMode === 'table-view'
"
class="observer-container sticky-left">
<IntersectionObserver
key="bottom-observer"
class="observer_section"
:loading="chunksLoading"
@visible="loadMore">
<div class="clickable_load_more" @click="loadMore">
{{
n(
'polls',
'%n participant is hidden. Click here to load more',
'%n participants are hidden. Click here to load more',
votesStore.countHiddenParticipants,
)
}}
</div>
</IntersectionObserver>
</div>
</template>

<style lang="scss">
.observer-container {
display: flex;
justify-content: center;
}

.observer_section {
position: sticky;
left: 70px;
}

.vote-table {
display: grid;
grid-template-columns: max-content repeat(
Expand Down
66 changes: 59 additions & 7 deletions src/views/Vote.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
-->

<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue'
import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus'
import { t } from '@nextcloud/l10n'
import { n, t } from '@nextcloud/l10n'

import NcAppContent from '@nextcloud/vue/components/NcAppContent'
import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent'
Expand Down Expand Up @@ -34,13 +34,17 @@ import Collapsible from '../components/Base/modules/Collapsible.vue'
import type { CollapsibleProps } from '../components/Base/modules/Collapsible.vue'
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
import IntersectionObserver from '../components/Base/modules/IntersectionObserver.vue'
import { useVotesStore } from '../stores/votes.ts'
import { showError } from '@nextcloud/dialogs'

const pollStore = usePollStore()
const optionsStore = useOptionsStore()
const preferencesStore = usePreferencesStore()
const votesStore = useVotesStore()
const voteMainId = 'watched-scroll-area'
const topObserverVisible = ref(false)
const voteHeaderDownPage = ref(false)
const tableSticky = ref(false)
const chunksLoading = ref(false)

const loadingOverlayProps = {
name: t('polls', 'Loading poll…'),
Expand Down Expand Up @@ -73,6 +77,23 @@ const emptyContentProps = computed(() => {
}
})

async function loadChunks() {
if (chunksLoading.value) {
return
}

try {
chunksLoading.value = true
await nextTick()
await votesStore.addChunk()
} catch {
showError(t('polls', 'Error loading more participants'))
} finally {
await nextTick()
chunksLoading.value = false
}
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const windowTitle = computed(
() => `${t('polls', 'Polls')} - ${pollStore.configuration.title}`,
Expand All @@ -95,10 +116,13 @@ const collapsibleProps = computed<CollapsibleProps>(() => ({
initialState: pollStore.currentUserStatus.countVotes === 0 ? 'max' : 'min',
}))

const scrolled = computed(
() => !topObserverVisible.value && voteHeaderDownPage.value,
)
const scrolled = computed(() => !topObserverVisible.value && tableSticky.value)

const showBottomObserver = computed(
() =>
votesStore.countHiddenParticipants > 0
&& pollStore.viewMode === 'table-view',
)
onBeforeRouteUpdate(async () => {
pollStore.load()
emit(Event.TransitionsOff, 500)
Expand Down Expand Up @@ -145,6 +169,7 @@ onUnmounted(() => {

<div class="vote_main">
<IntersectionObserver id="top-observer" v-model="topObserverVisible" />

<Collapsible
v-if="pollStore.configuration.description"
class="sticky-left"
Expand All @@ -154,9 +179,29 @@ onUnmounted(() => {

<VoteInfoCards class="sticky-left" />

<IntersectionObserver id="table-observer" v-model="tableSticky" />

<VoteTable
v-show="optionsStore.options.length"
v-model:down-page="voteHeaderDownPage" />
:down-page="tableSticky" />

<IntersectionObserver
v-if="showBottomObserver"
id="bottom-observer"
class="sticky-left"
:loading="chunksLoading"
@visible="loadChunks">
<div class="clickable_load_more" @click="loadChunks">
{{
n(
'polls',
'%n participant is hidden. Click here to load more',
'%n participants are hidden. Click here to load more',
votesStore.countHiddenParticipants,
)
}}
</div>
</IntersectionObserver>

<NcEmptyContent
v-if="!optionsStore.options.length"
Expand Down Expand Up @@ -187,6 +232,13 @@ onUnmounted(() => {
</template>

<style lang="scss">
#bottom-observer {
display: flex;
justify-content: center;
position: sticky;
left: 70px;
}

.table-view .vote_main {
flex: 1;
overflow: auto;
Expand Down