Merge pull request #1676 from albanbruder/feature-admin-message-queue
Display multiple admin messages
This commit is contained in:
commit
7d796611ae
@ -1,27 +1,22 @@
|
|||||||
import { AdminMessageEventTypes, adminMessagesService } from "../Connexion/AdminMessagesService";
|
import { AdminMessageEventTypes, adminMessagesService } from "../Connexion/AdminMessagesService";
|
||||||
import { textMessageContentStore, textMessageVisibleStore } from "../Stores/TypeMessageStore/TextMessageStore";
|
import { textMessageStore } from "../Stores/TypeMessageStore/TextMessageStore";
|
||||||
import { soundPlayingStore } from "../Stores/SoundPlayingStore";
|
import { soundPlayingStore } from "../Stores/SoundPlayingStore";
|
||||||
import { UPLOADER_URL } from "../Enum/EnvironmentVariable";
|
import { UPLOADER_URL } from "../Enum/EnvironmentVariable";
|
||||||
import { banMessageContentStore, banMessageVisibleStore } from "../Stores/TypeMessageStore/BanMessageStore";
|
import { banMessageStore } from "../Stores/TypeMessageStore/BanMessageStore";
|
||||||
|
|
||||||
class UserMessageManager {
|
class UserMessageManager {
|
||||||
receiveBannedMessageListener!: Function;
|
receiveBannedMessageListener!: Function;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
adminMessagesService.messageStream.subscribe((event) => {
|
adminMessagesService.messageStream.subscribe((event) => {
|
||||||
textMessageVisibleStore.set(false);
|
|
||||||
banMessageVisibleStore.set(false);
|
|
||||||
if (event.type === AdminMessageEventTypes.admin) {
|
if (event.type === AdminMessageEventTypes.admin) {
|
||||||
textMessageContentStore.set(event.text);
|
textMessageStore.addMessage(event.text);
|
||||||
textMessageVisibleStore.set(true);
|
|
||||||
} else if (event.type === AdminMessageEventTypes.audio) {
|
} else if (event.type === AdminMessageEventTypes.audio) {
|
||||||
soundPlayingStore.playSound(UPLOADER_URL + event.text);
|
soundPlayingStore.playSound(UPLOADER_URL + event.text);
|
||||||
} else if (event.type === AdminMessageEventTypes.ban) {
|
} else if (event.type === AdminMessageEventTypes.ban) {
|
||||||
banMessageContentStore.set(event.text);
|
banMessageStore.addMessage(event.text);
|
||||||
banMessageVisibleStore.set(true);
|
|
||||||
} else if (event.type === AdminMessageEventTypes.banned) {
|
} else if (event.type === AdminMessageEventTypes.banned) {
|
||||||
banMessageContentStore.set(event.text);
|
banMessageStore.addMessage(event.text);
|
||||||
banMessageVisibleStore.set(true);
|
|
||||||
this.receiveBannedMessageListener();
|
this.receiveBannedMessageListener();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -30,10 +30,10 @@
|
|||||||
import EmoteMenu from "./EmoteMenu/EmoteMenu.svelte";
|
import EmoteMenu from "./EmoteMenu/EmoteMenu.svelte";
|
||||||
import VideoOverlay from "./Video/VideoOverlay.svelte";
|
import VideoOverlay from "./Video/VideoOverlay.svelte";
|
||||||
import { gameOverlayVisibilityStore } from "../Stores/GameOverlayStoreVisibility";
|
import { gameOverlayVisibilityStore } from "../Stores/GameOverlayStoreVisibility";
|
||||||
import AdminMessage from "./TypeMessage/BanMessage.svelte";
|
import BanMessageContainer from "./TypeMessage/BanMessageContainer.svelte";
|
||||||
import TextMessage from "./TypeMessage/TextMessage.svelte";
|
import TextMessageContainer from "./TypeMessage/TextMessageContainer.svelte";
|
||||||
import { banMessageVisibleStore } from "../Stores/TypeMessageStore/BanMessageStore";
|
import { banMessageStore } from "../Stores/TypeMessageStore/BanMessageStore";
|
||||||
import { textMessageVisibleStore } from "../Stores/TypeMessageStore/TextMessageStore";
|
import { textMessageStore } from "../Stores/TypeMessageStore/TextMessageStore";
|
||||||
import { warningContainerStore } from "../Stores/MenuStore";
|
import { warningContainerStore } from "../Stores/MenuStore";
|
||||||
import WarningContainer from "./WarningContainer/WarningContainer.svelte";
|
import WarningContainer from "./WarningContainer/WarningContainer.svelte";
|
||||||
import { layoutManagerVisibilityStore } from "../Stores/LayoutManagerStore";
|
import { layoutManagerVisibilityStore } from "../Stores/LayoutManagerStore";
|
||||||
@ -72,14 +72,13 @@
|
|||||||
<EnableCameraScene {game} />
|
<EnableCameraScene {game} />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if $banMessageVisibleStore}
|
{#if $banMessageStore.length > 0}
|
||||||
<div>
|
<div>
|
||||||
<AdminMessage />
|
<BanMessageContainer />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{:else if $textMessageStore.length > 0}
|
||||||
{#if $textMessageVisibleStore}
|
|
||||||
<div>
|
<div>
|
||||||
<TextMessage />
|
<TextMessageContainer />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if $soundPlayingStore}
|
{#if $soundPlayingStore}
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { fly } from "svelte/transition";
|
import { fly, fade } from "svelte/transition";
|
||||||
import { banMessageVisibleStore, banMessageContentStore } from "../../Stores/TypeMessageStore/BanMessageStore";
|
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
|
import type { Message } from "../../Stores/TypeMessageStore/MessageStore";
|
||||||
|
import { banMessageStore } from "../../Stores/TypeMessageStore/BanMessageStore";
|
||||||
|
|
||||||
|
export let message: Message;
|
||||||
|
|
||||||
let text: string;
|
|
||||||
$: {
|
|
||||||
text = $banMessageContentStore;
|
|
||||||
}
|
|
||||||
const NAME_BUTTON = "Ok";
|
const NAME_BUTTON = "Ok";
|
||||||
let nbSeconds = 10;
|
let nbSeconds = 10;
|
||||||
let nameButton = "";
|
let nameButton = "";
|
||||||
@ -28,17 +27,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function closeBanMessage() {
|
function closeBanMessage() {
|
||||||
banMessageVisibleStore.set(false);
|
banMessageStore.clearMessageById(message.id);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="main-ban-message nes-container is-rounded" transition:fly={{ y: -1000, duration: 500 }}>
|
<div
|
||||||
|
class="main-ban-message nes-container is-rounded"
|
||||||
|
in:fly={{ y: -1000, duration: 500, delay: 250 }}
|
||||||
|
out:fade={{ duration: 200 }}
|
||||||
|
>
|
||||||
<h2 class="title-ban-message">
|
<h2 class="title-ban-message">
|
||||||
<img src="resources/logos/report.svg" alt="***" /> Important message
|
<img src="resources/logos/report.svg" alt="***" /> Important message
|
||||||
<img src="resources/logos/report.svg" alt="***" />
|
<img src="resources/logos/report.svg" alt="***" />
|
||||||
</h2>
|
</h2>
|
||||||
<div class="content-ban-message">
|
<div class="content-ban-message">
|
||||||
<p>{text}</p>
|
<p>{message.text}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer-ban-message">
|
<div class="footer-ban-message">
|
||||||
<button
|
<button
|
||||||
|
13
front/src/Components/TypeMessage/BanMessageContainer.svelte
Normal file
13
front/src/Components/TypeMessage/BanMessageContainer.svelte
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { flip } from "svelte/animate";
|
||||||
|
import { banMessageStore } from "../../Stores/TypeMessageStore/BanMessageStore";
|
||||||
|
import BanMessage from "./BanMessage.svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="main-ban-message-container">
|
||||||
|
{#each $banMessageStore.slice(0, 1) as message (message.id)}
|
||||||
|
<div animate:flip={{ duration: 250 }}>
|
||||||
|
<BanMessage {message} />
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
@ -1,17 +1,17 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { fly } from "svelte/transition";
|
import { fly, fade } from "svelte/transition";
|
||||||
import { textMessageContentStore, textMessageVisibleStore } from "../../Stores/TypeMessageStore/TextMessageStore";
|
|
||||||
import { QuillDeltaToHtmlConverter } from "quill-delta-to-html";
|
import { QuillDeltaToHtmlConverter } from "quill-delta-to-html";
|
||||||
|
import type { Message } from "../../Stores/TypeMessageStore/MessageStore";
|
||||||
|
import { textMessageStore } from "../../Stores/TypeMessageStore/TextMessageStore";
|
||||||
|
|
||||||
let converter: QuillDeltaToHtmlConverter;
|
export let message: Message;
|
||||||
$: {
|
|
||||||
const content = JSON.parse($textMessageContentStore);
|
const content = JSON.parse(message.text);
|
||||||
converter = new QuillDeltaToHtmlConverter(content.ops, { inlineStyles: true });
|
const converter = new QuillDeltaToHtmlConverter(content.ops, { inlineStyles: true });
|
||||||
}
|
|
||||||
const NAME_BUTTON = "Ok";
|
const NAME_BUTTON = "Ok";
|
||||||
|
|
||||||
function closeTextMessage() {
|
function closeTextMessage() {
|
||||||
textMessageVisibleStore.set(false);
|
textMessageStore.clearMessageById(message.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onKeyDown(e: KeyboardEvent) {
|
function onKeyDown(e: KeyboardEvent) {
|
||||||
@ -23,7 +23,11 @@
|
|||||||
|
|
||||||
<svelte:window on:keydown={onKeyDown} />
|
<svelte:window on:keydown={onKeyDown} />
|
||||||
|
|
||||||
<div class="main-text-message nes-container is-rounded" transition:fly={{ x: -1000, duration: 500 }}>
|
<div
|
||||||
|
class="main-text-message nes-container is-rounded"
|
||||||
|
in:fly={{ x: -1000, duration: 500, delay: 250 }}
|
||||||
|
out:fade={{ duration: 250 }}
|
||||||
|
>
|
||||||
<div class="content-text-message">
|
<div class="content-text-message">
|
||||||
{@html converter.convert()}
|
{@html converter.convert()}
|
||||||
</div>
|
</div>
|
||||||
@ -43,6 +47,8 @@
|
|||||||
width: 80vw;
|
width: 80vw;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
margin-top: 0;
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
|
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
|
21
front/src/Components/TypeMessage/TextMessageContainer.svelte
Normal file
21
front/src/Components/TypeMessage/TextMessageContainer.svelte
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { flip } from "svelte/animate";
|
||||||
|
import TextMessage from "./TextMessage.svelte";
|
||||||
|
import { textMessageStore } from "../../Stores/TypeMessageStore/TextMessageStore";
|
||||||
|
|
||||||
|
const MAX_MESSAGES = 3;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="main-text-message-container">
|
||||||
|
{#each $textMessageStore.slice(0, MAX_MESSAGES) as message (message.id)}
|
||||||
|
<div animate:flip={{ duration: 250 }}>
|
||||||
|
<TextMessage {message} />
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
div.main-text-message-container {
|
||||||
|
padding-top: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,5 +1,3 @@
|
|||||||
import { writable } from "svelte/store";
|
import { createMessageStore } from "./MessageStore";
|
||||||
|
|
||||||
export const banMessageVisibleStore = writable(false);
|
export const banMessageStore = createMessageStore();
|
||||||
|
|
||||||
export const banMessageContentStore = writable("");
|
|
||||||
|
29
front/src/Stores/TypeMessageStore/MessageStore.ts
Normal file
29
front/src/Stores/TypeMessageStore/MessageStore.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { writable } from "svelte/store";
|
||||||
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
|
||||||
|
export interface Message {
|
||||||
|
id: string;
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A store that contains a list of messages to be displayed.
|
||||||
|
*/
|
||||||
|
export function createMessageStore() {
|
||||||
|
const { subscribe, update } = writable<Message[]>([]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
subscribe,
|
||||||
|
addMessage: (text: string): void => {
|
||||||
|
update((messages: Message[]) => {
|
||||||
|
return [...messages, { id: uuidv4(), text }];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
clearMessageById: (id: string): void => {
|
||||||
|
update((messages: Message[]) => {
|
||||||
|
messages = messages.filter((message) => message.id !== id);
|
||||||
|
return messages;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
@ -1,5 +1,3 @@
|
|||||||
import { writable } from "svelte/store";
|
import { createMessageStore } from "./MessageStore";
|
||||||
|
|
||||||
export const textMessageVisibleStore = writable(false);
|
export const textMessageStore = createMessageStore();
|
||||||
|
|
||||||
export const textMessageContentStore = writable("");
|
|
||||||
|
Loading…
Reference in New Issue
Block a user