Skip to content

Commit c27a42d

Browse files
authored
Merge pull request #2 from workadventure/congrats
fix: Display the congratulation screen
2 parents d64b4e8 + 525da18 commit c27a42d

File tree

8 files changed

+1007
-10
lines changed

8 files changed

+1007
-10
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"dist"
1919
],
2020
"scripts": {
21-
"dev": "vite",
21+
"dev": "vite --host",
2222
"build": "tsc && vite build",
2323
"preview": "vite preview --host",
2424
"test": "vitest",

src/LevelUpResponse.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface LevelUpResponse {
2+
awardedBadges: string[];
3+
currentXp: number;
4+
}

src/index.ts

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33

44
import { type QuestDescriptor } from "./QuestDescriptor";
55
import { type LeaderboardResponse } from "./LeaderboardResponse";
6+
import { type UIWebsite } from "@workadventure/iframe-api-typings";
7+
import { type LevelUpResponse } from "./LevelUpResponse";
68

7-
let questBaseUrl = "https://admin.workadventure.localhost";
9+
let questBaseUrl = "http://admin.workadventure.localhost";
810

911
/**
1012
* INTERNAL: Sets the base URL of the quest server. This function should only be called if you are performing
@@ -16,10 +18,6 @@ export function setQuestBaseUrl(baseUrl: string): void {
1618
questBaseUrl = baseUrl;
1719
}
1820

19-
export function grantXp(questKey: string, xp: number): void {
20-
console.log("grantXp", questKey, xp);
21-
}
22-
2321
function getUserRoomToken(): string {
2422
const userRoomToken = WA.player.userRoomToken;
2523
if (userRoomToken === undefined) {
@@ -49,7 +47,7 @@ export async function getQuest(questKey: string): Promise<QuestDescriptor> {
4947
}
5048

5149
/**
52-
* Returns the leaderboard for the quest whose key is `questKey`.
50+
* Returns the leaderboard for the quest whose key is `questKey` as JS object.
5351
*/
5452
export async function getLeaderboard(questKey: string): Promise<LeaderboardResponse> {
5553
const url = new URL(`/api/quests/${questKey}/leaderboard`, questBaseUrl);
@@ -66,13 +64,23 @@ export async function getLeaderboard(questKey: string): Promise<LeaderboardRespo
6664
return await response.json();
6765
}
6866

67+
/**
68+
* Returns the URL of the leaderboard as an HTML page (to be displayed in an iframe).
69+
* @return URL
70+
*/
71+
export function getLeaderboardURL(questKey: string): URL {
72+
const url = new URL(`/quests/${questKey}/leaderboard`, questBaseUrl);
73+
url.search = new URLSearchParams({ room: WA.room.id, token: getUserRoomToken() }).toString();
74+
return url;
75+
}
76+
6977
/**
7078
* Earns `xp` XP for the quest whose key is `questKey` for the current user.
7179
*/
72-
export async function levelUp(questKey: string, xp: number): Promise<void> {
80+
export async function levelUp(questKey: string, xp: number): Promise<LevelUpResponse> {
7381
const url = new URL(`/api/quests/${questKey}/level-up`, questBaseUrl);
7482
const response = await fetch(url, {
75-
method: "GET",
83+
method: "POST",
7684
headers: {
7785
"Content-Type": "application/json",
7886
Authorization: getUserRoomToken(),
@@ -82,5 +90,57 @@ export async function levelUp(questKey: string, xp: number): Promise<void> {
8290
if (!response.ok) {
8391
throw new Error(`An error occurred. HTTP Code: ${response.status} ${response.statusText}.`);
8492
}
85-
return await response.json();
93+
const data: LevelUpResponse = await response.json();
94+
if (data.awardedBadges.length > 0) {
95+
(async () => {
96+
for (const badge of data.awardedBadges) {
97+
// Display awarded badges one by one
98+
await displayCongratulations(questKey, badge);
99+
}
100+
})().catch((e) => {
101+
console.error(e);
102+
});
103+
}
104+
return data;
105+
}
106+
107+
let congratulationsWebsitePromise: Promise<UIWebsite> | undefined;
108+
109+
async function displayCongratulations(quest: string, badge: string): Promise<void> {
110+
if (congratulationsWebsitePromise !== undefined) {
111+
await (await congratulationsWebsitePromise).close();
112+
}
113+
114+
const url = new URL(`/quests/${quest}/badge/${badge}/congratulations`, questBaseUrl);
115+
url.search = new URLSearchParams({ token: getUserRoomToken() }).toString();
116+
congratulationsWebsitePromise = WA.ui.website.open({
117+
url: url.toString(),
118+
position: {
119+
vertical: "middle",
120+
horizontal: "middle",
121+
},
122+
allowApi: true,
123+
visible: true,
124+
size: {
125+
width: "100%",
126+
height: "100%",
127+
},
128+
});
129+
130+
const soundUrl = new URL(`/audio/clapping.mp3`, questBaseUrl);
131+
WA.sound.loadSound(soundUrl.toString()).play({
132+
loop: false,
133+
volume: 1,
134+
});
135+
136+
const congratulationsWebsite = await congratulationsWebsitePromise;
137+
await new Promise<void>((resolve) => {
138+
setTimeout(() => {
139+
resolve();
140+
}, 8000);
141+
});
142+
congratulationsWebsite.close().catch((e) => {
143+
console.error(e);
144+
});
145+
congratulationsWebsitePromise = undefined;
86146
}

test/maps/special-zones.png

10.7 KB
Loading

0 commit comments

Comments
 (0)