Merge branch 'develop' of github.com:thecodingmachine/workadventure into loadTileset
This commit is contained in:
commit
5f7361156b
21 changed files with 88 additions and 49 deletions
|
@ -3,9 +3,12 @@
|
|||
import { chatMessagesStore, chatVisibilityStore } from "../../Stores/ChatStore";
|
||||
import ChatMessageForm from './ChatMessageForm.svelte';
|
||||
import ChatElement from './ChatElement.svelte';
|
||||
import { afterUpdate, beforeUpdate } from "svelte";
|
||||
import {afterUpdate, beforeUpdate} from "svelte";
|
||||
import {HtmlUtils} from "../../WebRtc/HtmlUtils";
|
||||
|
||||
let listDom: HTMLElement;
|
||||
let chatWindowElement: HTMLElement;
|
||||
let handleFormBlur: { blur():void };
|
||||
let autoscroll: boolean;
|
||||
|
||||
beforeUpdate(() => {
|
||||
|
@ -16,6 +19,12 @@
|
|||
if (autoscroll) listDom.scrollTo(0, listDom.scrollHeight);
|
||||
});
|
||||
|
||||
function onClick(event: MouseEvent) {
|
||||
if (HtmlUtils.isClickedOutside(event, chatWindowElement)) {
|
||||
handleFormBlur.blur();
|
||||
}
|
||||
}
|
||||
|
||||
function closeChat() {
|
||||
chatVisibilityStore.set(false);
|
||||
}
|
||||
|
@ -26,10 +35,10 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={onKeyDown}/>
|
||||
<svelte:window on:keydown={onKeyDown} on:click={onClick}/>
|
||||
|
||||
|
||||
<aside class="chatWindow" transition:fly="{{ x: -1000, duration: 500 }}">
|
||||
<aside class="chatWindow" transition:fly="{{ x: -1000, duration: 500 }}" bind:this={chatWindowElement}>
|
||||
<p class="close-icon" on:click={closeChat}>×</p>
|
||||
<section class="messagesList" bind:this={listDom}>
|
||||
<ul>
|
||||
|
@ -40,7 +49,7 @@
|
|||
</ul>
|
||||
</section>
|
||||
<section class="messageForm">
|
||||
<ChatMessageForm></ChatMessageForm>
|
||||
<ChatMessageForm bind:handleForm={handleFormBlur}></ChatMessageForm>
|
||||
</section>
|
||||
</aside>
|
||||
|
||||
|
|
|
@ -7,13 +7,14 @@
|
|||
|
||||
export let message: ChatMessage;
|
||||
export let line: number;
|
||||
const chatStyleLink = "color: white; text-decoration: underline;";
|
||||
|
||||
$: author = message.author as PlayerInterface;
|
||||
$: targets = message.targets || [];
|
||||
$: texts = message.text || [];
|
||||
|
||||
function urlifyText(text: string): string {
|
||||
return HtmlUtils.urlify(text)
|
||||
return HtmlUtils.urlify(text, chatStyleLink);
|
||||
}
|
||||
function renderDate(date: Date) {
|
||||
return date.toLocaleTimeString(navigator.language, {
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
<script lang="ts">
|
||||
import {chatMessagesStore, chatInputFocusStore} from "../../Stores/ChatStore";
|
||||
|
||||
export const handleForm = {
|
||||
blur() {
|
||||
inputElement.blur();
|
||||
}
|
||||
}
|
||||
let inputElement: HTMLElement;
|
||||
let newMessageText = '';
|
||||
|
||||
function onFocus() {
|
||||
|
@ -18,7 +24,7 @@
|
|||
</script>
|
||||
|
||||
<form on:submit|preventDefault={saveMessage}>
|
||||
<input type="text" bind:value={newMessageText} placeholder="Enter your message..." on:focus={onFocus} on:blur={onBlur} >
|
||||
<input type="text" bind:value={newMessageText} placeholder="Enter your message..." on:focus={onFocus} on:blur={onBlur} bind:this={inputElement}>
|
||||
<button type="submit">
|
||||
<img src="/static/images/send.png" alt="Send" width="20">
|
||||
</button>
|
||||
|
|
|
@ -107,7 +107,7 @@ export const createLoadingPromise = (
|
|||
loadPlugin.spritesheet(playerResourceDescriptor.name, playerResourceDescriptor.img, frameConfig);
|
||||
const errorCallback = (file: { src: string }) => {
|
||||
if (file.src !== playerResourceDescriptor.img) return;
|
||||
console.error("failed loading player ressource: ", playerResourceDescriptor);
|
||||
console.error("failed loading player resource: ", playerResourceDescriptor);
|
||||
rej(playerResourceDescriptor);
|
||||
loadPlugin.off("filecomplete-spritesheet-" + playerResourceDescriptor.name, successCallback);
|
||||
loadPlugin.off("loaderror", errorCallback);
|
||||
|
|
|
@ -193,7 +193,7 @@ export class GameScene extends DirtyScene {
|
|||
private popUpElements: Map<number, DOMElement> = new Map<number, Phaser.GameObjects.DOMElement>();
|
||||
private originalMapUrl: string | undefined;
|
||||
private pinchManager: PinchManager | undefined;
|
||||
private mapTransitioning: boolean = false; //used to prevent transitions happenning at the same time.
|
||||
private mapTransitioning: boolean = false; //used to prevent transitions happening at the same time.
|
||||
private emoteManager!: EmoteManager;
|
||||
private preloading: boolean = true;
|
||||
private startPositionCalculator!: StartPositionCalculator;
|
||||
|
@ -435,7 +435,7 @@ export class GameScene extends DirtyScene {
|
|||
this.characterLayers = gameManager.getCharacterLayers();
|
||||
this.companion = gameManager.getCompanion();
|
||||
|
||||
//initalise map
|
||||
//initialise map
|
||||
this.Map = this.add.tilemap(this.MapUrlFile);
|
||||
const mapDirUrl = this.MapUrlFile.substr(0, this.MapUrlFile.lastIndexOf("/"));
|
||||
this.mapFile.tilesets.forEach((tileset: ITiledTileSet) => {
|
||||
|
|
|
@ -45,7 +45,7 @@ export class StartPositionCalculator {
|
|||
/**
|
||||
*
|
||||
* @param selectedLayer this is always the layer that is selected with the hash in the url
|
||||
* @param selectedOrDefaultLayer this can also be the {defaultStartLayerName} if the {selectedLayer} didnt yield any start points
|
||||
* @param selectedOrDefaultLayer this can also be the {defaultStartLayerName} if the {selectedLayer} did not yield any start points
|
||||
*/
|
||||
public initPositionFromLayerName(selectedOrDefaultLayer: string | null, selectedLayer: string | null) {
|
||||
if (!selectedOrDefaultLayer) {
|
||||
|
@ -73,7 +73,7 @@ export class StartPositionCalculator {
|
|||
/**
|
||||
*
|
||||
* @param selectedLayer this is always the layer that is selected with the hash in the url
|
||||
* @param selectedOrDefaultLayer this can also be the default layer if the {selectedLayer} didnt yield any start points
|
||||
* @param selectedOrDefaultLayer this can also be the default layer if the {selectedLayer} did not yield any start points
|
||||
*/
|
||||
private startUser(selectedOrDefaultLayer: ITiledMapTileLayer, selectedLayer: string | null): PositionInterface {
|
||||
const tiles = selectedOrDefaultLayer.data;
|
||||
|
|
|
@ -244,6 +244,7 @@ export class CustomizeScene extends AbstractCharacterScene {
|
|||
update(time: number, delta: number): void {
|
||||
if (this.lazyloadingAttempt) {
|
||||
this.moveLayers();
|
||||
this.doMoveCursorHorizontally(this.moveHorizontally);
|
||||
this.lazyloadingAttempt = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ export enum UserInputEvent {
|
|||
}
|
||||
|
||||
|
||||
//we cannot use a map structure so we have to create a replacment
|
||||
//we cannot use a map structure so we have to create a replacement
|
||||
export class ActiveEventList {
|
||||
private eventMap : Map<UserInputEvent, boolean> = new Map<UserInputEvent, boolean>();
|
||||
|
||||
|
|
|
@ -274,12 +274,12 @@ export const mediaStreamConstraintsStore = derived(
|
|||
currentAudioConstraint = false;
|
||||
}
|
||||
|
||||
// Disable webcam for privacy reasons (the game is not visible and we were talking to noone)
|
||||
// Disable webcam for privacy reasons (the game is not visible and we were talking to no one)
|
||||
if ($privacyShutdownStore === true) {
|
||||
currentVideoConstraint = false;
|
||||
}
|
||||
|
||||
// Disable webcam for energy reasons (the user is not moving and we are talking to noone)
|
||||
// Disable webcam for energy reasons (the user is not moving and we are talking to no one)
|
||||
if ($cameraEnergySavingStore === true) {
|
||||
currentVideoConstraint = false;
|
||||
currentAudioConstraint = false;
|
||||
|
|
|
@ -31,7 +31,7 @@ export class HtmlUtils {
|
|||
return p.innerHTML;
|
||||
}
|
||||
|
||||
public static urlify(text: string): string {
|
||||
public static urlify(text: string, style: string = ""): string {
|
||||
const urlRegex = /(https?:\/\/[^\s]+)/g;
|
||||
text = HtmlUtils.escapeHtml(text);
|
||||
return text.replace(urlRegex, (url: string) => {
|
||||
|
@ -40,10 +40,19 @@ export class HtmlUtils {
|
|||
link.target = "_blank";
|
||||
const text = document.createTextNode(url);
|
||||
link.appendChild(text);
|
||||
link.setAttribute("style", style);
|
||||
return link.outerHTML;
|
||||
});
|
||||
}
|
||||
|
||||
public static isClickedInside(event: MouseEvent, target: HTMLElement): boolean {
|
||||
return !!event.composedPath().find((et) => et === target);
|
||||
}
|
||||
|
||||
public static isClickedOutside(event: MouseEvent, target: HTMLElement): boolean {
|
||||
return !this.isClickedInside(event, target);
|
||||
}
|
||||
|
||||
private static isHtmlElement<T extends HTMLElement>(elem: HTMLElement | null): elem is T {
|
||||
return elem !== null;
|
||||
}
|
||||
|
|
|
@ -295,7 +295,7 @@ export class SimplePeer {
|
|||
// I do understand the method closeConnection is called twice, but I don't understand how they manage to run in parallel.
|
||||
peer.destroy();
|
||||
|
||||
//Comment this peer connexion because if we delete and try to reshare screen, the RTCPeerConnection send renegociate event. This array will be remove when user left circle discussion
|
||||
//Comment this peer connection because if we delete and try to reshare screen, the RTCPeerConnection send renegotiate event. This array will be remove when user left circle discussion
|
||||
/*if(!this.PeerScreenSharingConnectionArray.delete(userId)){
|
||||
throw 'Couln\'t delete peer screen sharing connexion';
|
||||
}*/
|
||||
|
@ -370,14 +370,14 @@ export class SimplePeer {
|
|||
console.error(
|
||||
'Could not find peer whose ID is "' + data.userId + '" in receiveWebrtcScreenSharingSignal'
|
||||
);
|
||||
console.info("Attempt to create new peer connexion");
|
||||
console.info("Attempt to create new peer connection");
|
||||
if (stream) {
|
||||
this.sendLocalScreenSharingStreamToUser(data.userId, stream);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`receiveWebrtcSignal => ${data.userId}`, e);
|
||||
//Comment this peer connexion because if we delete and try to reshare screen, the RTCPeerConnection send renegociate event. This array will be remove when user left circle discussion
|
||||
//Comment this peer connection because if we delete and try to reshare screen, the RTCPeerConnection send renegotiate event. This array will be remove when user left circle discussion
|
||||
//this.PeerScreenSharingConnectionArray.delete(data.userId);
|
||||
this.receiveWebrtcScreenSharingSignal(data);
|
||||
}
|
||||
|
@ -485,7 +485,7 @@ export class SimplePeer {
|
|||
|
||||
if (!PeerConnectionScreenSharing.isReceivingScreenSharingStream()) {
|
||||
PeerConnectionScreenSharing.destroy();
|
||||
//Comment this peer connexion because if we delete and try to reshare screen, the RTCPeerConnection send renegociate event. This array will be remove when user left circle discussion
|
||||
//Comment this peer connection because if we delete and try to reshare screen, the RTCPeerConnection send renegotiate event. This array will be remove when user left circle discussion
|
||||
//this.PeerScreenSharingConnectionArray.delete(userId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,19 +8,19 @@ describe("getRessourceDescriptor()", () => {
|
|||
expect(desc.img).toEqual('url');
|
||||
});
|
||||
|
||||
it(", if given a string as parameter, should search trough hardcoded values", () => {
|
||||
it(", if given a string as parameter, should search through hardcoded values", () => {
|
||||
const desc = getRessourceDescriptor('male1');
|
||||
expect(desc.name).toEqual('male1');
|
||||
expect(desc.img).toEqual("resources/characters/pipoya/Male 01-1.png");
|
||||
});
|
||||
|
||||
it(", if given a string as parameter, should search trough hardcoded values (bis)", () => {
|
||||
it(", if given a string as parameter, should search through hardcoded values (bis)", () => {
|
||||
const desc = getRessourceDescriptor('color_2');
|
||||
expect(desc.name).toEqual('color_2');
|
||||
expect(desc.img).toEqual("resources/customisation/character_color/character_color1.png");
|
||||
});
|
||||
|
||||
it(", if given a descriptor without url as parameter, should search trough hardcoded values", () => {
|
||||
it(", if given a descriptor without url as parameter, should search through hardcoded values", () => {
|
||||
const desc = getRessourceDescriptor({name: 'male1', img: ''});
|
||||
expect(desc.name).toEqual('male1');
|
||||
expect(desc.img).toEqual("resources/characters/pipoya/Male 01-1.png");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue