Skip to content

Commit

Permalink
Merge pull request #908 from sgfost/tournament-lobby
Browse files Browse the repository at this point in the history
finalize tournament lobby +  add variable event cards
  • Loading branch information
alee authored Nov 9, 2023
2 parents 1a26df6 + 5002c74 commit 896e3d9
Show file tree
Hide file tree
Showing 51 changed files with 1,202 additions and 364 deletions.
3 changes: 2 additions & 1 deletion client/src/api/admin/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ModerationActionData,
InspectData,
DynamicSettingsData,
LobbyActivityData,
} from "@port-of-mars/shared/types";
import { TStore } from "@port-of-mars/client/plugins/tstore";
import { AjaxRequest } from "@port-of-mars/client/plugins/ajax";
Expand Down Expand Up @@ -83,7 +84,7 @@ export class AdminAPI {
}
}

async getLobbyData(): Promise<any> {
async getLobbyData(): Promise<LobbyActivityData> {
try {
return await this.ajax.get(url("/admin/lobby"), ({ data }) => {
return data;
Expand Down
5 changes: 5 additions & 0 deletions client/src/api/game/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
AccomplishmentPurchaseData,
ChatMessageData,
GameData,
GameType,
MarsEventData,
MarsLogMessageData,
Phase,
Expand Down Expand Up @@ -292,6 +293,10 @@ export function applyGameServerResponses(room: Room, store: TStore, sfx: SfxMana
const heroOrPariah: "hero" | "pariah" = change.value;
store.commit("SET_HERO_OR_PARIAH", heroOrPariah);
}
if (change.field === "type") {
const gameType: GameType = change.value;
store.commit("SET_GAME_TYPE", gameType);
}
});
};
}
15 changes: 14 additions & 1 deletion client/src/components/global/TournamentOnboardingSteps.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
>
</div>
</div>
<b-button v-if="isDevMode" variant="link" :href="skipSurveyUrl"
>Skip survey (test mode)</b-button
>
<div class="line"></div>
<div class="d-flex align-items-center">
<div class="flex-shrink-1 mr-5">
Expand All @@ -58,13 +61,15 @@
import { CONSENT_PAGE, MANUAL_PAGE } from "@port-of-mars/shared/routes";
import { TournamentRoundInviteStatus } from "@port-of-mars/shared/types";
import { Component, Prop, Vue } from "vue-property-decorator";
import { Constants } from "@port-of-mars/shared/settings";
import { Constants, isDevOrStaging } from "@port-of-mars/shared/settings";
import { url } from "@port-of-mars/client/util";
@Component({})
export default class TournamentOnboardingSteps extends Vue {
@Prop()
invite!: TournamentRoundInviteStatus;
isDevMode = false;
consent = { name: CONSENT_PAGE };
manual = { name: MANUAL_PAGE };
Expand All @@ -79,6 +84,14 @@ export default class TournamentOnboardingSteps extends Vue {
get hasConsented() {
return this.$store.getters.hasConsented;
}
get skipSurveyUrl() {
return url(`/tournament/survey/complete?tid=${this.invite.id}`);
}
created() {
this.isDevMode = isDevOrStaging();
}
}
</script>

Expand Down
15 changes: 14 additions & 1 deletion client/src/components/lobby/LobbyChat.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,23 @@
:key="msg.username + msg.dateCreated"
class="mt-2 backdrop rounded p-1"
>
<p class="mb-0">
<p class="mb-0 text-break">
<b class="text-light">{{ msg.username }}: </b>
<span class="text-secondary">{{ msg.message }}</span>
</p>
</div>
</div>
<p class="m-3" v-if="showConductWarning">
Chat messages may be recorded. Please adhere to the
<b
><a
target="_blank"
href="https://github.com/virtualcommons/port-of-mars/wiki/Port-of-Mars-Chat-Code-of-Conduct"
>
Port of Mars Code of Conduct
</a></b
>
</p>
<div id="input" class="flex-shrink-1">
<b-form @submit.stop.prevent="submitToChat" class="p-2" inline>
<b-form-input
Expand Down Expand Up @@ -41,6 +52,7 @@ export default class LobbyChat extends Vue {
@Prop() messages!: Array<LobbyChatMessageData>;
pendingMessage: string = "";
showConductWarning = true;
get reversedMessages(): Array<LobbyChatMessageData> {
return this.messages.slice().reverse();
Expand All @@ -62,6 +74,7 @@ export default class LobbyChat extends Vue {
}
async submitToChat() {
this.showConductWarning = false;
if (this.pendingMessageCleaned && this.pendingMessageCleaned !== "") {
await this.api.sendChatMessage(this.pendingMessageCleaned);
this.pendingMessage = "";
Expand Down
36 changes: 34 additions & 2 deletions client/src/components/root/GameOver.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,19 @@
</b-list-group-item>
</b-list-group>
<h4 class="mt-5">Thank you for participating!</h4>
<b-button block class="w-100" variant="success" size="lg" :to="freePlayLobby">
<b-button
v-if="isTournament"
block
class="w-100"
variant="success"
size="lg"
:href="exitSurveyUrl"
:disabled="!exitSurveyUrl"
>
<h4 class="mb-0" v-if="exitSurveyUrl">Take Exit Survey</h4>
<h4 class="mb-0" v-else><b-spinner></b-spinner></h4>
</b-button>
<b-button v-else block class="w-100" variant="success" size="lg" :to="freePlayLobby">
<b-icon-chevron-left shift-v="-2" class="float-left"></b-icon-chevron-left>
<h4 class="mb-0">Return to Lobby</h4>
</b-button>
Expand Down Expand Up @@ -59,11 +71,12 @@

<script lang="ts">
import { Vue, Component } from "vue-property-decorator";
import { FREE_PLAY_LOBBY_PAGE } from "@port-of-mars/shared/routes";
import { FREE_PLAY_LOBBY_PAGE, TOURNAMENT_DASHBOARD_PAGE } from "@port-of-mars/shared/routes";
import { Phase, Role } from "@port-of-mars/shared/types";
import MarsLog from "@port-of-mars/client/components/game/MarsLog.vue";
import SocialShare from "@port-of-mars/client/components/global/SocialShare.vue";
import _ from "lodash";
import { TournamentAPI } from "@port-of-mars/client/api/tournament/request";
@Component({
components: {
Expand All @@ -73,6 +86,11 @@ import _ from "lodash";
})
export default class Victory extends Vue {
freePlayLobby = { name: FREE_PLAY_LOBBY_PAGE };
tournamentDashboard = { name: TOURNAMENT_DASHBOARD_PAGE };
tournamentAPI!: TournamentAPI;
exitSurveyUrl: string | null = null;
get players() {
return _.orderBy(this.$tstore.state.players, ["victoryPoints"], ["desc"]);
Expand All @@ -94,12 +112,26 @@ export default class Victory extends Vue {
return this.phase === Phase.victory;
}
get isTournament() {
return this.$tstore.state.gameType === "tournament";
}
get victoryPoints() {
return this.playerRole ? this.$tstore.state.players[this.playerRole].victoryPoints : 0;
}
roleLabel(role: Role) {
return role === this.playerRole ? `${role} (Your Role)` : role;
}
async created() {
this.tournamentAPI = new TournamentAPI(this.$tstore, this.$ajax);
if (this.isTournament) {
const invite = await this.tournamentAPI.getInviteStatus();
if (invite) {
this.exitSurveyUrl = invite.exitSurveyUrl;
}
}
}
}
</script>
7 changes: 6 additions & 1 deletion client/src/store/mutations/gameState.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MarsEventData, Phase, Role } from "@port-of-mars/shared/types";
import { GameType, MarsEventData, Phase, Role } from "@port-of-mars/shared/types";
import { Vue } from "vue-property-decorator";
import * as _ from "lodash";
import { State, User } from "@port-of-mars/shared/game/client/state";
Expand Down Expand Up @@ -91,6 +91,10 @@ function SET_HERO_OR_PARIAH(state: State, vote: "hero" | "pariah") {
state.heroOrPariah = vote;
}

function SET_GAME_TYPE(state: State, type: GameType) {
state.gameType = type;
}

export default {
SET_GAME_PHASE,
SET_ROUND,
Expand All @@ -105,5 +109,6 @@ export default {
SET_USER,
SET_WINNERS,
SET_HERO_OR_PARIAH,
SET_GAME_TYPE,
TOGGLE_LOADING,
};
3 changes: 3 additions & 0 deletions client/src/stylesheets/bootstrap-customize.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ $enable-rounded: true;

// Custom Sizes

// generates utility classes like w-10 (width: 10%), mh-40 (max-height: 40%), etc.
$sizes: (
"10" : 10%,
"30" : 30%,
"40" : 40%,
"70" : 70%,
);

Expand Down
2 changes: 1 addition & 1 deletion client/src/views/FreePlayLobby.vue
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export default class FreePlayLobby extends Vue {
}
async rejoinIfActiveGame() {
await this.$ajax.get(url("/game/has-active"), ({ data, status }) => {
await this.$ajax.get(url("/game/has-active?type=freeplay"), ({ data, status }) => {
if (status === 200 && data === true) {
this.$router.push(this.game);
}
Expand Down
10 changes: 9 additions & 1 deletion client/src/views/TournamentDashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
</span>
<span v-else></span>
</div>
<div v-else class="h-100 d-flex flex-column justify-content-around align-items-center">
<div v-else class="h-100 d-flex flex-column justify-content-center align-items-center">
<b-alert show v-if="loaded" variant="danger" class="mx-5">
<h4><b-icon-exclamation-circle></b-icon-exclamation-circle></h4>
<span v-if="invite?.hasParticipated">
Expand All @@ -62,6 +62,14 @@
</span>
</b-alert>
<b-spinner v-else></b-spinner>
<b-button
v-if="invite?.hasParticipated && !invite.hasCompletedExitSurvey"
variant="success"
size="lg"
:href="invite.exitSurveyUrl"
>
<h4 class="mb-0">Take Exit Survey</h4>
</b-button>
</div>
</b-col>
</b-row>
Expand Down
10 changes: 10 additions & 0 deletions client/src/views/TournamentLobby.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
MANUAL_PAGE,
TOURNAMENT_DASHBOARD_PAGE,
} from "@port-of-mars/shared/routes";
import { url } from "@port-of-mars/client/util";
import { Constants } from "@port-of-mars/shared/settings";
import Countdown from "@port-of-mars/client/components/global/Countdown.vue";
import HelpPanel from "@port-of-mars/client/components/lobby/HelpPanel.vue";
Expand Down Expand Up @@ -94,6 +95,7 @@ export default class TournamentLobby extends Vue {
}
async created() {
await this.rejoinIfActiveGame();
try {
const room = await this.$client.joinOrCreate(TOURNAMENT_LOBBY_NAME);
applyLobbyResponses(room, this, "tournament");
Expand All @@ -103,6 +105,14 @@ export default class TournamentLobby extends Vue {
}
}
async rejoinIfActiveGame() {
await this.$ajax.get(url("/game/has-active?type=tournament"), ({ data, status }) => {
if (status === 200 && data === true) {
this.$router.push(this.game);
}
});
}
beforeDestroy() {
this.api.leave();
this.$tstore.commit("RESET_LOBBY_STATE");
Expand Down
15 changes: 13 additions & 2 deletions client/src/views/admin/Games.vue
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@
sort-by="dateFinalized"
:sort-desc="true"
>
<template #cell(tournamentRound)="data">
<b-badge
variant="secondary"
v-if="data.item.tournamentRound.tournament.name === 'freeplay'"
>Freeplay</b-badge
>
<b-badge variant="primary" v-else>
{{ data.item.tournamentRound.tournament.name }}
(Round {{ data.item.tournamentRound.roundNumber }})
</b-badge>
</template>
<template #cell(dateFinalized)="data">
{{ new Date(data.item.dateFinalized).toDateString() }}
</template>
Expand Down Expand Up @@ -108,7 +119,7 @@
</b-col>
<!-- players -->
<b-col v-if="showPlayers" cols="5" class="mh-100 p-2">
<h4 class="header-nowrap">Game #{{ this.players[0].gameId }} Scoreboard</h4>
<h4 class="header-nowrap">Game #{{ players[0].gameId }} Scoreboard</h4>
<div class="h-100-header w-100 content-container">
<b-table
dark
Expand Down Expand Up @@ -174,7 +185,7 @@ export default class Games extends Vue {
games: any = [];
gameFields = [
{ key: "id", label: "Game ID" },
{ key: "tournamentRoundId", label: "Round" },
{ key: "tournamentRound", label: "Tournament" },
{ key: "dateFinalized", label: "Date" },
{ key: "status", label: "Status" },
{ key: "players", label: "Players" },
Expand Down
Loading

0 comments on commit 896e3d9

Please sign in to comment.