223 lines
6.8 KiB
Vue
223 lines
6.8 KiB
Vue
<template>
|
|
<v-dialog
|
|
v-model="showDialog"
|
|
v-show="room"
|
|
scrollable
|
|
class="ma-0 pa-0"
|
|
:width="$vuetify.breakpoint.smAndUp ? '940px' : '95%'"
|
|
>
|
|
<v-card>
|
|
<v-card-title>
|
|
<v-container fluid>
|
|
<div class="room-name no-upper">{{ $t("poll_create.title") }}</div>
|
|
<v-btn id="btn-close" text class="header-button-right" @click.stop="showDialog = false">
|
|
<v-icon>close</v-icon>
|
|
</v-btn>
|
|
</v-container>
|
|
</v-card-title>
|
|
<v-divider></v-divider>
|
|
<v-card-text class="poll-create">
|
|
<div class="text-center">
|
|
<v-form v-model="isValid" ref="pollcreateform">
|
|
<v-container fluid class="poll-create-dialog-content">
|
|
<!-- <v-row cols="12" no-gutters class="ma-0 pa-0">
|
|
<v-col cols="12">
|
|
<v-switch
|
|
v-model="pollIsDisclosed"
|
|
inset
|
|
:label="pollIsDisclosed ? $t('poll_create.poll_disclosed') : $t('poll_create.poll_undisclosed')"
|
|
></v-switch>
|
|
</v-col>
|
|
</v-row> -->
|
|
<v-row cols="12" no-gutters class="ma-0 pa-0">
|
|
<v-col cols="12" class="ma-0 pa-0">
|
|
<InputControl
|
|
v-model="pollQuestion"
|
|
:label="$t('poll_create.question_label')"
|
|
:disabled="isCreating"
|
|
:error="$t('poll_create.please_complete')"
|
|
/>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-row v-for="(answer, index) in pollAnswers" cols="12" :key="answer.id" no-gutters class="ma-0 pa-0">
|
|
<v-col cols="12" class="ma-0 pa-0">
|
|
<InputControl
|
|
v-model="answer.text"
|
|
:label="
|
|
index == 0 ? $t('poll_create.answer_label_1') : $t('poll_create.answer_label_n', { index: index + 1 })
|
|
"
|
|
:disabled="isCreating"
|
|
:error="$t('poll_create.please_complete')"
|
|
:class="{ deletable: pollAnswers.length > 1 }"
|
|
ref="answerInput"
|
|
>
|
|
<v-btn v-if="pollAnswers.length > 1" icon @click="removeAnswer(index)"><v-icon>delete</v-icon></v-btn>
|
|
</InputControl>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-row cols="12" no-gutters class="ma-0 pa-0">
|
|
<v-col class="ma-0 pa-0">
|
|
<div :class="{'add-answer-button':true, 'clickable': true, 'hidden': addingAnswer}" @click.stop="addAnswer">
|
|
<img src="@/assets/icons/ic_add.svg" />
|
|
</div>
|
|
</v-col>
|
|
</v-row>
|
|
<v-row justify="center">
|
|
<v-col cols="auto">
|
|
<v-btn
|
|
id="btn-create-poll"
|
|
depressed
|
|
block
|
|
class="filled-button publish-button"
|
|
@click.stop="onCreatePoll()"
|
|
:disabled="isCreating || !publishButtonEnabled"
|
|
>{{ $t("poll_create.create") }}</v-btn
|
|
>
|
|
</v-col>
|
|
</v-row>
|
|
</v-container>
|
|
</v-form>
|
|
<div class="poll-create-status">
|
|
{{ status }}
|
|
<v-progress-circular v-if="isCreating" indeterminate color="primary" size="14"></v-progress-circular>
|
|
</div>
|
|
</div>
|
|
</v-card-text>
|
|
<v-card-actions>
|
|
<v-container>
|
|
<v-row>
|
|
<v-col cols="auto">
|
|
<div class="tip">
|
|
<b>{{ $t("poll_create.tip_title") }}</b
|
|
> {{ $t("poll_create.tip_text") }}
|
|
</div>
|
|
</v-col>
|
|
</v-row>
|
|
</v-container>
|
|
</v-card-actions>
|
|
</v-card>
|
|
</v-dialog>
|
|
</template>
|
|
<script>
|
|
import roomInfoMixin from "./roomInfoMixin";
|
|
import util from "../plugins/utils";
|
|
import InputControl from "./InputControl.vue";
|
|
|
|
export default {
|
|
name: "CreatePollDialog",
|
|
mixins: [roomInfoMixin],
|
|
props: {
|
|
show: {
|
|
type: Boolean,
|
|
default: function() {
|
|
return false;
|
|
},
|
|
},
|
|
},
|
|
data() {
|
|
return this.defaultData();
|
|
},
|
|
watch: {
|
|
show: {
|
|
handler(newVal, ignoredOldVal) {
|
|
this.showDialog = newVal;
|
|
},
|
|
},
|
|
showDialog() {
|
|
if (!this.showDialog) {
|
|
this.$emit("close");
|
|
} else {
|
|
// Reset values
|
|
let defaults = this.defaultData();
|
|
this.isValid = defaults.isValid;
|
|
this.isCreating = defaults.isCreating;
|
|
this.status = defaults.status;
|
|
this.pollIsDisclosed = defaults.pollIsDisclosed;
|
|
this.pollQuestion = defaults.pollQuestion;
|
|
this.pollAnswers = defaults.pollAnswers;
|
|
this.autoIncrementId = defaults.autoIncrementId;
|
|
this.addingAnswer = defaults.addingAnswer;
|
|
if (this.$refs.pollcreateform) {
|
|
this.$refs.pollcreateform.resetValidation();
|
|
}
|
|
}
|
|
},
|
|
},
|
|
methods: {
|
|
defaultData() {
|
|
return {
|
|
showDialog: false,
|
|
isValid: true,
|
|
isCreating: false,
|
|
status: String.fromCharCode(160),
|
|
pollIsDisclosed: false,
|
|
pollQuestion: null,
|
|
pollAnswers: [
|
|
{ id: "1", text: null },
|
|
{ id: "2", text: null },
|
|
],
|
|
autoIncrementId: 2,
|
|
addingAnswer: false,
|
|
};
|
|
},
|
|
addAnswer() {
|
|
if (this.pollAnswers.length < 20) {
|
|
// MAX length according to spec
|
|
this.addingAnswer = true;
|
|
const idx = this.pollAnswers.length;
|
|
this.autoIncrementId += 1;
|
|
this.pollAnswers.push({ id: "" + this.autoIncrementId, text: null });
|
|
this.$nextTick(() => {
|
|
this.$refs.answerInput[idx].focus();
|
|
this.$nextTick(() => {
|
|
this.addingAnswer = false;
|
|
});
|
|
});
|
|
}
|
|
},
|
|
removeAnswer(index) {
|
|
this.pollAnswers.splice(index, 1);
|
|
},
|
|
onCreatePoll() {
|
|
if (this.$refs.pollcreateform.validate()) {
|
|
this.isCreating = true;
|
|
this.status = this.$t("poll_create.creating");
|
|
util
|
|
.createPoll(
|
|
this.$matrix.matrixClient,
|
|
this.room.roomId,
|
|
this.pollQuestion,
|
|
this.pollAnswers,
|
|
this.pollIsDisclosed
|
|
)
|
|
.then(() => {
|
|
console.log("Sent message");
|
|
this.isCreating = false;
|
|
this.showDialog = false;
|
|
})
|
|
.catch((err) => {
|
|
console.log("Failed to send:", err);
|
|
this.isCreating = false;
|
|
this.status = this.$t("poll_create.failed");
|
|
});
|
|
setTimeout(() => {}, 3000);
|
|
} else {
|
|
this.isValid = false;
|
|
}
|
|
},
|
|
},
|
|
computed: {
|
|
publishButtonEnabled() {
|
|
return this.pollQuestion && this.pollAnswers.length > 0 && this.pollAnswers.every(a => a.text);
|
|
}
|
|
},
|
|
components: { InputControl },
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
@import "@/assets/css/chat.scss";
|
|
@import "@/assets/css/components/poll.scss";
|
|
</style>
|