Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Custom emotes #9240

Closed
wants to merge 251 commits into from
Closed
Show file tree
Hide file tree
Changes from 195 commits
Commits
Show all changes
251 commits
Select commit Hold shift + click to select a range
4db0a7e
emotes show up in messages
nmscode Aug 10, 2022
d3ea501
added tooltips
nmscode Aug 11, 2022
d1b6068
removed extra logging
nmscode Aug 11, 2022
047f39e
edits to changelog
nmscode Aug 12, 2022
43ab685
fixed bug with User Appearance Settings Tab caused by changes in Text…
nmscode Aug 13, 2022
87aed98
added autocomplete custom emote functionality
nmscode Aug 13, 2022
48af2e3
Removing merge conflict blocks and fixing some formatting
nmscode Sep 2, 2022
99cf97b
some lint fixes
nmscode Sep 2, 2022
9555dc2
more lint fixes
nmscode Sep 2, 2022
776d40c
even more lint fixes
nmscode Sep 2, 2022
1d18c70
lint fixes 4
nmscode Sep 2, 2022
e2d08cb
lint fixes 5
nmscode Sep 2, 2022
c376e1d
removed extraneous file that got accidentally copied over
nmscode Sep 2, 2022
9d2b15f
fixed issue in autocomplete where title of normal emote was notsurrou…
nmscode Sep 2, 2022
147fd66
changed i18n files to include emote phrases
nmscode Sep 3, 2022
92d3bae
added some missing css
nmscode Sep 3, 2022
a2146be
added some more missing changes
nmscode Sep 3, 2022
7da8d5f
lint fixes 6
nmscode Sep 3, 2022
495774a
i18n fixes/changes
nmscode Sep 6, 2022
ced18d9
Merge branch 'develop' into prbranch
nmscode Sep 6, 2022
12d7bda
i18n changes retry
nmscode Sep 6, 2022
5c04be4
i18n changes retry 3
nmscode Sep 6, 2022
d7b0a44
i18n changes retry 4
nmscode Sep 6, 2022
0b95257
i18n changes undo
nmscode Sep 6, 2022
c310091
i18n changes retry 6
nmscode Sep 6, 2022
e0a4fc3
i18n changes retry 7
nmscode Sep 6, 2022
3d9d71c
Merge branch 'develop' into prbranch
nmscode Sep 6, 2022
91c669a
autocomplete fix
nmscode Sep 6, 2022
1507718
added encryption and decryption for emotes
nmscode Sep 8, 2022
c1a4727
encryption code cleanup
nmscode Sep 8, 2022
05ccbd5
encryption code type fixes
nmscode Sep 8, 2022
e5dcdbf
added multiple emote upload and read shortcode from filename
nmscode Sep 13, 2022
8d0a4e0
code cleanup
nmscode Sep 13, 2022
842bee4
code cleanup 2
nmscode Sep 13, 2022
c88f28e
Merge branch 'develop' into prbranch
nmscode Sep 13, 2022
8b190c1
Merge branch 'develop' into prbranch
nmscode Sep 13, 2022
4fefa5c
makes emotes work in public(unencrypted) rooms and encrypted rooms
nmscode Sep 14, 2022
53c9d35
code fix
nmscode Sep 14, 2022
2aef28f
space between import groups
nmscode Sep 14, 2022
a2de64c
build commits
nmscode Sep 25, 2022
42bf66e
Merge branch 'matrix-org:develop' into prbranch
nmscode Sep 28, 2022
ce04fce
Removing any and dictionary types
nmscode Oct 26, 2022
2834610
Merge branch 'develop' into prbranch
nmscode Oct 26, 2022
d92c6f0
Replacing dictionary and any 2
nmscode Oct 26, 2022
bdbd408
Merge branch 'master' into buildbranch
nmscode Dec 6, 2022
6bef012
Added custom emotes to the emojipicker
nmscode Dec 16, 2022
8c2bded
Merge branch 'prbranch' into buildbranch
nmscode Dec 18, 2022
ceec93e
Update MessageComposerButtons.tsx
nmscode Dec 19, 2022
59357f1
Merge remote-tracking branch 'upstream/master' into buildbranch
nmscode Dec 21, 2022
6b8ff65
Add compatibility option with other clients
nmscode Dec 28, 2022
3ba45ed
Merge branch 'prbranch' into buildbranch
nmscode Dec 28, 2022
eee9bb1
Update RoomEmoteSettings.tsx
nmscode Dec 29, 2022
35bba69
Set height on compatible emotes
nmscode Dec 29, 2022
0ce29b3
Emojipicker updates
nmscode Dec 29, 2022
96a1cd7
Merge branch 'prbranch' into buildbranch
nmscode Dec 29, 2022
d83c750
Autocomplete bug fix
nmscode Dec 30, 2022
6d2ba5d
Update Autocompleter.ts
nmscode Dec 30, 2022
8d8d851
emotes show up in messages
nmscode Aug 10, 2022
130fdda
emotes show up in messages
nmscode Aug 10, 2022
e866a98
added tooltips
nmscode Aug 11, 2022
12e826d
removed extra logging
nmscode Aug 11, 2022
6b07a69
edits to changelog
nmscode Aug 12, 2022
9d28392
fixed bug with User Appearance Settings Tab caused by changes in Text…
nmscode Aug 13, 2022
1fc4b9f
added autocomplete custom emote functionality
nmscode Aug 13, 2022
b740d1a
Removing merge conflict blocks and fixing some formatting
nmscode Sep 2, 2022
9659d79
some lint fixes
nmscode Sep 2, 2022
d528ff3
more lint fixes
nmscode Sep 2, 2022
d8a5069
even more lint fixes
nmscode Sep 2, 2022
24d63bc
lint fixes 4
nmscode Sep 2, 2022
3d6c461
lint fixes 5
nmscode Sep 2, 2022
c741b27
removed extraneous file that got accidentally copied over
nmscode Sep 2, 2022
e242ca2
fixed issue in autocomplete where title of normal emote was notsurrou…
nmscode Sep 2, 2022
135ce7d
changed i18n files to include emote phrases
nmscode Sep 3, 2022
0340ccf
added some missing css
nmscode Sep 3, 2022
dbbe589
added some more missing changes
nmscode Sep 3, 2022
1c103b0
lint fixes 6
nmscode Sep 3, 2022
9b657f4
i18n fixes/changes
nmscode Sep 6, 2022
3e1d525
i18n changes retry
nmscode Sep 6, 2022
eaa8f1b
i18n changes retry 3
nmscode Sep 6, 2022
4c11a9a
i18n changes retry 4
nmscode Sep 6, 2022
6026b34
i18n changes undo
nmscode Sep 6, 2022
1662830
i18n changes retry 6
nmscode Sep 6, 2022
af641b7
i18n changes retry 7
nmscode Sep 6, 2022
f7a4e57
autocomplete fix
nmscode Sep 6, 2022
dc7bee7
added encryption and decryption for emotes
nmscode Sep 8, 2022
92a836d
encryption code cleanup
nmscode Sep 8, 2022
3c39b30
encryption code type fixes
nmscode Sep 8, 2022
31ad8fc
added multiple emote upload and read shortcode from filename
nmscode Sep 13, 2022
3cf41dd
code cleanup
nmscode Sep 13, 2022
380cc54
code cleanup 2
nmscode Sep 13, 2022
9f5d49a
makes emotes work in public(unencrypted) rooms and encrypted rooms
nmscode Sep 14, 2022
2dfbc90
code fix
nmscode Sep 14, 2022
225d2b4
Removing any and dictionary types
nmscode Oct 26, 2022
03e700c
Replacing dictionary and any 2
nmscode Oct 26, 2022
6740a08
Added custom emotes to the emojipicker
nmscode Dec 16, 2022
8a28f23
Add compatibility option with other clients
nmscode Dec 28, 2022
a842e29
Update RoomEmoteSettings.tsx
nmscode Dec 29, 2022
b328efb
Set height on compatible emotes
nmscode Dec 29, 2022
b664b3a
Update EmojiButton.tsx
nmscode Dec 30, 2022
3f6f1c8
Merge branch 'buildbranch' into prbranch
nmscode Jun 8, 2023
583684c
Code format changes and some documentation
nmscode Jun 8, 2023
87ce27e
clean up
nmscode Jun 8, 2023
71aaead
fix in emoji
nmscode Jun 8, 2023
461c4f4
cache regex and fix parenthesis issue
nmscode Jun 8, 2023
3b3d696
Add UnstableValue and revert i18n
nmscode Jun 8, 2023
57d5ec3
Undo accidental deletion
nmscode Jun 8, 2023
ed1f402
fix: code style and white space
JiffyCat Jun 8, 2023
6cfd79e
fix: other lint and code style issues
JiffyCat Jun 8, 2023
ae01131
cleanup: comments in RoomEmoteSettings.tsx
JiffyCat Jun 8, 2023
9e4dba7
cleanup: comments from _EmoteSettings.pcss
JiffyCat Jun 8, 2023
9f77560
Unstable value update
nmscode Jun 8, 2023
9d50f1a
Typo fix
nmscode Jun 8, 2023
c79780d
added comment about use of dangerouslySetInnerHTML
nmscode Jun 8, 2023
9fec256
Directly use react components instead of using dangerouslySetInnerHTML
nmscode Jun 9, 2023
3e2f506
bug fix in textualbody
nmscode Jun 9, 2023
832f316
Restrict characters for shortcodes
nmscode Jun 9, 2023
99b1354
allow underscore in shortcode
nmscode Jun 9, 2023
646dd3b
Remove cheerio based bug fix
nmscode Jun 10, 2023
351e4a5
Restore some accidentally removed code from emojiprovider
nmscode Jun 12, 2023
029e1bc
Remove some duplicated code
nmscode Jun 14, 2023
c825e41
Update RoomSettingsDialog.tsx
nmscode Jun 14, 2023
d717eb1
Lint fixes 1
nmscode Jun 14, 2023
3cd8016
Lint fixes 2
nmscode Jun 14, 2023
9fd3d1e
Some fixes for tests
nmscode Jun 14, 2023
4912b81
Add some null checks and test fixes
nmscode Jun 14, 2023
ab9e31e
emojipicker bug fix and check for room
nmscode Jun 14, 2023
d52f35b
test fix 3
nmscode Jun 14, 2023
864ea57
Update EmojiProvider.tsx
nmscode Jun 14, 2023
9ab8ce8
keep custom emotes enabled in emojipicker
nmscode Jun 14, 2023
b53ae44
Ran i18n
nmscode Jun 15, 2023
35e091e
fix: automatic lint fixes
JiffyCat Jun 15, 2023
3aca4b3
type fixes
nmscode Jun 15, 2023
56899a2
Type and lint fixes
nmscode Jun 15, 2023
600c499
Restore removed code in emojibutton
nmscode Jun 15, 2023
533ce9b
i18n update
nmscode Jun 15, 2023
44ee160
Update SendMessageComposer.tsx
nmscode Jun 15, 2023
f587039
Compatibility mode bug fix
nmscode Jun 15, 2023
3dba10c
Remove Object type for more specific typing
nmscode Jun 15, 2023
72051e3
Merge remote-tracking branch 'upstream/develop' into prbranch
nmscode Jun 15, 2023
19569d6
lint fix
nmscode Jun 15, 2023
2b25543
fix: keyboardevent lint error
JiffyCat Jun 16, 2023
bafd034
fix: revert filterboolean
JiffyCat Jun 16, 2023
5005bbe
fix: test errors
JiffyCat Jun 16, 2023
92c150d
Bug fix in roomemptesettings
nmscode Jun 16, 2023
026e411
RoomEmoteSettings bug fix 2
nmscode Jun 16, 2023
6a6ed02
fix: add test snapshots
JiffyCat Jun 16, 2023
ecc19e6
Strict type fixes
nmscode Jun 19, 2023
18cfc7e
Lint fixes
nmscode Jun 19, 2023
6838d1f
Merge branch 'develop' into prbranch
nmscode Jun 19, 2023
8063c02
removed incorrect null safe assertions and used interface for imagePack
nmscode Jun 19, 2023
2d884ec
Merge branch 'develop' into prbranch
nmscode Jun 19, 2023
4e67a6b
fix: strict type check for emojiBodyElements
JiffyCat Jun 19, 2023
2ad5f2c
fix for final strict type issues in emoji.ts and emojiprovider
nmscode Jun 20, 2023
30303da
Added tests
nmscode Jun 20, 2023
f9c346f
Add more test coverage and remove sonar and strict type check bug
nmscode Jun 21, 2023
556b1d6
Adding some more tests to increase coverage
nmscode Jun 21, 2023
4c1298c
final test push
nmscode Jun 22, 2023
32c9ccf
Merge branch 'develop' into prbranch
t3chguy Jun 22, 2023
38efe85
Fix for new safeGet check
nmscode Jun 22, 2023
537dd52
Merge branch 'develop' into prbranch
nmscode Jun 23, 2023
68e0003
Merge branch 'develop' into prbranch
nmscode Jun 23, 2023
ab4e9ed
Merge branch 'develop' into prbranch
nmscode Jun 26, 2023
86a82e0
Merge branch 'develop' into prbranch
nmscode Jun 26, 2023
92e2f67
Merge branch 'develop' into prbranch
nmscode Jun 27, 2023
cebb2fd
Merge branch 'develop' into prbranch
nmscode Jun 27, 2023
22c47b7
Make custom emotes a lab setting
nmscode Jun 27, 2023
6193d09
i18n and a fix
nmscode Jun 27, 2023
22471f0
test: add test snapshot for RoomSettingsDialog
JiffyCat Jun 27, 2023
439a846
Merge branch 'develop' into prbranch
nmscode Jun 27, 2023
1f8ff10
fix: snapshot with HtmlUtils
JiffyCat Jun 27, 2023
f373fbe
lint fix htmlutils
nmscode Jun 27, 2023
6e205e7
Merge branch 'develop' into prbranch
nmscode Jun 28, 2023
3f774a8
Merge branch 'develop' into prbranch
nmscode Jun 28, 2023
fe0e17b
fix: batch apply suggestions from code review
JiffyCat Jun 28, 2023
89e9238
fix: cleanup comments and unused code
JiffyCat Jun 28, 2023
3a68e2b
fix: EmoteSettings copyright
JiffyCat Jun 28, 2023
875491b
revert: test-utils changes
JiffyCat Jun 28, 2023
7db0bfc
Review fixes
nmscode Jun 28, 2023
d5b8ade
Merge branch 'prbranch' of https://github.com/nmscode/matrix-react-sd…
nmscode Jun 28, 2023
47bab13
Review fixes 2
nmscode Jun 28, 2023
499638c
Update _EventTile.pcss
nmscode Jun 28, 2023
dbf1282
Emotes css fix
nmscode Jun 28, 2023
f71b528
Fix strings
nmscode Jun 28, 2023
1bbc67e
fix: unstable value and compat mode
JiffyCat Jun 28, 2023
b064451
Merge branch 'develop' into prbranch
nmscode Jun 29, 2023
5941022
strict type fix
nmscode Jun 29, 2023
a3f3320
Merge branch 'develop' into prbranch
nmscode Jun 29, 2023
4b1bf55
Merge branch 'develop' into prbranch
nmscode Jun 29, 2023
b8623eb
sonar coverage
nmscode Jun 29, 2023
29777b0
Merge branch 'develop' into prbranch
nmscode Jun 29, 2023
8f9d1ce
Merge branch 'develop' into prbranch
nmscode Jun 30, 2023
83a522e
compatibility fix
nmscode Jul 1, 2023
77f06b5
compatibility fix 2
nmscode Jul 1, 2023
0a6d184
Add test for loading emotes uploaded from other clients when compat m…
nmscode Jul 2, 2023
aa715fe
Merge branch 'develop' into prbranch
nmscode Jul 3, 2023
15ef7df
Merge branch 'develop' into prbranch
nmscode Jul 3, 2023
a2eaabe
Merge branch 'develop' into prbranch
nmscode Jul 3, 2023
e5273b7
Merge branch 'develop' into prbranch
nmscode Jul 3, 2023
984cf01
Merge branch 'develop' into prbranch
nmscode Jul 4, 2023
699bbf3
Merge branch 'develop' into prbranch
nmscode Jul 4, 2023
f85f36f
Merge branch 'develop' into prbranch
nmscode Jul 6, 2023
aa1ab71
Use readable state key instead of blank
nmscode Jul 6, 2023
46732bd
Merge remote-tracking branch 'upstream/develop' into prbranch
JiffyCat Jul 6, 2023
4c86ce1
fix: add copyright to Emotes css
JiffyCat Jul 6, 2023
c08bb72
Merge branch 'develop' into prbranch
nmscode Jul 6, 2023
7d6a9e0
Merge branch 'develop' into prbranch
nmscode Jul 7, 2023
949d889
Merge branch 'develop' into prbranch
nmscode Jul 7, 2023
35ac50c
Merge branch 'develop' into prbranch
JiffyCat Jul 7, 2023
d455df0
Merge branch 'develop' into prbranch
nmscode Jul 7, 2023
8ae190e
Merge branch 'develop' into prbranch
nmscode Jul 10, 2023
b11bb36
Add a pack name for the element compatible pack
nmscode Jul 10, 2023
50db6a7
Merge branch 'develop' into prbranch
nmscode Jul 10, 2023
bbba7d3
Merge branch 'develop' into prbranch
nmscode Jul 10, 2023
491006c
Merge branch 'develop' into prbranch
nmscode Jul 11, 2023
bd3e017
Merge branch 'develop' into prbranch
nmscode Jul 11, 2023
0dcfb68
Merge branch 'develop' into prbranch
nmscode Jul 12, 2023
b57c7ff
Merge branch 'develop' into prbranch
nmscode Jul 12, 2023
3f36820
Merge branch 'develop' into prbranch
nmscode Jul 12, 2023
9b99b36
Merge branch 'develop' into prbranch
nmscode Jul 13, 2023
bc95d26
Merge branch 'develop' into prbranch
nmscode Jul 14, 2023
870c48d
Merge branch 'develop' into prbranch
JiffyCat Jul 18, 2023
f8b6501
Merge branch 'develop' into prbranch
nmscode Jul 18, 2023
8b49381
Merge branch 'develop' into prbranch
nmscode Jul 19, 2023
3ad3e36
type and jest test fix
nmscode Jul 19, 2023
b9cbc72
Merge branch 'develop' into prbranch
nmscode Jul 19, 2023
19a261b
Merge branch 'develop' into prbranch
nmscode Jul 21, 2023
4e2e895
Merge branch 'develop' into prbranch
JiffyCat Jul 22, 2023
c78b5e5
Merge branch 'develop' into prbranch
nmscode Jul 25, 2023
286ec09
Merge branch 'develop' into prbranch
nmscode Jul 26, 2023
0533845
Merge branch 'develop' into prbranch
nmscode Jul 26, 2023
56a06f9
Merge branch 'develop' into prbranch
nmscode Jul 31, 2023
263fbb7
Merge branch 'develop' into prbranch
nmscode Aug 3, 2023
45a9d81
Merge branch 'develop' into prbranch
nmscode Aug 4, 2023
183ec44
lint fixes
nmscode Aug 4, 2023
8155eab
Merge branch 'develop' into prbranch
nmscode Aug 7, 2023
5e01cfc
new js sdk import lint fix
nmscode Aug 7, 2023
7d0b01e
Merge branch 'develop' into prbranch
nmscode Aug 8, 2023
ff2ed60
lint fix
nmscode Aug 8, 2023
0d2e8bb
Merge branch 'develop' into prbranch
nmscode Aug 9, 2023
63b2342
another import lint fix
nmscode Aug 9, 2023
18ed8c2
Merge branch 'develop' into prbranch
nmscode Aug 14, 2023
fc731cf
lint fix
nmscode Aug 14, 2023
9125480
Merge branch 'develop' into prbranch
nmscode Aug 15, 2023
9494f77
revert
nmscode Aug 28, 2023
dcc6aee
Merge branch 'develop' into prbranch
nmscode Aug 28, 2023
15881be
i18n and a type fix
nmscode Aug 28, 2023
c054095
lint fixes
nmscode Aug 28, 2023
62f8d53
Merge branch 'develop' into prbranch
nmscode Aug 30, 2023
cdebb6c
Merge branch 'develop' into prbranch
nmscode Aug 31, 2023
64c3f50
Merge branch 'develop' into prbranch
nmscode Aug 31, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions res/css/_components.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@
@import "./views/rooms/_E2EIcon.pcss";
@import "./views/rooms/_EditMessageComposer.pcss";
@import "./views/rooms/_EmojiButton.pcss";
@import "./views/rooms/_Emotes.pcss";
@import "./views/rooms/_EntityTile.pcss";
@import "./views/rooms/_EventBubbleTile.pcss";
@import "./views/rooms/_EventTile.pcss";
Expand Down Expand Up @@ -315,6 +316,7 @@
@import "./views/settings/_AvatarSetting.pcss";
@import "./views/settings/_CrossSigningPanel.pcss";
@import "./views/settings/_CryptographyPanel.pcss";
@import "./views/settings/_EmoteSettings.pcss";
@import "./views/settings/_FontScalingPanel.pcss";
@import "./views/settings/_ImageSizePanel.pcss";
@import "./views/settings/_IntegrationManager.pcss";
Expand Down
3 changes: 3 additions & 0 deletions res/css/views/dialogs/_RoomSettingsDialog.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ limitations under the License.
.mx_RoomSettingsDialog_warningIcon::before {
mask-image: url("$(res)/img/element-icons/room/settings/advanced.svg");
}
.mx_RoomSettingsDialog_emotesIcon::before {
mask-image: url("$(res)/img/element-icons/room/message-bar/emoji.svg");
}

