Skip to content

Commit 1857200

Browse files
committed
feat: Implement a custom common emojiPicker - MEED-9135 - Meeds-io/MPIs#164 (#4894)
Implement a custom common emojiPicker to be used a cross the platform
1 parent a51b23a commit 1857200

File tree

13 files changed

+33487
-1
lines changed

13 files changed

+33487
-1
lines changed

crowdin.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,5 +360,14 @@ files: [
360360
"update_option": "update_as_unapproved",
361361
"escape_special_characters": 0,
362362
"escape_quotes": 0,
363-
}
363+
},
364+
{
365+
"source": "/webapp/src/main/resources/locale/portlet/EmojiPicker_en.properties",
366+
"translation": "%original_path%/%file_name%!_%locale_with_underscore%.%file_extension%",
367+
"translation_replace": { YML_CROWDIN_LANGUAGES_ARG },
368+
"dest": "hub/social/webapp/EmojiPicker.properties",
369+
"update_option": "update_as_unapproved",
370+
"escape_special_characters": 0,
371+
"escape_quotes": 0,
372+
}
364373
]
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
emojiPicker.search.label=Search emojis...
2+
emojiPicker.category.recent.label=Frequently Used
3+
emojiPicker.category.smileys-emotion.label=Smileys & Emotion
4+
emojiPicker.category.people-body.label=People & Body
5+
emojiPicker.category.animals-nature.label=Animals & Nature
6+
emojiPicker.category.food-drink.label=Food & Drink
7+
emojiPicker.category.activities.label=Activities
8+
emojiPicker.category.travel-places.label=Travel & Places
9+
emojiPicker.category.objects.label=Objects
10+
emojiPicker.category.symbols.label=Symbols
11+
emojiPicker.category.flags.label=Flags
12+
emojiPicker.category.extras-unicode.label=Unicode Extras
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
emojiPicker.search.label=Rechercher des \u00e9mojis...
2+
emojiPicker.category.recent.label=Utilis\u00e9s fr\u00e9quemment
3+
emojiPicker.category.smileys-emotion.label=Smileys et \u00e9motions
4+
emojiPicker.category.people-body.label=Personnes et corps
5+
emojiPicker.category.animals-nature.label=Animaux et nature
6+
emojiPicker.category.food-drink.label=Nourriture et boissons
7+
emojiPicker.category.activities.label=Activit\u00e9s
8+
emojiPicker.category.travel-places.label=Voyages et lieux
9+
emojiPicker.category.objects.label=Objets
10+
emojiPicker.category.symbols.label=Symboles
11+
emojiPicker.category.flags.label=Drapeaux
12+
emojiPicker.category.extras-unicode.label=Extras Unicode

webapp/src/main/webapp/WEB-INF/gatein-resources.xml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3211,4 +3211,28 @@
32113211
</depends>
32123212
</module>
32133213

