From ce8bc84de086a669cbed8d9eb9db43607d02c265 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Fri, 22 Jan 2021 10:13:01 +1100 Subject: [PATCH] add way to add/remove moderators from the message click handler --- _locales/en/messages.json | 6 +++ js/models/conversations.js | 8 +-- preload.js | 8 --- ts/components/conversation/AddMentions.tsx | 2 +- ts/components/conversation/Message.tsx | 61 ++++++++++++++++++++-- ts/session/utils/Toast.tsx | 8 +++ ts/window.d.ts | 1 - 7 files changed, 76 insertions(+), 18 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 04b259fae..110748d36 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -2221,5 +2221,11 @@ }, "userRemovedFromModerators": { "message": "User removed from moderator list" + }, + "errorHappenedWhileRemovingModerator": { + "message": "An error happened" + }, + "errorHappenedWhileRemovingModeratorDesc": { + "message": "An error happened while removing this user from the moderator list." } } diff --git a/js/models/conversations.js b/js/models/conversations.js index 098d5c32b..a125ffe53 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -1560,9 +1560,11 @@ const profileName = this.getProfileName(); const number = this.getNumber(); let name; - if (window.shortenPubkey) { + if (window.libsession) { name = profileName - ? `${profileName} (${window.shortenPubkey(number)})` + ? `${profileName} (${window.libsession.Types.PubKey.shorten( + number + )})` : number; } else { name = profileName ? `${profileName} (${number})` : number; @@ -1589,7 +1591,7 @@ if (pubkey === textsecure.storage.user.getNumber()) { return i18n('you'); } - return profileName || window.shortenPubkey(pubkey); + return profileName || window.libsession.Types.PubKey.shorten(pubkey); }, /** diff --git a/preload.js b/preload.js index 6a2811a0e..baa2f30f2 100644 --- a/preload.js +++ b/preload.js @@ -440,14 +440,6 @@ if (process.env.USE_STUBBED_NETWORK) { window.SwarmPolling = new SwarmPolling(); } -window.shortenPubkey = pubkey => { - const pk = pubkey.key ? pubkey.key : pubkey; - - return `(...${pk.substring(pk.length - 6)})`; -}; - -window.pubkeyPattern = /@[a-fA-F0-9]{64,66}\b/g; - window.lokiFeatureFlags = { multiDeviceUnpairing: true, privateGroupChats: true, diff --git a/ts/components/conversation/AddMentions.tsx b/ts/components/conversation/AddMentions.tsx index 71a1be90c..81336ad33 100644 --- a/ts/components/conversation/AddMentions.tsx +++ b/ts/components/conversation/AddMentions.tsx @@ -66,7 +66,7 @@ export class AddMentions extends React.Component { public render() { const { text, renderOther, convoId } = this.props; const results: Array = []; - const FIND_MENTIONS = window.pubkeyPattern; + const FIND_MENTIONS = new RegExp(`@${PubKey.regexForPubkeys}`, 'g'); // We have to do this, because renderNonNewLine is not required in our Props object, // but it is always provided via defaultProps. diff --git a/ts/components/conversation/Message.tsx b/ts/components/conversation/Message.tsx index aa2638e52..88924fb84 100644 --- a/ts/components/conversation/Message.tsx +++ b/ts/components/conversation/Message.tsx @@ -39,6 +39,8 @@ import { withTheme } from 'styled-components'; import { MessageMetadata } from './message/MessageMetadata'; import { MessageRegularProps } from '../../../js/models/messages'; import { PubKey } from '../../session/types'; +import { ToastUtils } from '../../session/utils'; +import { ConversationController } from '../../session/conversations'; // Same as MIN_WIDTH in ImageGrid.tsx const MINIMUM_LINK_PREVIEW_IMAGE_WIDTH = 200; @@ -65,6 +67,8 @@ class MessageInner extends React.PureComponent { this.handleImageErrorBound = this.handleImageError.bind(this); this.onReplyPrivate = this.onReplyPrivate.bind(this); this.handleContextMenu = this.handleContextMenu.bind(this); + this.onAddModerator = this.onAddModerator.bind(this); + this.onRemoveFromModerator = this.onRemoveFromModerator.bind(this); this.state = { expiring: false, @@ -688,12 +692,16 @@ class MessageInner extends React.PureComponent { {weAreAdmin && isPublic ? ( {window.i18n('banUser')} ) : null} - {/* {weAreAdmin && isPublic && !isAdmin ? ( - {window.i18n('addAsModerator')} + {weAreAdmin && isPublic && !isAdmin ? ( + + {window.i18n('addAsModerator')} + ) : null} {weAreAdmin && isPublic && isAdmin ? ( - {window.i18n('removeFromModerators')} - ) : null} */} + + {window.i18n('removeFromModerators')} + + ) : null} ); } @@ -788,7 +796,8 @@ class MessageInner extends React.PureComponent { // We parse the message later, but we still need to do an early check // to see if the message mentions us, so we can display the entire // message differently - const mentions = text ? text.match(window.pubkeyPattern) : []; + const regex = new RegExp(`@${PubKey.regexForPubkeys}`, 'g'); + const mentions = text ? text.match(regex) : []; const mentionMe = mentions && mentions.some(m => m.slice(1) === window.lokiPublicChatAPI.ourKey); @@ -969,6 +978,48 @@ class MessageInner extends React.PureComponent { this.props.onReply(this.props.timestamp); } } + + private async onAddModerator() { + const { authorPhoneNumber: pubkey, convoId } = this.props; + try { + const convo = ConversationController.getInstance().getOrThrow(convoId); + const channelAPI = await convo.getPublicSendData(); + const res = await channelAPI.serverAPI.addModerator([pubkey]); + if (!res) { + window.log.warn('failed to add moderators:', res); + + ToastUtils.pushUserNeedsToHaveJoined(); + } else { + window.log.info(`${pubkey} added as moderator...`); + ToastUtils.pushUserAddedToModerators(); + } + } catch (e) { + window.log.error('Got error while adding moderator:', e); + } + } + + private async onRemoveFromModerator() { + const { authorPhoneNumber: pubkey, convoId } = this.props; + try { + const convo = ConversationController.getInstance().getOrThrow(convoId); + const channelAPI = await convo.getPublicSendData(); + const res = await channelAPI.serverAPI.removeModerators([pubkey]); + if (!res) { + window.log.warn('failed to remove moderators:', res); + + ToastUtils.pushErrorHappenedWhileRemovingModerator(); + } else { + // refresh the moderator list. Will trigger a refresh + const modPubKeys = (await channelAPI.getModerators()) as Array; + convo.updateGroupAdmins(modPubKeys); + + window.log.info(`${pubkey} removed from moderators...`); + ToastUtils.pushUserRemovedToModerators(); + } + } catch (e) { + window.log.error('Got error while removing moderator:', e); + } + } } export const Message = withTheme(MessageInner); diff --git a/ts/session/utils/Toast.tsx b/ts/session/utils/Toast.tsx index 3fc8e75b5..0ffcf7a59 100644 --- a/ts/session/utils/Toast.tsx +++ b/ts/session/utils/Toast.tsx @@ -246,3 +246,11 @@ export function pushUserRemovedToModerators() { export function pushInvalidPubKey() { pushToastSuccess('invalidPubKey', window.i18n('invalidPubkeyFormat')); } + +export function pushErrorHappenedWhileRemovingModerator() { + pushToastError( + 'errorHappenedWhileRemovingModerator', + window.i18n('errorHappenedWhileRemovingModerator'), + window.i18n('errorHappenedWhileRemovingModeratorDesc') + ); +} diff --git a/ts/window.d.ts b/ts/window.d.ts index 2b28a4eaf..c79d74d01 100644 --- a/ts/window.d.ts +++ b/ts/window.d.ts @@ -91,7 +91,6 @@ declare global { userConfig: any; versionInfo: any; getStoragePubKey: any; - pubkeyPattern: any; getConversations: () => ConversationCollection; getGuid: any; ContactBuffer: any;