diff --git a/services/matrix-manadeck-bot/src/bot/matrix.service.ts b/services/matrix-manadeck-bot/src/bot/matrix.service.ts index 7e272a826..9a286e7ac 100644 --- a/services/matrix-manadeck-bot/src/bot/matrix.service.ts +++ b/services/matrix-manadeck-bot/src/bot/matrix.service.ts @@ -4,6 +4,7 @@ import { BaseMatrixService, MatrixBotConfig, MatrixRoomEvent, + UserListMapper, } from '@manacore/matrix-bot-common'; import { ManadeckService, Deck, Card } from '../manadeck/manadeck.service'; import { SessionService } from '@manacore/bot-services'; @@ -12,8 +13,9 @@ import { HELP_MESSAGE } from '../config/configuration'; @Injectable() export class MatrixService extends BaseMatrixService { // Store last shown decks/cards per user for reference by number - private lastDecksList: Map = new Map(); - private lastCardsList: Map = new Map(); + private decksMapper = new UserListMapper(); + private cardsMapper = new UserListMapper(); + private currentDeckId: Map = new Map(); constructor( configService: ConfigService, @@ -206,7 +208,7 @@ export class MatrixService extends BaseMatrixService { } const decks = result.data || []; - this.lastDecksList.set(sender, decks); + this.decksMapper.setList(sender, decks); if (decks.length === 0) { await this.sendHtml( @@ -304,7 +306,7 @@ export class MatrixService extends BaseMatrixService { } // Clear cached list - this.lastDecksList.delete(sender); + this.decksMapper.clearList(sender); await this.sendHtml(roomId, `

Deck ${deck.title} geloescht.

`); } @@ -329,7 +331,8 @@ export class MatrixService extends BaseMatrixService { } const cards = result.data || []; - this.lastCardsList.set(sender, { deckId: deck.id, cards }); + this.cardsMapper.setList(sender, cards); + this.currentDeckId.set(sender, deck.id); if (cards.length === 0) { await this.sendHtml( @@ -358,10 +361,7 @@ export class MatrixService extends BaseMatrixService { cardNumStr: string ) { const token = this.requireAuth(sender); - - // Try to get from cache first - let cachedCards = this.lastCardsList.get(sender); - const deck = this.getDeckByNumber(sender, deckNumStr); + const deck = this.decksMapper.getByNumber(sender, parseInt(deckNumStr, 10)); if (!deck) { await this.sendHtml( @@ -372,26 +372,26 @@ export class MatrixService extends BaseMatrixService { } // Refresh cards if needed - if (!cachedCards || cachedCards.deckId !== deck.id) { + const cachedDeckId = this.currentDeckId.get(sender); + if (!cachedDeckId || cachedDeckId !== deck.id || !this.cardsMapper.hasList(sender)) { const result = await this.manadeckService.getCards(token, deck.id); if (result.error) { await this.sendHtml(roomId, `

Fehler: ${result.error}

`); return; } - cachedCards = { deckId: deck.id, cards: result.data || [] }; - this.lastCardsList.set(sender, cachedCards); + this.cardsMapper.setList(sender, result.data || []); + this.currentDeckId.set(sender, deck.id); } - const cardIndex = parseInt(cardNumStr, 10) - 1; - if (isNaN(cardIndex) || cardIndex < 0 || cardIndex >= cachedCards.cards.length) { + const cardNum = parseInt(cardNumStr, 10); + const card = this.cardsMapper.getByNumber(sender, cardNum); + if (!card) { await this.sendHtml( roomId, `

Ungueltige Kartennummer. Nutze !karten ${deckNumStr}

` ); return; } - - const card = cachedCards.cards[cardIndex]; let html = `

Karte #${cardNumStr}

`; html += `

Typ: ${card.cardType}

`; @@ -618,13 +618,9 @@ export class MatrixService extends BaseMatrixService { // Helper methods private getDeckByNumber(sender: string, numberStr: string): Deck | null { - const decks = this.lastDecksList.get(sender); - if (!decks) return null; - - const index = parseInt(numberStr, 10) - 1; - if (isNaN(index) || index < 0 || index >= decks.length) return null; - - return decks[index]; + const num = parseInt(numberStr, 10); + if (isNaN(num)) return null; + return this.decksMapper.getByNumber(sender, num); } private getCardPreview(card: Card): string { diff --git a/services/matrix-planta-bot/src/bot/matrix.service.ts b/services/matrix-planta-bot/src/bot/matrix.service.ts index 31bc5415c..43fc49a0d 100644 --- a/services/matrix-planta-bot/src/bot/matrix.service.ts +++ b/services/matrix-planta-bot/src/bot/matrix.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; -import { BaseMatrixService, MatrixBotConfig, MatrixRoomEvent } from '@manacore/matrix-bot-common'; +import { BaseMatrixService, MatrixBotConfig, MatrixRoomEvent, UserListMapper } from '@manacore/matrix-bot-common'; import { PlantaService, Plant } from '../planta/planta.service'; import { SessionService } from '@manacore/bot-services'; import { HELP_MESSAGE } from '../config/configuration'; @@ -8,7 +8,7 @@ import { HELP_MESSAGE } from '../config/configuration'; @Injectable() export class MatrixService extends BaseMatrixService { // Store last shown plants per user for reference by number - private lastPlantsList: Map = new Map(); + private plantsMapper = new UserListMapper(); // Field mappings for edit command private readonly fieldMappings: Record = { @@ -196,7 +196,7 @@ export class MatrixService extends BaseMatrixService { } const plants = result.data || []; - this.lastPlantsList.set(sender, plants); + this.plantsMapper.setList(sender, plants); if (plants.length === 0) { await this.sendMessage( @@ -274,7 +274,7 @@ export class MatrixService extends BaseMatrixService { } // Clear cached list - this.lastPlantsList.delete(sender); + this.plantsMapper.clearList(sender); await this.sendMessage( roomId, `

Pflanze ${result.data!.name} hinzugefuegt!

@@ -302,7 +302,7 @@ export class MatrixService extends BaseMatrixService { } // Clear cached list - this.lastPlantsList.delete(sender); + this.plantsMapper.clearList(sender); await this.sendMessage(roomId, `

Pflanze ${plant.name} entfernt.

`); } @@ -448,7 +448,7 @@ export class MatrixService extends BaseMatrixService { html += ''; // Store plants for reference - this.lastPlantsList.set(sender, upcoming.map(u => u.plant)); + this.plantsMapper.setList(sender, upcoming.map(u => u.plant)); await this.sendMessage(roomId, html); } @@ -544,13 +544,9 @@ export class MatrixService extends BaseMatrixService { // Helper methods private getPlantByNumber(sender: string, numberStr: string): Plant | null { - const plants = this.lastPlantsList.get(sender); - if (!plants) return null; - - const index = parseInt(numberStr, 10) - 1; - if (isNaN(index) || index < 0 || index >= plants.length) return null; - - return plants[index]; + const num = parseInt(numberStr, 10); + if (isNaN(num)) return null; + return this.plantsMapper.getByNumber(sender, num); } private getHealthEmoji(status?: string): string { diff --git a/services/matrix-questions-bot/src/bot/matrix.service.ts b/services/matrix-questions-bot/src/bot/matrix.service.ts index c6c28c364..f0fcdb6bd 100644 --- a/services/matrix-questions-bot/src/bot/matrix.service.ts +++ b/services/matrix-questions-bot/src/bot/matrix.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; -import { BaseMatrixService, MatrixBotConfig, MatrixRoomEvent } from '@manacore/matrix-bot-common'; +import { BaseMatrixService, MatrixBotConfig, MatrixRoomEvent, UserListMapper } from '@manacore/matrix-bot-common'; import { QuestionsService, Question, Collection, Answer } from '../questions/questions.service'; import { SessionService } from '@manacore/bot-services'; import { HELP_MESSAGE } from '../config/configuration'; @@ -8,9 +8,9 @@ import { HELP_MESSAGE } from '../config/configuration'; @Injectable() export class MatrixService extends BaseMatrixService { // Store last shown items per user for reference by number - private lastQuestionsList: Map = new Map(); - private lastCollectionsList: Map = new Map(); - private lastAnswersList: Map = new Map(); + private questionsMapper = new UserListMapper(); + private collectionsMapper = new UserListMapper(); + private answersMapper = new UserListMapper(); constructor( configService: ConfigService, @@ -220,7 +220,7 @@ export class MatrixService extends BaseMatrixService { } const questions = result.data || []; - this.lastQuestionsList.set(sender, questions); + this.questionsMapper.setList(sender, questions); if (questions.length === 0) { await this.sendMessage( @@ -292,7 +292,7 @@ export class MatrixService extends BaseMatrixService { return; } - this.lastQuestionsList.delete(sender); + this.questionsMapper.clearList(sender); await this.sendMessage( roomId, `

Frage erstellt: ${result.data!.title}

@@ -316,7 +316,7 @@ export class MatrixService extends BaseMatrixService { return; } - this.lastQuestionsList.delete(sender); + this.questionsMapper.clearList(sender); await this.sendMessage(roomId, `

Frage geloescht: ${question.title}

`); } @@ -496,7 +496,7 @@ export class MatrixService extends BaseMatrixService { } const answers = result.data || []; - this.lastAnswersList.set(sender, answers); + this.answersMapper.setList(sender, answers); if (answers.length === 0) { await this.sendMessage( @@ -532,9 +532,8 @@ export class MatrixService extends BaseMatrixService { private async handleRateAnswer(roomId: string, sender: string, numberStr: string, ratingStr: string) { const token = this.requireAuth(sender); - const answers = this.lastAnswersList.get(sender); - if (!answers || answers.length === 0) { + if (!this.answersMapper.hasList(sender)) { await this.sendMessage(roomId, '

Zeige zuerst eine Antwort mit !antwort [nr]

'); return; } @@ -545,7 +544,12 @@ export class MatrixService extends BaseMatrixService { return; } - const answer = answers[0]; + // Get first answer (most recent) + const answer = this.answersMapper.getByNumber(sender, 1); + if (!answer) { + await this.sendMessage(roomId, '

Keine Antwort gefunden.

'); + return; + } const result = await this.questionsService.rateAnswer(token, answer.id, rating); if (result.error) { @@ -558,14 +562,18 @@ export class MatrixService extends BaseMatrixService { private async handleAcceptAnswer(roomId: string, sender: string, numberStr: string) { const token = this.requireAuth(sender); - const answers = this.lastAnswersList.get(sender); - if (!answers || answers.length === 0) { + if (!this.answersMapper.hasList(sender)) { await this.sendMessage(roomId, '

Zeige zuerst eine Antwort mit !antwort [nr]

'); return; } - const answer = answers[0]; + // Get first answer (most recent) + const answer = this.answersMapper.getByNumber(sender, 1); + if (!answer) { + await this.sendMessage(roomId, '

Keine Antwort gefunden.

'); + return; + } const result = await this.questionsService.acceptAnswer(token, answer.id); if (result.error) { @@ -587,7 +595,7 @@ export class MatrixService extends BaseMatrixService { } const collections = result.data || []; - this.lastCollectionsList.set(sender, collections); + this.collectionsMapper.setList(sender, collections); if (collections.length === 0) { await this.sendMessage( @@ -622,7 +630,7 @@ export class MatrixService extends BaseMatrixService { return; } - this.lastCollectionsList.delete(sender); + this.collectionsMapper.clearList(sender); await this.sendMessage(roomId, `

Sammlung ${result.data!.name} erstellt.

`); } @@ -642,7 +650,7 @@ export class MatrixService extends BaseMatrixService { } const questions = result.data || []; - this.lastQuestionsList.set(sender, questions); + this.questionsMapper.setList(sender, questions); if (questions.length === 0) { await this.sendMessage(roomId, `

Keine Fragen gefunden fuer "${query}"

`); @@ -661,13 +669,9 @@ export class MatrixService extends BaseMatrixService { // Helper methods private getQuestionByNumber(sender: string, numberStr: string): Question | null { - const questions = this.lastQuestionsList.get(sender); - if (!questions) return null; - - const index = parseInt(numberStr, 10) - 1; - if (isNaN(index) || index < 0 || index >= questions.length) return null; - - return questions[index]; + const num = parseInt(numberStr, 10); + if (isNaN(num)) return null; + return this.questionsMapper.getByNumber(sender, num); } private getStatusEmoji(status: string): string { diff --git a/services/matrix-storage-bot/src/bot/matrix.service.ts b/services/matrix-storage-bot/src/bot/matrix.service.ts index 2393e3588..a15132351 100644 --- a/services/matrix-storage-bot/src/bot/matrix.service.ts +++ b/services/matrix-storage-bot/src/bot/matrix.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; -import { BaseMatrixService, MatrixBotConfig, MatrixRoomEvent } from '@manacore/matrix-bot-common'; +import { BaseMatrixService, MatrixBotConfig, MatrixRoomEvent, UserListMapper } from '@manacore/matrix-bot-common'; import { StorageService, StorageFile, Folder, ShareLink, TrashItem } from '../storage/storage.service'; import { SessionService } from '@manacore/bot-services'; import { HELP_MESSAGE } from '../config/configuration'; @@ -8,10 +8,10 @@ import { HELP_MESSAGE } from '../config/configuration'; @Injectable() export class MatrixService extends BaseMatrixService { // Store last shown items per user for reference by number - private lastFilesList: Map = new Map(); - private lastFoldersList: Map = new Map(); - private lastSharesList: Map = new Map(); - private lastTrashList: Map = new Map(); + private filesMapper = new UserListMapper(); + private foldersMapper = new UserListMapper(); + private sharesMapper = new UserListMapper(); + private trashMapper = new UserListMapper(); private currentFolder: Map = new Map(); constructor( @@ -245,7 +245,7 @@ export class MatrixService extends BaseMatrixService { } const files = result.data || []; - this.lastFilesList.set(sender, files); + this.filesMapper.setList(sender, files); if (files.length === 0) { await this.sendMessage(roomId, '

Keine Dateien vorhanden.

'); @@ -331,7 +331,7 @@ export class MatrixService extends BaseMatrixService { return; } - this.lastFilesList.delete(sender); + this.filesMapper.clearList(sender); await this.sendMessage(roomId, `

${file.name} in Papierkorb verschoben.

`); } @@ -413,7 +413,7 @@ export class MatrixService extends BaseMatrixService { } const folders = result.data || []; - this.lastFoldersList.set(sender, folders); + this.foldersMapper.setList(sender, folders); if (folders.length === 0) { await this.sendMessage(roomId, '

Keine Ordner vorhanden.

'); @@ -460,7 +460,7 @@ export class MatrixService extends BaseMatrixService { return; } - this.lastFoldersList.delete(sender); + this.foldersMapper.clearList(sender); await this.sendMessage(roomId, `

Ordner ${result.data!.name} erstellt.

`); } @@ -480,7 +480,7 @@ export class MatrixService extends BaseMatrixService { return; } - this.lastFoldersList.delete(sender); + this.foldersMapper.clearList(sender); await this.sendMessage(roomId, `

Ordner ${folder.name} in Papierkorb verschoben.

`); } @@ -547,7 +547,7 @@ export class MatrixService extends BaseMatrixService { } const shares = result.data || []; - this.lastSharesList.set(sender, shares); + this.sharesMapper.setList(sender, shares); if (shares.length === 0) { await this.sendMessage(roomId, '

Keine Share-Links vorhanden.

'); @@ -568,20 +568,18 @@ export class MatrixService extends BaseMatrixService { private async handleDeleteShare(roomId: string, sender: string, numberStr: string) { const token = this.requireAuth(sender); - const shares = this.lastSharesList.get(sender); - if (!shares) { + if (!this.sharesMapper.hasList(sender)) { await this.sendMessage(roomId, '

Nutze zuerst !links

'); return; } - const index = parseInt(numberStr, 10) - 1; - if (isNaN(index) || index < 0 || index >= shares.length) { + const num = parseInt(numberStr, 10); + const share = isNaN(num) ? null : this.sharesMapper.getByNumber(sender, num); + if (!share) { await this.sendMessage(roomId, '

Ungueltige Nummer.

'); return; } - - const share = shares[index]; const result = await this.storageService.deleteShare(token, share.id); if (result.error) { @@ -589,7 +587,7 @@ export class MatrixService extends BaseMatrixService { return; } - this.lastSharesList.delete(sender); + this.sharesMapper.clearList(sender); await this.sendMessage(roomId, '

Share-Link geloescht.

'); } @@ -609,8 +607,8 @@ export class MatrixService extends BaseMatrixService { } const { files, folders } = result.data!; - this.lastFilesList.set(sender, files); - this.lastFoldersList.set(sender, folders); + this.filesMapper.setList(sender, files); + this.foldersMapper.setList(sender, folders); if (files.length === 0 && folders.length === 0) { await this.sendMessage(roomId, `

Keine Ergebnisse fuer "${query}"

`); @@ -648,8 +646,8 @@ export class MatrixService extends BaseMatrixService { } const { files, folders } = result.data!; - this.lastFilesList.set(sender, files); - this.lastFoldersList.set(sender, folders); + this.filesMapper.setList(sender, files); + this.foldersMapper.setList(sender, folders); if (files.length === 0 && folders.length === 0) { await this.sendMessage(roomId, '

Keine Favoriten vorhanden.

'); @@ -720,7 +718,7 @@ export class MatrixService extends BaseMatrixService { } const items = result.data || []; - this.lastTrashList.set(sender, items); + this.trashMapper.setList(sender, items); if (items.length === 0) { await this.sendMessage(roomId, '

Papierkorb ist leer.

'); @@ -741,20 +739,18 @@ export class MatrixService extends BaseMatrixService { private async handleRestore(roomId: string, sender: string, numberStr: string) { const token = this.requireAuth(sender); - const items = this.lastTrashList.get(sender); - if (!items) { + if (!this.trashMapper.hasList(sender)) { await this.sendMessage(roomId, '

Nutze zuerst !papierkorb

'); return; } - const index = parseInt(numberStr, 10) - 1; - if (isNaN(index) || index < 0 || index >= items.length) { + const num = parseInt(numberStr, 10); + const item = isNaN(num) ? null : this.trashMapper.getByNumber(sender, num); + if (!item) { await this.sendMessage(roomId, '

Ungueltige Nummer.

'); return; } - - const item = items[index]; const result = await this.storageService.restoreFromTrash(token, item.id, item.type); if (result.error) { @@ -762,7 +758,7 @@ export class MatrixService extends BaseMatrixService { return; } - this.lastTrashList.delete(sender); + this.trashMapper.clearList(sender); await this.sendMessage(roomId, `

${item.name} wiederhergestellt.

`); } @@ -775,29 +771,21 @@ export class MatrixService extends BaseMatrixService { return; } - this.lastTrashList.delete(sender); + this.trashMapper.clearList(sender); await this.sendMessage(roomId, '

Papierkorb geleert.

'); } // Helper methods private getFileByNumber(sender: string, numberStr: string): StorageFile | null { - const files = this.lastFilesList.get(sender); - if (!files) return null; - - const index = parseInt(numberStr, 10) - 1; - if (isNaN(index) || index < 0 || index >= files.length) return null; - - return files[index]; + const num = parseInt(numberStr, 10); + if (isNaN(num)) return null; + return this.filesMapper.getByNumber(sender, num); } private getFolderByNumber(sender: string, numberStr: string): Folder | null { - const folders = this.lastFoldersList.get(sender); - if (!folders) return null; - - const index = parseInt(numberStr, 10) - 1; - if (isNaN(index) || index < 0 || index >= folders.length) return null; - - return folders[index]; + const num = parseInt(numberStr, 10); + if (isNaN(num)) return null; + return this.foldersMapper.getByNumber(sender, num); } private formatSize(bytes: number): string {