Merge pull request #17 from KevinMidboe/refactor/chat-history

Refactor/chat history
This commit is contained in:
2020-06-26 13:28:59 +02:00
committed by GitHub
4 changed files with 104 additions and 26 deletions

View File

@@ -11,9 +11,7 @@ import VirtualLotteryPage from "@/components/VirtualLotteryPage";
export default {
components: {
Tabs,
GeneratePage,
VirtualLotteryPage
Tabs
},
data() {
return {

View File

@@ -43,9 +43,11 @@
<Chat
class="outer-chat"
:chatHistory="chatHistory"
:historyPageSize="historyPageSize"
:usernameAllowed="usernameAllowed"
v-on:message="sendMessage"
v-on:username="setUsername"
@loadMoreHistory="loadMoreHistory"
@message="sendMessage"
@username="setUsername"
/>
</div>
<Vipps class="vipps" :amount="1" />
@@ -74,6 +76,9 @@ export default {
attendeesFetched: false,
winnersFetched: false,
chatHistory: [],
historyPage: 0,
historyPageSize: 100,
lastHistoryPage: false,
usernameAccepted: false,
username: null,
wasDisconnected: false,
@@ -158,6 +163,15 @@ export default {
sendMessage: function(msg) {
this.socket.emit("chat", { message: msg });
},
loadMoreHistory: function() {
const { historyPage, historyPageSize } = this;
const page = historyPage + 1;
getChatHistory(page * historyPageSize, historyPageSize).then(messages => {
this.chatHistory = messages.concat(this.chatHistory);
this.historyPage = page;
});
},
getWinners: async function() {
let response = await winners();
if (response) {

View File

@@ -3,12 +3,18 @@
<hr />
<h2>Chat</h2>
<div class="history" ref="history">
<div
<div class="opaque-skirt"></div>
<div v-if="existsMore" class="fetch-older-history">
<button @click="$emit('loadMoreHistory')">Hent eldre meldinger</button>
</div>
<div class="history-message"
v-for="(history, index) in chatHistory"
:key="`${history.username}-${history.timestamp}-${index}`"
>
<span class="timestamp">[{{ getTime(history.timestamp) }}]</span>
<span class="user-name">{{ history.username }}:</span>
<div>
<span class="user-name">{{ history.username }}</span>
<span class="timestamp">{{ getTime(history.timestamp) }}</span>
</div>
<span class="message">{{ history.message }}</span>
</div>
</div>
@@ -38,6 +44,9 @@ export default {
},
chatHistory: {
type: Array
},
historyPageSize: {
type: Number
}
},
data() {
@@ -45,16 +54,27 @@ export default {
message: "",
temporaryUsername: null,
username: null,
usernameSet: false
usernameSet: false,
existsMore: true
};
},
watch: {
chatHistory: {
handler() {
handler: function(newVal, oldVal) {
if (this.$refs && this.$refs.history) {
const firstMessages = oldVal.length == 0;
const diffLargerThanOne = newVal.length - oldVal.length > 1;
setTimeout(() => {
this.$refs.history.scrollTop = this.$refs.history.scrollHeight;
}, 10);
if (firstMessages || diffLargerThanOne == false) {
this.scrollToBottomOfHistory();
} else {
this.scrollToStartOfNewMessages();
// what shows the load more button - if we scroll page and less than page size
// come back we have reached a limit
this.existsMore = newVal.length - oldVal.length == this.historyPageSize
}
}, 100);
}
},
deep: true
@@ -62,12 +82,11 @@ export default {
},
mounted() {
let username = window.localStorage.getItem("username");
if (!username) {
return;
if (username) {
this.username = username;
this.usernameSet = true;
this.$emit("username", username);
}
this.username = username;
this.usernameSet = true;
this.$emit("username", username);
},
methods: {
pad: function(num) {
@@ -105,6 +124,20 @@ export default {
this.usernameSet = true;
this.$emit("username", this.username);
}
},
scrollToBottomOfHistory() {
if (this.$refs && this.$refs.history) {
const { history } = this.$refs;
history.scrollTop = history.scrollHeight;
}
},
scrollToStartOfNewMessages() {
const { history } = this.$refs;
const histLength = history.children.length;
const pages = Math.floor(histLength / 100);
const messageToScrollTo = history.children[histLength - ((pages * 100) + 3)]
history.scrollTop = messageToScrollTo.offsetTop;
}
}
};
@@ -127,6 +160,7 @@ hr {
.chat-container {
height: 100%;
width: 50%;
position: relative;
@include mobile {
width: 100%;
@@ -146,6 +180,46 @@ input {
height: 75%;
overflow-y: scroll;
&-message {
display: flex;
flex-direction: column;
margin: 0.35rem 0;
position: relative;
.user-name {
font-weight: bold;
font-size: 1.05rem;
margin-right: 0.3rem;
}
.timestamp {
font-size: 0.9rem;
top: 2px;
position: absolute;
}
}
&-message:nth-of-type(2) {
margin-top: 1rem;
}
& .opaque-skirt {
width: 100%;
position: absolute;
height: 1rem;
z-index: 1;
background: linear-gradient(
to bottom,
white,
rgba(255, 255, 255, 0)
);
}
& .fetch-older-history {
display: flex;
justify-content: center;
margin: 0.2rem 0 0.5rem;
}
@include mobile {
height: 300px;
}

View File

@@ -10,12 +10,7 @@
>{{ tab.name }}</div>
</div>
<div class="tab-elements">
<component
v-for="(tab, index) in tabs"
:key="index"
:is="tab.component"
:class="chosenTab == index ? null : 'hide'"
/>
<component :is="tabs[chosenTab].component" />
</div>
</div>
</template>
@@ -54,9 +49,6 @@ export default {
h1 {
text-align: center;
}
.hide {
display: none;
}
.tab-container {
display: flex;