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",
|
"name": "barertc",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"floating-vue": "^2.0.0-beta.24",
|
||||||
"interactjs": "^1.10.18",
|
"interactjs": "^1.10.18",
|
||||||
"vue": "^3.3.4",
|
"vue": "^3.3.4",
|
||||||
|
"vue-mention": "^2.0.0-alpha.3",
|
||||||
"vue3-emoji-picker": "^1.1.7"
|
"vue3-emoji-picker": "^1.1.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -447,6 +449,27 @@
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"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": {
|
"node_modules/@humanwhocodes/config-array": {
|
||||||
"version": "0.11.11",
|
"version": "0.11.11",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
|
"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==",
|
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
|
||||||
"dev": true
|
"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": {
|
"node_modules/fs.realpath": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
|
@ -1817,6 +1858,11 @@
|
||||||
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||||
"dev": true
|
"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": {
|
"node_modules/type-check": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||||
|
@ -1947,6 +1993,26 @@
|
||||||
"eslint": ">=6.0.0"
|
"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": {
|
"node_modules/vue3-emoji-picker": {
|
||||||
"version": "1.1.7",
|
"version": "1.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/vue3-emoji-picker/-/vue3-emoji-picker-1.1.7.tgz",
|
"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"
|
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"floating-vue": "^2.0.0-beta.24",
|
||||||
"interactjs": "^1.10.18",
|
"interactjs": "^1.10.18",
|
||||||
"vue": "^3.3.4",
|
"vue": "^3.3.4",
|
||||||
|
"vue-mention": "^2.0.0-alpha.3",
|
||||||
"vue3-emoji-picker": "^1.1.7"
|
"vue3-emoji-picker": "^1.1.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
background-color: rgba(15, 129, 204, 0.25) !important;
|
background-color: rgba(15, 129, 204, 0.25) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.has-background-at-mention {
|
||||||
|
background-color: rgb(50, 50, 0);
|
||||||
|
}
|
||||||
|
|
||||||
.tag.is-success {
|
.tag.is-success {
|
||||||
background-color: #15241d !important;
|
background-color: #15241d !important;
|
||||||
color: #85dfb6 !important;
|
color: #85dfb6 !important;
|
||||||
|
|
|
@ -22,6 +22,9 @@ body {
|
||||||
.has-background-dm {
|
.has-background-dm {
|
||||||
background-color: #ffefff;
|
background-color: #ffefff;
|
||||||
}
|
}
|
||||||
|
.has-background-at-mention {
|
||||||
|
background-color: rgb(250, 250, 192);
|
||||||
|
}
|
||||||
|
|
||||||
/* Truncate long text, e.g. usernames in the who list */
|
/* Truncate long text, e.g. usernames in the who list */
|
||||||
.truncate-text-line {
|
.truncate-text-line {
|
||||||
|
|
99
src/App.vue
99
src/App.vue
|
@ -1,5 +1,9 @@
|
||||||
<script>
|
<script>
|
||||||
import interact from 'interactjs';
|
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 LoginModal from './components/LoginModal.vue';
|
||||||
import ExplicitOpenModal from './components/ExplicitOpenModal.vue';
|
import ExplicitOpenModal from './components/ExplicitOpenModal.vue';
|
||||||
import ReportModal from './components/ReportModal.vue';
|
import ReportModal from './components/ReportModal.vue';
|
||||||
|
@ -32,6 +36,9 @@ const FileUploadMaxSize = 1024 * 1024 * 8; // 8 MB
|
||||||
export default {
|
export default {
|
||||||
name: 'BareRTC',
|
name: 'BareRTC',
|
||||||
components: {
|
components: {
|
||||||
|
FloatingVue,
|
||||||
|
Mentionable,
|
||||||
|
|
||||||
LoginModal,
|
LoginModal,
|
||||||
ExplicitOpenModal,
|
ExplicitOpenModal,
|
||||||
ReportModal,
|
ReportModal,
|
||||||
|
@ -517,6 +524,27 @@ export default {
|
||||||
// Return the count of other peoples videos we have open.
|
// Return the count of other peoples videos we have open.
|
||||||
return Object.keys(this.WebRTC.streams).length;
|
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() {
|
sortedWhoList() {
|
||||||
let result = [...this.whoList];
|
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.
|
// Append the message.
|
||||||
this.channels[channel].updated = new Date().getTime();
|
this.channels[channel].updated = new Date().getTime();
|
||||||
|
@ -3617,9 +3653,35 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
<div class="column pr-1" :class="{ 'pl-1': canUploadFile }">
|
<div class="column pr-1" :class="{ 'pl-1': canUploadFile }">
|
||||||
<form @submit.prevent="sendMessage()">
|
<form @submit.prevent="sendMessage()">
|
||||||
<input type="text" class="input" id="messageBox" v-model="message"
|
|
||||||
placeholder="Write a message" @keydown="sendTypingNotification()" autocomplete="off"
|
<!-- At Mentions -->
|
||||||
:disabled="!ws.connected">
|
<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>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="column pl-1 is-narrow">
|
<div class="column pl-1 is-narrow">
|
||||||
|
@ -3763,31 +3825,14 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style>
|
||||||
/* header {
|
/* At-mention styles */
|
||||||
line-height: 1.5;
|
.mention-item {
|
||||||
|
padding: 4px 10px;
|
||||||
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.mention-selected {
|
||||||
display: block;
|
background: rgb(192, 250, 153);
|
||||||
margin: 0 auto 2rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@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>
|
</style>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user