diff --git a/src/lib/Chat.svelte b/src/lib/Chat.svelte index 99553b9..8c1297a 100644 --- a/src/lib/Chat.svelte +++ b/src/lib/Chat.svelte @@ -2,13 +2,36 @@ import { apclient } from "./stores/apclient.svelte"; import { get } from "svelte/store"; import Window from "./Window.svelte"; + import { toast_queue } from "./stores/toast"; let { show, onClose } = $props(); let msgs = $state([]); let sendContent = $state(""); - get(apclient).messages.on("message", (msg, _) => { + get(apclient).messages.on("connected", (msg, player) => { + toast_queue.update((queue) => { + queue.push({ + title: `${player.alias} joined.`, + description: `Team #${player.team + 1} - ${player.game}`, + image: "/sprites/elements/void.png", + }); + return queue; + }); + }); + + get(apclient).messages.on("disconnected", (msg, player) => { + toast_queue.update((queue) => { + queue.push({ + title: `${player.alias} left.`, + description: `Team #${player.team + 1} - ${player.game}`, + image: "/sprites/elements/void.png", + }); + return queue; + }); + }); + + get(apclient).messages.on("message", (msg, nodes) => { msgs.push(msg); }); diff --git a/src/lib/stores/apclient.svelte.js b/src/lib/stores/apclient.svelte.js index 1028a4b..8c254a3 100644 --- a/src/lib/stores/apclient.svelte.js +++ b/src/lib/stores/apclient.svelte.js @@ -7,7 +7,7 @@ import { draw } from "svelte/transition"; import { INTERMEDIATE_AMOUNT, LOCATION_AMOUNT, NON_ELEMENT_ITEMS } from "../../consts"; import { get_name, init_naming } from "./names.js"; import { ElementKind } from "../graph.js"; -import { sendReceivedToasts } from "./toast"; +import { sendElementToasts, sendUpgradeToasts } from "./toast"; /** * @import { Graph, ElementID } from "../graph.js" @@ -306,29 +306,48 @@ function extendReceivedHints(hint) { * @param {Item[]} items */ function extendReceivedElements(items) { + const game_id = get(apclient).room.seedName + "_" + get(apclient).name; + + const slotDataMap = JSON.parse(localStorage.getItem("ap.slotData")) ?? {}; + if (!slotDataMap.hasOwnProperty(game_id)) { + slotDataMap[game_id] = { receivedItems: [], upgrades, date: new Date() }; + + let entries = Object.entries(slotDataMap); + if (entries.length > 100) { + let [oldest, _] = entries + .map(([k, v]) => [k, v.date]) + .reduce(([ka, da], [kc, dc]) => (da > dc ? [kc, dc] : [ka, da])); + + delete slotDataMap[oldest]; + } + } + /** @type string[] */ + const localReceived = slotDataMap[game_id].receivedItems; + + const newLocalReceived = [...localReceived]; for (const item of items) { // it isn't an element, but an upgrade or todo instead if (item.id < NON_ELEMENT_ITEMS) { - if (item.name == "TODO") { - // do nothing - continue; - } if (item.name == "Progressive Filter") { upgrades.progressive_filter += 1; } if (item.name == "Progressive Item Limit") { upgrades.field_size += 1; } - continue; } + if (!newLocalReceived.includes(item.name)) { + newLocalReceived.push(item.name); + } let elem_id = parse_element(item.name); - const loc = elem_id.kind === ElementKind.INTERMEDIATE || item.locationGame === "Archipelago" - ? get_name() - : item.locationName; + const loc = + elem_id.kind === ElementKind.INTERMEDIATE || item.locationGame === "Archipelago" + ? get_name() + : item.locationName; let icon_name = iconForItem(item.game, loc); receivedElements.add(item.name); + if (elementData.has(item.name)) { continue; } @@ -343,7 +362,16 @@ function extendReceivedElements(items) { game: item.sender.game, }); } - sendReceivedToasts(items); + const oldUpgrades = slotDataMap[game_id].upgrades; + slotDataMap[game_id].upgrades = upgrades; + slotDataMap[game_id].receivedItems = newLocalReceived; + localStorage.setItem("ap.slotData", JSON.stringify(slotDataMap)); + + const newItems = items.filter( + (item) => item.id >= NON_ELEMENT_ITEMS && !localReceived.includes(item.name), + ); + sendElementToasts(newItems); + sendUpgradeToasts(oldUpgrades, upgrades); } /** diff --git a/src/lib/stores/toast.js b/src/lib/stores/toast.js index da282fe..8126743 100644 --- a/src/lib/stores/toast.js +++ b/src/lib/stores/toast.js @@ -19,26 +19,26 @@ const initialized = writable(false); /** * @param {Item[]} items */ -export function sendReceivedToasts(items) { - console.log(items); - let elements = items.filter((item) => { - return item.id >= NON_ELEMENT_ITEMS; - }); - - let upgrades = items.filter((item) => { - return item.id < NON_ELEMENT_ITEMS; - }); - - toast_queue.update((queue) => { - queue.push(elementsReceivedMessage(elements)); - return queue; - }); +export function sendElementToasts(items) { + if (items.length > 0) { + toast_queue.update((queue) => { + queue.push(elementsReceivedMessage(items)); + return queue; + }); + } +} +/** + * @param {*} oldUpgrades + * @param {*} newUpgrades + */ +export function sendUpgradeToasts(oldUpgrades, newUpgrades) { toast_queue.update((queue) => { - for (const upgrade of upgrades) { - queue.push(upgradeReceivedMessage(upgrade)); + for (const key in oldUpgrades) { + let count = newUpgrades[key] - oldUpgrades[key]; + if (count == 0) continue; + queue.push(upgradeReceivedMessage(key, count)); } - return queue; }); } @@ -48,8 +48,7 @@ export function sendReceivedToasts(items) { @returns {{title: string, description: string, image: string}} */ function elementsReceivedMessage(elements) { - if (elements.length == 0) return; - const first_item_data = getElementData().get(elements[0].name) + const first_item_data = getElementData().get(elements[0].name); let image = first_item_data.icon; let first_item = first_item_data.location; let others_suffix = elements.length > 1 ? ` + ${elements.length - 1} more` : ""; @@ -62,16 +61,19 @@ function elementsReceivedMessage(elements) { }; } +const upgradeKeyToItem = { + field_size: "Progressive Item Limit", + progressive_filter: "Progressive Filter", +}; /** - @param {Item} upgrade + @param {string} upgrade + @param {number} count @returns {{title: string, description: string, image: string}} */ -function upgradeReceivedMessage(upgrade) { - let image = iconForItem(upgrade.game, upgrade.name); - +function upgradeReceivedMessage(upgrade, count) { return { title: "Upgrade received!", - description: upgrade.name, - image: "/sprites/elements/" + image + ".png", + description: `${upgradeKeyToItem[upgrade]} (x${count})`, + image: "/sprites/elements/upgrade.png", }; }