Changed menu that dialogues can be opened too; added random chat
This commit is contained in:
@@ -1,50 +1,104 @@
|
||||
<template>
|
||||
<nav>
|
||||
<ul>
|
||||
<li v-for="(item, key) in menu" :key="key" class="mainmenuitem"
|
||||
@click="openPage(item.path ?? null, !!item.children)">
|
||||
<span v-if="item.icon" :style="`background-image:url('/images/icons/${item.icon}')`"
|
||||
class="menu-icon"> </span>
|
||||
<!-- Hauptmenü -->
|
||||
<li
|
||||
v-for="(item, key) in menu"
|
||||
:key="key"
|
||||
class="mainmenuitem"
|
||||
@click="handleItem(item, $event)"
|
||||
>
|
||||
<span
|
||||
v-if="item.icon"
|
||||
:style="`background-image:url('/images/icons/${item.icon}')`"
|
||||
class="menu-icon"
|
||||
> </span>
|
||||
<span>{{ $t(`navigation.${key}`) }}</span>
|
||||
|
||||
<!-- Untermenü Ebene 1 -->
|
||||
<ul v-if="item.children" class="submenu1">
|
||||
<li v-for="(subitem, subkey) in item.children" :key="subitem.text"
|
||||
@click="openPage(subitem.path ?? null, !!subitem.children && subkey !== 'forum')">
|
||||
<span v-if="subitem.icon" :style="`background-image:url('/images/icons/${subitem.icon}')`"
|
||||
class="submenu-icon"> </span>
|
||||
<li
|
||||
v-for="(subitem, subkey) in item.children"
|
||||
:key="subkey"
|
||||
@click="handleItem(subitem, $event)"
|
||||
>
|
||||
<span
|
||||
v-if="subitem.icon"
|
||||
:style="`background-image:url('/images/icons/${subitem.icon}')`"
|
||||
class="submenu-icon"
|
||||
> </span>
|
||||
<span>{{ $t(`navigation.m-${key}.${subkey}`) }}</span>
|
||||
<span v-if="subkey === 'forum'" class="subsubmenu">▶</span>
|
||||
<span v-else-if="subitem.children" class="subsubmenu">▶</span>
|
||||
<ul v-if="subkey === 'forum' && forumList.length > 0" class="submenu2">
|
||||
<li v-for="forum in forumList" :key="forum.id" @click="openForum(forum.id, $event)">
|
||||
<span
|
||||
v-if="subkey === 'forum' || subitem.children"
|
||||
class="subsubmenu"
|
||||
>▶</span>
|
||||
|
||||
<!-- Forum‑Unterliste -->
|
||||
<ul
|
||||
v-if="subkey === 'forum' && forumList.length"
|
||||
class="submenu2"
|
||||
>
|
||||
<li
|
||||
v-for="forum in forumList"
|
||||
:key="forum.id"
|
||||
@click="handleItem({ action: 'openForum', params: forum.id }, $event)"
|
||||
>
|
||||
{{ forum.name }}
|
||||
</li>
|
||||
</ul>
|
||||
<ul v-else-if="subitem.children" class="submenu2">
|
||||
<li v-for="(subsubitem, subsubkey) in subitem.children" :key="subsubitem.text"
|
||||
@click="openPage(subsubitem.path ?? null)">
|
||||
<span v-if="subsubitem.icon" :style="`background-image:url('/images/icons/${subsubitem.icon}')`"
|
||||
class="submenu-icon"> </span>
|
||||
|
||||
<!-- Weiteres Untermenü Ebene 2 -->
|
||||
<ul
|
||||
v-else-if="subitem.children"
|
||||
class="submenu2"
|
||||
>
|
||||
<li
|
||||
v-for="(subsubitem, subsubkey) in subitem.children"
|
||||
:key="subsubkey"
|
||||
@click="handleItem(subsubitem, $event)"
|
||||
>
|
||||
<span
|
||||
v-if="subsubitem.icon"
|
||||
:style="`background-image:url('/images/icons/${subsubitem.icon}')`"
|
||||
class="submenu-icon"
|
||||
> </span>
|
||||
<span>{{ $t(`navigation.m-${key}.m-${subkey}.${subsubkey}`) }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li v-if="item.showLoggedinFriends === 1 && friendsList.length > 0" v-for="friend in friendsList" :key="friend.id">
|
||||
|
||||
<!-- Eingeloggte Freunde -->
|
||||
<li
|
||||
v-if="item.showLoggedinFriends === 1 && friendsList.length"
|
||||
v-for="friend in friendsList"
|
||||
:key="friend.id"
|
||||
@click="handleItem({ action: 'openChat', params: friend.id }, $event)"
|
||||
>
|
||||
{{ friend.username }}
|
||||
<ul class="submenu2">
|
||||
<li @click="openChat(friend.id)">{{ $t('navigation.m-friends.chat') }}</li>
|
||||
<li @click="openProfile(friend.id)">{{ $t('navigation.m-friends.profile') }}</li>
|
||||
<li
|
||||
@click="handleItem({ action: 'openChat', params: friend.id }, $event)"
|
||||
>
|
||||
{{ $t('navigation.m-friends.chat') }}
|
||||
</li>
|
||||
<li
|
||||
@click="handleItem({ action: 'openProfile', params: friend.id }, $event)"
|
||||
>
|
||||
{{ $t('navigation.m-friends.profile') }}
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="submenu1">
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="right-block">
|
||||
<span @click="accessMailbox" class="mailbox"></span>
|
||||
<span class="logoutblock">
|
||||
<span class="username">{{ user.username }} </span>
|
||||
<span @click="logout" class="menuitem">{{ $t('navigation.logout') }}</span>
|
||||
<span class="username">{{ user.username }}</span>
|
||||
<span @click="logout" class="menuitem">
|
||||
{{ $t('navigation.logout') }}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -52,109 +106,123 @@
|
||||
|
||||
<script>
|
||||
import { mapGetters, mapActions } from 'vuex';
|
||||
import { createApp } from 'vue';
|
||||
import apiClient from '@/utils/axios.js';
|
||||
|
||||
import RandomChatDialog from '../dialogues/chat/RandomChatDialog.vue';
|
||||
|
||||
// Wichtig: die zentrale Instanzen importieren
|
||||
import store from '@/store';
|
||||
import router from '@/router';
|
||||
import i18n from '@/i18n';
|
||||
|
||||
export default {
|
||||
name: 'AppNavigation',
|
||||
components: {
|
||||
RandomChatDialog
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
forumList: [],
|
||||
friendsList: [],
|
||||
}
|
||||
friendsList: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['menu', 'user', 'menuNeedsUpdate', 'socket']),
|
||||
...mapGetters(['menu', 'user', 'menuNeedsUpdate', 'socket'])
|
||||
},
|
||||
watch: {
|
||||
menuNeedsUpdate(newValue) {
|
||||
if (newValue) {
|
||||
this.loadMenu();
|
||||
}
|
||||
menuNeedsUpdate(newVal) {
|
||||
if (newVal) this.loadMenu();
|
||||
},
|
||||
socket(newValue) {
|
||||
if (newValue) {
|
||||
newValue.on('forumschanged', (data) => {
|
||||
this.fetchForums();
|
||||
});
|
||||
newValue.on('friendloginchanged', () => {
|
||||
this.fetchFriends();
|
||||
});
|
||||
newValue.on('reloadmenu', () => {
|
||||
this.loadMenu();
|
||||
})
|
||||
socket(newSocket) {
|
||||
if (newSocket) {
|
||||
newSocket.on('forumschanged', this.fetchForums);
|
||||
newSocket.on('friendloginchanged', this.fetchFriends);
|
||||
newSocket.on('reloadmenu', this.loadMenu);
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.user && this.user.id) {
|
||||
if (this.user?.id) {
|
||||
this.loadMenu();
|
||||
this.fetchForums();
|
||||
this.fetchFriends();
|
||||
} else {
|
||||
console.log(this.user);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.$store.getters.socket) {
|
||||
this.$store.getters.socket.on('forumschanged', (data) => {
|
||||
this.fetchForums();
|
||||
});
|
||||
this.$store.getters.socket.on('friendloginchanged', () => {
|
||||
this.fetchFriends();
|
||||
});
|
||||
}
|
||||
},
|
||||
beforeUnmount() {
|
||||
if (this.$store.getters.socket) {
|
||||
this.$store.getters.socket.off('forumschanged');
|
||||
this.$store.getters.socket.off('friendloginchanged');
|
||||
const sock = this.socket;
|
||||
if (sock) {
|
||||
sock.off('forumschanged');
|
||||
sock.off('friendloginchanged');
|
||||
sock.off('reloadmenu');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['loadMenu', 'logout']),
|
||||
openPage(url, hasSubmenu = false) {
|
||||
if (hasSubmenu) {
|
||||
return;
|
||||
}
|
||||
if (url) {
|
||||
this.$router.push(url);
|
||||
}
|
||||
},
|
||||
openForum(forumId, event) {
|
||||
event.stopPropagation();
|
||||
console.log('openForum', forumId);
|
||||
this.$router.push({ name: 'Forum', params: { id: forumId } });
|
||||
},
|
||||
|
||||
async fetchForums() {
|
||||
try {
|
||||
const response = await apiClient.get('/api/forum');
|
||||
this.forumList = response.data;
|
||||
} catch (error) {
|
||||
console.error('Error fetching forums:', error);
|
||||
const res = await apiClient.get('/api/forum');
|
||||
this.forumList = res.data;
|
||||
} catch (err) {
|
||||
console.error('Error fetching forums:', err);
|
||||
}
|
||||
},
|
||||
|
||||
async fetchFriends() {
|
||||
try {
|
||||
const response = await apiClient.get('/api/socialnetwork/friends/loggedin');
|
||||
this.friendsList = response.data;
|
||||
} catch (error) {
|
||||
console.error('Error fetching friends:', error);
|
||||
const res = await apiClient.get('/api/socialnetwork/friends/loggedin');
|
||||
this.friendsList = res.data;
|
||||
} catch (err) {
|
||||
console.error('Error fetching friends:', err);
|
||||
}
|
||||
},
|
||||
|
||||
async openProfile(hashedId) {
|
||||
console.log(hashedId);
|
||||
this.$root.$refs.userProfileDialog.userId = hashedId;
|
||||
openForum(forumId) {
|
||||
this.$router.push({ name: 'Forum', params: { id: forumId } });
|
||||
},
|
||||
|
||||
openProfile(userId) {
|
||||
this.$root.$refs.userProfileDialog.userId = userId;
|
||||
this.$root.$refs.userProfileDialog.open();
|
||||
},
|
||||
|
||||
async openChat(hashedId) {
|
||||
try {
|
||||
|
||||
} catch (error) {
|
||||
|
||||
openChat(userId) {
|
||||
console.log('openChat:', userId);
|
||||
// Datei erstellen und ans body anhängen
|
||||
const container = document.createElement('div');
|
||||
document.body.appendChild(container);
|
||||
// Programmatisch ein neues App-Instance randomChatauen, mit Store, Router & i18n
|
||||
this.$root.$refs.randomChatDialog.open(contact);
|
||||
},
|
||||
|
||||
/**
|
||||
* Einheitliche Klick‑Logik:
|
||||
* 1) Nur aufklappen, wenn noch Untermenüs existieren
|
||||
* 2) Bei `view`: Dialog/Window öffnen
|
||||
* 3) Bei `action`: custom action aufrufen
|
||||
* 4) Sonst: normale Router-Navigation
|
||||
*/
|
||||
handleItem(item, event) {
|
||||
event.stopPropagation();
|
||||
|
||||
// 1) nur aufklappen
|
||||
if (item.children) return;
|
||||
|
||||
// 2) view → Dialog/Window
|
||||
if (item.view) {
|
||||
this.$root.$refs[item.class].open();
|
||||
return;
|
||||
}
|
||||
|
||||
// 3) custom action (openForum, openChat, ...)
|
||||
if (item.action && typeof this[item.action] === 'function') {
|
||||
return this[item.action](item.params, event);
|
||||
}
|
||||
|
||||
// 4) Standard‑Navigation
|
||||
if (item.path) {
|
||||
this.$router.push(item.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,15 +233,15 @@ export default {
|
||||
@import '../assets/styles.scss';
|
||||
|
||||
nav,
|
||||
nav>ul {
|
||||
nav > ul {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
background-color: #F9A22C;
|
||||
color: #000000;
|
||||
background-color: #f9a22c;
|
||||
color: #000;
|
||||
padding: 0;
|
||||
flex-direction: row;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
flex-direction: row;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
@@ -183,22 +251,22 @@ ul {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
nav>ul>li {
|
||||
nav > ul > li {
|
||||
padding: 0 1em;
|
||||
line-height: 2.5em;
|
||||
transition: background-color 0.25s;
|
||||
}
|
||||
|
||||
nav>ul>li:hover {
|
||||
background-color: #D37C06;
|
||||
nav > ul > li:hover {
|
||||
background-color: #d37c06;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
nav>ul>li:hover>span {
|
||||
color: #000000;
|
||||
nav > ul > li:hover > span {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
nav>ul>li:hover>ul {
|
||||
nav > ul > li:hover > ul {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@@ -218,7 +286,7 @@ a {
|
||||
|
||||
.menuitem {
|
||||
cursor: pointer;
|
||||
color: #7E471B;
|
||||
color: #7e471b;
|
||||
}
|
||||
|
||||
.mailbox {
|
||||
@@ -236,84 +304,93 @@ a {
|
||||
|
||||
.submenu1 {
|
||||
position: absolute;
|
||||
border: 1px solid #7E471B;
|
||||
background-color: #F9A22C;
|
||||
border: 1px solid #7e471b;
|
||||
background-color: #f9a22c;
|
||||
left: 0;
|
||||
top: 2.5em;
|
||||
max-height: 0;
|
||||
overflow: visible;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: max-height 0.25s ease-in-out, opacity 0.05s ease-in-out, visibility 0s 0.05s;
|
||||
transition: max-height 0.25s ease-in-out,
|
||||
opacity 0.05s ease-in-out,
|
||||
visibility 0s 0.05s;
|
||||
}
|
||||
|
||||
.mainmenuitem:hover .submenu1 {
|
||||
max-height: 500px;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transition: max-height 0.25s ease-in-out, opacity 0.05s ease-in-out, visibility 0s;
|
||||
transition: max-height 0.25s ease-in-out,
|
||||
opacity 0.05s ease-in-out,
|
||||
visibility 0s;
|
||||
}
|
||||
|
||||
.submenu1>li {
|
||||
.submenu1 > li {
|
||||
padding: 0.5em;
|
||||
line-height: 1em;
|
||||
color: #7E471B;
|
||||
color: #7e471b;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.submenu1>li:hover {
|
||||
color: #000000;
|
||||
background-color: #D37C06;
|
||||
.submenu1 > li:hover {
|
||||
color: #000;
|
||||
background-color: #d37c06;
|
||||
}
|
||||
|
||||
.menu-icon,
|
||||
.submenu-icon {
|
||||
display: inline-block;
|
||||
background-repeat: no-repeat;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 3px;
|
||||
background-repeat: no-repeat;
|
||||
display: inline-block;
|
||||
line-height: 1.6em;
|
||||
}
|
||||
|
||||
.submenu-icon {
|
||||
width: 1.2em;
|
||||
height: 1em;
|
||||
margin-right: 3px;
|
||||
background-repeat: no-repeat;
|
||||
display: inline-block;
|
||||
line-height: 1em;
|
||||
background-size: 1.2em 1.2em;
|
||||
}
|
||||
|
||||
.submenu2 {
|
||||
position: absolute;
|
||||
background-color: #F9A22C;
|
||||
background-color: #f9a22c;
|
||||
left: 100%;
|
||||
top: 0;
|
||||
border: 1px solid #7E471B;
|
||||
border: 1px solid #7e471b;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: max-height 0.25s ease-in-out, opacity 0.05s ease-in-out, visibility 0s 0.05s;
|
||||
transition: max-height 0.25s ease-in-out,
|
||||
opacity 0.05s ease-in-out,
|
||||
visibility 0s 0.05s;
|
||||
}
|
||||
|
||||
.submenu1>li:hover .submenu2 {
|
||||
.submenu1 > li:hover .submenu2 {
|
||||
max-height: 500px;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transition: max-height 0.25s ease-in-out, opacity 0.05s ease-in-out, visibility 0s;
|
||||
transition: max-height 0.25s ease-in-out,
|
||||
opacity 0.05s ease-in-out,
|
||||
visibility 0s;
|
||||
}
|
||||
|
||||
.submenu2>li {
|
||||
.submenu2 > li {
|
||||
padding: 0.5em;
|
||||
line-height: 1em;
|
||||
color: #7E471B;
|
||||
color: #7e471b;
|
||||
}
|
||||
|
||||
.submenu2>li:hover {
|
||||
color: #000000;
|
||||
background-color: #D37C06;
|
||||
.submenu2 > li:hover {
|
||||
color: #000;
|
||||
background-color: #d37c06;
|
||||
}
|
||||
|
||||
.subsubmenu {
|
||||
|
||||
Reference in New Issue
Block a user