Browse Source

feat(polls): allow to manage polls from ConversationSettings

Signed-off-by: Maksim Sukharev <antreesy.web@gmail.com>
pull/14038/head
Maksim Sukharev 10 months ago
parent
commit
c99c1053fa
  1. 9
      src/components/ConversationSettings/ConversationSettingsDialog.vue
  2. 23
      src/components/ConversationSettings/LobbySettings.vue
  3. 4
      src/components/PollViewer/PollDraftHandler.vue
  4. 14
      src/components/PollViewer/PollEditor.vue
  5. 21
      src/components/PollViewer/PollManager.vue
  6. 2
      src/components/RightSidebar/SharedItems/SharedItemsTab.vue
  7. 4
      src/services/EventBus.ts

9
src/components/ConversationSettings/ConversationSettingsDialog.vue

@ -8,7 +8,8 @@
:aria-label="t('spreed', 'Conversation settings')"
:name="t('spreed', 'Conversation settings')"
:open.sync="showSettings"
show-navigation>
show-navigation
@update:open="handleUpdateOpen">
<NcAppSettingsSection id="basic-info"
:name="t('spreed', 'Basic Info')">
<BasicInfo :conversation="conversation"
@ -292,6 +293,12 @@ export default {
this.$store.dispatch('updateConversationSettingsToken', '')
},
handleUpdateOpen(value) {
if (!value) {
this.$store.dispatch('updateConversationSettingsToken', '')
}
},
setShowMediaSettings(newValue) {
this.settingsStore.setShowMediaSettings(this.token, newValue)
},

23
src/components/ConversationSettings/LobbySettings.vue

