33
44import { type QuestDescriptor } from "./QuestDescriptor" ;
55import { 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-
2321function 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 */
5452export 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}
0 commit comments