diff --git a/src/components/LotteryPage.vue b/src/components/LotteryPage.vue index b0d6454..5306a90 100644 --- a/src/components/LotteryPage.vue +++ b/src/components/LotteryPage.vue @@ -11,9 +11,7 @@ import VirtualLotteryPage from "@/components/VirtualLotteryPage"; export default { components: { - Tabs, - GeneratePage, - VirtualLotteryPage + Tabs }, data() { return { diff --git a/src/components/VirtualLotteryPage.vue b/src/components/VirtualLotteryPage.vue index 38bb08a..cb2730b 100644 --- a/src/components/VirtualLotteryPage.vue +++ b/src/components/VirtualLotteryPage.vue @@ -43,9 +43,11 @@ @@ -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) { diff --git a/src/ui/Chat.vue b/src/ui/Chat.vue index 0ac2a4f..522e214 100644 --- a/src/ui/Chat.vue +++ b/src/ui/Chat.vue @@ -3,12 +3,18 @@

Chat

-
+
+ +
+
- [{{ getTime(history.timestamp) }}] - {{ history.username }}: +
+ {{ history.username }} + {{ getTime(history.timestamp) }} +
{{ history.message }}
@@ -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; } diff --git a/src/ui/Tabs.vue b/src/ui/Tabs.vue index aebc734..b2b7cc2 100644 --- a/src/ui/Tabs.vue +++ b/src/ui/Tabs.vue @@ -10,12 +10,7 @@ >{{ tab.name }}
- +
@@ -54,9 +49,6 @@ export default { h1 { text-align: center; } -.hide { - display: none; -} .tab-container { display: flex;