mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-03-03 18:40:46 +08:00
Compare commits
1 Commits
codex/refa
...
codex/refa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
39c34a9048 |
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="post-prize-container">
|
||||
<div class="post-prize-container" v-if="lottery">
|
||||
<div class="prize-content">
|
||||
<div class="prize-info">
|
||||
<div class="prize-info-left">
|
||||
@@ -79,30 +79,20 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch, onBeforeUnmount } from 'vue'
|
||||
import { toast } from '~/main'
|
||||
import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { getToken, authState } from '~/utils/auth'
|
||||
import { toast } from '~/main'
|
||||
import { useRuntimeConfig } from '#imports'
|
||||
import { useIsMobile } from '~/utils/screen'
|
||||
|
||||
const props = defineProps({
|
||||
lottery: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
postId: {
|
||||
type: [String, Number],
|
||||
required: true,
|
||||
},
|
||||
lottery: { type: Object, required: true },
|
||||
postId: { type: [String, Number], required: true },
|
||||
})
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
const API_BASE_URL = config.public.apiBaseUrl
|
||||
|
||||
const loggedIn = computed(() => authState.loggedIn)
|
||||
const isMobile = useIsMobile()
|
||||
|
||||
const loggedIn = computed(() => authState.loggedIn)
|
||||
const lotteryParticipants = computed(() => props.lottery?.participants || [])
|
||||
const lotteryWinners = computed(() => props.lottery?.winners || [])
|
||||
const lotteryEnded = computed(() => {
|
||||
@@ -115,8 +105,7 @@ const hasJoined = computed(() => {
|
||||
})
|
||||
|
||||
const countdown = ref('00:00:00')
|
||||
let countdownTimer = null
|
||||
|
||||
let timer = null
|
||||
const updateCountdown = () => {
|
||||
if (!props.lottery || !props.lottery.endTime) {
|
||||
countdown.value = '00:00:00'
|
||||
@@ -125,9 +114,9 @@ const updateCountdown = () => {
|
||||
const diff = new Date(props.lottery.endTime).getTime() - Date.now()
|
||||
if (diff <= 0) {
|
||||
countdown.value = '00:00:00'
|
||||
if (countdownTimer) {
|
||||
clearInterval(countdownTimer)
|
||||
countdownTimer = null
|
||||
if (timer) {
|
||||
clearInterval(timer)
|
||||
timer = null
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -136,30 +125,28 @@ const updateCountdown = () => {
|
||||
const s = String(Math.floor((diff % 60000) / 1000)).padStart(2, '0')
|
||||
countdown.value = `${h}:${m}:${s}`
|
||||
}
|
||||
|
||||
const startCountdown = () => {
|
||||
if (!import.meta.client) return
|
||||
if (countdownTimer) clearInterval(countdownTimer)
|
||||
updateCountdown()
|
||||
countdownTimer = setInterval(updateCountdown, 1000)
|
||||
if (timer) clearInterval(timer)
|
||||
timer = setInterval(updateCountdown, 1000)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.lottery?.endTime,
|
||||
() => {
|
||||
if (props.lottery && props.lottery.endTime) {
|
||||
startCountdown()
|
||||
}
|
||||
if (props.lottery && props.lottery.endTime) startCountdown()
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
if (props.lottery && props.lottery.endTime) startCountdown()
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
if (countdownTimer) clearInterval(countdownTimer)
|
||||
if (timer) clearInterval(timer)
|
||||
})
|
||||
|
||||
const gotoUser = (id) => navigateTo(`/users/${id}`, { replace: true })
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
const API_BASE_URL = config.public.apiBaseUrl
|
||||
const joinLottery = async () => {
|
||||
const token = getToken()
|
||||
if (!token) {
|
||||
@@ -313,4 +300,11 @@ const joinLottery = async () => {
|
||||
font-size: 13px;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.join-prize-button,
|
||||
.join-prize-button-disabled {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="post-poll-container">
|
||||
<div class="post-poll-container" v-if="poll">
|
||||
<div class="poll-top-container">
|
||||
<div class="poll-options-container">
|
||||
<div v-if="showPollResult || pollEnded || hasVoted">
|
||||
@@ -70,26 +70,18 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch, onBeforeUnmount } from 'vue'
|
||||
import { toast } from '~/main'
|
||||
import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { getToken, authState } from '~/utils/auth'
|
||||
import { toast } from '~/main'
|
||||
import { useRuntimeConfig } from '#imports'
|
||||
|
||||
const props = defineProps({
|
||||
poll: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
postId: {
|
||||
type: [String, Number],
|
||||
required: true,
|
||||
},
|
||||
poll: { type: Object, required: true },
|
||||
postId: { type: [String, Number], required: true },
|
||||
})
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
const API_BASE_URL = config.public.apiBaseUrl
|
||||
|
||||
const loggedIn = computed(() => authState.loggedIn)
|
||||
const showPollResult = ref(false)
|
||||
|
||||
const pollParticipants = computed(() => props.poll?.participants || [])
|
||||
@@ -109,17 +101,15 @@ const pollEnded = computed(() => {
|
||||
return new Date(props.poll.endTime).getTime() <= Date.now()
|
||||
})
|
||||
const hasVoted = computed(() => {
|
||||
if (!authState.loggedIn) return false
|
||||
if (!loggedIn.value) return false
|
||||
return pollParticipants.value.some((p) => p.id === Number(authState.userId))
|
||||
})
|
||||
|
||||
watch([hasVoted, pollEnded], ([voted, ended]) => {
|
||||
if (voted || ended) showPollResult.value = true
|
||||
})
|
||||
|
||||
const countdown = ref('00:00:00')
|
||||
let countdownTimer = null
|
||||
|
||||
let timer = null
|
||||
const updateCountdown = () => {
|
||||
if (!props.poll || !props.poll.endTime) {
|
||||
countdown.value = '00:00:00'
|
||||
@@ -128,9 +118,9 @@ const updateCountdown = () => {
|
||||
const diff = new Date(props.poll.endTime).getTime() - Date.now()
|
||||
if (diff <= 0) {
|
||||
countdown.value = '00:00:00'
|
||||
if (countdownTimer) {
|
||||
clearInterval(countdownTimer)
|
||||
countdownTimer = null
|
||||
if (timer) {
|
||||
clearInterval(timer)
|
||||
timer = null
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -139,30 +129,28 @@ const updateCountdown = () => {
|
||||
const s = String(Math.floor((diff % 60000) / 1000)).padStart(2, '0')
|
||||
countdown.value = `${h}:${m}:${s}`
|
||||
}
|
||||
|
||||
const startCountdown = () => {
|
||||
if (!import.meta.client) return
|
||||
if (countdownTimer) clearInterval(countdownTimer)
|
||||
updateCountdown()
|
||||
countdownTimer = setInterval(updateCountdown, 1000)
|
||||
if (timer) clearInterval(timer)
|
||||
timer = setInterval(updateCountdown, 1000)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.poll?.endTime,
|
||||
() => {
|
||||
if (props.poll && props.poll.endTime) {
|
||||
startCountdown()
|
||||
}
|
||||
if (props.poll && props.poll.endTime) startCountdown()
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
if (props.poll && props.poll.endTime) startCountdown()
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
if (countdownTimer) clearInterval(countdownTimer)
|
||||
if (timer) clearInterval(timer)
|
||||
})
|
||||
|
||||
const gotoUser = (id) => navigateTo(`/users/${id}`, { replace: true })
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
const API_BASE_URL = config.public.apiBaseUrl
|
||||
const voteOption = async (idx) => {
|
||||
const token = getToken()
|
||||
if (!token) {
|
||||
@@ -185,6 +173,16 @@ const voteOption = async (idx) => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.post-poll-container {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
background-color: var(--lottery-background-color);
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.poll-option-button {
|
||||
color: var(--text-color);
|
||||
padding: 5px 10px;
|
||||
@@ -272,7 +270,6 @@ const voteOption = async (idx) => {
|
||||
.poll-left-time-title {
|
||||
font-size: 13px;
|
||||
opacity: 0.7;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.poll-left-time-value {
|
||||
@@ -281,21 +278,6 @@ const voteOption = async (idx) => {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.post-poll-container {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
background-color: var(--lottery-background-color);
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.poll-question {
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.poll-option-progress {
|
||||
position: relative;
|
||||
background-color: rgb(187, 187, 187);
|
||||
@@ -321,13 +303,6 @@ const voteOption = async (idx) => {
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.poll-vote-button {
|
||||
margin-top: 5px;
|
||||
color: var(--primary-color);
|
||||
cursor: pointer;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.poll-participants {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
@@ -1032,7 +1032,120 @@ onMounted(async () => {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.action-menu-icon {
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.article-info-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-top: 10px;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.info-content-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
padding: 0px;
|
||||
border-bottom: 1px solid var(--normal-border-color);
|
||||
}
|
||||
|
||||
.user-avatar-container {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.user-avatar-item {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.user-avatar-item-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.info-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.info-content-header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.user-medal {
|
||||
font-size: 12px;
|
||||
margin-left: 4px;
|
||||
opacity: 0.6;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.post-time {
|
||||
font-size: 14px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.info-content-text {
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.article-footer-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.reactions-viewer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 20px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.reactions-viewer-item-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 2px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.reactions-viewer-item {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.make-reaction-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.copy-link:hover {
|
||||
background-color: #e2e2e2;
|
||||
}
|
||||
|
||||
.comment-editor-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.post-page-main-container {
|
||||
@@ -1084,8 +1197,5 @@ onMounted(async () => {
|
||||
.loading-container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user