websocket消息支持 (#188)
* Release (#162) * feat: ✨ websocket server demo * feat: ✨ ws server demo dev * feat: ✨ ws server and mobile page * feat: ✨ 手机端发送消息 * feat: ✨ 手机网页发送消息 * 添加了抽奖中和抽奖完成时的音效 * feat: ✨ 自定义设置弹幕服务器地址 * feat: ✨ ws not done * fix: 🐛 fix pr-185 #185 为播放音效添加控制 * feat: ✨ server worker demo not done * feat: ✨ websocket server * feat: ✨ 全局接收websocket消息并存储到indexdb中 --------- Co-authored-by: Silence@2024 <707261624@qq.com>
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
<script setup lang='ts'>
|
||||
import { useFullscreen } from '@vueuse/core'
|
||||
import { Maximize, Minimize } from 'lucide-vue-next'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { useQRCode } from '@vueuse/integrations/useQRCode'
|
||||
import { Maximize, Minimize, TabletSmartphone } from 'lucide-vue-next'
|
||||
import { onMounted, ref, shallowRef, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import CustomDialog from '@/components/Dialog/index.vue'
|
||||
import { getOriginUrl, getUniqueSignature } from '@/utils/auth'
|
||||
import { usePlayMusic } from './usePlayMusic'
|
||||
|
||||
const { playMusic, currentMusic, nextPlay } = usePlayMusic()
|
||||
@@ -12,8 +15,12 @@ const { t } = useI18n()
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
const customDialogRef = ref()
|
||||
const settingRef = ref()
|
||||
const fullScreenRef = ref()
|
||||
const mobileUrl = shallowRef<string>('')
|
||||
const qrCodeImg = useQRCode(mobileUrl)
|
||||
const visible = ref(true)
|
||||
|
||||
function enterConfig() {
|
||||
router.push('/log-lottery/config')
|
||||
@@ -21,7 +28,26 @@ function enterConfig() {
|
||||
function enterHome() {
|
||||
router.push('/log-lottery')
|
||||
}
|
||||
async function openMobileQrCode() {
|
||||
const originUrl = getOriginUrl()
|
||||
const userSignature = await getUniqueSignature()
|
||||
mobileUrl.value = `${originUrl}/log-lottery/mobile?userSignature=${userSignature}`
|
||||
customDialogRef.value.showDialog()
|
||||
}
|
||||
function handleSubmit() {
|
||||
|
||||
}
|
||||
|
||||
watch(() => route, (val) => {
|
||||
const { meta } = val
|
||||
if (meta && meta.isMobile) {
|
||||
visible.value = false
|
||||
}
|
||||
}, { immediate: true })
|
||||
onMounted(() => {
|
||||
if (!settingRef.value) {
|
||||
return
|
||||
}
|
||||
settingRef.value.addEventListener('mouseenter', () => {
|
||||
fullScreenRef.value.style.display = 'block'
|
||||
})
|
||||
@@ -32,7 +58,20 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="settingRef" class="flex flex-col gap-3">
|
||||
<div v-if="visible" ref="settingRef" class="flex flex-col gap-3">
|
||||
<CustomDialog
|
||||
ref="customDialogRef"
|
||||
title=""
|
||||
:submit-func="handleSubmit"
|
||||
footer="center"
|
||||
dialog-class="h-120 p-6"
|
||||
>
|
||||
<template #content>
|
||||
<div class="flex w-full justify-center h-90">
|
||||
<img :src="qrCodeImg" alt="qr code">
|
||||
</div>
|
||||
</template>
|
||||
</CustomDialog>
|
||||
<div ref="fullScreenRef" class="tooltip tooltip-left hidden" @click="toggleScreen">
|
||||
<div
|
||||
v-if="isFullscreen"
|
||||
@@ -71,6 +110,11 @@ onMounted(() => {
|
||||
<svg-icon :name="currentMusic.paused ? 'play' : 'pause'" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="tooltip tooltip-left" data-tip="访问手机端">
|
||||
<div class="flex items-center justify-center w-10 h-10 p-0 m-0 cursor-pointer setting-container bg-slate-500/50 rounded-l-xl hover:bg-slate-500/80 hover:text-blue-400/90" @click="openMobileQrCode">
|
||||
<TabletSmartphone />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import type { Ref } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onMounted, provide, ref } from 'vue'
|
||||
import { onMounted, provide, ref, toRaw, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { loadingKey, loadingState } from '@/components/Loading'
|
||||
import { useWebsocket } from '@/hooks/useWebsocket'
|
||||
import useStore from '@/store'
|
||||
import { themeChange } from '@/utils'
|
||||
import { IndexDb } from '@/utils/dexie'
|
||||
|
||||
export function useMounted(tipDialog: Ref<any>) {
|
||||
provide(loadingKey, loadingState)
|
||||
@@ -15,6 +18,9 @@ export function useMounted(tipDialog: Ref<any>) {
|
||||
const { getPrizeConfig: prizeList, getTemporaryPrize: temporaryPrize } = storeToRefs(prizeConfig)
|
||||
const tipDesc = ref('')
|
||||
const { t } = useI18n()
|
||||
const route = useRoute()
|
||||
const { data } = useWebsocket()
|
||||
const msgListDb = new IndexDb('msgList', ['msgList'], 1, ['createTime'])
|
||||
// 设置当前奖列表
|
||||
function setCurrentPrize() {
|
||||
if (prizeList.value.length <= 0) {
|
||||
@@ -52,10 +58,26 @@ export function useMounted(tipDialog: Ref<any>) {
|
||||
|
||||
return isChrome || isEdge
|
||||
}
|
||||
const isShowMobileWarn = () => {
|
||||
const isMobilePage = judgeMobile()
|
||||
const { meta } = route
|
||||
let allowMobile = false
|
||||
if (meta && meta.isMobile) {
|
||||
allowMobile = true
|
||||
}
|
||||
return !allowMobile && isMobilePage
|
||||
}
|
||||
|
||||
watch(() => data.value, (newValue) => {
|
||||
if (!newValue) {
|
||||
return
|
||||
}
|
||||
msgListDb.setData('msgList', toRaw(newValue))
|
||||
}, { immediate: true, deep: true })
|
||||
onMounted(() => {
|
||||
themeChange(localTheme.value.name)
|
||||
setCurrentPrize()
|
||||
if (judgeMobile()) {
|
||||
if (isShowMobileWarn()) {
|
||||
tipDialog.value.showDialog()
|
||||
tipDesc.value = t('dialog.dialogPCWeb')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user