// (C) Copyright 2015 Moodle Pty Ltd. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import { Injectable } from '@angular/core'; import { makeSingleton, Translate } from '@singletons'; import * as moment from 'moment'; import { AddonModChatMessage, AddonModChatSessionMessage } from './chat'; const patternTo = new RegExp(/^To\s([^:]+):(.*)/); /** * Helper service that provides some features for chat. */ @Injectable({ providedIn: 'root' }) export class AddonModChatHelperProvider { /** * Give some format info about messages. * * @param currentUserId User Id. * @param message Message. * @param prevMessage Previous message (if any). * @return Message with additional info. */ formatMessage( currentUserId: number, message: AddonModChatMessage, prevMessage?: AddonModChatFormattedMessage, ): AddonModChatFormattedMessage; formatMessage( currentUserId: number, message: AddonModChatSessionMessage, prevMessage?: AddonModChatFormattedSessionMessage, ): AddonModChatFormattedSessionMessage; formatMessage( currentUserId: number, message: AddonModChatMessage | AddonModChatSessionMessage, prevMessage?: AddonModChatAnyFormattedMessage, ): AddonModChatAnyFormattedMessage { const formattedMessage: AddonModChatAnyFormattedMessage = message; formattedMessage.message = formattedMessage.message.trim(); formattedMessage.showDate = this.showDate(message, prevMessage); formattedMessage.beep = (message.message.substr(0, 5) == 'beep ' && message.message.substr(5).trim()) || undefined; formattedMessage.special = !!formattedMessage.beep || ( message).issystem || ( message).system; if (formattedMessage.message.substr(0, 4) == '/me ') { formattedMessage.special = true; formattedMessage.message = formattedMessage.message.substr(4).trim(); } if (!formattedMessage.special && formattedMessage.message.match(patternTo)) { const matches = formattedMessage.message.match(patternTo); formattedMessage.message = '' + Translate.instant('addon.mod_chat.saidto') + ' ' + matches![1] + ': ' + matches![2]; } formattedMessage.showUserData = this.showUserData(currentUserId, message, prevMessage); if (prevMessage) { prevMessage.showTail = this.showTail(prevMessage, message); } return formattedMessage; } /** * Check if the user info should be displayed for the current message. * User data is only displayed if the previous message was from another user. * * @param message Current message where to show the user info. * @param prevMessage Previous message. * @return Whether user data should be shown. */ protected showUserData( currentUserId: number, message: AddonModChatAnyFormattedMessage, prevMessage?: AddonModChatAnyFormattedMessage, ): boolean { return message.userid != currentUserId && (!prevMessage || prevMessage.userid != message.userid || !!message.showDate || !!prevMessage.special); } /** * Check if a css tail should be shown. * * @param message Current message where to show the user info. * @param nextMessage Next message. * @return Whether user data should be shown. */ protected showTail(message: AddonModChatAnyFormattedMessage, nextMessage?: AddonModChatAnyFormattedMessage): boolean { return !nextMessage || nextMessage.userid != message.userid || !!nextMessage.showDate || !!nextMessage.special; } /** * Check if the date should be displayed between messages (when the day changes at midnight for example). * * @param message New message object. * @param prevMessage Previous message object. * @return True if messages are from diferent days, false othetwise. */ protected showDate(message: AddonModChatAnyFormattedMessage, prevMessage?: AddonModChatAnyFormattedMessage): boolean { if (!prevMessage) { return true; } // Check if day has changed. return !moment(message.timestamp * 1000).isSame(prevMessage.timestamp * 1000, 'day'); } } export const AddonModChatHelper = makeSingleton(AddonModChatHelperProvider); /** * Special info for view usage. */ type AddonModChatInfoForView = { showDate?: boolean; // If date should be displayed before the message. beep?: string; // User id of the beeped user or 'all'. special?: boolean; // True if is an special message (system, beep or command). showUserData?: boolean; // If user data should be displayed. showTail?: boolean; // If tail should be displayed (decoration). beepWho?: string; // Fullname of the beeped user. }; /** * Message with data for view usage. */ export type AddonModChatFormattedMessage = AddonModChatMessage & AddonModChatInfoForView; /** * Session message with data for view usage. */ export type AddonModChatFormattedSessionMessage = AddonModChatSessionMessage & AddonModChatInfoForView; /** * Any possivle formatted message. */ export type AddonModChatAnyFormattedMessage = AddonModChatFormattedMessage | AddonModChatFormattedSessionMessage;