Merge branch 'develop' of github.com:thecodingmachine/workadventure

This commit is contained in:
_Bastler
2021-12-07 08:38:21 +01:00
80 changed files with 3438 additions and 1792 deletions
+62 -59
View File
@@ -1,23 +1,23 @@
<script lang="ts">
import { fly } from 'svelte/transition';
import { fly } from "svelte/transition";
import { chatMessagesStore, chatVisibilityStore } from "../../Stores/ChatStore";
import ChatMessageForm from './ChatMessageForm.svelte';
import ChatElement from './ChatElement.svelte';
import {afterUpdate, beforeUpdate, onMount} from "svelte";
import {HtmlUtils} from "../../WebRtc/HtmlUtils";
import ChatMessageForm from "./ChatMessageForm.svelte";
import ChatElement from "./ChatElement.svelte";
import { afterUpdate, beforeUpdate, onMount } from "svelte";
import { HtmlUtils } from "../../WebRtc/HtmlUtils";
let listDom: HTMLElement;
let chatWindowElement: HTMLElement;
let handleFormBlur: { blur():void };
let handleFormBlur: { blur(): void };
let autoscroll: boolean;
beforeUpdate(() => {
autoscroll = listDom && (listDom.offsetHeight + listDom.scrollTop) > (listDom.scrollHeight - 20);
autoscroll = listDom && listDom.offsetHeight + listDom.scrollTop > listDom.scrollHeight - 20;
});
onMount(() => {
listDom.scrollTo(0, listDom.scrollHeight);
})
});
afterUpdate(() => {
if (autoscroll) listDom.scrollTo(0, listDom.scrollHeight);
@@ -32,78 +32,81 @@
function closeChat() {
chatVisibilityStore.set(false);
}
function onKeyDown(e:KeyboardEvent) {
if (e.key === 'Escape') {
function onKeyDown(e: KeyboardEvent) {
if (e.key === "Escape") {
closeChat();
}
}
</script>
<svelte:window on:keydown={onKeyDown} on:click={onClick}/>
<svelte:window on:keydown={onKeyDown} on:click={onClick} />
<aside class="chatWindow nes-container is-rounded is-dark" transition:fly="{{ x: -1000, duration: 500 }}" bind:this={chatWindowElement}>
<aside class="chatWindow nes-container is-rounded is-dark" transition:fly={{ x: -1000, duration: 500 }}
bind:this={chatWindowElement}>
<p class="close-icon" on:click={closeChat}>&times</p>
<section class="messagesList" bind:this={listDom}>
<ul>
<li><p class="system-text">Here is your chat history: </p></li>
{#each $chatMessagesStore as message, i}
<li><ChatElement message={message} line={i}></ChatElement></li>
{/each}
<li><p class="system-text">Here is your chat history:</p></li>
{#each $chatMessagesStore as message, i}
<li><ChatElement {message} line={i} /></li>
{/each}
</ul>
</section>
<section class="messageForm">
<ChatMessageForm bind:handleForm={handleFormBlur}></ChatMessageForm>
<ChatMessageForm bind:handleForm={handleFormBlur} />
</section>
</aside>
<style lang="scss">
p.close-icon {
position: absolute;
padding: 4px;
right: 12px;
font-size: 30px;
line-height: 25px;
cursor: pointer;
position: absolute;
padding: 4px;
right: 12px;
font-size: 30px;
line-height: 25px;
cursor: pointer;
}
p.system-text {
border-radius: 8px;
margin-bottom: 10px;
padding:6px;
overflow-wrap: break-word;
max-width: 100%;
display: inline-block;
border-radius: 8px;
margin-bottom: 10px;
padding: 6px;
overflow-wrap: break-word;
max-width: 100%;
display: inline-block;
}
aside.chatWindow {
z-index:100;
pointer-events: auto;
position: absolute;
top: 0;
left: 0;
height: 100vh;
width:30vw;
min-width: 350px;
color: whitesmoke;
display: flex;
flex-direction: column;
margin: 0;
padding: 10px;
.messagesList {
margin-top: 35px;
overflow-y: auto;
flex: auto;
z-index: 100;
pointer-events: auto;
position: absolute;
top: 0;
left: 0;
height: 100vh;
width: 30vw;
min-width: 350px;
color: whitesmoke;
display: flex;
flex-direction: column;
padding: 10px;
margin: 0;
ul {
list-style-type: none;
padding-left: 0;
border-bottom-right-radius: 16px;
border-top-right-radius: 16px;
.messagesList {
margin-top: 35px;
overflow-y: auto;
flex: auto;
ul {
list-style-type: none;
padding-left: 0;
}
}
.messageForm {
flex: 0 70px;
padding-top: 15px;
}
}
.messageForm {
flex: 0 70px;
padding-top: 15px;
}
}
</style>
</style>
+50 -38
View File
@@ -1,47 +1,55 @@
<script lang="ts">
import {ChatMessageTypes} from "../../Stores/ChatStore";
import type {ChatMessage} from "../../Stores/ChatStore";
import {HtmlUtils} from "../../WebRtc/HtmlUtils";
import ChatPlayerName from './ChatPlayerName.svelte';
import type {PlayerInterface} from "../../Phaser/Game/PlayerInterface";
import { ChatMessageTypes } from "../../Stores/ChatStore";
import type { ChatMessage } from "../../Stores/ChatStore";
import { HtmlUtils } from "../../WebRtc/HtmlUtils";
import ChatPlayerName from "./ChatPlayerName.svelte";
import type { PlayerInterface } from "../../Phaser/Game/PlayerInterface";
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, chatStyleLink);
}
function renderDate(date: Date) {
return date.toLocaleTimeString(navigator.language, {
hour: '2-digit',
minute:'2-digit'
hour: "2-digit",
minute: "2-digit",
});
}
function isLastIteration(index: number) {
return targets.length -1 === index;
return targets.length - 1 === index;
}
</script>
<div class="chatElement">
<div class="messagePart">
{#if message.type === ChatMessageTypes.userIncoming}
&gt;&gt; {#each targets as target, index}<ChatPlayerName player={target} line={line}></ChatPlayerName>{#if !isLastIteration(index)}, {/if}{/each} entered <span class="date">({renderDate(message.date)})</span>
&gt;&gt; {#each targets as target, index}<ChatPlayerName
player={target}
{line}
/>{#if !isLastIteration(index)}, {/if}{/each} entered
<span class="date">({renderDate(message.date)})</span>
{:else if message.type === ChatMessageTypes.userOutcoming}
&lt;&lt; {#each targets as target, index}<ChatPlayerName player={target} line={line}></ChatPlayerName>{#if !isLastIteration(index)}, {/if}{/each} left <span class="date">({renderDate(message.date)})</span>
&lt;&lt; {#each targets as target, index}<ChatPlayerName
player={target}
{line}
/>{#if !isLastIteration(index)}, {/if}{/each} left
<span class="date">({renderDate(message.date)})</span>
{:else if message.type === ChatMessageTypes.me}
<h4>Me: <span class="date">({renderDate(message.date)})</span></h4>
{#each texts as text}
<div><p class="my-text nes-balloon from-left is-dark">{@html urlifyText(text)}</p></div>
<div><p class="my-text">{@html urlifyText(text)}</p></div>
{/each}
{:else}
<h4><ChatPlayerName player={author} line={line}></ChatPlayerName>: <span class="date">({renderDate(message.date)})</span></h4>
<h4><ChatPlayerName player={author} {line} />: <span class="date">({renderDate(message.date)})</span></h4>
{#each texts as text}
<div><p class="other-text nes-balloon from-right is-dark">{@html urlifyText(text)}</p></div>
<div><p class="other-text">{@html urlifyText(text)}</p></div>
{/each}
{/if}
</div>
@@ -49,29 +57,33 @@
<style lang="scss">
div.chatElement {
display: flex;
margin-bottom: 20px;
.messagePart {
flex-grow:1;
max-width: 100%;
display: flex;
margin-bottom: 20px;
span.date {
font-size: 80%;
color: gray;
.messagePart {
flex-grow: 1;
max-width: 100%;
span.date {
font-size: 80%;
color: gray;
}
div > p {
border-radius: 8px;
margin-bottom: 10px;
padding: 6px;
overflow-wrap: break-word;
max-width: 100%;
display: inline-block;
&.other-text {
background: gray;
}
&.other-text {
float: right;
}
}
}
div > p {
overflow-wrap: break-word;
max-width: 100%;
display: inline-block;
min-width: 75px;
padding: 5px;
&.other-text {
float: right;
}
}
}
}
</style>
</style>
@@ -1,14 +1,14 @@
<script lang="ts">
import {chatMessagesStore, chatInputFocusStore} from "../../Stores/ChatStore";
import { chatMessagesStore, chatInputFocusStore } from "../../Stores/ChatStore";
export const handleForm = {
blur() {
inputElement.blur();
}
}
},
};
let inputElement: HTMLElement;
let newMessageText = '';
let newMessageText = "";
function onFocus() {
chatInputFocusStore.set(true);
}
@@ -19,14 +19,14 @@
function saveMessage() {
if (!newMessageText) return;
chatMessagesStore.addPersonnalMessage(newMessageText);
newMessageText = '';
newMessageText = "";
}
</script>
<form on:submit|preventDefault={saveMessage}>
<input class="nes-input is-dark" type="text" bind:value={newMessageText} placeholder="Enter your message..." on:focus={onFocus} on:blur={onBlur} bind:this={inputElement}>
<button class="nes-btn" type="submit">
<img src="/static/images/send.png" alt="Send" width="20">
<img src="/static/images/send.png" alt="Send" width="20" />
</button>
</form>
@@ -36,4 +36,4 @@
padding-left: 4px;
padding-right: 4px;
}
</style>
</style>
+20 -22
View File
@@ -1,8 +1,8 @@
<script lang="ts">
import type {PlayerInterface} from "../../Phaser/Game/PlayerInterface";
import {chatSubMenuVisibilityStore} from "../../Stores/ChatStore";
import {onDestroy, onMount} from "svelte";
import type {Unsubscriber} from "svelte/store";
import type { PlayerInterface } from "../../Phaser/Game/PlayerInterface";
import { chatSubMenuVisibilityStore } from "../../Stores/ChatStore";
import { onDestroy, onMount } from "svelte";
import type { Unsubscriber } from "svelte/store";
import ChatSubMenu from "./ChatSubMenu.svelte";
export let player: PlayerInterface;
@@ -17,35 +17,33 @@
onMount(() => {
chatSubMenuVisivilytUnsubcribe = chatSubMenuVisibilityStore.subscribe((newValue) => {
isSubMenuOpen = (newValue === player.name + line);
})
})
isSubMenuOpen = newValue === player.name + line;
});
});
onDestroy(() => {
chatSubMenuVisivilytUnsubcribe();
})
});
</script>
<span class="subMenu">
<span class="chatPlayerName" style="color: {player.color || 'white'}" on:click={openSubMenu}>
{player.name}
{player.name}
</span>
{#if isSubMenuOpen}
<ChatSubMenu player={player}/>
<ChatSubMenu {player} />
{/if}
</span>
<style lang="scss">
span.subMenu {
display: inline-block;
}
span.chatPlayerName {
margin-left: 3px;
}
.chatPlayerName:hover {
text-decoration: underline;
cursor: pointer;
span.subMenu {
display: inline-block;
}
</style>
span.chatPlayerName {
margin-left: 3px;
}
.chatPlayerName:hover {
text-decoration: underline;
cursor: pointer;
}
</style>
+12 -14
View File
@@ -1,10 +1,9 @@
<script lang="ts">
import type {PlayerInterface} from "../../Phaser/Game/PlayerInterface";
import {requestVisitCardsStore} from "../../Stores/GameStore";
import type { PlayerInterface } from "../../Phaser/Game/PlayerInterface";
import { requestVisitCardsStore } from "../../Stores/GameStore";
export let player: PlayerInterface;
function openVisitCard() {
if (player.visitCardUrl) {
requestVisitCardsStore.set(player.visitCardUrl);
@@ -17,17 +16,16 @@
<li><button class="text-btn" disabled>Add friend</button></li>
</ul>
<style lang="scss">
ul.selectMenu {
background-color: whitesmoke;
position: absolute;
padding: 5px;
border-radius: 4px;
list-style-type: none;
ul.selectMenu {
background-color: whitesmoke;
position: absolute;
padding: 5px;
border-radius: 4px;
list-style-type: none;
li {
text-align: center;
li {
text-align: center;
}
}
}
</style>
</style>