diff --git a/src/components/chat/bubbles.ts b/src/components/chat/bubbles.ts index b851e19e..47559b04 100644 --- a/src/components/chat/bubbles.ts +++ b/src/components/chat/bubbles.ts @@ -1820,7 +1820,11 @@ export default class ChatBubbles { bubble.className = 'bubble service'; - bubbleContainer.innerHTML = `
${message.rReply}
`; + bubbleContainer.innerHTML = ''; + const s = document.createElement('div'); + s.classList.add('service-msg'); + s.append(this.appMessagesManager.wrapMessageActionTextNew(message)); + bubbleContainer.append(s); if(updatePosition) { this.renderMessagesQueue(message, bubble, reverse, loadPromises); diff --git a/src/lang.ts b/src/lang.ts index e2733f83..68fef30b 100644 --- a/src/lang.ts +++ b/src/lang.ts @@ -41,6 +41,21 @@ const lang = { }, // * android + ActionCreateChannel: "Channel created", + ActionCreateGroup: "un1 created the group", + ActionChangedTitle: "un1 changed the group name to un2", + ActionRemovedPhoto: "un1 removed the group photo", + ActionChangedPhoto: "un1 changed the group photo", + ActionChangedVideo: "un1 changed the group video", + ActionAddUser: "un1 added un2", + ActionAddUserSelf: "un1 returned to the group", + ActionAddUserSelfMega: "un1 joined the group", + ActionAddUserSelfYou: "You returned to the group", + ActionLeftUser: "un1 left the group", + ActionKickUser: "un1 removed un2", + ActionInviteUser: "un1 joined the group via invite link", + ActionPinnedNoText: "un1 pinned a message", + ActionMigrateFromGroup: "This group was upgraded to a supergroup", FilterAlwaysShow: 'Include Chats', FilterNeverShow: 'Exclude Chats', FilterInclude: 'Included Chats', @@ -125,8 +140,18 @@ const lang = { WhoCanAddMe: "Who can add me to group chats?", ArchivedChats: "Archived Chats", Cancel: "Cancel", + HistoryCleared: "History was cleared", // * macos + "Chat.Service.PeerJoinedTelegram": "%@ joined Telegram", + "Chat.Service.Channel.UpdatedTitle": "Channel renamed to \"%@\"", + "Chat.Service.Channel.UpdatedPhoto": "Channel photo updated", + "Chat.Service.Channel.RemovedPhoto": "Channel photo removed", + "Chat.Service.BotPermissionAllowed": "You allowed this bot to message you when you logged in on %@", + "ChatList.Service.Call.incoming": "Incoming Call (%@)", + "ChatList.Service.Call.outgoing": "Outgoing Call (%@)", + "ChatList.Service.Call.Cancelled": "Cancelled Call", + "ChatList.Service.Call.Missed": "Missed Call", "ChatList.Filter.Header": "Create folders for different groups of chats and quickly switch between them.", "ChatList.Filter.NewTitle": "Create Folder", "ChatList.Filter.List.Title": "Chat Folders", diff --git a/src/lib/appManagers/appMessagesManager.ts b/src/lib/appManagers/appMessagesManager.ts index 56c89976..b69254f1 100644 --- a/src/lib/appManagers/appMessagesManager.ts +++ b/src/lib/appManagers/appMessagesManager.ts @@ -8,7 +8,7 @@ import { randomLong } from "../../helpers/random"; import { splitStringByLength, limitSymbols } from "../../helpers/string"; import { Chat, ChatFull, Dialog as MTDialog, DialogPeer, DocumentAttribute, InputMedia, InputMessage, InputPeerNotifySettings, InputSingleMedia, Message, MessageAction, MessageEntity, MessageFwdHeader, MessageReplies, MessageReplyHeader, MessagesDialogs, MessagesFilter, MessagesMessages, MessagesPeerDialogs, MethodDeclMap, NotifyPeer, PeerNotifySettings, PhotoSize, SendMessageAction, Update } from "../../layer"; import { InvokeApiOptions } from "../../types"; -import { langPack } from "../langPack"; +import I18n, { langPack, LangPackKey, _i18n } from "../langPack"; import { logger, LogLevels } from "../logger"; import type { ApiFileManager } from '../mtproto/apiFileManager'; //import apiManager from '../mtproto/apiManager'; @@ -2681,6 +2681,105 @@ export class AppMessagesManager { return str; } + public wrapMessageActionTextNew(message: any, plain: true): string; + public wrapMessageActionTextNew(message: any, plain?: false): HTMLElement; + public wrapMessageActionTextNew(message: any, plain?: boolean): HTMLElement | string { + const element: HTMLElement = plain ? undefined : document.createElement('span'); + const action = message.action as MessageAction; + + if((action as MessageAction.messageActionCustomAction).message) { + const richText = RichTextProcessor.wrapRichText((action as MessageAction.messageActionCustomAction).message, {noLinebreaks: true}); + if(plain) { + return richText; + } else { + element.innerHTML = richText; + return element; + } + } else { + let _ = action._; + //let suffix = ''; + let langPackKey: LangPackKey = ''; + let args: any[]; + + const getNameDivHTML = (peerId: number) => { + const title = appPeersManager.getPeerTitle(peerId); + return title ? (plain ? title + ' ' : `
${title}
`) : ''; + }; + + switch(action._) { + case "messageActionPhoneCall": { + _ += '.' + (action as any).type; + + const duration = action.duration || 1; + const d: string[] = []; + + d.push(duration % 60 + ' s'); + if(duration >= 60) d.push((duration / 60 | 0) + ' min'); + //if(duration >= 3600) d.push((duration / 3600 | 0) + ' h'); + + langPackKey = langPack[_]; + args = [d.reverse().join(' ')]; + break; + } + + case 'messageActionChatJoinedByLink': { + langPackKey = langPack[_]; + args = [getNameDivHTML(message.fromId)]; + break; + } + + case 'messageActionChatDeleteUser': + // @ts-ignore + case 'messageActionChatAddUsers': + case 'messageActionChatAddUser': { + const users: number[] = (action as MessageAction.messageActionChatAddUser).users + || [(action as MessageAction.messageActionChatDeleteUser).user_id]; + + langPackKey = langPack[_]; + args = [getNameDivHTML(message.fromId), users.map((userId: number) => getNameDivHTML(userId).trim()).join(', ')]; + break; + } + + case 'messageActionBotAllowed': { + const anchorHTML = RichTextProcessor.wrapRichText(action.domain, { + entities: [{ + _: 'messageEntityUrl', + length: action.domain.length, + offset: 0 + }] + }); + + langPackKey = langPack[_]; + args = [anchorHTML]; + break; + } + + default: + langPackKey = langPack[_] || `[${action._}]`; + break; + } + + if(!langPackKey) { + langPackKey = langPack[_]; + if(langPackKey === undefined) { + langPackKey = '[' + _ + ']'; + } + } + + if(plain) { + return I18n.getString(langPackKey, args); + } else { + return _i18n(element, langPackKey, args); + } + + //str = !langPackKey || langPackKey[0].toUpperCase() === langPackKey[0] ? langPackKey : getNameDivHTML(message.fromId) + langPackKey + (suffix ? ' ' : ''); + } + + //this.log('message action:', action); + + return element; + } + public editPeerFolders(peerIds: number[], folderId: number) { apiManager.invokeApi('folders.editPeerFolders', { folder_peers: peerIds.map(peerId => { diff --git a/src/lib/langPack.ts b/src/lib/langPack.ts index 37400c45..5f8a68be 100644 --- a/src/lib/langPack.ts +++ b/src/lib/langPack.ts @@ -5,34 +5,34 @@ import { LangPackDifference, LangPackString } from "../layer"; import apiManager from "./mtproto/mtprotoworker"; import sessionStorage from "./sessionStorage"; -export const langPack: {[actionType: string]: string} = { - "messageActionChatCreate": "created the group", - "messageActionChatEditTitle": "changed group name", - "messageActionChatEditPhoto": "changed group photo", - "messageActionChatDeletePhoto": "removed group photo", - "messageActionChatReturn": "returned to group", - "messageActionChatJoined": "joined the group", - "messageActionChatAddUser": "invited {}", - "messageActionChatAddUsers": "invited {} users", - "messageActionChatLeave": "left the group", - "messageActionChatDeleteUser": "removed user {}", - "messageActionChatJoinedByLink": "joined the group via invite link", - "messageActionPinMessage": "pinned message", - "messageActionContactSignUp": "joined Telegram", - "messageActionChannelCreate": "Channel created", - "messageActionChannelEditTitle": "Channel renamed", - "messageActionChannelEditPhoto": "Channel photo updated", - "messageActionChannelDeletePhoto": "Channel photo removed", - "messageActionHistoryClear": "History was cleared", - - "messageActionChannelMigrateFrom": "", - - "messageActionPhoneCall.in_ok": "Incoming Call", - "messageActionPhoneCall.out_ok": "Outgoing Call", - "messageActionPhoneCall.in_missed": "Missed Call", - "messageActionPhoneCall.out_missed": "Cancelled Call", - - "messageActionBotAllowed": "You allowed this bot to message you when logged in {}" +export const langPack: {[actionType: string]: LangPackKey} = { + "messageActionChatCreate": "ActionCreateGroup", + "messageActionChatEditTitle": "ActionChangedTitle", + "messageActionChatEditPhoto": "ActionChangedPhoto", + "messageActionChatDeletePhoto": "ActionRemovedPhoto", + "messageActionChatReturn": "ActionAddUserSelf", + "messageActionChatJoined": "ActionAddUserSelfMega", + "messageActionChatAddUser": "ActionAddUser", + "messageActionChatAddUsers": "ActionAddUser", + "messageActionChatLeave": "ActionLeftUser", + "messageActionChatDeleteUser": "ActionKickUser", + "messageActionChatJoinedByLink": "ActionInviteUser", + "messageActionPinMessage": "ActionPinnedNoText", + "messageActionContactSignUp": "Chat.Service.PeerJoinedTelegram", + "messageActionChannelCreate": "ActionCreateChannel", + "messageActionChannelEditTitle": "Chat.Service.Channel.UpdatedTitle", + "messageActionChannelEditPhoto": "Chat.Service.Channel.UpdatedPhoto", + "messageActionChannelDeletePhoto": "Chat.Service.Channel.RemovedPhoto", + "messageActionHistoryClear": "HistoryCleared", + + "messageActionChannelMigrateFrom": "ActionMigrateFromGroup", + + "messageActionPhoneCall.in_ok": "ChatList.Service.Call.incoming", + "messageActionPhoneCall.out_ok": "ChatList.Service.Call.outgoing", + "messageActionPhoneCall.in_missed": "ChatList.Service.Call.Missed", + "messageActionPhoneCall.out_missed": "ChatList.Service.Call.Cancelled", + + "messageActionBotAllowed": "Chat.Service.BotPermissionAllowed" }; export type LangPackKey = string | keyof typeof lang; @@ -109,11 +109,11 @@ namespace I18n { } export const polyfillPromise = (function checkIfPolyfillNeeded() { - if(typeof(Intl) !== 'undefined' && typeof(Intl.PluralRules) !== 'undefined' && false) { + if(typeof(Intl) !== 'undefined' && typeof(Intl.PluralRules) !== 'undefined'/* && false */) { return Promise.resolve(); } else { - return import('./pluralPolyfill').then(_Intl => { - (window as any).Intl = _Intl.default; + return import('./pluralPolyfill').then((_Intl) => { + (window as any).Intl = Object.assign(typeof(Intl) !== 'undefined' ? Intl : {}, _Intl.default); }); } })(); @@ -167,15 +167,16 @@ namespace I18n { .replace(/\*\*(.+?)\*\*/g, '$1'); if(args?.length) { - out = out.replace(/%\d\$.|%./g, (match, offset, string) => { - return '' + args.shift(); + let i = 0; + out = out.replace(/un\d|%\d\$.|%./g, (match, offset, string) => { + return '' + args[i++]; }); } return out; } - const weakMap: WeakMap = new WeakMap(); + export const weakMap: WeakMap = new WeakMap(); export type IntlElementOptions = { element?: HTMLElement,