Make user list and message list components
This commit is contained in:
parent
ebb63f2742
commit
9290264fa5
@ -51,62 +51,11 @@
|
|||||||
v-else
|
v-else
|
||||||
class="btn">Show older messages</button>
|
class="btn">Show older messages</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<MessageList :channel="channel"/>
|
||||||
class="messages"
|
|
||||||
role="log"
|
|
||||||
aria-live="polite"
|
|
||||||
aria-relevant="additions"
|
|
||||||
>
|
|
||||||
<template v-for="(message, id) in channel.messages">
|
|
||||||
<div
|
|
||||||
v-if="shouldDisplayDateMarker(id)"
|
|
||||||
:key="message.id + '-date'"
|
|
||||||
:data-time="message.time"
|
|
||||||
:aria-label="message.time | localedate"
|
|
||||||
class="date-marker-container tooltipped tooltipped-s"
|
|
||||||
>
|
|
||||||
<div class="date-marker">
|
|
||||||
<span
|
|
||||||
:data-label="message.time | friendlydate"
|
|
||||||
class="date-marker-text"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="shouldDisplayUnreadMarker(message.id)"
|
|
||||||
:key="message.id + '-unread'"
|
|
||||||
class="unread-marker"
|
|
||||||
>
|
|
||||||
<span class="unread-marker-text"/>
|
|
||||||
</div>
|
|
||||||
<Message
|
|
||||||
:message="message"
|
|
||||||
:key="message.id"/>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<aside
|
<ChatUserList
|
||||||
v-if="channel.type === 'channel'"
|
v-if="channel.type === 'channel'"
|
||||||
class="userlist">
|
:channel="channel"/>
|
||||||
<div class="count">
|
|
||||||
<input
|
|
||||||
:placeholder="channel.users.length + ' user' + (channel.users.length === 1 ? '' : 's')"
|
|
||||||
type="search"
|
|
||||||
class="search"
|
|
||||||
aria-label="Search among the user list"
|
|
||||||
tabindex="-1">
|
|
||||||
</div>
|
|
||||||
<div class="names">
|
|
||||||
<div
|
|
||||||
v-for="(users, mode) in groupedUsers"
|
|
||||||
:key="mode"
|
|
||||||
:class="['user-mode', getModeClass(mode)]">
|
|
||||||
<Username
|
|
||||||
v-for="user in users"
|
|
||||||
:key="user.nick"
|
|
||||||
:user="user"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</aside>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -120,46 +69,21 @@
|
|||||||
<script>
|
<script>
|
||||||
require("intersection-observer");
|
require("intersection-observer");
|
||||||
const socket = require("../js/socket");
|
const socket = require("../js/socket");
|
||||||
import Message from "./Message.vue";
|
import MessageList from "./MessageList.vue";
|
||||||
import Username from "./Username.vue";
|
|
||||||
import ChatInput from "./ChatInput.vue";
|
import ChatInput from "./ChatInput.vue";
|
||||||
|
import ChatUserList from "./ChatUserList.vue";
|
||||||
const modes = {
|
|
||||||
"~": "owner",
|
|
||||||
"&": "admin",
|
|
||||||
"!": "admin",
|
|
||||||
"@": "op",
|
|
||||||
"%": "half-op",
|
|
||||||
"+": "voice",
|
|
||||||
"": "normal",
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Chat",
|
name: "Chat",
|
||||||
components: {
|
components: {
|
||||||
Message,
|
MessageList,
|
||||||
Username,
|
|
||||||
ChatInput,
|
ChatInput,
|
||||||
|
ChatUserList,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
network: Object,
|
network: Object,
|
||||||
channel: Object,
|
channel: Object,
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
groupedUsers() {
|
|
||||||
const groups = {};
|
|
||||||
|
|
||||||
for (const user of this.channel.users) {
|
|
||||||
if (!groups[user.mode]) {
|
|
||||||
groups[user.mode] = [user];
|
|
||||||
} else {
|
|
||||||
groups[user.mode].push(user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return groups;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
created() {
|
||||||
if (window.IntersectionObserver) {
|
if (window.IntersectionObserver) {
|
||||||
this.historyObserver = new window.IntersectionObserver(loadMoreHistory, {
|
this.historyObserver = new window.IntersectionObserver(loadMoreHistory, {
|
||||||
@ -178,29 +102,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
shouldDisplayDateMarker(id) {
|
|
||||||
const previousTime = this.channel.messages[id - 1];
|
|
||||||
|
|
||||||
if (!previousTime) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentTime = this.channel.messages[id];
|
|
||||||
|
|
||||||
return (new Date(previousTime.time)).getDay() !== (new Date(currentTime.time)).getDay();
|
|
||||||
},
|
|
||||||
shouldDisplayUnreadMarker(msgId) {
|
|
||||||
if (this.channel.firstUnread < msgId) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.channel.firstUnread = 0;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
getModeClass(mode) {
|
|
||||||
return modes[mode];
|
|
||||||
},
|
|
||||||
onShowMoreClick() {
|
onShowMoreClick() {
|
||||||
let lastMessage = this.channel.messages[0];
|
let lastMessage = this.channel.messages[0];
|
||||||
lastMessage = lastMessage ? lastMessage.id : -1;
|
lastMessage = lastMessage ? lastMessage.id : -1;
|
||||||
|
67
client/components/ChatUserList.vue
Normal file
67
client/components/ChatUserList.vue
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<template>
|
||||||
|
<aside class="userlist">
|
||||||
|
<div class="count">
|
||||||
|
<input
|
||||||
|
:placeholder="channel.users.length + ' user' + (channel.users.length === 1 ? '' : 's')"
|
||||||
|
type="search"
|
||||||
|
class="search"
|
||||||
|
aria-label="Search among the user list"
|
||||||
|
tabindex="-1">
|
||||||
|
</div>
|
||||||
|
<div class="names">
|
||||||
|
<div
|
||||||
|
v-for="(users, mode) in groupedUsers"
|
||||||
|
:key="mode"
|
||||||
|
:class="['user-mode', getModeClass(mode)]">
|
||||||
|
<Username
|
||||||
|
v-for="user in users"
|
||||||
|
:key="user.nick"
|
||||||
|
:user="user"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Username from "./Username.vue";
|
||||||
|
|
||||||
|
const modes = {
|
||||||
|
"~": "owner",
|
||||||
|
"&": "admin",
|
||||||
|
"!": "admin",
|
||||||
|
"@": "op",
|
||||||
|
"%": "half-op",
|
||||||
|
"+": "voice",
|
||||||
|
"": "normal",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ChatUserList",
|
||||||
|
components: {
|
||||||
|
Username,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
channel: Object,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
groupedUsers() {
|
||||||
|
const groups = {};
|
||||||
|
|
||||||
|
for (const user of this.channel.users) {
|
||||||
|
if (!groups[user.mode]) {
|
||||||
|
groups[user.mode] = [user];
|
||||||
|
} else {
|
||||||
|
groups[user.mode].push(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return groups;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getModeClass(mode) {
|
||||||
|
return modes[mode];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
70
client/components/MessageList.vue
Normal file
70
client/components/MessageList.vue
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="messages"
|
||||||
|
role="log"
|
||||||
|
aria-live="polite"
|
||||||
|
aria-relevant="additions"
|
||||||
|
>
|
||||||
|
<template v-for="(message, id) in channel.messages">
|
||||||
|
<div
|
||||||
|
v-if="shouldDisplayDateMarker(id)"
|
||||||
|
:key="message.id + '-date'"
|
||||||
|
:data-time="message.time"
|
||||||
|
:aria-label="message.time | localedate"
|
||||||
|
class="date-marker-container tooltipped tooltipped-s"
|
||||||
|
>
|
||||||
|
<div class="date-marker">
|
||||||
|
<span
|
||||||
|
:data-label="message.time | friendlydate"
|
||||||
|
class="date-marker-text"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="shouldDisplayUnreadMarker(message.id)"
|
||||||
|
:key="message.id + '-unread'"
|
||||||
|
class="unread-marker"
|
||||||
|
>
|
||||||
|
<span class="unread-marker-text"/>
|
||||||
|
</div>
|
||||||
|
<Message
|
||||||
|
:message="message"
|
||||||
|
:key="message.id"/>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Message from "./Message.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "MessageList",
|
||||||
|
components: {
|
||||||
|
Message,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
channel: Object,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
shouldDisplayDateMarker(id) {
|
||||||
|
const previousTime = this.channel.messages[id - 1];
|
||||||
|
|
||||||
|
if (!previousTime) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentTime = this.channel.messages[id];
|
||||||
|
|
||||||
|
return (new Date(previousTime.time)).getDay() !== (new Date(currentTime.time)).getDay();
|
||||||
|
},
|
||||||
|
shouldDisplayUnreadMarker(msgId) {
|
||||||
|
if (this.channel.firstUnread < msgId) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.channel.firstUnread = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
Loading…
Reference in New Issue
Block a user