Better emoji keyboard

This commit is contained in:
Noah 2023-09-08 19:37:39 -07:00
parent cbfbcd768f
commit 3b06676343
5 changed files with 80 additions and 33 deletions

View File

@ -48,6 +48,21 @@
$modal.classList.add("is-active");
return false;
}
document.addEventListener('DOMContentLoaded', () => {
// Add global body click to hide the hamburger menu for chat settings.
const settingsMenu = document.querySelector("#chat-settings-hamburger-menu");
settingsMenu.addEventListener('click', (e) => {
settingsMenu.classList.toggle('is-active');
e.stopPropagation();
});
document.body.addEventListener('click', () => {
if (settingsMenu != undefined && settingsMenu.classList.contains("is-active")) {
settingsMenu.classList.remove('is-active');
}
})
});
</script>
<script type="module" src="/src/main.js"></script>

27
package-lock.json generated
View File

@ -9,7 +9,8 @@
"version": "0.0.0",
"dependencies": {
"interactjs": "^1.10.18",
"vue": "^3.3.4"
"vue": "^3.3.4",
"vue3-emoji-picker": "^1.1.7"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.3.1",
@ -524,6 +525,15 @@
"node": ">= 8"
}
},
"node_modules/@popperjs/core": {
"version": "2.11.8",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@vitejs/plugin-vue": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.3.4.tgz",
@ -1216,6 +1226,11 @@
"node": ">=8"
}
},
"node_modules/idb": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz",
"integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ=="
},
"node_modules/ignore": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
@ -1932,6 +1947,16 @@
"eslint": ">=6.0.0"
}
},
"node_modules/vue3-emoji-picker": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/vue3-emoji-picker/-/vue3-emoji-picker-1.1.7.tgz",
"integrity": "sha512-dKSI1NyrinYFykllwcOqBB1sw7EHdwQG4tjHYSO+khQkY8Csn4Evn5X2nAdz8Kl8o3P1J0jV4BGwbQ2dVWCxMA==",
"dependencies": {
"@popperjs/core": "^2.11.0",
"idb": "^7.1.0",
"vue": "^3.2.23"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",

View File

@ -11,7 +11,8 @@
},
"dependencies": {
"interactjs": "^1.10.18",
"vue": "^3.3.4"
"vue": "^3.3.4",
"vue3-emoji-picker": "^1.1.7"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.3.1",

View File

@ -3252,8 +3252,9 @@ export default {
<i class="fa fa-fire mr-1" :class="{ 'has-text-danger': !webcam.nsfw }"></i> Explicit
</button>
</div>
<div class="column dropdown is-right is-narrow pl-1"
onclick="this.classList.toggle('is-active')">
<div class="column dropdown is-right is-narrow pl-1" id="chat-settings-hamburger-menu">
<!-- Note: the onclick for the previous div is handled in index.html -->
<div class="dropdown-trigger">
<button type="button" class="button is-small is-link px-2"
aria-haspopup="true"

View File

@ -1,4 +1,7 @@
<script>
import EmojiPicker from 'vue3-emoji-picker';
import 'vue3-emoji-picker/css';
export default {
props: {
message: Object, // chat Message object
@ -15,16 +18,13 @@ export default {
isOp: Boolean, // current user is Operator (always show takeback button)
noButtons: Boolean, // hide all message buttons (e.g. for Report Modal)
},
components: {
EmojiPicker,
},
data() {
return {
reactionsAvailable: [
['❤️', '👍', '😂', '😉', '😢', '😡', '🥰'],
['😘', '👎', '☹️', '😭', '🤔', '🙄', '🤩'],
['👋', '🔥', '😈', '🍑', '🍆', '💦', '🍌'],
['😋', '⭐', '😇', '😴', '😱', '👀', '🎃'],
['🤮', '🥳', '🙏', '🤦', '💩', '🤯', '💯'],
['😏', '🙈', '🙉', '🙊', '☀️', '🌈', '🎂'],
],
// Emoji picker visible
showEmojiPicker: false,
};
},
computed: {
@ -51,10 +51,6 @@ export default {
},
},
methods: {
signIn() {
this.$emit('signIn', this.username);
},
openProfile() {
let url = this.profileURL;
if (url) {
@ -88,6 +84,20 @@ export default {
this.$emit('react', this.message, emoji);
},
// Vue3-emoji-picker callback
onSelectEmoji(emoji) {
this.sendReact(emoji.i);
this.hideEmojiPicker();
},
// Hide the emoji menu (after sending an emoji or clicking the react button again)
hideEmojiPicker() {
if (!this.showEmojiPicker) return;
window.requestAnimationFrame(() => {
this.showEmojiPicker = false;
});
},
urlFor(url) {
// Prepend the base websiteUrl if the given URL is relative.
if (url.match(/^https?:/i)) {
@ -244,12 +254,12 @@ export default {
</button>
</div>
<!-- Emoji reactions menu -->
<div class="column dropdown is-right" :class="{ 'is-up': position >= 2 }"
onclick="this.classList.toggle('is-active')">
<div class="column dropdown is-right" :class="{ 'is-up': position >= 2, 'is-active': showEmojiPicker }"
@click="showEmojiPicker=true">
<div class="dropdown-trigger">
<button class="button is-small px-2" aria-haspopup="true"
:aria-controls="`react-menu-${message.msgID}`">
<button type="button" class="button is-small px-2" aria-haspopup="true"
:aria-controls="`react-menu-${message.msgID}`"
@click="hideEmojiPicker()">
<span>
<i class="fa fa-heart has-text-grey"></i>
<i class="fa fa-plus has-text-grey pl-1"></i>
@ -258,18 +268,13 @@ export default {
</div>
<div class="dropdown-menu" :id="`react-menu-${message.msgID}`" role="menu">
<div class="dropdown-content p-0">
<!-- Iterate over reactions in rows of emojis-->
<div class="columns is-mobile ml-0 mb-2 mr-1"
v-for="row in reactionsAvailable">
<!-- Loop over the icons -->
<div class="column p-0 is-narrow" v-for="i in row">
<button type="button" class="button px-2 mt-1 ml-1 mr-0 mb-1"
@click="sendReact(i)">
{{ i }}
</button>
</div>
</div>
<!-- Emoji reactions menu -->
<EmojiPicker
:native="true"
:display-recent="true"
:disable-skin-tones="true"
theme="auto"
@select="onSelectEmoji"></EmojiPicker>
</div>
</div>
</div>