Make user list and message list components

This commit is contained in:
Pavel Djundik 2018-07-08 20:22:01 +03:00 committed by Pavel Djundik
parent ebb63f2742
commit 9290264fa5
3 changed files with 144 additions and 106 deletions

View File

@ -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;

View 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>

View 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>