添加分享房间链接和对战结束返回房间
This commit is contained in:
@@ -18,7 +18,18 @@ const totalPoints = ref(0);
|
||||
const rank = ref(0);
|
||||
|
||||
function exit() {
|
||||
uni.navigateBack();
|
||||
const battleInfo = uni.getStorageSync("last-battle");
|
||||
if (battleInfo && battleInfo.roomId) {
|
||||
uni.redirectTo({
|
||||
url: `/pages/battle-room?roomNumber=${battleInfo.roomId}`,
|
||||
});
|
||||
} else if (data.value.roomId) {
|
||||
uni.redirectTo({
|
||||
url: `/pages/battle-room?roomNumber=${data.value.roomId}`,
|
||||
});
|
||||
} else {
|
||||
uni.navigateBack();
|
||||
}
|
||||
}
|
||||
|
||||
onLoad(async (options) => {
|
||||
@@ -310,7 +321,7 @@ const checkBowData = () => {
|
||||
</text>
|
||||
<view class="op-btn">
|
||||
<view @click="checkBowData">查看成绩</view>
|
||||
<view @click="exit">退出</view>
|
||||
<view @click="exit">返回</view>
|
||||
</view>
|
||||
<UserUpgrade />
|
||||
</view>
|
||||
@@ -420,6 +431,7 @@ const checkBowData = () => {
|
||||
border-radius: 20px;
|
||||
padding: 10px 0;
|
||||
text-align: center;
|
||||
color: #000;
|
||||
}
|
||||
.op-btn > view:last-child {
|
||||
color: #fff;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup>
|
||||
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
|
||||
import { onLoad, onShow, onHide } from "@dcloudio/uni-app";
|
||||
import { onLoad, onShareAppMessage } from "@dcloudio/uni-app";
|
||||
import Container from "@/components/Container.vue";
|
||||
import PlayerSeats from "@/components/PlayerSeats.vue";
|
||||
import Guide from "@/components/Guide.vue";
|
||||
@@ -13,12 +13,15 @@ import {
|
||||
exitRoomAPI,
|
||||
startRoomAPI,
|
||||
chooseTeamAPI,
|
||||
getReadyAPI,
|
||||
} from "@/apis";
|
||||
|
||||
import { MESSAGETYPES } from "@/constants";
|
||||
import useStore from "@/store";
|
||||
import { storeToRefs } from "pinia";
|
||||
const store = useStore();
|
||||
const { user } = storeToRefs(store);
|
||||
|
||||
const room = ref({});
|
||||
const roomNumber = ref("");
|
||||
const owner = ref({});
|
||||
@@ -30,14 +33,27 @@ const redTeam = ref([]);
|
||||
const showModal = ref(false);
|
||||
const battleType = ref(0);
|
||||
const refreshRoomTimer = ref(null);
|
||||
const ready = ref(false);
|
||||
const allReady = ref(false);
|
||||
const timer = ref(null);
|
||||
|
||||
async function refreshRoomData() {
|
||||
if (!roomNumber.value) return;
|
||||
const result = await getRoomAPI(roomNumber.value);
|
||||
if (result.started) return;
|
||||
room.value = result;
|
||||
battleType.value = result.battleType;
|
||||
(result.members || []).some((m) => {
|
||||
const members = result.members || [];
|
||||
if (members.length === result.count) {
|
||||
allReady.value = members.every((m) => !!m.userInfo.state);
|
||||
}
|
||||
members.some((m) => {
|
||||
if (m.userInfo.id === user.value.id) {
|
||||
ready.value = !!m.userInfo.state;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
members.some((m) => {
|
||||
if (m.userInfo.id === result.creator) {
|
||||
owner.value = {
|
||||
id: m.userInfo.id,
|
||||
@@ -77,13 +93,19 @@ async function refreshRoomData() {
|
||||
players.value = new Array(result.count).fill({});
|
||||
refreshMembers(result.members);
|
||||
}
|
||||
if (timer.value) clearInterval(timer.value);
|
||||
timer.value = setTimeout(refreshRoomData, 1000);
|
||||
}
|
||||
|
||||
const startGame = async () => {
|
||||
const result = await startRoomAPI(room.value.number);
|
||||
};
|
||||
|
||||
const refreshMembers = (members) => {
|
||||
const getReady = async () => {
|
||||
await getReadyAPI(roomNumber.value);
|
||||
};
|
||||
|
||||
const refreshMembers = (members = []) => {
|
||||
blueTeam.value = [];
|
||||
redTeam.value = [];
|
||||
members.forEach((m, index) => {
|
||||
@@ -138,8 +160,7 @@ async function onReceiveMessage(messages = []) {
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (msg.constructor === MESSAGETYPES.UserExitRoom) {
|
||||
} else if (msg.constructor === MESSAGETYPES.UserExitRoom) {
|
||||
if (battleType.value === 1) {
|
||||
if (msg.userId === room.value.creator) {
|
||||
owner.value = {
|
||||
@@ -157,25 +178,22 @@ async function onReceiveMessage(messages = []) {
|
||||
if (msg.room && msg.room.members) {
|
||||
refreshMembers(msg.room.members);
|
||||
}
|
||||
}
|
||||
if (msg.constructor === MESSAGETYPES.TeamUpdate) {
|
||||
} else if (msg.constructor === MESSAGETYPES.TeamUpdate) {
|
||||
if (msg.room && msg.room.members) {
|
||||
refreshMembers(msg.room.members);
|
||||
}
|
||||
}
|
||||
if (msg.constructor === MESSAGETYPES.RoomDestroy) {
|
||||
} else if (msg.constructor === MESSAGETYPES.RoomDestroy) {
|
||||
uni.showToast({
|
||||
title: "房间已解散",
|
||||
icon: "none",
|
||||
});
|
||||
roomNumber.value = "";
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 1000);
|
||||
} else if (msg.constructor === MESSAGETYPES.SomeoneIsReady) {
|
||||
refreshRoomData();
|
||||
}
|
||||
}
|
||||
if (msg.constructor === MESSAGETYPES.WaitForAllReady) {
|
||||
roomNumber.value = "";
|
||||
} else if (msg.constructor === MESSAGETYPES.WaitForAllReady) {
|
||||
if (msg.groupUserStatus) {
|
||||
uni.setStorageSync("red-team", msg.groupUserStatus.redTeam);
|
||||
uni.setStorageSync("blue-team", msg.groupUserStatus.blueTeam);
|
||||
@@ -184,6 +202,8 @@ async function onReceiveMessage(messages = []) {
|
||||
...msg.groupUserStatus.blueTeam,
|
||||
]);
|
||||
uni.removeStorageSync("current-battle");
|
||||
// 避免离开页面,触发退出房间
|
||||
roomNumber.value = "";
|
||||
if (msg.groupUserStatus.config.mode == 1) {
|
||||
uni.redirectTo({
|
||||
url: `/pages/team-battle?battleId=${msg.id}&gameMode=1`,
|
||||
@@ -226,15 +246,18 @@ const setClipboardData = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const onBack = () => {
|
||||
showModal.value = true;
|
||||
};
|
||||
onShareAppMessage(() => {
|
||||
return {
|
||||
title: "邀请您进入房间对战",
|
||||
path: "/pages/friend-battle?roomID=" + roomNumber.value,
|
||||
imageUrl: "",
|
||||
};
|
||||
});
|
||||
|
||||
onLoad(async (options) => {
|
||||
if (options.roomNumber) {
|
||||
roomNumber.value = options.roomNumber;
|
||||
refreshRoomData();
|
||||
refreshRoomTimer.value = setInterval(refreshRoomData, 2000);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -251,19 +274,14 @@ onBeforeUnmount(() => {
|
||||
keepScreenOn: false,
|
||||
});
|
||||
uni.$off("socket-inbox", onReceiveMessage);
|
||||
if (roomNumber.value && owner.value.id !== user.value.id) {
|
||||
exitRoomAPI(roomNumber.value);
|
||||
}
|
||||
if (roomNumber.value) exitRoomAPI(roomNumber.value);
|
||||
if (timer.value) clearInterval(timer.value);
|
||||
timer.value = null;
|
||||
});
|
||||
|
||||
onShow(async () => {
|
||||
refreshRoomData();
|
||||
});
|
||||
onHide(() => {});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Container :title="`好友约战 - ${roomNumber}`" :onBack="onBack">
|
||||
<Container :title="`好友约战 - ${roomNumber}`">
|
||||
<view class="standby-phase">
|
||||
<Guide>
|
||||
<view class="battle-guide">
|
||||
@@ -274,7 +292,7 @@ onHide(() => {});
|
||||
}}</text>
|
||||
<text v-if="battleType === 2">大乱斗即将开始! </text>
|
||||
</view>
|
||||
<view @click="setClipboardData">复制房间号</view>
|
||||
<button hover-class="none" open-type="share">邀请</button>
|
||||
</view>
|
||||
</Guide>
|
||||
<view v-if="battleType === 1 && room.count === 2" class="team-mode">
|
||||
@@ -389,7 +407,7 @@ onHide(() => {});
|
||||
</view>
|
||||
</block>
|
||||
<view>
|
||||
<SButton
|
||||
<!-- <SButton
|
||||
v-if="user.id === owner.id && battleType === 1 && room.count === 2"
|
||||
:disabled="!opponent.id"
|
||||
:onClick="startGame"
|
||||
@@ -409,11 +427,14 @@ onHide(() => {});
|
||||
:onClick="startGame"
|
||||
>开启对局</SButton
|
||||
>
|
||||
<SButton v-if="user.id !== owner.id" disabled>等待房主开启对战</SButton>
|
||||
<text class="tips">创建者点击下一步,所有人即可进入游戏。</text>
|
||||
<SButton v-if="user.id !== owner.id" disabled>等待房主开启对战</SButton> -->
|
||||
<SButton :disabled="ready" :onClick="getReady">{{
|
||||
allReady.value ? "即将进入对局..." : "我准备好了"
|
||||
}}</SButton>
|
||||
<!-- <text class="tips">创建者点击下一步,所有人即可进入游戏。</text> -->
|
||||
</view>
|
||||
</view>
|
||||
<SModal
|
||||
<!-- <SModal
|
||||
:show="showModal"
|
||||
:onClose="() => (showModal = false)"
|
||||
height="520rpx"
|
||||
@@ -429,7 +450,7 @@ onHide(() => {});
|
||||
</SButton>
|
||||
</block>
|
||||
</view>
|
||||
</SModal>
|
||||
</SModal> -->
|
||||
</Container>
|
||||
</template>
|
||||
|
||||
@@ -537,7 +558,7 @@ onHide(() => {});
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.battle-guide > view:last-child {
|
||||
.battle-guide > button:last-child {
|
||||
color: #fed847;
|
||||
border: 1px solid #fed847;
|
||||
margin-right: 10px;
|
||||
|
||||
@@ -1,52 +1,54 @@
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { onShow } from "@dcloudio/uni-app";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import Container from "@/components/Container.vue";
|
||||
import Guide from "@/components/Guide.vue";
|
||||
import SButton from "@/components/SButton.vue";
|
||||
import SModal from "@/components/SModal.vue";
|
||||
import Signin from "@/components/Signin.vue";
|
||||
import CreateRoom from "@/components/CreateRoom.vue";
|
||||
import Avatar from "@/components/Avatar.vue";
|
||||
import { getRoomAPI, joinRoomAPI, isGamingAPI, getBattleDataAPI } from "@/apis";
|
||||
|
||||
import { getRoomAPI, joinRoomAPI, getBattleDataAPI } from "@/apis";
|
||||
import { debounce, canEenter } from "@/util";
|
||||
|
||||
import useStore from "@/store";
|
||||
import { storeToRefs } from "pinia";
|
||||
const store = useStore();
|
||||
const { user, device, online } = storeToRefs(store);
|
||||
import { debounce, canEenter } from "@/util";
|
||||
const { user, device, online, game } = storeToRefs(store);
|
||||
|
||||
const showModal = ref(false);
|
||||
const showSignin = ref(false);
|
||||
const warnning = ref("");
|
||||
const roomNumber = ref("");
|
||||
const data = ref({});
|
||||
const roomID = ref("");
|
||||
|
||||
const enterRoom = debounce(async () => {
|
||||
const enterRoom = debounce(async (number) => {
|
||||
if (!canEenter(user.value, device.value, online.value)) return;
|
||||
const isGaming = await isGamingAPI();
|
||||
if (isGaming) {
|
||||
if (game.value.inBattle) {
|
||||
uni.$showHint(1);
|
||||
return;
|
||||
}
|
||||
if (!roomNumber.value) {
|
||||
if (!number) {
|
||||
warnning.value = "请输入房间号";
|
||||
showModal.value = true;
|
||||
} else {
|
||||
const room = await getRoomAPI(roomNumber.value);
|
||||
const room = await getRoomAPI(number);
|
||||
if (room.number) {
|
||||
const alreadyIn = room.members.find(
|
||||
(item) => item.userInfo.id === user.value.id
|
||||
);
|
||||
if (!alreadyIn) {
|
||||
const result = await joinRoomAPI(roomNumber.value);
|
||||
const result = await joinRoomAPI(number);
|
||||
if (result.full) {
|
||||
warnning.value = "房间已满员";
|
||||
showModal.value = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
roomNumber.value = "";
|
||||
showModal.value = false;
|
||||
uni.navigateTo({
|
||||
url: `/pages/battle-room?roomNumber=${room.number}`,
|
||||
url: "/pages/battle-room?roomNumber=" + number,
|
||||
});
|
||||
} else {
|
||||
warnning.value = room.started ? "该房间对战已开始,无法加入" : "查无此房";
|
||||
@@ -56,18 +58,24 @@ const enterRoom = debounce(async () => {
|
||||
});
|
||||
const onCreateRoom = async () => {
|
||||
if (!canEenter(user.value, device.value, online.value)) return;
|
||||
const isGaming = await isGamingAPI();
|
||||
if (isGaming) {
|
||||
uni.$showHint(1);
|
||||
return;
|
||||
}
|
||||
warnning.value = "";
|
||||
showModal.value = true;
|
||||
};
|
||||
const onSignin = () => {
|
||||
showSignin.value = false;
|
||||
if (roomID.value) enterRoom(roomID.value);
|
||||
};
|
||||
onShow(async () => {
|
||||
const result = await getBattleDataAPI();
|
||||
data.value = result;
|
||||
});
|
||||
onLoad(async (options) => {
|
||||
roomID.value = options.roomID || "";
|
||||
if (options.roomID) {
|
||||
if (user.value.id) enterRoom(options.roomID);
|
||||
else showSignin.value = true;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -127,7 +135,7 @@ onShow(async () => {
|
||||
v-model="roomNumber"
|
||||
placeholder-style="color: #ccc"
|
||||
/>
|
||||
<view @click="enterRoom">进入房间</view>
|
||||
<view @click="enterRoom(roomNumber)">进入房间</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="create-room">
|
||||
@@ -159,6 +167,9 @@ onShow(async () => {
|
||||
</view>
|
||||
<CreateRoom v-if="!warnning" :onConfirm="() => (showModal = false)" />
|
||||
</SModal>
|
||||
<SModal :show="showSignin" :onClose="() => (showSignin = false)">
|
||||
<Signin :onClose="onSignin" />
|
||||
</SModal>
|
||||
</view>
|
||||
</Container>
|
||||
</template>
|
||||
|
||||
@@ -30,8 +30,8 @@ const {
|
||||
getLvlName,
|
||||
updateOnline,
|
||||
} = store;
|
||||
const { user, device, rankData, online, game } = storeToRefs(store);
|
||||
|
||||
const { user, device, rankData, online } = storeToRefs(store);
|
||||
const showModal = ref(false);
|
||||
const showGuide = ref(false);
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@ import { onShow } from "@dcloudio/uni-app";
|
||||
import Container from "@/components/Container.vue";
|
||||
import Avatar from "@/components/Avatar.vue";
|
||||
import { topThreeColors } from "@/constants";
|
||||
import { isGamingAPI, getHomeData } from "@/apis";
|
||||
import { getHomeData } from "@/apis";
|
||||
import { canEenter } from "@/util";
|
||||
import useStore from "@/store";
|
||||
import { storeToRefs } from "pinia";
|
||||
const store = useStore();
|
||||
const { user, device, online } = storeToRefs(store);
|
||||
const { user, device, online, game } = storeToRefs(store);
|
||||
const { getLvlName } = store;
|
||||
|
||||
const defaultSeasonData = {
|
||||
@@ -43,8 +43,7 @@ const handleSelect = (index) => {
|
||||
|
||||
const toMatchPage = async (gameType, teamSize) => {
|
||||
if (!canEenter(user.value, device.value, online.value)) return;
|
||||
const isGaming = await isGamingAPI();
|
||||
if (isGaming) {
|
||||
if (game.value.inBattle) {
|
||||
uni.$showHint(1);
|
||||
return;
|
||||
}
|
||||
@@ -64,14 +63,14 @@ const toRankListPage = () => {
|
||||
});
|
||||
};
|
||||
const onChangeSeason = async (seasonId, name) => {
|
||||
showSeasonList.value = false;
|
||||
if (name !== seasonName.value) {
|
||||
handleSelect(selectedIndex.value);
|
||||
const result = await getHomeData(seasonId);
|
||||
rankData.value = result;
|
||||
seasonName.value = name;
|
||||
handleSelect(selectedIndex.value);
|
||||
updateData();
|
||||
}
|
||||
showSeasonList.value = false;
|
||||
};
|
||||
const updateData = () => {
|
||||
const { userGameStats, seasonList } = rankData.value;
|
||||
@@ -502,10 +501,11 @@ onShow(async () => {
|
||||
}
|
||||
.ranking-data > view:first-of-type > view {
|
||||
width: 25%;
|
||||
padding: 7px 10px;
|
||||
text-align: center;
|
||||
border-radius: 20px;
|
||||
font-size: 30rpx;
|
||||
word-break: keep-all;
|
||||
line-height: 70rpx;
|
||||
}
|
||||
.rank-item {
|
||||
width: calc(100% - 30px);
|
||||
@@ -595,13 +595,19 @@ onShow(async () => {
|
||||
.season-list > view {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px 20px;
|
||||
word-break: keep-all;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
.season-list > view > text {
|
||||
width: 140rpx;
|
||||
text-align: right;
|
||||
}
|
||||
.season-list > view > image {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-left: 10px;
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
min-width: 24rpx;
|
||||
min-height: 24rpx;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
.my-rank-score {
|
||||
position: absolute !important;
|
||||
|
||||
Reference in New Issue
Block a user