@ -63,12 +63,25 @@
:token="token"
container=".import-email-participants"
@close="isImportEmailsDialogOpen = false" />
<template v-if="canCreatePollDrafts">
<h4 class="app-settings-section__subtitle">
{{ t('spreed', 'Poll drafts') }}
</h4>
<NcButton @click="openPollDraftHandler">
<template #icon>
<IconPoll :size="20" />
</template>
{{ t('spreed', 'Browse poll drafts') }}
</NcButton>
</template>
</div>
</div>
</template>
<script>
import IconFileUpload from 'vue-material-design-icons/FileUpload.vue'
import IconPoll from 'vue-material-design-icons/Poll.vue'
import { showError, showSuccess } from '@nextcloud/dialogs'
import { t } from '@nextcloud/l10n'
@ -82,6 +95,7 @@ import ImportEmailsDialog from '../ImportEmailsDialog.vue'
import { WEBINAR } from '../../constants.js'
import { hasTalkFeature } from '../../services/CapabilitiesManager.ts'
import { EventBus } from '../../services/EventBus.ts'
import { futureRelativeTime } from '../../utils/formattedTime.ts'
const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000
@ -91,6 +105,7 @@ export default {
components: {
IconFileUpload,
IconPoll,
ImportEmailsDialog,
NcButton,
NcCheckboxRadioSwitch,
@ -186,6 +201,10 @@ export default {
getRelativeTime() {
return futureRelativeTime(this.lobbyTimer)
},
canCreatePollDrafts() {
return hasTalkFeature(this.token, 'talk-polls-drafts')
},
},
methods: {
@ -231,6 +250,10 @@ export default {
this.isLobbyTimerLoading = false
},
openPollDraftHandler() {
EventBus.emit('poll-drafts-open', { selector: '#settings-section_meeting' })
}
},
}
</script>

4
src/components/PollViewer/PollDraftHandler.vue

@ -6,6 +6,7 @@
<template>
<NcDialog class="drafts"
:name="t('spreed', 'Poll drafts')"
:container="container"
size="normal"
close-on-click-outside
v-on="$listeners"
@ -56,6 +57,7 @@ import { usePollsStore } from '../../stores/polls.ts'
const props = defineProps<{
token: string,
editorOpened?: boolean,
container?: string,
}>()
const emit = defineEmits<{
(event: 'close'): void,
@ -74,7 +76,7 @@ const pollDraftsLoaded = computed(() => pollsStore.draftsLoaded(props.token))
* @param id poll draft ID
*/
function openPollEditor(id: number | null) {
EventBus.emit('poll-editor-open', { id, fromDrafts: !props.editorOpened })
EventBus.emit('poll-editor-open', { id, fromDrafts: !props.editorOpened, selector: props.container })
}
</script>

14
src/components/PollViewer/PollEditor.vue

@ -6,6 +6,7 @@
<template>
<NcDialog :name="t('spreed', 'Create new poll')"
:close-on-click-outside="!isFilled"
:container="container"
v-on="$listeners"
@update:open="emit('close')">
<NcButton v-if="supportPollDrafts && isOpenedFromDraft"
@ -31,7 +32,7 @@
class="hidden-visually"
@change="importPoll">
<NcActions v-if="supportPollDrafts" force-menu>
<NcActionButton v-if="props.canCreatePollDrafts" close-after-click @click="openPollDraftHandler">
<NcActionButton v-if="props.canCreatePollDrafts && !isOpenedFromDraft" close-after-click @click="openPollDraftHandler">
<template #icon>
<IconFileEdit :size="20" />
</template>
@ -102,7 +103,7 @@
</NcActionLink>
</NcActions>
<NcButton type="primary" :disabled="!isFilled" @click="createPoll">
{{ t('spreed', 'Create poll') }}
{{ createPollLabel }}
</NcButton>
</template>
</NcDialog>
@ -141,6 +142,7 @@ import { validatePollForm } from '../../utils/validatePollForm.ts'
const props = defineProps<{
token: string,
canCreatePollDrafts: boolean,
container?: string,
}>()
const emit = defineEmits<{
(event: 'close'): void,
@ -166,6 +168,12 @@ const pollForm = reactive<createPollParams>({
})
const isFilled = computed(() => Boolean(pollForm.question) && pollForm.options.filter(option => Boolean(option)).length >= 2)
const createPollLabel = computed(() => {
return store.getters.getToken() !== props.token
? t('spreed', 'Create poll in {name}', { name: store.getters.conversation(props.token).displayName },
undefined, { escape: false, sanitize: false })
: t('spreed', 'Create poll')
})
const isAnonymous = computed({
get() {
@ -289,7 +297,7 @@ async function createPollDraft() {
* Open a PollDraftHandler dialog
*/
function openPollDraftHandler() {
EventBus.emit('poll-drafts-open')
EventBus.emit('poll-drafts-open', { selector: props.container })
}
/**

21
src/components/PollViewer/PollManager.vue

@ -21,6 +21,7 @@ const pollEditorRef = ref(null)
const showPollEditor = ref(false)
const showPollDraftHandler = ref(false)
const container = ref<string|undefined>(undefined)
const token = computed(() => store.getters.getConversationSettingsToken() || store.getters.getToken())
const canCreatePollDrafts = computed(() => {
@ -41,11 +42,25 @@ onBeforeUnmount(() => {
EventBus.off('poll-drafts-open', openPollDraftHandler)
})
const openPollDraftHandler = () => {
/**
* Opens PollDraftHandler dialog
* @param payload event payload
* @param [payload.selector] selector to mount dialog to (body by default)
*/
function openPollDraftHandler({ selector }: Events['poll-drafts-open']) {
container.value = selector
showPollDraftHandler.value = true
}
const openPollEditor = ({ id, fromDrafts }: Events['poll-editor-open']) => {
/**
* Opens PollEditor dialog
* @param payload event payload
* @param payload.id poll draft ID to fill form with (null for empty form)
* @param payload.fromDrafts whether editor was opened from PollDraftHandler dialog
* @param [payload.selector] selector to mount dialog to (body by default)
*/
function openPollEditor({ id, fromDrafts, selector }: Events['poll-editor-open']) {
container.value = selector
showPollEditor.value = true
nextTick(() => {
pollEditorRef.value?.fillPollEditorFromDraft(id, fromDrafts)
@ -62,10 +77,12 @@ const openPollEditor = ({ id, fromDrafts }: Events['poll-editor-open']) => {
ref="pollEditorRef"
:token="token"
:can-create-poll-drafts="canCreatePollDrafts"
:container="container"
@close="showPollEditor = false" />
<!-- Poll drafts dialog -->
<PollDraftHandler v-if="canCreatePollDrafts && showPollDraftHandler"
:token="token"
:container="container"
:editor-opened="showPollEditor"
@close="showPollDraftHandler = false" />
</div>

2
src/components/RightSidebar/SharedItems/SharedItemsTab.vue

@ -214,7 +214,7 @@ export default {
},
openPollDraftHandler() {
EventBus.emit('poll-drafts-open')
EventBus.emit('poll-drafts-open', {})
}
},
}

4
src/services/EventBus.ts

@ -23,8 +23,8 @@ export type Events = Record<EventType, unknown> & {
'forbidden-route': { error: string },
'joined-conversation': { token: string },
'message-height-changed': { heightDiff: number },
'poll-drafts-open': void,
'poll-editor-open': { id: number | null, fromDrafts: boolean },
'poll-drafts-open': { selector?: string },
'poll-editor-open': { id: number | null, fromDrafts: boolean, selector?: string },
'refresh-peer-list': void,
'retry-message': number,
'route-change': { from: Route, to: Route },

Loading…
Cancel
Save