client: tweak ui
This commit is contained in:
		
							parent
							
								
									705b46b3a0
								
							
						
					
					
						commit
						8de8de7669
					
				
					 2 changed files with 64 additions and 75 deletions
				
			
		|  | @ -24,7 +24,7 @@ export default defineComponent({ | ||||||
| 		marginMax: { | 		marginMax: { | ||||||
| 			type: Number, | 			type: Number, | ||||||
| 			required: false, | 			required: false, | ||||||
| 			default: 32, | 			default: 24, | ||||||
| 		}, | 		}, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| <template> | <template> | ||||||
| <div class="tivcixzd" :class="{ done: closed || isVoted }"> | <div class="tivcixzd" :class="{ done: closed || isVoted }"> | ||||||
| 	<ul> | 	<ul> | ||||||
| 		<li v-for="(choice, i) in poll.choices" :key="i" :class="{ voted: choice.voted }" @click="vote(i)"> | 		<li v-for="(choice, i) in note.poll.choices" :key="i" :class="{ voted: choice.voted }" @click="vote(i)"> | ||||||
| 			<div class="backdrop" :style="{ 'width': `${showResult ? (choice.votes / total * 100) : 0}%` }"></div> | 			<div class="backdrop" :style="{ 'width': `${showResult ? (choice.votes / total * 100) : 0}%` }"></div> | ||||||
| 			<span> | 			<span> | ||||||
| 				<template v-if="choice.isVoted"><i class="fas fa-check"></i></template> | 				<template v-if="choice.isVoted"><i class="fas fa-check"></i></template> | ||||||
|  | @ -13,7 +13,7 @@ | ||||||
| 	<p v-if="!readOnly"> | 	<p v-if="!readOnly"> | ||||||
| 		<span>{{ $t('_poll.totalVotes', { n: total }) }}</span> | 		<span>{{ $t('_poll.totalVotes', { n: total }) }}</span> | ||||||
| 		<span> · </span> | 		<span> · </span> | ||||||
| 		<a v-if="!closed && !isVoted" @click="toggleShowResult">{{ showResult ? $ts._poll.vote : $ts._poll.showResult }}</a> | 		<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-if="isVoted">{{ $ts._poll.voted }}</span> | ||||||
| 		<span v-else-if="closed">{{ $ts._poll.closed }}</span> | 		<span v-else-if="closed">{{ $ts._poll.closed }}</span> | ||||||
| 		<span v-if="remaining > 0"> · {{ timer }}</span> | 		<span v-if="remaining > 0"> · {{ timer }}</span> | ||||||
|  | @ -22,9 +22,10 @@ | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent } from 'vue'; | import { computed, defineComponent, onUnmounted, ref, toRef } from 'vue'; | ||||||
| import { sum } from '@/scripts/array'; | import { sum } from '@/scripts/array'; | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
|  | import { i18n } from '@/i18n'; | ||||||
| 
 | 
 | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
| 	props: { | 	props: { | ||||||
|  | @ -38,71 +39,67 @@ export default defineComponent({ | ||||||
| 			default: false, | 			default: false, | ||||||
| 		} | 		} | ||||||
| 	}, | 	}, | ||||||
| 	data() { |  | ||||||
| 		return { |  | ||||||
| 			remaining: -1, |  | ||||||
| 			showResult: false, |  | ||||||
| 		}; |  | ||||||
| 	}, |  | ||||||
| 	computed: { |  | ||||||
| 		poll(): any { |  | ||||||
| 			return this.note.poll; |  | ||||||
| 		}, |  | ||||||
| 		total(): number { |  | ||||||
| 			return sum(this.poll.choices.map(x => x.votes)); |  | ||||||
| 		}, |  | ||||||
| 		closed(): boolean { |  | ||||||
| 			return !this.remaining; |  | ||||||
| 		}, |  | ||||||
| 		timer(): string { |  | ||||||
| 			return this.$t( |  | ||||||
| 				this.remaining >= 86400 ? '_poll.remainingDays' : |  | ||||||
| 				this.remaining >= 3600 ? '_poll.remainingHours' : |  | ||||||
| 				this.remaining >= 60 ? '_poll.remainingMinutes' : '_poll.remainingSeconds', { |  | ||||||
| 					s: Math.floor(this.remaining % 60), |  | ||||||
| 					m: Math.floor(this.remaining / 60) % 60, |  | ||||||
| 					h: Math.floor(this.remaining / 3600) % 24, |  | ||||||
| 					d: Math.floor(this.remaining / 86400) |  | ||||||
| 				}); |  | ||||||
| 		}, |  | ||||||
| 		isVoted(): boolean { |  | ||||||
| 			return !this.poll.multiple && this.poll.choices.some(c => c.isVoted); |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 	created() { |  | ||||||
| 		this.showResult = this.readOnly || this.isVoted; |  | ||||||
| 
 | 
 | ||||||
| 		if (this.note.poll.expiresAt) { | 	setup(props) { | ||||||
| 			const update = () => { | 		const remaining = ref(-1); | ||||||
| 				if (this.remaining = Math.floor(Math.max(new Date(this.note.poll.expiresAt).getTime() - Date.now(), 0) / 1000)) | 
 | ||||||
| 					requestAnimationFrame(update); | 		const total = computed(() => sum(props.note.poll.choices.map(x => x.votes))); | ||||||
| 				else | 		const closed = computed(() => remaining.value === 0); | ||||||
| 					this.showResult = true; | 		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); | ||||||
|  | 
 | ||||||
|  | 		// 期限付きアンケート | ||||||
|  | 		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; | ||||||
|  | 				} | ||||||
| 			}; | 			}; | ||||||
| 
 | 
 | ||||||
| 			update(); | 			tick(); | ||||||
|  | 			const intevalId = window.setInterval(tick, 3000); | ||||||
|  | 			onUnmounted(() => { | ||||||
|  | 				window.clearInterval(intevalId); | ||||||
|  | 			}); | ||||||
| 		} | 		} | ||||||
| 	}, | 
 | ||||||