3214+
<module>
3215+
<name>emojiPicker</name>
3216+
<load-group>emojisGRP</load-group>
3217+
<script>
3218+
<minify>false</minify>
3219+
<path>/js/emojiPicker.bundle.js</path>
3220+
</script>
3221+
<depends>
3222+
<module>vue</module>
3223+
</depends>
3224+
<depends>
3225+
<module>vuetify</module>
3226+
</depends>
3227+
<depends>
3228+
<module>eXoVueI18n</module>
3229+
</depends>
3230+
<depends>
3231+
<module>commonVueComponents</module>
3232+
</depends>
3233+
<depends>
3234+
<module>extensionRegistry</module>
3235+
</depends>
3236+
</module>
3237+
32143238
</gatein-resources>
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<!--
2+
This file is part of the Meeds project (https://meeds.io/).
3+
4+
Copyright (C) 2025 Meeds Association [email protected]
5+
6+
This program is free software; you can redistribute it and/or
7+
modify it under the terms of the GNU Lesser General Public
8+
License as published by the Free Software Foundation; either
9+
version 3 of the License, or (at your option) any later version.
10+
This program is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public License
16+
along with this program; if not, write to the Free Software Foundation,
17+
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18+
-->
19+
20+
<template>
21+
<v-menu
22+
v-model="showPicker"
23+
:close-on-content-click="false"
24+
:position-x="menuX"
25+
:position-y="menuY"
26+
content-class="z-index-modal bord pickerMenu border-radius-8 overflow-hidden"
27+
:max-height="maxHeight"
28+
:max-width="maxWidth"
29+
absolute
30+
offset-x
31+
offset-y>
32+
<emoji-picker-list
33+
:emojis="emojis"
34+
@select-emoji="selectEmoji" />
35+
</v-menu>
36+
</template>
37+
38+
<script>
39+
40+
export default {
41+
data() {
42+
return {
43+
emojiPickerPosition: {
44+
top: '40px',
45+
left: '0px'
46+
},
47+
showPicker: false,
48+
search: '',
49+
launcherInstance: null,
50+
maxHeight: 450,
51+
maxWidth: 308
52+
};
53+
},
54+
created() {
55+
document.addEventListener('show-emoji-picker', this.showEmojiPicker);
56+
document.addEventListener('mousedown', this.handleClickOutside);
57+
},
58+
beforeDestroy() {
59+
document.removeEventListener('show-emoji-picker', this.showEmojiPicker);
60+
document.removeEventListener('mousedown', this.handleClickOutside);
61+
},
62+
computed: {
63+
emojis() {
64+
return this.$root.emojiBank;
65+
},
66+
menuX() {
67+
return this.emojiPickerPosition?.left;
68+
},
69+
menuY() {
70+
return this.emojiPickerPosition?.top;
71+
}
72+
},
73+
methods: {
74+
handleClickOutside(event) {
75+
const menuEl = document.querySelector('.pickerMenu');
76+
if (!menuEl?.contains(event.target)) {
77+
this.showPicker = false;
78+
}
79+
},
80+
showEmojiPicker(event) {
81+
const data = event.detail;
82+
this.launcherInstance = data.launcherInstance;
83+
const launcherTop = parseFloat(data.top);
84+
const launcherLeft = parseFloat(data.left);
85+
const menuHeight = this.maxHeight;
86+
87+
const spaceBelow = window.innerHeight - launcherTop;
88+
const showAbove = spaceBelow < menuHeight;
89+
90+
this.emojiPickerPosition = {
91+
top: showAbove ? launcherTop - menuHeight - 45 : launcherTop,
92+
left: launcherLeft - (this.maxWidth + 32) / 2
93+
};
94+
this.showPicker = true;
95+
},
96+
selectEmoji(emoji) {
97+
this.launcherInstance.$emit('select-emoji', emoji);
98+
this.$nextTick(() => {
99+
this.showPicker = false;
100+
});
101+
}
102+
}
103+
};
104+
</script>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<!--
2+
This file is part of the Meeds project (https://meeds.io/).
3+
4+
Copyright (C) 2025 Meeds Association [email protected]
5+
6+
This program is free software; you can redistribute it and/or
7+
modify it under the terms of the GNU Lesser General Public
8+
License as published by the Free Software Foundation; either
9+
version 3 of the License, or (at your option) any later version.
10+
This program is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public License
16+
along with this program; if not, write to the Free Software Foundation,
17+
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18+
-->
19+
20+
<template>
21+
<div class="d-flex my-auto ">
22+
<emoji-picker-quick-emojis
23+
@select-emoji="selectEmoji" />
24+
<v-btn
25+
ref="launcher"
26+
width="28"
27+
height="28"
28+
min-width="28"
29+
class="pa-0"
30+
icon
31+
@click="showEmojiPicker">
32+
<v-icon
33+
size="16"
34+
class="icon-default-color">
35+
fas fa-plus
36+
</v-icon>
37+
</v-btn>
38+
</div>
39+
</template>
40+
41+
<script>
42+
43+
44+
export default {
45+
methods: {
46+
selectEmoji(emoji) {
47+
this.$emit('select-emoji', emoji);
48+
},
49+
showEmojiPicker() {
50+
const button = this.$refs.launcher?.$el;
51+
if (button) {
52+
const rect = button.getBoundingClientRect();
53+
document.dispatchEvent(new CustomEvent('show-emoji-picker', {
54+
detail: {
55+
top: `${rect.bottom + 8}px`,
56+
left: `${rect.left}px`,
57+
launcherInstance: this
58+
}
59+
}));
60+
}
61+
}
62+
}
63+
};
64+
</script>

0 commit comments

Comments
 (0)