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
3 changes: 2 additions & 1 deletion src/components/MessagesList/MessagesList.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
import { createLocalVue, shallowMount } from '@vue/test-utils'
import { cloneDeep } from 'lodash'
import { createPinia, setActivePinia } from 'pinia'
import Vuex from 'vuex'

import MessagesList from './MessagesList.vue'
Expand All @@ -23,7 +24,7 @@ describe('MessagesList.vue', () => {
beforeEach(() => {
localVue = createLocalVue()
localVue.use(Vuex)

setActivePinia(createPinia())
testStoreConfig = cloneDeep(storeConfig)
testStoreConfig.modules.messagesStore.getters.getVisualLastReadMessageId
= jest.fn().mockReturnValue(getVisualLastReadMessageIdMock)
Expand Down
22 changes: 19 additions & 3 deletions src/components/MessagesList/MessagesList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@ import LoadingPlaceholder from '../UIShared/LoadingPlaceholder.vue'
import TransitionWrapper from '../UIShared/TransitionWrapper.vue'

import { useIsInCall } from '../../composables/useIsInCall.js'
import { ATTENDEE, CHAT } from '../../constants.js'
import { ATTENDEE, CHAT, CONVERSATION } from '../../constants.js'
import { EventBus } from '../../services/EventBus.js'
import { useChatExtrasStore } from '../../stores/chatExtras.js'
import { debugTimer } from '../../utils/debugTimer.ts'

export default {
Expand Down Expand Up @@ -119,9 +120,9 @@ export default {
emits: ['update:is-chat-scrolled-to-bottom'],

setup() {
const isInCall = useIsInCall()
return {
isInCall,
isInCall: useIsInCall(),
chatExtrasStore: useChatExtrasStore(),
}
},

Expand Down Expand Up @@ -289,6 +290,12 @@ export default {

// scroll to bottom if needed
this.scrollToBottom({ smooth: true })

if (this.conversation?.type === CONVERSATION.TYPE.NOTE_TO_SELF) {
this.$nextTick(() => {
this.updateTasksCount()
})
}
},
},
},
Expand Down Expand Up @@ -1238,6 +1245,15 @@ export default {
// scroll down by the height difference
this.$refs.scroller.scrollTop += heightDiff
},

updateTasksCount() {
if (!this.$refs.scroller) {
return
}
const tasksDoneCount = this.$refs.scroller.querySelectorAll('.checkbox-content__icon--checked')?.length
const tasksCount = this.$refs.scroller.querySelectorAll('.task-list-item')?.length
this.chatExtrasStore.setTasksCounters({ tasksCount, tasksDoneCount })
},
},
}
</script>
Expand Down
60 changes: 60 additions & 0 deletions src/components/TopBar/TasksCounter.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<!--
- SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->

<script setup lang="ts">
import { computed } from 'vue'

import { t } from '@nextcloud/l10n'

import NcProgressBar from '@nextcloud/vue/dist/Components/NcProgressBar.js'

import { useChatExtrasStore } from '../../stores/chatExtras.js'

const chatExtrasStore = useChatExtrasStore()

const tasksCount = computed(() => chatExtrasStore.tasksCount)
const tasksDoneCount = computed(() => chatExtrasStore.tasksDoneCount)

const tasksRatio = computed(() => {
if (tasksCount.value === 0) {
return 0
}
return (tasksDoneCount.value / tasksCount.value) * 100
})

const tasksSummary = computed(() => {
if (tasksRatio.value === 100) {
return t('spreed', 'All tasks done!')
}
// TRANSLATORS number of tasks done of total number of tasks
return t('spreed', '{done} of {total} tasks', {
done: tasksDoneCount.value,
total: tasksCount.value,
})
})

</script>

<template>
<div v-if="tasksCount" class="tasks-counter">
<NcProgressBar type="circular" :value="tasksRatio" :color="tasksRatio === 100 ? 'var(--color-success)' : null" />
<div class="tasks-counter__count">
{{ tasksSummary }}
</div>
</div>
</template>

<style lang="scss" scoped>
.tasks-counter {
display: flex;
align-items: center;
margin-inline: calc(var(--default-grid-baseline) * 2);

&__count {
font-weight: 500;
}
}

</style>
7 changes: 7 additions & 0 deletions src/components/TopBar/TopBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
</div>
</a>

<TasksCounter v-if="conversation.type === CONVERSATION.TYPE.NOTE_TO_SELF" />

<!-- Upcoming event -->
<a v-if="showUpcomingEvent"
class="upcoming-event"
:href="nextEvent.calendarAppUrl"
Expand Down Expand Up @@ -123,6 +126,7 @@ import richEditor from '@nextcloud/vue/dist/Mixins/richEditor.js'
import CallButton from './CallButton.vue'
import CallTime from './CallTime.vue'
import ReactionMenu from './ReactionMenu.vue'
import TasksCounter from './TasksCounter.vue'
import TopBarMediaControls from './TopBarMediaControls.vue'
import TopBarMenu from './TopBarMenu.vue'
import BreakoutRoomsEditor from '../BreakoutRoomsEditor/BreakoutRoomsEditor.vue'
Expand Down Expand Up @@ -152,6 +156,7 @@ export default {
TopBarMediaControls,
NcButton,
TopBarMenu,
TasksCounter,
ReactionMenu,
// Icons
AccountMultiple,
Expand Down Expand Up @@ -184,6 +189,7 @@ export default {
localMediaModel,
chatExtrasStore: useChatExtrasStore(),
isMobile: useIsMobile(),
CONVERSATION,
}
},

Expand Down Expand Up @@ -299,6 +305,7 @@ export default {

showUpcomingEvent() {
return this.nextEvent && !this.isInCall && !this.isSidebar && !this.isMobile
&& this.conversation.type === CONVERSATION.TYPE.NOTE_TO_SELF
},
},

Expand Down
7 changes: 7 additions & 0 deletions src/stores/chatExtras.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export const useChatExtrasStore = defineStore('chatExtras', {
chatInput: {},
messageIdToEdit: {},
chatEditInput: {},
tasksCount: 0,
tasksDoneCount: 0,
}),

getters: {
Expand Down Expand Up @@ -240,5 +242,10 @@ export const useChatExtrasStore = defineStore('chatExtras', {
this.removeUserAbsence(token)
this.removeChatInput(token)
},

setTasksCounters({ tasksCount, tasksDoneCount }) {
this.tasksCount = tasksCount
this.tasksDoneCount = tasksDoneCount
}
},
})