Merge pull request #17 from KevinMidboe/refactor/chat-history
Refactor/chat history
This commit is contained in:
@@ -11,9 +11,7 @@ import VirtualLotteryPage from "@/components/VirtualLotteryPage";
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Tabs,
|
Tabs
|
||||||
GeneratePage,
|
|
||||||
VirtualLotteryPage
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -43,9 +43,11 @@
|
|||||||
<Chat
|
<Chat
|
||||||
class="outer-chat"
|
class="outer-chat"
|
||||||
:chatHistory="chatHistory"
|
:chatHistory="chatHistory"
|
||||||
|
:historyPageSize="historyPageSize"
|
||||||
:usernameAllowed="usernameAllowed"
|
:usernameAllowed="usernameAllowed"
|
||||||
v-on:message="sendMessage"
|
@loadMoreHistory="loadMoreHistory"
|
||||||
v-on:username="setUsername"
|
@message="sendMessage"
|
||||||
|
@username="setUsername"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Vipps class="vipps" :amount="1" />
|
<Vipps class="vipps" :amount="1" />
|
||||||
@@ -74,6 +76,9 @@ export default {
|
|||||||
attendeesFetched: false,
|
attendeesFetched: false,
|
||||||
winnersFetched: false,
|
winnersFetched: false,
|
||||||
chatHistory: [],
|
chatHistory: [],
|
||||||
|
historyPage: 0,
|
||||||
|
historyPageSize: 100,
|
||||||
|
lastHistoryPage: false,
|
||||||
usernameAccepted: false,
|
usernameAccepted: false,
|
||||||
username: null,
|
username: null,
|
||||||
wasDisconnected: false,
|
wasDisconnected: false,
|
||||||
@@ -158,6 +163,15 @@ export default {
|
|||||||
sendMessage: function(msg) {
|
sendMessage: function(msg) {
|
||||||
this.socket.emit("chat", { message: 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() {
|
getWinners: async function() {
|
||||||
let response = await winners();
|
let response = await winners();
|
||||||
if (response) {
|
if (response) {
|
||||||
|
|||||||
@@ -3,12 +3,18 @@
|
|||||||
<hr />
|
<hr />
|
||||||
<h2>Chat</h2>
|
<h2>Chat</h2>
|
||||||
<div class="history" ref="history">
|
<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"
|
v-for="(history, index) in chatHistory"
|
||||||
:key="`${history.username}-${history.timestamp}-${index}`"
|
:key="`${history.username}-${history.timestamp}-${index}`"
|
||||||
>
|
>
|
||||||
<span class="timestamp">[{{ getTime(history.timestamp) }}]</span>
|
<div>
|
||||||
<span class="user-name">{{ history.username }}:</span>
|
<span class="user-name">{{ history.username }}</span>
|
||||||
|
<span class="timestamp">{{ getTime(history.timestamp) }}</span>
|
||||||
|
</div>
|
||||||
<span class="message">{{ history.message }}</span>
|
<span class="message">{{ history.message }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -38,6 +44,9 @@ export default {
|
|||||||
},
|
},
|
||||||
chatHistory: {
|
chatHistory: {
|
||||||
type: Array
|
type: Array
|
||||||
|
},
|
||||||
|
historyPageSize: {
|
||||||
|
type: Number
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@@ -45,16 +54,27 @@ export default {
|
|||||||
message: "",
|
message: "",
|
||||||
temporaryUsername: null,
|
temporaryUsername: null,
|
||||||
username: null,
|
username: null,
|
||||||
usernameSet: false
|
usernameSet: false,
|
||||||
|
existsMore: true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
chatHistory: {
|
chatHistory: {
|
||||||
handler() {
|
handler: function(newVal, oldVal) {
|
||||||
if (this.$refs && this.$refs.history) {
|
if (this.$refs && this.$refs.history) {
|
||||||
|
const firstMessages = oldVal.length == 0;
|
||||||
|
const diffLargerThanOne = newVal.length - oldVal.length > 1;
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.$refs.history.scrollTop = this.$refs.history.scrollHeight;
|
if (firstMessages || diffLargerThanOne == false) {
|
||||||
}, 10);
|
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
|
deep: true
|
||||||
@@ -62,12 +82,11 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
let username = window.localStorage.getItem("username");
|
let username = window.localStorage.getItem("username");
|
||||||
if (!username) {
|
if (username) {
|
||||||
return;
|
this.username = username;
|
||||||
|
this.usernameSet = true;
|
||||||
|
this.$emit("username", username);
|
||||||
}
|
}
|
||||||
this.username = username;
|
|
||||||
this.usernameSet = true;
|
|
||||||
this.$emit("username", username);
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
pad: function(num) {
|
pad: function(num) {
|
||||||
@@ -105,6 +124,20 @@ export default {
|
|||||||
this.usernameSet = true;
|
this.usernameSet = true;
|
||||||
this.$emit("username", this.username);
|
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 {
|
.chat-container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
@include mobile {
|
@include mobile {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -146,6 +180,46 @@ input {
|
|||||||
height: 75%;
|
height: 75%;
|
||||||
overflow-y: scroll;
|
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 {
|
@include mobile {
|
||||||
height: 300px;
|
height: 300px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,7 @@
|
|||||||
>{{ tab.name }}</div>
|
>{{ tab.name }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-elements">
|
<div class="tab-elements">
|
||||||
<component
|
<component :is="tabs[chosenTab].component" />
|
||||||
v-for="(tab, index) in tabs"
|
|
||||||
:key="index"
|
|
||||||
:is="tab.component"
|
|
||||||
:class="chosenTab == index ? null : 'hide'"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -54,9 +49,6 @@ export default {
|
|||||||
h1 {
|
h1 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.hide {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-container {
|
.tab-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
Reference in New Issue
Block a user