2020-10-13 16:46:46 +02:00
import Axios from "axios" ;
import { API_URL } from "../Enum/EnvironmentVariable" ;
2020-10-12 16:23:07 +02:00
export class Room {
2020-10-13 16:46:46 +02:00
public readonly id : string ;
public readonly isPublic : boolean ;
private mapUrl : string | undefined ;
2020-10-13 18:44:50 +02:00
private instance : string | undefined ;
2020-10-13 16:46:46 +02:00
2020-10-13 17:08:24 +02:00
constructor ( id : string ) {
2020-10-13 16:46:46 +02:00
if ( id . startsWith ( '/' ) ) {
id = id . substr ( 1 ) ;
}
this . id = id ;
if ( id . startsWith ( '_/' ) ) {
this . isPublic = true ;
} else if ( id . startsWith ( '@/' ) ) {
this . isPublic = false ;
} else {
throw new Error ( 'Invalid room ID' ) ;
}
2020-10-15 15:50:51 +02:00
const indexOfHash = this . id . indexOf ( '#' ) ;
if ( indexOfHash !== - 1 ) {
this . id = this . id . substr ( 0 , indexOfHash ) ;
}
2020-10-12 16:23:07 +02:00
}
2021-01-17 20:34:35 +01:00
2020-11-18 18:15:57 +01:00
public static getIdFromIdentifier ( identifier : string , baseUrl : string , currentInstance : string ) : { roomId : string , hash : string } {
let roomId = '' ;
let hash = '' ;
if ( ! identifier . startsWith ( '/_/' ) && ! identifier . startsWith ( '/@/' ) ) { //relative file link
2021-01-05 17:08:33 +01:00
//Relative identifier can be deep enough to rewrite the base domain, so we cannot use the variable 'baseUrl' as the actual base url for the URL objects.
//We instead use 'workadventure' as a dummy base value.
const baseUrlObject = new URL ( baseUrl ) ;
const absoluteExitSceneUrl = new URL ( identifier , 'http://workadventure/_/' + currentInstance + '/' + baseUrlObject . hostname + baseUrlObject . pathname ) ;
roomId = absoluteExitSceneUrl . pathname ; //in case of a relative url, we need to create a public roomId
roomId = roomId . substring ( 1 ) ; //remove the leading slash
2020-11-18 18:15:57 +01:00
hash = absoluteExitSceneUrl . hash ;
hash = hash . substring ( 1 ) ; //remove the leading diese
} else { //absolute room Id
const parts = identifier . split ( '#' ) ;
roomId = parts [ 0 ] ;
roomId = roomId . substring ( 1 ) ; //remove the leading slash
if ( parts . length > 1 ) {
hash = parts [ 1 ]
}
}
return { roomId , hash }
}
2020-10-13 16:46:46 +02:00
public async getMapUrl ( ) : Promise < string > {
2020-10-13 17:30:53 +02:00
return new Promise < string > ( ( resolve , reject ) = > {
2020-10-13 16:46:46 +02:00
if ( this . mapUrl !== undefined ) {
resolve ( this . mapUrl ) ;
return ;
}
if ( this . isPublic ) {
2020-10-13 17:30:53 +02:00
const match = /_\/[^/]+\/(.+)/ . exec ( this . id ) ;
2020-10-13 16:46:46 +02:00
if ( ! match ) throw new Error ( 'Could not extract url from "' + this . id + '"' ) ;
this . mapUrl = window . location . protocol + '//' + match [ 1 ] ;
resolve ( this . mapUrl ) ;
return ;
} else {
// We have a private ID, we need to query the map URL from the server.
const urlParts = this . parsePrivateUrl ( this . id ) ;
2020-10-13 17:30:53 +02:00
Axios . get ( ` ${ API_URL } /map ` , {
2020-10-13 16:46:46 +02:00
params : urlParts
2020-10-13 17:30:53 +02:00
} ) . then ( ( { data } ) = > {
console . log ( 'Map ' , this . id , ' resolves to URL ' , data . mapUrl ) ;
resolve ( data . mapUrl ) ;
return ;
2021-01-17 20:34:35 +01:00
} ) . catch ( ( reason ) = > {
reject ( reason ) ;
2020-10-13 16:46:46 +02:00
} ) ;
}
} ) ;
}
2020-10-13 18:44:50 +02:00
/ * *
* Instance name is :
* - In a public URL : the second part of the URL ( _ / [ instance ] / map . json )
* - In a private URL : [ organizationId / worldId ]
* /
public getInstance ( ) : string {
if ( this . instance !== undefined ) {
return this . instance ;
}
if ( this . isPublic ) {
const match = /_\/([^/]+)\/.+/ . exec ( this . id ) ;
if ( ! match ) throw new Error ( 'Could not extract instance from "' + this . id + '"' ) ;
this . instance = match [ 1 ] ;
return this . instance ;
} else {
2020-10-14 10:37:00 +02:00
const match = /@\/([^/]+)\/([^/]+)\/.+/ . exec ( this . id ) ;
2020-10-13 18:44:50 +02:00
if ( ! match ) throw new Error ( 'Could not extract instance from "' + this . id + '"' ) ;
this . instance = match [ 1 ] + '/' + match [ 2 ] ;
return this . instance ;
}
}
2020-10-13 16:46:46 +02:00
private parsePrivateUrl ( url : string ) : { organizationSlug : string , worldSlug : string , roomSlug? : string } {
2020-10-13 17:30:53 +02:00
const regex = /@\/([^/]+)\/([^/]+)(?:\/([^/]*))?/gm ;
2020-10-13 16:46:46 +02:00
const match = regex . exec ( url ) ;
if ( ! match ) {
throw new Error ( 'Invalid URL ' + url ) ;
}
2020-10-13 17:30:53 +02:00
const results : { organizationSlug : string , worldSlug : string , roomSlug? : string } = {
2020-10-13 16:46:46 +02:00
organizationSlug : match [ 1 ] ,
worldSlug : match [ 2 ] ,
}
if ( match [ 3 ] !== undefined ) {
results . roomSlug = match [ 3 ] ;
}
return results ;
}
}