165 lines
3.5 KiB
Vue
165 lines
3.5 KiB
Vue
<script setup>
|
||
import Avatar from "@/components/Avatar.vue";
|
||
|
||
const props = defineProps({
|
||
total: {
|
||
type: Number,
|
||
default: 10,
|
||
},
|
||
players: {
|
||
type: Array,
|
||
default: () => [],
|
||
},
|
||
removePlayer: {
|
||
type: Function,
|
||
default: () => {},
|
||
},
|
||
/** 当前用户是否为房主;仅房主可见踢人按钮 */
|
||
isOwner: {
|
||
type: Boolean,
|
||
default: false,
|
||
},
|
||
});
|
||
const seats = new Array(props.total).fill(1);
|
||
</script>
|
||
|
||
<template>
|
||
<view class="players">
|
||
<view v-for="(_, index) in seats" :key="index">
|
||
<image src="../static/player-bg.png" mode="widthFix" />
|
||
<view v-if="players[index] && players[index].name" class="avatar">
|
||
<Avatar
|
||
:src="players[index].avatar || '../static/user-icon.png'"
|
||
:size="40"
|
||
/>
|
||
<text
|
||
:style="{ opacity: players[index] && !!players[index].state ? 1 : 0 }"
|
||
>已准备</text
|
||
>
|
||
</view>
|
||
<view v-else class="player-unknow">
|
||
<image src="../static/question-mark.png" mode="widthFix" />
|
||
</view>
|
||
<text v-if="players[index] && players[index].name">{{
|
||
players[index].name
|
||
}}</text>
|
||
<text v-else :style="{ color: '#fff9' }">虚位以待</text>
|
||
<view v-if="index === 0" class="founder">管理员</view>
|
||
<!-- <image
|
||
:src="`../static/player-${index + 1}.png`"
|
||
mode="widthFix"
|
||
class="player-bg"
|
||
/> -->
|
||
<!-- 仅房主(isOwner=true)且非空座位时展示踢人按钮 -->
|
||
<button
|
||
v-if="index > 0 && players[index] && isOwner"
|
||
hover-class="none"
|
||
class="remove-player"
|
||
@click="() => removePlayer(players[index])"
|
||
>
|
||
<image src="../static/close-white.png" mode="widthFix" />
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.players {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
row-gap: 20rpx;
|
||
column-gap: 25rpx;
|
||
margin-bottom: 20px;
|
||
font-size: 14px;
|
||
padding: 0 14px;
|
||
}
|
||
.players > view {
|
||
display: flex;
|
||
align-items: center;
|
||
position: relative;
|
||
color: #fff;
|
||
height: 176rpx;
|
||
overflow: hidden;
|
||
}
|
||
.players > view > image:first-child {
|
||
width: 100%;
|
||
height: 100%;
|
||
position: absolute;
|
||
z-index: -1;
|
||
top: 0;
|
||
}
|
||
.avatar {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding: 0 24rpx;
|
||
margin-top: 16rpx;
|
||
}
|
||
.avatar > text {
|
||
background-color: #2c261fb3;
|
||
border: 1rpx solid #a3793f66;
|
||
color: #fed847;
|
||
font-size: 16rpx;
|
||
border-radius: 20rpx;
|
||
width: 70rpx;
|
||
text-align: center;
|
||
margin-top: -16rpx;
|
||
position: relative;
|
||
height: 28rpx;
|
||
line-height: 28rpx;
|
||
}
|
||
.players > view > text:nth-child(3) {
|
||
width: 20vw;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
.founder {
|
||
position: absolute;
|
||
background-color: #fed847;
|
||
top: 0;
|
||
left: 0;
|
||
color: #000;
|
||
font-size: 10px;
|
||
padding: 2px 5px;
|
||
border-top-left-radius: 10px;
|
||
border-bottom-right-radius: 10px;
|
||
}
|
||
/* .player-bg {
|
||
position: absolute;
|
||
width: 52px;
|
||
right: 0;
|
||
} */
|
||
.player-unknow {
|
||
width: 84rpx;
|
||
height: 84rpx;
|
||
margin: 0 24rpx;
|
||
border: 1rpx solid #fff3;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background-color: #69686866;
|
||
box-sizing: border-box;
|
||
}
|
||
.player-unknow > image {
|
||
width: 40%;
|
||
}
|
||
.remove-player {
|
||
width: 48rpx;
|
||
height: 48rpx;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
position: absolute;
|
||
top: 10rpx;
|
||
right: 0;
|
||
}
|
||
.remove-player > image {
|
||
width: 100%;
|
||
height: 100%;
|
||
opacity: 0.6;
|
||
}
|
||
</style>
|