| 	methods: { | 		const vote = async (id) => { | ||||||
| 		toggleShowResult() { | 			if (props.readOnly || closed.value || isVoted.value) return; | ||||||
| 			this.showResult = !this.showResult; |  | ||||||
| 		}, |  | ||||||
| 		async vote(id) { |  | ||||||
| 			if (this.readOnly || this.closed || !this.poll.multiple && this.poll.choices.some(c => c.isVoted)) return; |  | ||||||
| 
 | 
 | ||||||
| 			const { canceled } = await os.confirm({ | 			const { canceled } = await os.confirm({ | ||||||
| 				type: 'question', | 				type: 'question', | ||||||
| 				text: this.$t('voteConfirm', { choice: this.poll.choices[id].text }), | 				text: i18n.t('voteConfirm', { choice: props.note.poll.choices[id].text }), | ||||||
| 			}); | 			}); | ||||||
| 			if (canceled) return; | 			if (canceled) return; | ||||||
| 
 | 
 | ||||||
| 			await os.api('notes/polls/vote', { | 			await os.api('notes/polls/vote', { | ||||||
| 				noteId: this.note.id, | 				noteId: props.note.id, | ||||||
| 				choice: id | 				choice: id, | ||||||
| 			}); | 			}); | ||||||
| 			if (!this.showResult) this.showResult = !this.poll.multiple; | 			if (!showResult.value) showResult.value = !props.note.poll.multiple; | ||||||
| 		} | 		}; | ||||||
| 	} | 
 | ||||||
|  | 		return { | ||||||
|  | 			remaining, | ||||||
|  | 			showResult, | ||||||
|  | 			total, | ||||||
|  | 			isVoted, | ||||||
|  | 			closed, | ||||||
|  | 			timer, | ||||||
|  | 			vote, | ||||||
|  | 		}; | ||||||
|  | 	}, | ||||||
| }); | }); | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
|  | @ -118,38 +115,38 @@ export default defineComponent({ | ||||||
| 			display: block; | 			display: block; | ||||||
| 			position: relative; | 			position: relative; | ||||||
| 			margin: 4px 0; | 			margin: 4px 0; | ||||||
| 			padding: 4px 8px; | 			padding: 4px; | ||||||
| 			border: solid 0.5px var(--divider); | 			//border: solid 0.5px var(--divider); | ||||||
|  | 			background: var(--accentedBg); | ||||||
| 			border-radius: 4px; | 			border-radius: 4px; | ||||||
| 			overflow: hidden; | 			overflow: hidden; | ||||||
| 			cursor: pointer; | 			cursor: pointer; | ||||||
| 
 | 
 | ||||||
| 			&:hover { |  | ||||||
| 				background: rgba(#000, 0.05); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			&:active { |  | ||||||
| 				background: rgba(#000, 0.1); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			> .backdrop { | 			> .backdrop { | ||||||
| 				position: absolute; | 				position: absolute; | ||||||
| 				top: 0; | 				top: 0; | ||||||
| 				left: 0; | 				left: 0; | ||||||
| 				height: 100%; | 				height: 100%; | ||||||
| 				background: var(--accent); | 				background: var(--accent); | ||||||
|  | 				background: linear-gradient(90deg,var(--buttonGradateA),var(--buttonGradateB)); | ||||||
| 				transition: width 1s ease; | 				transition: width 1s ease; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			> span { | 			> span { | ||||||
| 				position: relative; | 				position: relative; | ||||||
|  | 				display: inline-block; | ||||||
|  | 				padding: 3px 5px; | ||||||
|  | 				background: var(--panel); | ||||||
|  | 				border-radius: 3px; | ||||||
| 
 | 
 | ||||||
| 				> i { | 				> i { | ||||||
| 					margin-right: 4px; | 					margin-right: 4px; | ||||||
|  | 					color: var(--accent); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				> .votes { | 				> .votes { | ||||||
| 					margin-left: 4px; | 					margin-left: 4px; | ||||||
|  | 					opacity: 0.7; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | @ -166,14 +163,6 @@ export default defineComponent({ | ||||||
| 	&.done { | 	&.done { | ||||||
| 		> ul > li { | 		> ul > li { | ||||||
| 			cursor: default; | 			cursor: default; | ||||||
| 
 |  | ||||||
| 			&:hover { |  | ||||||
| 				background: transparent; |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			&:active { |  | ||||||
| 				background: transparent; |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue