At-mention popups for chat
This commit is contained in:
parent
3b06676343
commit
f091747380
66
package-lock.json
generated
66
package-lock.json
generated
|
@ -8,8 +8,10 @@
|
|||
"name": "barertc",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"floating-vue": "^2.0.0-beta.24",
|
||||
"interactjs": "^1.10.18",
|
||||
"vue": "^3.3.4",
|
||||
"vue-mention": "^2.0.0-alpha.3",
|
||||
"vue3-emoji-picker": "^1.1.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -447,6 +449,27 @@
|
|||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/core": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.4.1.tgz",
|
||||
"integrity": "sha512-jk3WqquEJRlcyu7997NtR5PibI+y5bi+LS3hPmguVClypenMsCY3CBa3LAQnozRCtCrYWSEtAdiskpamuJRFOQ==",
|
||||
"dependencies": {
|
||||
"@floating-ui/utils": "^0.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/dom": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.1.1.tgz",
|
||||
"integrity": "sha512-TpIO93+DIujg3g7SykEAGZMDtbJRrmnYRCNYSjJlvIbGhBjRSNTLVbNeDQBrzy9qDgUbiWdc7KA0uZHZ2tJmiw==",
|
||||
"dependencies": {
|
||||
"@floating-ui/core": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/utils": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.1.tgz",
|
||||
"integrity": "sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw=="
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.11.11",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
|
||||
|
@ -1144,6 +1167,24 @@
|
|||
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/floating-vue": {
|
||||
"version": "2.0.0-beta.24",
|
||||
"resolved": "https://registry.npmjs.org/floating-vue/-/floating-vue-2.0.0-beta.24.tgz",
|
||||
"integrity": "sha512-URSzP6YXaF4u1oZ9XGL8Sn8puuM7ivp5jkOUrpy5Q1mfo9BfGppJOn+ierTmsSUfJEeHBae8KT7r5DeI3vQIEw==",
|
||||
"dependencies": {
|
||||
"@floating-ui/dom": "~1.1.1",
|
||||
"vue-resize": "^2.0.0-alpha.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nuxt/kit": "^3.2.0",
|
||||
"vue": "^3.2.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@nuxt/kit": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
|
@ -1817,6 +1858,11 @@
|
|||
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/textarea-caret": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/textarea-caret/-/textarea-caret-3.1.0.tgz",
|
||||
"integrity": "sha512-cXAvzO9pP5CGa6NKx0WYHl+8CHKZs8byMkt3PCJBCmq2a34YA9pO1NrQET5pzeqnBjBdToF5No4rrmkDUgQC2Q=="
|
||||
},
|
||||
"node_modules/type-check": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||
|
@ -1947,6 +1993,26 @@
|
|||
"eslint": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-mention": {
|
||||
"version": "2.0.0-alpha.3",
|
||||
"resolved": "https://registry.npmjs.org/vue-mention/-/vue-mention-2.0.0-alpha.3.tgz",
|
||||
"integrity": "sha512-NtM6Z6UpqHByKJPyiy2SrBy3K7wyi/6bvXltaRfWcSQdNwW3YrWzrr1M7lYB4NoWRhDFuk+4X1GpY8HH06g+XQ==",
|
||||
"dependencies": {
|
||||
"textarea-caret": "^3.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"floating-vue": "^2.0.0-beta.1",
|
||||
"vue": "^3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-resize": {
|
||||
"version": "2.0.0-alpha.1",
|
||||
"resolved": "https://registry.npmjs.org/vue-resize/-/vue-resize-2.0.0-alpha.1.tgz",
|
||||
"integrity": "sha512-7+iqOueLU7uc9NrMfrzbG8hwMqchfVfSzpVlCMeJQe4pyibqyoifDNbKTZvwxZKDvGkB+PdFeKvnGZMoEb8esg==",
|
||||
"peerDependencies": {
|
||||
"vue": "^3.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",
|
||||
|
|
|
@ -10,8 +10,10 @@
|
|||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
|
||||
},
|
||||
"dependencies": {
|
||||
"floating-vue": "^2.0.0-beta.24",
|
||||
"interactjs": "^1.10.18",
|
||||
"vue": "^3.3.4",
|
||||
"vue-mention": "^2.0.0-alpha.3",
|
||||
"vue3-emoji-picker": "^1.1.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
background-color: rgba(15, 129, 204, 0.25) !important;
|
||||
}
|
||||
|
||||
.has-background-at-mention {
|
||||
background-color: rgb(50, 50, 0);
|
||||
}
|
||||
|
||||
.tag.is-success {
|
||||
background-color: #15241d !important;
|
||||
color: #85dfb6 !important;
|
||||
|
|
|
@ -22,6 +22,9 @@ body {
|
|||
.has-background-dm {
|
||||
background-color: #ffefff;
|
||||
}
|
||||
.has-background-at-mention {
|
||||
background-color: rgb(250, 250, 192);
|
||||
}
|
||||
|
||||
/* Truncate long text, e.g. usernames in the who list */
|
||||
.truncate-text-line {
|
||||
|
|
99
src/App.vue
99
src/App.vue
|
@ -1,5 +1,9 @@
|
|||
<script>
|
||||
import interact from 'interactjs';
|
||||
import FloatingVue from 'floating-vue';
|
||||
import 'floating-vue/dist/style.css';
|
||||
import { Mentionable } from 'vue-mention';
|
||||
|
||||
import LoginModal from './components/LoginModal.vue';
|
||||
import ExplicitOpenModal from './components/ExplicitOpenModal.vue';
|
||||
import ReportModal from './components/ReportModal.vue';
|
||||
|
@ -32,6 +36,9 @@ const FileUploadMaxSize = 1024 * 1024 * 8; // 8 MB
|
|||
export default {
|
||||
name: 'BareRTC',
|
||||
components: {
|
||||
FloatingVue,
|
||||
Mentionable,
|
||||
|
||||
LoginModal,
|
||||
ExplicitOpenModal,
|
||||
ReportModal,
|
||||
|
@ -517,6 +524,27 @@ export default {
|
|||
// Return the count of other peoples videos we have open.
|
||||
return Object.keys(this.WebRTC.streams).length;
|
||||
},
|
||||
atMentionItems() {
|
||||
// Available users in chat for the at-mentions support.
|
||||
let result = [
|
||||
{
|
||||
value: "all",
|
||||
label: "All people in the current room",
|
||||
},
|
||||
{
|
||||
value: "here",
|
||||
label: "Everybody here in the current room",
|
||||
},
|
||||
];
|
||||
for (let user of this.whoList) {
|
||||
if (user.username === this.username) continue;
|
||||
result.push({
|
||||
value: user.username,
|
||||
label: user.nickname,
|
||||
});
|
||||
}
|
||||
return result;
|
||||
},
|
||||
sortedWhoList() {
|
||||
let result = [...this.whoList];
|
||||
|
||||
|
@ -2371,6 +2399,14 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
// Were we at mentioned in this message?
|
||||
if (message.indexOf("@"+this.username) > -1) {
|
||||
let re = new RegExp("@"+this.username+"\\b");
|
||||
message = message.replace(re, `<strong class="has-background-at-mention">@${this.username}</strong>`);
|
||||
}
|
||||
|
||||
// And same for @here or @all
|
||||
message = message.replace(/@(here|all)\b/i, `<strong class="has-background-at-mention">@$1</strong>`);
|
||||
|
||||
// Append the message.
|
||||
this.channels[channel].updated = new Date().getTime();
|
||||
|
@ -3617,9 +3653,35 @@ export default {
|
|||
</div>
|
||||
<div class="column pr-1" :class="{ 'pl-1': canUploadFile }">
|
||||
<form @submit.prevent="sendMessage()">
|
||||
<input type="text" class="input" id="messageBox" v-model="message"
|
||||
placeholder="Write a message" @keydown="sendTypingNotification()" autocomplete="off"
|
||||
:disabled="!ws.connected">
|
||||
|
||||
<!-- At Mentions -->
|
||||
<Mentionable
|
||||
:keys="['@']"
|
||||
:items="atMentionItems"
|
||||
offset="12"
|
||||
insert-space>
|
||||
|
||||
<!-- My text entry box -->
|
||||
<input type="text" class="input" id="messageBox" v-model="message"
|
||||
placeholder="Write a message" @keydown="sendTypingNotification()" autocomplete="off"
|
||||
:disabled="!ws.connected">
|
||||
|
||||
<!-- At Mention templates-->
|
||||
<template #no-result>
|
||||
<div class="has-text-grey m-2">
|
||||
No result
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #item-@="{ item }">
|
||||
<div class="has-text-link m-2">
|
||||
@{{ item.value }}
|
||||
<span class="has-text-grey">
|
||||
{{ item.label }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</Mentionable>
|
||||
</form>
|
||||
</div>
|
||||
<div class="column pl-1 is-narrow">
|
||||
|
@ -3763,31 +3825,14 @@ export default {
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* header {
|
||||
line-height: 1.5;
|
||||
<style>
|
||||
/* At-mention styles */
|
||||
.mention-item {
|
||||
padding: 4px 10px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: block;
|
||||
margin: 0 auto 2rem;
|
||||
.mention-selected {
|
||||
background: rgb(192, 250, 153);
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
header {
|
||||
display: flex;
|
||||
place-items: center;
|
||||
padding-right: calc(var(--section-gap) / 2);
|
||||
}
|
||||
|
||||
.logo {
|
||||
margin: 0 2rem 0 0;
|
||||
}
|
||||
|
||||
header .wrapper {
|
||||
display: flex;
|
||||
place-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
} */
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue
Block a user