Skip to content

Commit

Permalink
fix: 增加聊天服务
Browse files Browse the repository at this point in the history
  • Loading branch information
humandetail committed Jan 5, 2024
1 parent 9df2355 commit 61457bf
Show file tree
Hide file tree
Showing 19 changed files with 517 additions and 114 deletions.
4 changes: 4 additions & 0 deletions packages/Chinese-chess/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ export {}

declare module '@vue/runtime-core' {
export interface GlobalComponents {
ABadge: typeof import('ant-design-vue/es')['Badge']
AButton: typeof import('ant-design-vue/es')['Button']
AInput: typeof import('ant-design-vue/es')['Input']
AInputGroup: typeof import('ant-design-vue/es')['InputGroup']
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
ASpin: typeof import('ant-design-vue/es')['Spin']
CampSeat: typeof import('./src/components/ChessMain/CampSeat.vue')['default']
Expand All @@ -19,6 +22,7 @@ declare module '@vue/runtime-core' {
LeftOutlined: typeof import('@ant-design/icons-vue')['LeftOutlined']
Modal: typeof import('./src/components/Message/Modal.vue')['default']
ModeSelector: typeof import('./src/components/ModeSelector.vue')['default']
SoundOutlined: typeof import('@ant-design/icons-vue')['SoundOutlined']
Spectator: typeof import('./src/components/ChessMain/Spectator.vue')['default']
StatusWrapper: typeof import('./src/components/ChessMain/StatusWrapper.vue')['default']
}
Expand Down
2 changes: 1 addition & 1 deletion packages/Chinese-chess/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"@ant-design/icons-vue": "^6.1.0",
"@vitejs/plugin-vue": "^4.5.2",
"ant-design-vue": "^3.2.15",
"chinese-chess-service": "^0.0.24",
"chinese-chess-service": "^0.0.25",
"lodash.clonedeep": "^4.5.0",
"socket.io-client": "^4.7.2",
"vue": "^3.2.41"
Expand Down
Binary file removed packages/Chinese-chess/public/fzlsft.ttf
Binary file not shown.
File renamed without changes.
File renamed without changes
File renamed without changes
1 change: 1 addition & 0 deletions packages/Chinese-chess/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<div class="chinese-chess">
<a-button v-if="loading" @click="loading = false">放弃加载资源</a-button>
<a-spin
:spinning="loading"
tip="资源加载中..."
Expand Down
Binary file not shown.
Binary file not shown.
Binary file removed packages/Chinese-chess/src/assets/resources/win.png
Binary file not shown.
6 changes: 5 additions & 1 deletion packages/Chinese-chess/src/definitions/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ export default {
game: {
ready: 'game:ready',
start: 'game:start',
over: 'game:over',
change: 'game:change',
pointer: 'game:pointer:click'
pointer: 'game:pointer:click',
undoRequest: 'game:undo:request',
undoResponse: 'game:undo:response',
giveUp: 'game:give'
},
client: {
connect: 'connect',
Expand Down
13 changes: 9 additions & 4 deletions packages/Chinese-chess/src/libs/Resource.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
const resources = import.meta.glob('../assets/resources/*')
/* eslint-disable import/no-absolute-path */
export const loadResources = async () => {
const data = Object.values(resources)
const data = await Promise.all([
import('/resources/FZLSFT.ttf'),
import('/resources/STXINGKAI.ttf'),
import('/resources/sword.png'),
import('/resources/win.png')
])

const result: any = {}
let type
let name
let resource

for (let i = 0; i < data.length; i++) {
resource = await data[i]() as any
resource = data[i] as any

[name, type] = resource.default.split('/').at(-1).split('.')
;[name, type] = resource.default.split('/').at(-1).split('.')

if (type === 'png') {
result[name] = await loadPic(resource.default)
Expand Down
213 changes: 213 additions & 0 deletions packages/Chinese-chess/src/pages/OnlineGame/GameAside.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
<template>
<div class="game-aside">
<section class="section manual-wrapper">
<ul
class="list manual-list"
ref="manualListRef"
>
<li
v-for="(item, index) of manual"
:key="item.value + item.camp + index"
class="manual-item"
>
<a-badge
:color="colorMapper[item.camp]"
:text="`[${index + 1}] ${item.value}`"
/>
</li>
</ul>
</section>
<section class="section chat-wrapper">
<ul
class="list chat-list"
ref="chatListRef"
>
<li
v-for="item of chatList"
:key="item.userId + item.createdTime"
class="chat-item"
:class="{
'is-system': item.userId === '',
'is-self': item.userId === currentUser?.id
}"
>
<div
v-if="item.userId !== ''"
class="nickname"
>
{{ item.nickname }}
</div>
<div class="content">
<SoundOutlined v-if="item.userId === ''" />
{{ item.content }}
</div>
</li>
</ul>
<a-input-group compact>
<a-input
v-model:value="msg"
allow-clear
placeholder="按「回车」键发送"
style="width: 70%"
@keydown="handleInputKeydown"
/>
<a-button
type="primary"
style="width: 30%"
@click="handleSend"
>
发送
</a-button>
</a-input-group>
</section>
</div>
</template>

<script setup lang="ts">
import { Camp } from 'chinese-chess-service'
import { colorMapper } from '../../definitions'
import { ComputedRef } from 'vue'
import { message } from 'ant-design-vue'
import { ChatInfo, User } from '@/types'
const emits = defineEmits<(e: 'chat', content: string) => void>()
const manualListRef = ref<HTMLElement | null>(null)
const chatListRef = ref<HTMLElement | null>(null)
const msg = ref<string>()
let lastTime = Date.now()
const manual = inject<ComputedRef<Array<{
camp: Camp
value: string
}>>>('manual')
const chatList = inject('chatList', ref<ChatInfo[]>([]))
const currentUser = inject('currentUser', ref<User | null>(null))
watch(() => manual?.value, () => {
nextTick(() => {
if (manualListRef.value) {
manualListRef.value.scroll(0, manualListRef.value.scrollHeight + 32)
}
})
})
watch(chatList, () => {
nextTick(() => {
if (chatListRef.value) {
chatListRef.value.scroll(0, chatListRef.value.scrollHeight + 32)
}
})
}, { deep: true })
const handleInputKeydown = (e: KeyboardEvent) => {
if (e.key === 'Enter' && msg.value) {
handleSend()
}
}
const handleSend = () => {
if (!msg.value) {
return
}
const currentTime = Date.now()
if (currentTime - lastTime < 1000) {
message.destroy()
message.info('喝杯茶休息一下吧')
return
}
emits('chat', msg.value)
msg.value = undefined
lastTime = currentTime
}
</script>

<style lang="scss" scoped>
.game-aside {
display: flex;
flex-direction: column;
gap: 16px;
height: 100%;
padding: 16px;
box-sizing: border-box;
.section {
.list {
border: 1px solid var(--line);
border-radius: 8px;
overflow-y: auto;
}
}
.manual-wrapper {
height: 40%;
.list {
height: 100%;
padding: 16px 0;
.manual-item {
display: inline-block;
width: 50%;
margin: 4px 0;
padding: 0 16px;
&:nth-child(even) {
text-align: left;
}
}
}
}
.chat-wrapper {
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
.list {
flex: 1;
min-height: 0;
padding: 16px;
.chat-item {
& + .chat-item {
margin-top: 8px;
}
.nickname {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: 700;
}
.content {
word-break: break-all;
}
&.is-self {
padding-left: 32px;
.nickname,
.content {
text-align: right;
}
}
&.is-system {
background-color: var(--red);
margin-left: -16px;
margin-right: -16px;
padding: 0 16px;
color: #fff;
}
}
}
}
}
</style>
45 changes: 41 additions & 4 deletions packages/Chinese-chess/src/pages/OnlineGame/GameLobby.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
<div class="lobby-container">
<header class="header">
<a-button
class="btn-back"
@click="handleBack"
>
Back
游戏大厅
</a-button>
<h1 class="title">
Room
Expand All @@ -19,7 +20,17 @@
class="room"
@click="handleRoomJoin(room)"
>
{{ room.name }}({{ room.users.length }})
<h3 class="title">{{ room.name }} 房</h3>
<div class="number">({{ room.users.length }}/{{ room.limit }})</div>
<div class="status">
{{
room.status === GameStatus.Finished
? '游戏结束'
: room.status === GameStatus.Playing
? '游戏中'
: '空闲'
}}
</div>
</li>
</ul>
</section>
Expand All @@ -28,6 +39,7 @@

<script setup lang="ts">
import { Room } from '@/types'
import { GameStatus } from 'chinese-chess-service'
defineProps<{
handleRoomJoin: (room: Room) => void
Expand All @@ -43,19 +55,44 @@ const handleBack = () => {
</script>

<style lang="scss" scoped>
.header {
position: relative;
padding: 8px;
.btn-back {
position: absolute;
left: 8px;
top: 8px;
}
.title {
margin: 0;
text-align: center;
line-height: 24px;
}
}
.rooms {
display: flex;
justify-content: center;
align-items: center;
gap: 32px;
.room {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 8px;
width: 108px;
height: 108px;
text-align: center;
line-height: 108px;
box-shadow: 0 0 1px #666;
cursor: pointer;
.title {
margin: 0;
}
}
}
</style>
Loading

0 comments on commit 61457bf

Please sign in to comment.