.mx_RoomSettingsDialog .mx_Dialog_title {
-ms-text-overflow: ellipsis;
Expand Down
3 changes: 3 additions & 0 deletions res/css/views/rooms/_Emotes.pcss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.mx_Emote {
nmscode marked this conversation as resolved.
Show resolved Hide resolved
height: 32px;
}
78 changes: 78 additions & 0 deletions res/css/views/settings/_EmoteSettings.pcss
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
Copyright 2023 The Matrix.org Foundation C.I.C.

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.
*/

.mx_EmoteSettings {
margin-inline-end: var(--SettingsTab_fullWidthField-margin-inline-end);
border-bottom: 1px solid $quinary-content;

.mx_EmoteSettings_emoteUpload {
display: none;
}
.mx_EmoteSettings_addEmoteField {
display: flex;
width: 100%;
}
.mx_EmoteSettings_uploadButton {
margin-left: auto;
align-self: center;
}
.mx_EmoteSettings_deleteButton {
margin-left: auto;
align-self: center;
}
.mx_EmoteSettings_uploadedEmoteImage {
height: 30px;
width: var(--emote-image-width) * 30 / var(--emote-image-height); // Sets emote height to 30px and scales the width accordingly
margin-left: 30px;
align-self: center;
}
.mx_EmoteSettings_Emote {
display: flex;

.mx_EmoteSettings_Emote_controls {
flex-grow: 1;
margin-inline-end: 54px;

.mx_Field:first-child {
margin-top: 0;
}

.mx_EmoteSettings_Emote_controls_topic {
& > textarea {
font-family: inherit;
resize: vertical;
}

&.mx_EmoteSettings_Emote_controls_topic--room textarea {
min-height: 4em;
}
}

.mx_EmoteSettings_Emote_controls_userId {
margin-inline-end: $spacing-20;
}
}
}

.mx_EmoteSettings_buttons {
margin-top: 10px; /* 18px is already accounted for by the <p> above the buttons */

> .mx_AccessibleButton_kind_link {
font-size: $font-14px;
margin-inline-end: 10px;
}
}
}
16 changes: 15 additions & 1 deletion src/HtmlUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ const BIGEMOJI_REGEX = new RegExp(`^(${EMOJIBASE_REGEX.source})+$`, "i");

const COLOR_REGEX = /^#[0-9a-fA-F]{6}$/;

const CUSTOM_EMOTES_REGEX = /:[\w+-]+:/g;

export const PERMITTED_URL_SCHEMES = [
"bitcoin",
"ftp",
Expand Down Expand Up @@ -438,6 +440,7 @@ interface IOpts {
returnString?: boolean;
forComposerQuote?: boolean;
ref?: React.Ref<HTMLSpanElement>;
emotes?: Map<string, string>;
}

export interface IOptsReturnNode extends IOpts {
Expand Down Expand Up @@ -548,6 +551,12 @@ export function bodyToHtml(content: IContent, highlights: Optional<string[]>, op
// by an attempt to search for 'foobar'. Then again, the search query probably wouldn't work either
// XXX: hacky bodge to temporarily apply a textFilter to the sanitizeParams structure.
sanitizeParams.textFilter = function (safeText) {
if (opts.emotes) {
return highlighter
.applyHighlights(safeText, safeHighlights!)
.join("")
.replace(CUSTOM_EMOTES_REGEX, (m) => (opts?.emotes?.has(m) ? opts.emotes.get(m)! : m));
}
Comment on lines +528 to +533
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for @matrix-org/product - this rendering is done on the receiving side, regardless of whether a sender intended it. It may not play well with bridges. If a room has a :short: emote defined in its state then a user will not be able to send the literal :short: without it being inflated into the emote image.

return highlighter.applyHighlights(safeText, safeHighlights!).join("");
};
}
Expand Down Expand Up @@ -610,7 +619,12 @@ export function bodyToHtml(content: IContent, highlights: Optional<string[]>, op
"mx_EventTile_bigEmoji": emojiBody,
"markdown-body": isHtmlMessage && !emojiBody,
});

if (opts.emotes) {
const tmp = strippedBody?.replace(CUSTOM_EMOTES_REGEX, (m) => (opts?.emotes?.has(m) ? opts.emotes.get(m)! : m));
if (tmp !== strippedBody) {
safeBody = tmp;
}
}
let emojiBodyElements: JSX.Element[] | undefined;
if (!safeBody && bodyHasEmoji) {
emojiBodyElements = formatEmojis(strippedBody, false) as JSX.Element[];
Expand Down
6 changes: 5 additions & 1 deletion src/autocomplete/Components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ export const PillCompletion = forwardRef<IPillCompletionProps, any>((props, ref)
className,
children,
"aria-selected": ariaSelectedAttribute,
isEmote,
titleComponent,
...restProps
} = props;
return (
Expand All @@ -70,7 +72,9 @@ export const PillCompletion = forwardRef<IPillCompletionProps, any>((props, ref)
ref={ref}
>
{children}
<span className="mx_Autocomplete_Completion_title">{title}</span>
<span className="mx_Autocomplete_Completion_title">
{isEmote ? <img className="mx_Emote" src={titleComponent} alt="" /> : title}
</span>
<span className="mx_Autocomplete_Completion_subtitle">{subtitle}</span>
<span className="mx_Autocomplete_Completion_description">{description}</span>
</div>
Expand Down
64 changes: 60 additions & 4 deletions src/autocomplete/EmojiProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ import React from "react";
import { uniq, sortBy, uniqBy, ListIteratee } from "lodash";
import EMOTICON_REGEX from "emojibase-regex/emoticon";
import { Room } from "matrix-js-sdk/src/models/room";
import { UnstableValue } from "matrix-js-sdk/src/NamespacedValue";

import { MatrixClientPeg } from "../MatrixClientPeg";
import { _t } from "../languageHandler";
import AutocompleteProvider from "./AutocompleteProvider";
import QueryMatcher from "./QueryMatcher";
Expand All @@ -33,12 +35,16 @@ import { EMOJI, IEmoji, getEmojiFromUnicode } from "../emoji";
import { TimelineRenderingType } from "../contexts/RoomContext";
import * as recent from "../emojipicker/recent";
import { filterBoolean } from "../utils/arrays";
import { decryptFile } from "../utils/DecryptFile";
import { mediaFromMxc } from "../customisations/Media";
import { IEncryptedFile } from "../customisations/models/IMediaEventContent";

const LIMIT = 20;

// Match for ascii-style ";-)" emoticons or ":wink:" shortcodes provided by emojibase
// anchored to only match from the start of parts otherwise it'll show emoji suggestions whilst typing matrix IDs
const EMOJI_REGEX = new RegExp("(" + EMOTICON_REGEX.source + "|(?:^|\\s):[+-\\w]*:?)$", "g");
const EMOTES_STATE = new UnstableValue("m.room.emotes", "org.matrix.msc3892.emotes");

interface ISortedEmoji {
emoji: IEmoji;
Expand Down Expand Up @@ -80,9 +86,20 @@ export default class EmojiProvider extends AutocompleteProvider {
public matcher: QueryMatcher<ISortedEmoji>;
public nameMatcher: QueryMatcher<ISortedEmoji>;
private readonly recentlyUsed: IEmoji[];

private emotes: Map<string, string> = new Map();
private emotesPromise?: Promise<Map<string, string>>;
public constructor(room: Room, renderingType?: TimelineRenderingType) {
super({ commandRegex: EMOJI_REGEX, renderingType });
const emotesEvent = room?.currentState.getStateEvents(EMOTES_STATE.name, "");
const rawEmotes = emotesEvent ? emotesEvent.getContent() || {} : {};
const emotesMap = new Map();
const customEmotesEnabled = SettingsStore.getValue("feature_custom_emotes");
for (const shortcode in rawEmotes) {
emotesMap.set(shortcode, rawEmotes[shortcode]);
}
if (room && customEmotesEnabled) {
this.emotesPromise = this.decryptEmotes(emotesMap, room?.roomId);
}
this.matcher = new QueryMatcher<ISortedEmoji>(SORTED_EMOJI, {
keys: [],
funcs: [(o) => o.emoji.shortcodes.map((s) => `:${s}:`)],
Expand All @@ -98,6 +115,25 @@ export default class EmojiProvider extends AutocompleteProvider {
this.recentlyUsed = Array.from(new Set(filterBoolean(recent.get().map(getEmojiFromUnicode))));
}

private async decryptEmotes(
emotes: Map<string, string | IEncryptedFile>,
roomId: string,
): Promise<Map<string, string>> {
const decryptedEmoteMap = new Map<string, string>();
let decryptedurl = "";
const isEnc = MatrixClientPeg.get()?.isRoomEncrypted(roomId);
for (const [shortcode, val] of emotes) {
if (isEnc) {
const blob = await decryptFile(val as IEncryptedFile);
decryptedurl = URL.createObjectURL(blob);
} else {
decryptedurl = mediaFromMxc(val as string).srcHttp!;
}
decryptedEmoteMap.set(":" + shortcode + ":", decryptedurl);
}
return decryptedEmoteMap;
}

public async getCompletions(
query: string,
selection: ISelectionRange,
Expand All @@ -108,6 +144,21 @@ export default class EmojiProvider extends AutocompleteProvider {
return []; // don't give any suggestions if the user doesn't want them
}

const returnedEmotes = await this.emotesPromise;
if (!returnedEmotes) {
this.emotes = new Map();
} else {
this.emotes = returnedEmotes;
}
const emojisAndEmotes = [...SORTED_EMOJI];
for (const [key, val] of this.emotes) {
emojisAndEmotes.push({
emoji: { label: key, shortcodes: [key], hexcode: key, unicode: val as string, order: 0, group: 0 },
_orderBy: 0,
});
}
this.matcher.setObjects(emojisAndEmotes);
this.nameMatcher.setObjects(emojisAndEmotes);
let completions: ISortedEmoji[] = [];
const { command, range } = this.getCurrentCommand(query, selection);

Expand Down Expand Up @@ -163,10 +214,15 @@ export default class EmojiProvider extends AutocompleteProvider {
completions = uniqBy(completions, "emoji");

return completions.map((c) => ({
completion: c.emoji.unicode,
completion: this.emotes.get(c.emoji.hexcode) ? c.emoji.hexcode : c.emoji.unicode,
component: (
<PillCompletion title={`:${c.emoji.shortcodes[0]}:`} aria-label={c.emoji.unicode}>
<span>{c.emoji.unicode}</span>
<PillCompletion
isEmote={this.emotes.get(c.emoji.hexcode) ? true : false}
titleComponent={c.emoji.unicode}
title={`:${c.emoji.shortcodes[0]}:`}
aria-label={c.emoji.unicode}
>
<span>{this.emotes.get(c.emoji.hexcode) ? c.emoji.hexcode : c.emoji.unicode}</span>
</PillCompletion>
),
range: range!,
Expand Down
13 changes: 13 additions & 0 deletions src/components/views/dialogs/RoomSettingsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import GeneralRoomSettingsTab from "../settings/tabs/room/GeneralRoomSettingsTab
import SecurityRoomSettingsTab from "../settings/tabs/room/SecurityRoomSettingsTab";
import NotificationSettingsTab from "../settings/tabs/room/NotificationSettingsTab";
import BridgeSettingsTab from "../settings/tabs/room/BridgeSettingsTab";
import EmoteSettingsTab from "../settings/tabs/room/EmoteSettingsTab";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import dis from "../../../dispatcher/dispatcher";
import SettingsStore from "../../../settings/SettingsStore";
Expand All @@ -48,6 +49,7 @@ export const enum RoomSettingsTab {
Notifications = "ROOM_NOTIFICATIONS_TAB",
Bridges = "ROOM_BRIDGES_TAB",
Advanced = "ROOM_ADVANCED_TAB",
Emotes = "ROOM_EMOTES_TAB",
PollHistory = "ROOM_POLL_HISTORY_TAB",
}

Expand Down Expand Up @@ -175,6 +177,17 @@ class RoomSettingsDialog extends React.Component<IProps, IState> {
),
);

if (SettingsStore.getValue("feature_custom_emotes")) {
tabs.push(
new Tab(
RoomSettingsTab.Emotes,
_td("Emotes"),
"mx_RoomSettingsDialog_emotesIcon",
<EmoteSettingsTab roomId={this.props.roomId} />,
),
);
}

if (SettingsStore.getValue("feature_bridge_state")) {
tabs.push(
new Tab(
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/emojipicker/Category.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { ButtonEvent } from "../elements/AccessibleButton";

const OVERFLOW_ROWS = 3;

export type CategoryKey = keyof typeof DATA_BY_CATEGORY | "recent";
export type CategoryKey = keyof typeof DATA_BY_CATEGORY | "recent" | "custom";

export interface ICategory {
id: CategoryKey;
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/emojipicker/Emoji.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class Emoji extends React.PureComponent<IProps> {
focusOnMouseOver
>
<div className={`mx_EmojiPicker_item ${isSelected ? "mx_EmojiPicker_item_selected" : ""}`}>
{emoji.unicode}
{emoji.customComponent ?? emoji.unicode}
</div>
</RovingAccessibleButton>
);
Expand Down
Loading