|
|
|
|
@@ -1,41 +1,73 @@
|
|
|
|
|
<template>
|
|
|
|
|
<div style="width:100%;display: flex; align-items: center; justify-content: space-between;height:100vh;">
|
|
|
|
|
<div style="background: gray; width: 30%;height:100%;padding: 20px;">
|
|
|
|
|
<div>
|
|
|
|
|
<div style="width:100%;display: flex; align-items: center; justify-content: space-between;height:100vh;position: fixed;">
|
|
|
|
|
<div style="background: gray; width: 25%;height:100%;">
|
|
|
|
|
<div style="display: flex; align-items: center; justify-content: space-between;" class="navigation">
|
|
|
|
|
<div title="Nach Nutzern suchen" @click="activeMenu = 'search'" :class="{menuItemActive : activeMenu === 'search', menuItemInactive : activeMenu !== 'search'}">
|
|
|
|
|
<q-icon name="search"></q-icon>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div title="Meine Chats anzeigen" @click="activeMenu = 'chats'" :class="{menuItemActive : activeMenu === 'chats', menuItemInactive : activeMenu !== 'chats'}">
|
|
|
|
|
<q-icon name="chat"></q-icon>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div style="margin: 20px;" v-if="activeMenu == 'search'">
|
|
|
|
|
<q-input filled v-model="searchQuery" placeholder="Nach Nutzern suchen">
|
|
|
|
|
<template v-slot:prepend>
|
|
|
|
|
<q-icon name="search"></q-icon>
|
|
|
|
|
</template>
|
|
|
|
|
</q-input>
|
|
|
|
|
<p>{{searchQuery}}</p>
|
|
|
|
|
|
|
|
|
|
<ProfileCardComponent displayName="Max Mustermann" username="maxmustermann" profilePictureUrl="https://th.bing.com/th/id/OIP.ab5MRsPm1MXfNDVSMW6cjQHaHa?rs=1&pid=ImgDetMain" status="Hey there!"></ProfileCardComponent>
|
|
|
|
|
|
|
|
|
|
<div v-if="userStore.usersLoaded && searchQuery.length > 0" style="margin-top: 20px;">
|
|
|
|
|
<ProfileCardComponent v-for="user in userStore.users.filter(u => u.username.includes(searchQuery) || searchQuery == '*')" :displayName="user.firstName + ' ' + user.lastName" :username="user.username" profilePictureUrl="https://th.bing.com/th/id/OIP.ab5MRsPm1MXfNDVSMW6cjQHaHa?rs=1&pid=ImgDetMain" status="Hey there!"></ProfileCardComponent>
|
|
|
|
|
<div v-if="userStore.users.filter(u => u.username.includes(searchQuery) || searchQuery == '*').length == 0" style="text-align: center;">
|
|
|
|
|
<!--<q-icon name="error"></q-icon>
|
|
|
|
|
<p>Wir konnten keine Nutzer mit diesem Nutzernamen finden</p>-->
|
|
|
|
|
<img src="https://media.tenor.com/KOZLvzU0o4kAAAAd/no-results.gif" style="border-radius: 1rem;" alt="No search results found">
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div style="width: 70%;height: 100%;background: #DFD0BF;">
|
|
|
|
|
<p v-else>Gib einen Nutzername ein, um die Suche zu beginnen</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div style="margin: 20px;" v-if="activeMenu == 'chats'">
|
|
|
|
|
<p>Hier werden dann die Chats angezeigt</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div style="width: 75%;height: 100%;background: #DFD0BF;">
|
|
|
|
|
|
|
|
|
|
<div id="messageContainer" style="padding: 25px;overflow-y: auto;height: 90%;display: flex;flex-direction: column-reverse;">
|
|
|
|
|
<MessageComponent timestamp="13:12" url="https://media.tenor.com/mtiOW6O-k8YAAAAd/shrek-shrek-rizz.gif" gif></MessageComponent>
|
|
|
|
|
<MessageComponent message="Halo" timestamp="13:03" own-message></MessageComponent>
|
|
|
|
|
<MessageComponent message="Hallo na" timestamp="13:04"></MessageComponent>
|
|
|
|
|
<MessageComponent message="Blubber" timestamp="13:06"></MessageComponent>
|
|
|
|
|
<MessageComponent message="Testtt" timestamp="13:03" own-message></MessageComponent>
|
|
|
|
|
<MessageComponent message="Hola" timestamp="13:03" own-message></MessageComponent>
|
|
|
|
|
<MessageComponent message="Mal schauen was hier passiert, wenn man viel reinschreibt hahahahahahhahahaha" timestamp="13:06"></MessageComponent>
|
|
|
|
|
<MessageComponent message="Mal schauen was hier passiert, wenn man viel reinschreibt hahahahahahhahahaha" timestamp="13:06"></MessageComponent>
|
|
|
|
|
<MessageComponent message="Mal schauen was hier passiert, wenn man viel reinschreibt hahahahahahhahahaha" timestamp="13:06"></MessageComponent>
|
|
|
|
|
<MessageComponent message="Mal schauen was hier passiert, wenn man viel reinschreibt hahahahahahhahahaha" timestamp="13:06"></MessageComponent><MessageComponent message="Mal schauen was hier passiert, wenn man viel reinschreibt hahahahahahhahahaha" timestamp="13:06"></MessageComponent>
|
|
|
|
|
<MessageComponent message="Mal schauen was hier passiert, wenn man viel reinschreibt hahahahahahhahahaha" timestamp="13:06"></MessageComponent>
|
|
|
|
|
<MessageComponent message="Mal schauen was hier passiert, wenn man viel reinschreibt hahahahahahhahahaha" timestamp="13:06"></MessageComponent>
|
|
|
|
|
<MessageComponent message="Mal schauen was hier passiert, wenn man viel reinschreibt hahahahahahhahahaha" timestamp="13:06"></MessageComponent>
|
|
|
|
|
<MessageComponent message="Mal schauen was hier passiert, wenn man viel reinschreibt hahahahahahhahahaha" timestamp="13:06"></MessageComponent>
|
|
|
|
|
<MessageComponent message="Mal schauen was hier passiert, wenn man viel reinschreibt hahahahahahhahahaha" timestamp="13:06"></MessageComponent>
|
|
|
|
|
<MessageComponent message="Mal schauen was hier passiert, wenn man viel reinschreibt hahahahahahhahahaha" timestamp="13:06"></MessageComponent>
|
|
|
|
|
<div v-for="(message, index) in messages" :key="index">
|
|
|
|
|
<MessageComponent
|
|
|
|
|
v-if="message.gif"
|
|
|
|
|
:url="message.content"
|
|
|
|
|
:timestamp="message.timestamp"
|
|
|
|
|
:own-message="message.isOwn"
|
|
|
|
|
gif
|
|
|
|
|
></MessageComponent>
|
|
|
|
|
|
|
|
|
|
<MessageComponent
|
|
|
|
|
v-if="!message.gif && message.link"
|
|
|
|
|
:url="message.content"
|
|
|
|
|
:timestamp="message.timestamp"
|
|
|
|
|
:own-message="message.isOwn"
|
|
|
|
|
link
|
|
|
|
|
></MessageComponent>
|
|
|
|
|
|
|
|
|
|
<MessageComponent
|
|
|
|
|
v-if="!message.gif && !message.link"
|
|
|
|
|
:message="message.content"
|
|
|
|
|
:timestamp="message.timestamp"
|
|
|
|
|
:own-message="message.isOwn"
|
|
|
|
|
></MessageComponent>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div style="width: 70%;height:auto; background: gray;position: absolute;bottom:0;padding: 10px;">
|
|
|
|
|
<div class="footer">
|
|
|
|
|
|
|
|
|
|
<q-input filled v-model="message" placeholder="Nachricht eingeben" tabindex="0" @keyup.enter.prevent="sendMessage">
|
|
|
|
|
<template v-slot:after>
|
|
|
|
|
@@ -46,7 +78,9 @@
|
|
|
|
|
<q-btn round dense flat icon="send" id="sendMessageBtn" @click="sendMessage"></q-btn>
|
|
|
|
|
</template>
|
|
|
|
|
</q-input>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- GIF SUCHE -->
|
|
|
|
|
<div style="background: white;padding: 10px;border-radius: 10px;width: 20rem;height: 30rem;overflow-y:auto;position: absolute;right:20px;bottom:5rem;" v-if="showGifMenu" id="gifSearchMenu">
|
|
|
|
|
<q-input v-model="gifSearch" @update:model-value="inputChanged" dense placeholder="Nach GIF suchen" id="gifSearchBar">
|
|
|
|
|
<template v-slot:append>
|
|
|
|
|
@@ -63,11 +97,14 @@
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div style="text-align: center;" v-if="loadedGifsAmount < 50">
|
|
|
|
|
<q-btn round dense flat @click="loadMoreGifs" title="Mehr anzeigen">+</q-btn>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- GIF SUCHE ENDE -->
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
@@ -76,6 +113,8 @@ import { ref } from 'vue';
|
|
|
|
|
import MessageComponent from 'components/MessageComponent.vue';
|
|
|
|
|
import { useTenorStore } from 'stores/tenor-store';
|
|
|
|
|
import ProfileCardComponent from 'components/ProfileCardComponent.vue';
|
|
|
|
|
import {message} from 'src/models';
|
|
|
|
|
import {useUserStore} from 'stores/user-store';
|
|
|
|
|
|
|
|
|
|
defineOptions({
|
|
|
|
|
name: 'IndexPage'
|
|
|
|
|
@@ -85,20 +124,69 @@ const searchQuery = ref("")
|
|
|
|
|
const message = ref("");
|
|
|
|
|
const gifSearch = ref("");
|
|
|
|
|
|
|
|
|
|
const activeMenu = ref("search");
|
|
|
|
|
|
|
|
|
|
let loadedGifsAmount = 10;
|
|
|
|
|
|
|
|
|
|
let messages : message[] = [
|
|
|
|
|
{content: "Halllo", timestamp: "13:38", isOwn: true, gif: false, link: false},
|
|
|
|
|
{content: "https://www.google.com/", timestamp: "13:20", isOwn: false, gif: false, link: false},
|
|
|
|
|
{content: "Halllo", timestamp: "13:15", isOwn: false, gif: false, link: false},
|
|
|
|
|
{content: "Halllo", timestamp: "13:14", isOwn: true, gif: false, link: false},
|
|
|
|
|
{content: "Halllo", timestamp: "13:13", isOwn: true, gif: false, link: false},
|
|
|
|
|
{content: "https://media.tenor.com/mtiOW6O-k8YAAAAd/shrek-shrek-rizz.gif", timestamp: "13:11", isOwn: false, gif: false, link: false},
|
|
|
|
|
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
|
|
|
|
|
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
|
|
|
|
|
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
|
|
|
|
|
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
|
|
|
|
|
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
|
|
|
|
|
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
|
|
|
|
|
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
|
|
|
|
|
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
|
|
|
|
|
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
|
|
|
|
|
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
|
|
|
|
|
{content: "Hallo", timestamp: "13:10", isOwn: true, gif: false, link: false}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
function isUrl(url : string) {
|
|
|
|
|
try {
|
|
|
|
|
new URL(url);
|
|
|
|
|
return true;
|
|
|
|
|
} catch (err) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function isTenorGifUrl(url : string) {
|
|
|
|
|
return url.startsWith("https://media.tenor.com/") && url.endsWith(".gif");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
messages.forEach((msg) => {
|
|
|
|
|
if(isTenorGifUrl(msg.content)) {
|
|
|
|
|
msg.gif = true;
|
|
|
|
|
} else if(isUrl(msg.content)) {
|
|
|
|
|
msg.link = true;
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const selectedGifURL = ref("");
|
|
|
|
|
const showGifMenu = ref(false);
|
|
|
|
|
|
|
|
|
|
const changed = ref(false);
|
|
|
|
|
const changed = ref(true);
|
|
|
|
|
|
|
|
|
|
function inputChanged() {
|
|
|
|
|
changed.value = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const tenorStore = useTenorStore();
|
|
|
|
|
const userStore = useUserStore();
|
|
|
|
|
|
|
|
|
|
function getGifs() {
|
|
|
|
|
let query = gifSearch.value != "" ? gifSearch.value : "shrek";
|
|
|
|
|
|
|
|
|
|
if(changed.value) {
|
|
|
|
|
tenorStore.getGifsBySearchTerm(gifSearch.value);
|
|
|
|
|
tenorStore.getGifsBySearchTerm(query, loadedGifsAmount);
|
|
|
|
|
changed.value = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -107,23 +195,33 @@ function toggleGifMenu() {
|
|
|
|
|
showGifMenu.value = !showGifMenu.value;
|
|
|
|
|
if(showGifMenu.value) {
|
|
|
|
|
// Somehow focus the input field
|
|
|
|
|
document.getElementById("gifSearchBar")!.focus();
|
|
|
|
|
//document.getElementById("gifSearchBar")!.focus();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function sendMessage() {
|
|
|
|
|
alert(message.value);
|
|
|
|
|
messages.unshift({content: message.value, timestamp: new Date().toTimeString().split(' ')[0].substring(0, 5), isOwn: true, gif: false, link: false});
|
|
|
|
|
message.value = "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function sendGif(url : string) {
|
|
|
|
|
alert(url);
|
|
|
|
|
messages.unshift({content: url, timestamp: new Date().toTimeString().split(' ')[0].substring(0, 5), isOwn: true, gif: true, link: false});
|
|
|
|
|
toggleGifMenu();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tenorStore.getGifsBySearchTerm("shrek");
|
|
|
|
|
function loadMoreGifs() {
|
|
|
|
|
loadedGifsAmount += 10;
|
|
|
|
|
console.log(loadedGifsAmount);
|
|
|
|
|
changed.value = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setInterval(getGifs, 500);
|
|
|
|
|
|
|
|
|
|
userStore.getAllPtpUsers();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
@@ -146,4 +244,37 @@ setInterval(getGifs, 500);
|
|
|
|
|
transition: .3s;
|
|
|
|
|
filter: brightness(0.5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.footer {
|
|
|
|
|
width: 75%;
|
|
|
|
|
height:auto;
|
|
|
|
|
background: gray;
|
|
|
|
|
position: absolute;
|
|
|
|
|
bottom:0;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.navigation {
|
|
|
|
|
font-size: 2rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.navigation > div {
|
|
|
|
|
width: 50%;
|
|
|
|
|
text-align: center;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
transition: .3s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.navigation > div:hover {
|
|
|
|
|
background: #555555;
|
|
|
|
|
transition: .3s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.menuItemActive {
|
|
|
|
|
border-bottom: 2px solid black;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.menuItemInactive {
|
|
|
|
|
border-bottom: 2px solid transparent;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
|