summaryrefslogtreecommitdiff
path: root/packages/client/src/components/poll.vue
diff options
context:
space:
mode:
Diffstat (limited to 'packages/client/src/components/poll.vue')
-rw-r--r--packages/client/src/components/poll.vue120
1 files changed, 50 insertions, 70 deletions
diff --git a/packages/client/src/components/poll.vue b/packages/client/src/components/poll.vue
index 35f87325d8..d90af1cfee 100644
--- a/packages/client/src/components/poll.vue
+++ b/packages/client/src/components/poll.vue
@@ -13,97 +13,77 @@
<p v-if="!readOnly">
<span>{{ $t('_poll.totalVotes', { n: total }) }}</span>
<span> · </span>
- <a v-if="!closed && !isVoted" @click="showResult = !showResult">{{ showResult ? $ts._poll.vote : $ts._poll.showResult }}</a>
- <span v-if="isVoted">{{ $ts._poll.voted }}</span>
- <span v-else-if="closed">{{ $ts._poll.closed }}</span>
+ <a v-if="!closed && !isVoted" @click="showResult = !showResult">{{ showResult ? i18n.ts._poll.vote : i18n.ts._poll.showResult }}</a>
+ <span v-if="isVoted">{{ i18n.ts._poll.voted }}</span>
+ <span v-else-if="closed">{{ i18n.ts._poll.closed }}</span>
<span v-if="remaining > 0"> · {{ timer }}</span>
</p>
</div>
</template>
-<script lang="ts">
-import { computed, defineComponent, onUnmounted, ref, toRef } from 'vue';
+<script lang="ts" setup>
+import { computed, onUnmounted, ref, toRef } from 'vue';
+import * as misskey from 'misskey-js';
import { sum } from '@/scripts/array';
import { pleaseLogin } from '@/scripts/please-login';
import * as os from '@/os';
import { i18n } from '@/i18n';
import { useInterval } from '@/scripts/use-interval';
-export default defineComponent({
- props: {
- note: {
- type: Object,
- required: true,
- },
- readOnly: {
- type: Boolean,
- required: false,
- default: false,
- },
- },
+const props = defineProps<{
+ note: misskey.entities.Note;
+ readOnly?: boolean;
+}>();
- setup(props) {
- const remaining = ref(-1);
+const remaining = ref(-1);
- const total = computed(() => sum(props.note.poll.choices.map(x => x.votes)));
- const closed = computed(() => remaining.value === 0);
- const isVoted = computed(() => !props.note.poll.multiple && props.note.poll.choices.some(c => c.isVoted));
- const timer = computed(() => i18n.t(
- remaining.value >= 86400 ? '_poll.remainingDays' :
- remaining.value >= 3600 ? '_poll.remainingHours' :
- remaining.value >= 60 ? '_poll.remainingMinutes' : '_poll.remainingSeconds', {
- s: Math.floor(remaining.value % 60),
- m: Math.floor(remaining.value / 60) % 60,
- h: Math.floor(remaining.value / 3600) % 24,
- d: Math.floor(remaining.value / 86400),
- }));
+const total = computed(() => sum(props.note.poll.choices.map(x => x.votes)));
+const closed = computed(() => remaining.value === 0);
+const isVoted = computed(() => !props.note.poll.multiple && props.note.poll.choices.some(c => c.isVoted));
+const timer = computed(() => i18n.t(
+ remaining.value >= 86400 ? '_poll.remainingDays' :
+ remaining.value >= 3600 ? '_poll.remainingHours' :
+ remaining.value >= 60 ? '_poll.remainingMinutes' : '_poll.remainingSeconds', {
+ s: Math.floor(remaining.value % 60),
+ m: Math.floor(remaining.value / 60) % 60,
+ h: Math.floor(remaining.value / 3600) % 24,
+ d: Math.floor(remaining.value / 86400),
+ }));
- const showResult = ref(props.readOnly || isVoted.value);
+const showResult = ref(props.readOnly || isVoted.value);
- // 期限付きアンケート
- if (props.note.poll.expiresAt) {
- const tick = () => {
- remaining.value = Math.floor(Math.max(new Date(props.note.poll.expiresAt).getTime() - Date.now(), 0) / 1000);
- if (remaining.value === 0) {
- showResult.value = true;
- }
- };
-
- useInterval(tick, 3000, {
- immediate: true,
- afterMounted: false,
- });
+// 期限付きアンケート
+if (props.note.poll.expiresAt) {
+ const tick = () => {
+ remaining.value = Math.floor(Math.max(new Date(props.note.poll.expiresAt).getTime() - Date.now(), 0) / 1000);
+ if (remaining.value === 0) {
+ showResult.value = true;
}
+ };
- const vote = async (id) => {
- pleaseLogin();
+ useInterval(tick, 3000, {
+ immediate: true,
+ afterMounted: false,
+ });
+}
- if (props.readOnly || closed.value || isVoted.value) return;
+const vote = async (id) => {
+ pleaseLogin();
- const { canceled } = await os.confirm({
- type: 'question',
- text: i18n.t('voteConfirm', { choice: props.note.poll.choices[id].text }),
- });
- if (canceled) return;
+ if (props.readOnly || closed.value || isVoted.value) return;
- await os.api('notes/polls/vote', {
- noteId: props.note.id,
- choice: id,
- });
- if (!showResult.value) showResult.value = !props.note.poll.multiple;
- };
+ const { canceled } = await os.confirm({
+ type: 'question',
+ text: i18n.t('voteConfirm', { choice: props.note.poll.choices[id].text }),
+ });
+ if (canceled) return;
- return {
- remaining,
- showResult,
- total,
- isVoted,
- closed,
- timer,
- vote,
- };
- },
-});
+ await os.api('notes/polls/vote', {
+ noteId: props.note.id,
+ choice: id,
+ });
+ if (!showResult.value) showResult.value = !props.note.poll.multiple;
+};
</script>
<style lang="scss" scoped>