Changed menu that dialogues can be opened too; added random chat
This commit is contained in:
@@ -78,15 +78,21 @@ const menuStructure = {
|
|||||||
children: {
|
children: {
|
||||||
multiChat: {
|
multiChat: {
|
||||||
visible: ["over12"],
|
visible: ["over12"],
|
||||||
action: "openMultiChat"
|
action: "openMultiChat",
|
||||||
|
view: "window",
|
||||||
|
class: "multiChatWindow"
|
||||||
},
|
},
|
||||||
randomChat: {
|
randomChat: {
|
||||||
visible: ["over12"],
|
visible: ["over12"],
|
||||||
action: "openRanomChat"
|
action: "openRanomChat",
|
||||||
|
view: "window",
|
||||||
|
class: "randomChatDialog"
|
||||||
},
|
},
|
||||||
eroticChat: {
|
eroticChat: {
|
||||||
visible: ["over18"],
|
visible: ["over18"],
|
||||||
action: "openEroticChat"
|
action: "openEroticChat",
|
||||||
|
view: "window",
|
||||||
|
class: "eroticChatWindow"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,50 +1,104 @@
|
|||||||
<template>
|
<template>
|
||||||
<nav>
|
<nav>
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="(item, key) in menu" :key="key" class="mainmenuitem"
|
<!-- Hauptmenü -->
|
||||||
@click="openPage(item.path ?? null, !!item.children)">
|
<li
|
||||||
<span v-if="item.icon" :style="`background-image:url('/images/icons/${item.icon}')`"
|
v-for="(item, key) in menu"
|
||||||
class="menu-icon"> </span>
|
: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>
|
<span>{{ $t(`navigation.${key}`) }}</span>
|
||||||
|
|
||||||
|
<!-- Untermenü Ebene 1 -->
|
||||||
<ul v-if="item.children" class="submenu1">
|
<ul v-if="item.children" class="submenu1">
|
||||||
<li v-for="(subitem, subkey) in item.children" :key="subitem.text"
|
<li
|
||||||
@click="openPage(subitem.path ?? null, !!subitem.children && subkey !== 'forum')">
|
v-for="(subitem, subkey) in item.children"
|
||||||
<span v-if="subitem.icon" :style="`background-image:url('/images/icons/${subitem.icon}')`"
|
:key="subkey"
|
||||||
class="submenu-icon"> </span>
|
@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>{{ $t(`navigation.m-${key}.${subkey}`) }}</span>
|
||||||
<span v-if="subkey === 'forum'" class="subsubmenu">▶</span>
|
<span
|
||||||
<span v-else-if="subitem.children" class="subsubmenu">▶</span>
|
v-if="subkey === 'forum' || subitem.children"
|
||||||
<ul v-if="subkey === 'forum' && forumList.length > 0" class="submenu2">
|
class="subsubmenu"
|
||||||
<li v-for="forum in forumList" :key="forum.id" @click="openForum(forum.id, $event)">
|
>▶</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 }}
|
{{ forum.name }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul v-else-if="subitem.children" class="submenu2">
|
|
||||||
<li v-for="(subsubitem, subsubkey) in subitem.children" :key="subsubitem.text"
|
<!-- Weiteres Untermenü Ebene 2 -->
|
||||||
@click="openPage(subsubitem.path ?? null)">
|
<ul
|
||||||
<span v-if="subsubitem.icon" :style="`background-image:url('/images/icons/${subsubitem.icon}')`"
|
v-else-if="subitem.children"
|
||||||
class="submenu-icon"> </span>
|
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>
|
<span>{{ $t(`navigation.m-${key}.m-${subkey}.${subsubkey}`) }}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</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 }}
|
{{ friend.username }}
|
||||||
<ul class="submenu2">
|
<ul class="submenu2">
|
||||||
<li @click="openChat(friend.id)">{{ $t('navigation.m-friends.chat') }}</li>
|
<li
|
||||||
<li @click="openProfile(friend.id)">{{ $t('navigation.m-friends.profile') }}</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>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="submenu1">
|
|
||||||
</ul>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="right-block">
|
<div class="right-block">
|
||||||
<span @click="accessMailbox" class="mailbox"></span>
|
<span @click="accessMailbox" class="mailbox"></span>
|
||||||
<span class="logoutblock">
|
<span class="logoutblock">
|
||||||
<span class="username">{{ user.username }} </span>
|
<span class="username">{{ user.username }}</span>
|
||||||
<span @click="logout" class="menuitem">{{ $t('navigation.logout') }}</span>
|
<span @click="logout" class="menuitem">
|
||||||
|
{{ $t('navigation.logout') }}
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
@@ -52,109 +106,123 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters, mapActions } from 'vuex';
|
import { mapGetters, mapActions } from 'vuex';
|
||||||
|
import { createApp } from 'vue';
|
||||||
import apiClient from '@/utils/axios.js';
|
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 {
|
export default {
|
||||||
name: 'AppNavigation',
|
name: 'AppNavigation',
|
||||||
|
components: {
|
||||||
|
RandomChatDialog
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
forumList: [],
|
forumList: [],
|
||||||
friendsList: [],
|
friendsList: []
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['menu', 'user', 'menuNeedsUpdate', 'socket']),
|
...mapGetters(['menu', 'user', 'menuNeedsUpdate', 'socket'])
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
menuNeedsUpdate(newValue) {
|
menuNeedsUpdate(newVal) {
|
||||||
if (newValue) {
|
if (newVal) this.loadMenu();
|
||||||
this.loadMenu();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
socket(newValue) {
|
socket(newSocket) {
|
||||||
if (newValue) {
|
if (newSocket) {
|
||||||
newValue.on('forumschanged', (data) => {
|
newSocket.on('forumschanged', this.fetchForums);
|
||||||
this.fetchForums();
|
newSocket.on('friendloginchanged', this.fetchFriends);
|
||||||
});
|
newSocket.on('reloadmenu', this.loadMenu);
|
||||||
newValue.on('friendloginchanged', () => {
|
|
||||||
this.fetchFriends();
|
|
||||||
});
|
|
||||||
newValue.on('reloadmenu', () => {
|
|
||||||
this.loadMenu();
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
if (this.user && this.user.id) {
|
if (this.user?.id) {
|
||||||
this.loadMenu();
|
this.loadMenu();
|
||||||
this.fetchForums();
|
this.fetchForums();
|
||||||
this.fetchFriends();
|
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() {
|
beforeUnmount() {
|
||||||
if (this.$store.getters.socket) {
|
const sock = this.socket;
|
||||||
this.$store.getters.socket.off('forumschanged');
|
if (sock) {
|
||||||
this.$store.getters.socket.off('friendloginchanged');
|
sock.off('forumschanged');
|
||||||
|
sock.off('friendloginchanged');
|
||||||
|
sock.off('reloadmenu');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['loadMenu', 'logout']),
|
...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() {
|
async fetchForums() {
|
||||||
try {
|
try {
|
||||||
const response = await apiClient.get('/api/forum');
|
const res = await apiClient.get('/api/forum');
|
||||||
this.forumList = response.data;
|
this.forumList = res.data;
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
console.error('Error fetching forums:', error);
|
console.error('Error fetching forums:', err);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async fetchFriends() {
|
async fetchFriends() {
|
||||||
try {
|
try {
|
||||||
const response = await apiClient.get('/api/socialnetwork/friends/loggedin');
|
const res = await apiClient.get('/api/socialnetwork/friends/loggedin');
|
||||||
this.friendsList = response.data;
|
this.friendsList = res.data;
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
console.error('Error fetching friends:', error);
|
console.error('Error fetching friends:', err);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async openProfile(hashedId) {
|
openForum(forumId) {
|
||||||
console.log(hashedId);
|
this.$router.push({ name: 'Forum', params: { id: forumId } });
|
||||||
this.$root.$refs.userProfileDialog.userId = hashedId;
|
},
|
||||||
|
|
||||||
|
openProfile(userId) {
|
||||||
|
this.$root.$refs.userProfileDialog.userId = userId;
|
||||||
this.$root.$refs.userProfileDialog.open();
|
this.$root.$refs.userProfileDialog.open();
|
||||||
},
|
},
|
||||||
|
|
||||||
async openChat(hashedId) {
|
openChat(userId) {
|
||||||
try {
|
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);
|
||||||
|
},
|
||||||
|
|
||||||
} catch (error) {
|
/**
|
||||||
|
* 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';
|
@import '../assets/styles.scss';
|
||||||
|
|
||||||
nav,
|
nav,
|
||||||
nav>ul {
|
nav > ul {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
background-color: #F9A22C;
|
background-color: #f9a22c;
|
||||||
color: #000000;
|
color: #000;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
flex-direction: row;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
flex-direction: row;
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,22 +251,22 @@ ul {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav>ul>li {
|
nav > ul > li {
|
||||||
padding: 0 1em;
|
padding: 0 1em;
|
||||||
line-height: 2.5em;
|
line-height: 2.5em;
|
||||||
transition: background-color 0.25s;
|
transition: background-color 0.25s;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav>ul>li:hover {
|
nav > ul > li:hover {
|
||||||
background-color: #D37C06;
|
background-color: #d37c06;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav>ul>li:hover>span {
|
nav > ul > li:hover > span {
|
||||||
color: #000000;
|
color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav>ul>li:hover>ul {
|
nav > ul > li:hover > ul {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,7 +286,7 @@ a {
|
|||||||
|
|
||||||
.menuitem {
|
.menuitem {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: #7E471B;
|
color: #7e471b;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mailbox {
|
.mailbox {
|
||||||
@@ -236,84 +304,93 @@ a {
|
|||||||
|
|
||||||
.submenu1 {
|
.submenu1 {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border: 1px solid #7E471B;
|
border: 1px solid #7e471b;
|
||||||
background-color: #F9A22C;
|
background-color: #f9a22c;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 2.5em;
|
top: 2.5em;
|
||||||
max-height: 0;
|
max-height: 0;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
visibility: hidden;
|
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 {
|
.mainmenuitem:hover .submenu1 {
|
||||||
max-height: 500px;
|
max-height: 500px;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
visibility: visible;
|
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;
|
padding: 0.5em;
|
||||||
line-height: 1em;
|
line-height: 1em;
|
||||||
color: #7E471B;
|
color: #7e471b;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.submenu1>li:hover {
|
.submenu1 > li:hover {
|
||||||
color: #000000;
|
color: #000;
|
||||||
background-color: #D37C06;
|
background-color: #d37c06;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-icon,
|
||||||
|
.submenu-icon {
|
||||||
|
display: inline-block;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
line-height: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-icon {
|
.menu-icon {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
margin-right: 3px;
|
margin-right: 3px;
|
||||||
background-repeat: no-repeat;
|
|
||||||
display: inline-block;
|
|
||||||
line-height: 1.6em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.submenu-icon {
|
.submenu-icon {
|
||||||
width: 1.2em;
|
width: 1.2em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
margin-right: 3px;
|
margin-right: 3px;
|
||||||
background-repeat: no-repeat;
|
|
||||||
display: inline-block;
|
|
||||||
line-height: 1em;
|
|
||||||
background-size: 1.2em 1.2em;
|
background-size: 1.2em 1.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.submenu2 {
|
.submenu2 {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: #F9A22C;
|
background-color: #f9a22c;
|
||||||
left: 100%;
|
left: 100%;
|
||||||
top: 0;
|
top: 0;
|
||||||
border: 1px solid #7E471B;
|
border: 1px solid #7e471b;
|
||||||
max-height: 0;
|
max-height: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
visibility: hidden;
|
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;
|
max-height: 500px;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
visibility: visible;
|
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;
|
padding: 0.5em;
|
||||||
line-height: 1em;
|
line-height: 1em;
|
||||||
color: #7E471B;
|
color: #7e471b;
|
||||||
}
|
}
|
||||||
|
|
||||||
.submenu2>li:hover {
|
.submenu2 > li:hover {
|
||||||
color: #000000;
|
color: #000;
|
||||||
background-color: #D37C06;
|
background-color: #d37c06;
|
||||||
}
|
}
|
||||||
|
|
||||||
.subsubmenu {
|
.subsubmenu {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<DialogWidget ref="dialog" title="randomchat.title" icon="dice24.png" :show-close=true :buttons="buttons"
|
<DialogWidget ref="dialog" title="randomchat.title" icon="dice24.png" :show-close="true" :buttons="buttons"
|
||||||
:modal=false :isTitleTranslated=true @close="closeDialog" name="RandomChat">
|
:modal="false" :isTitleTranslated="true" @close="closeDialog" name="RandomChat">
|
||||||
<div v-if="chatIsRunning" class="randomchat">
|
<div v-if="chatIsRunning" class="randomchat">
|
||||||
<div class="headline">
|
<div class="headline">
|
||||||
{{ $t("randomchat.agerange") }}
|
{{ $t("randomchat.agerange") }}
|
||||||
@@ -12,36 +12,42 @@
|
|||||||
<div>
|
<div>
|
||||||
<label><input type="checkbox" v-model="searchmale" />{{ $t("randomchat.gender.male") }}</label>
|
<label><input type="checkbox" v-model="searchmale" />{{ $t("randomchat.gender.male") }}</label>
|
||||||
<label><input type="checkbox" v-model="searchfemale" />{{ $t("randomchat.gender.female")
|
<label><input type="checkbox" v-model="searchfemale" />{{ $t("randomchat.gender.female")
|
||||||
}}</label>
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
<label><input type="checkbox" v-model="camonlysearch" />{{ $t("randomchat.camonly") }}</label>
|
<label><input type="checkbox" v-model="camonlysearch" />{{ $t("randomchat.camonly") }}</label>
|
||||||
<label><input type="checkbox" v-model="showcam" />{{ $t("randomchat.showcam") }}</label>
|
<label><input type="checkbox" v-model="showcam" />{{ $t("randomchat.showcam") }}</label>
|
||||||
<img v-if="isLoggedIn" src="/images/icons/friendsadd16.png" ::tooltip="$t('randomchat.addfriend')" />
|
<img v-if="isLoggedIn" src="/images/icons/friendsadd16.png" :tooltip="$t('randomchat.addfriend')" />
|
||||||
<label><input type="checkbox" v-model="autosearch" />{{ $t("randomchat.autosearch") }}</label>
|
<label><input type="checkbox" v-model="autosearch" />{{ $t("randomchat.autosearch") }}</label>
|
||||||
<button @click="nextUser" v-if="partner != null">{{ $t("randomchat.jumptonext") }}</button>
|
<button @click="nextUser" v-if="partner != null">{{ $t("randomchat.jumptonext") }}</button>
|
||||||
<button @click="startSearch" v-if="partner == null && !searching">{{ $t("randomchat.startsearch") }}</button>
|
<button @click="startSearch" v-if="partner == null && !searching">{{ $t("randomchat.startsearch")
|
||||||
|
}}</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="output">
|
<div class="output">
|
||||||
<div v-for="message in messages" v-html="renderMessage(message)">
|
<div v-for="message in messages" v-html="renderMessage(message)" />
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="inputline">
|
<div class="inputline">
|
||||||
<label>{{ $t("randomchat.input") }} <input type="text" v-model="inputtext" @keyup.enter="sendMessage" /></label>
|
<label>
|
||||||
|
{{ $t("randomchat.input") }}
|
||||||
|
<input type="text" v-model="inputtext" @keyup.enter="sendMessage" />
|
||||||
|
</label>
|
||||||
<img src="/images/icons/enter16.png" @click="sendMessage" />
|
<img src="/images/icons/enter16.png" @click="sendMessage" />
|
||||||
<img src="/images/icons/dice16.png" />
|
<img src="/images/icons/dice16.png" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div>
|
<div>
|
||||||
<label>{{ $t("randomchat.age") }} <input type="number" v-model="age" min="18" max="150"
|
<label>{{ $t("randomchat.age") }}
|
||||||
value="18" /></label>
|
<input type="number" v-model="age" min="18" max="150" value="18" />
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>{{ $t("randomchat.gender.title") }} <select v-model="gender">
|
<label>{{ $t("randomchat.gender.title") }}
|
||||||
|
<select v-model="gender">
|
||||||
<option value="f">{{ $t("randomchat.gender.female") }}</option>
|
<option value="f">{{ $t("randomchat.gender.female") }}</option>
|
||||||
<option value="m">{{ $t("randomchat.gender.male") }}</option>
|
<option value="m">{{ $t("randomchat.gender.male") }}</option>
|
||||||
</select></label>
|
</select>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button @click="startRandomChat()">{{ $t("randomchat.start") }}</button>
|
<button @click="startRandomChat()">{{ $t("randomchat.start") }}</button>
|
||||||
@@ -61,122 +67,165 @@ export default {
|
|||||||
DialogWidget,
|
DialogWidget,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['isLoggedIn']),
|
...mapGetters(['isLoggedIn', 'user']),
|
||||||
buttons() {
|
buttons() {
|
||||||
return [{ text: this.$t("randomchat.close")}];
|
return [{ text: this.$t('randomchat.close') }];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
chatIsRunning: false,
|
chatIsRunning: false,
|
||||||
age: 18,
|
age: 18,
|
||||||
gender: "f",
|
gender: 'f',
|
||||||
agefromsearch: 18,
|
agefromsearch: 18,
|
||||||
agetosearch: 150,
|
agetosearch: 150,
|
||||||
searchmale: true,
|
searchmale: true,
|
||||||
searchfemale: true,
|
searchfemale: true,
|
||||||
|
camonlysearch: false,
|
||||||
|
showcam: false,
|
||||||
autosearch: false,
|
autosearch: false,
|
||||||
inputtext: '',
|
inputtext: '',
|
||||||
searching: false,
|
searching: false,
|
||||||
userId: null,
|
userId: null, // ID, die vom Chat-Backend beim Register zurückkommt
|
||||||
searchInterval: null,
|
searchInterval: null,
|
||||||
messages: [],
|
messages: [],
|
||||||
partner: null,
|
partner: null,
|
||||||
messagesInterval: null,
|
messagesInterval: null,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async open() {
|
async open() {
|
||||||
|
if (this.user && Array.isArray(this.user.param)) {
|
||||||
|
const bdParam = this.user.param.find(p => p.name === 'birthdate')?.value;
|
||||||
|
if (bdParam) {
|
||||||
|
const birth = new Date(bdParam);
|
||||||
|
const ageYears = Math.floor(
|
||||||
|
(Date.now() - birth.getTime()) / (365.25 * 24 * 60 * 60 * 1000)
|
||||||
|
);
|
||||||
|
this.age = ageYears;
|
||||||
|
}
|
||||||
|
const gParam = this.user.param.find(p => p.name === 'gender')?.value;
|
||||||
|
if (gParam != null) {
|
||||||
|
// value==='1' ⇒ männlich
|
||||||
|
this.gender = gParam === '1' ? 'm' : 'f';
|
||||||
|
}
|
||||||
|
}
|
||||||
this.$refs.dialog.open();
|
this.$refs.dialog.open();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async closeDialog() {
|
||||||
|
// ① Stoppe alle laufenden Intervalle
|
||||||
|
if (this.searchInterval) {
|
||||||
|
clearInterval(this.searchInterval);
|
||||||
|
this.searchInterval = null;
|
||||||
|
}
|
||||||
|
if (this.messagesInterval) {
|
||||||
|
clearInterval(this.messagesInterval);
|
||||||
|
this.messagesInterval = null;
|
||||||
|
}
|
||||||
|
// ② verlasse Chat auf Server-Seite
|
||||||
|
this.$refs.dialog.close();
|
||||||
|
await axios.post('/api/chat/exit', { id: this.userId });
|
||||||
|
await this.removeUserFromChat();
|
||||||
|
// Reset-Status
|
||||||
|
this.chatIsRunning = false;
|
||||||
|
this.partner = null;
|
||||||
|
this.messages = [];
|
||||||
|
},
|
||||||
|
|
||||||
async registerUser() {
|
async registerUser() {
|
||||||
try {
|
try {
|
||||||
const response = await axios.post('/api/chat/register', {
|
const response = await axios.post('/api/chat/register', {
|
||||||
gender: this.gender,
|
gender: this.gender,
|
||||||
age: this.age
|
age: this.age,
|
||||||
});
|
});
|
||||||
this.userId = response.data.id;
|
this.userId = response.data.id;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error registering user:', error);
|
console.error('Error registering user:', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async closeDialog() {
|
async closeDialog() {
|
||||||
this.$refs.dialog.close();
|
this.$refs.dialog.close();
|
||||||
await axios.push('/api/chat/exit', { id: this.userId })
|
await axios.post('/api/chat/exit', { id: this.userId });
|
||||||
await this.removeUserFromChat();
|
await this.removeUserFromChat();
|
||||||
},
|
},
|
||||||
|
|
||||||
async startRandomChat() {
|
async startRandomChat() {
|
||||||
this.chatIsRunning = true;
|
this.chatIsRunning = true;
|
||||||
await this.registerUser();
|
await this.registerUser();
|
||||||
await this.startSearch();
|
await this.startSearch();
|
||||||
},
|
},
|
||||||
|
|
||||||
async startSearch() {
|
async startSearch() {
|
||||||
this.searching = true;
|
this.searching = true;
|
||||||
await this.findMatch();
|
await this.findMatch();
|
||||||
this.messages.push({ type: "system", tr: "randomchat.waitingForMatch" })
|
this.messages.push({ type: 'system', tr: 'randomchat.waitingForMatch' });
|
||||||
this.searchInterval = setInterval(this.findMatch, 500);
|
this.searchInterval = setInterval(this.findMatch, 500);
|
||||||
},
|
},
|
||||||
|
|
||||||
async findMatch() {
|
async findMatch() {
|
||||||
try {
|
try {
|
||||||
const response = await axios.post('/api/chat/findMatch', {
|
const response = await axios.post('/api/chat/findMatch', {
|
||||||
genders: this.getSearchGenders(),
|
genders: this.getSearchGenders(),
|
||||||
age: {
|
age: { min: this.agefromsearch, max: this.agetosearch },
|
||||||
min: this.agefromsearch,
|
id: this.userId,
|
||||||
max: this.agetosearch
|
|
||||||
},
|
|
||||||
id: this.userId
|
|
||||||
});
|
});
|
||||||
if (response.data.status && response.data.status === 'matched') {
|
if (response.data.status === 'matched') {
|
||||||
this.searching = false;
|
this.searching = false;
|
||||||
if (this.searchInterval) {
|
clearInterval(this.searchInterval);
|
||||||
clearInterval(this.searchInterval);
|
const initText = this.$t('randomchat.chatpartner')
|
||||||
this.searchInterval = null;
|
.replace(
|
||||||
}
|
'<gender>',
|
||||||
const initText = this.$t("randomchat.chatpartner")
|
this.$t(`randomchat.partnergender${response.data.user.gender}`)
|
||||||
.replace("<gender>", this.$t(`randomchat.partnergender${response.data.user.gender}`))
|
)
|
||||||
.replace("<age>", response.data.user.age);
|
.replace('<age>', response.data.user.age);
|
||||||
this.messages = [];
|
this.messages = [{ type: 'system', text: initText }];
|
||||||
this.messages.push({ "type": "system", text: initText })
|
|
||||||
this.partner = response.data.user;
|
this.partner = response.data.user;
|
||||||
this.messagesInterval = setInterval(this.getNewMessages, 250);
|
this.messagesInterval = setInterval(this.getNewMessages, 250);
|
||||||
} else {
|
} else if (this.autosearch && !this.searchInterval) {
|
||||||
if (this.autosearch && !this.searching && ! this.searchInterval) {
|
this.searchInterval = setInterval(this.findMatch, 500);
|
||||||
this.searchInterval = setInterval(this.findMatch, 500);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error finding match:', error);
|
console.error('Error finding match:', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getSearchGenders() {
|
getSearchGenders() {
|
||||||
const genders = [];
|
const genders = [];
|
||||||
if (this.searchmale) genders.push('m');
|
if (this.searchmale) genders.push('m');
|
||||||
if (this.searchfemale) genders.push('f');
|
if (this.searchfemale) genders.push('f');
|
||||||
return genders;
|
return genders;
|
||||||
},
|
},
|
||||||
|
|
||||||
async sendMessage() {
|
async sendMessage() {
|
||||||
if (this.inputtext.trim() !== '') {
|
if (!this.inputtext.trim()) return;
|
||||||
const response = await axios.post('/api/chat/sendMessage', { from: this.userId, to: this.partner.id, text: this.inputtext });
|
const response = await axios.post('/api/chat/sendMessage', {
|
||||||
this.messages.push({ type: "self", text: response.data.text });
|
from: this.userId,
|
||||||
this.inputtext = '';
|
to: this.partner.id,
|
||||||
}
|
text: this.inputtext,
|
||||||
|
});
|
||||||
|
this.messages.push({ type: 'self', text: response.data.text });
|
||||||
|
this.inputtext = '';
|
||||||
},
|
},
|
||||||
|
|
||||||
async getNewMessages() {
|
async getNewMessages() {
|
||||||
if (!this.partner) {
|
if (!this.partner) return;
|
||||||
return;
|
const response = await axios.post('/api/chat/getMessages', {
|
||||||
}
|
to: this.userId,
|
||||||
const response = await axios.post('/api/chat/getMessages', { to: this.userId, from: this.partner.id });
|
from: this.partner.id,
|
||||||
const messages = response.data.filter(item => !item.activity);
|
});
|
||||||
const activities = response.data.filter(item => item.activity);
|
const newMsgs = response.data.filter((m) => !m.activity);
|
||||||
for (let i = 0; i < activities.length; ++i) {
|
const activities = response.data.filter((m) => m.activity);
|
||||||
const activity = activities[i];
|
activities.forEach((act) => {
|
||||||
if (activity.activity === 'otheruserleft') {
|
if (act.activity === 'otheruserleft') {
|
||||||
this.partner = null;
|
this.partner = null;
|
||||||
this.messages.push({ type: 'system', tr: 'randomchat.userleftchat' });
|
this.messages.push({ type: 'system', tr: 'randomchat.userleftchat' });
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
this.messages.push(...messages);
|
this.messages.push(...newMsgs);
|
||||||
},
|
},
|
||||||
|
|
||||||
async removeUserFromChat() {
|
async removeUserFromChat() {
|
||||||
try {
|
try {
|
||||||
await axios.post('/api/chat/remove', { id: this.userId });
|
await axios.post('/api/chat/remove', { id: this.userId });
|
||||||
@@ -184,31 +233,27 @@ export default {
|
|||||||
console.error('Error removing user from chat:', error);
|
console.error('Error removing user from chat:', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async nextUser() {
|
async nextUser() {
|
||||||
await axios.post('/api/chat/leave', { id: this.userId });
|
await axios.post('/api/chat/leave', { id: this.userId });
|
||||||
this.partner = null;
|
this.partner = null;
|
||||||
this.messages.push({ type: 'system', tr: 'randomchat.selfstopped' });
|
this.messages.push({ type: 'system', tr: 'randomchat.selfstopped' });
|
||||||
if (this.autosearch) {
|
if (this.autosearch) {
|
||||||
this.searchInterval = setInterval(this.findMatch, 500);
|
this.searchInterval = setInterval(this.findMatch, 500);
|
||||||
this.messages.push({ type: "system", tr: "randomchat.waitingForMatch" })
|
this.messages.push({ type: 'system', tr: 'randomchat.waitingForMatch' });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
renderMessage(message) {
|
renderMessage(message) {
|
||||||
let className = '';
|
|
||||||
let tr = '';
|
|
||||||
if (message.type === 'system') {
|
if (message.type === 'system') {
|
||||||
const text = message.tr ? this.$t(message.tr) : message.text;
|
const txt = message.tr ? this.$t(message.tr) : message.text;
|
||||||
return `<span class="rc-system">${text}</span>`;
|
return `<span class="rc-system">${txt}</span>`;
|
||||||
} else if (message.type === 'self') {
|
|
||||||
className = 'rc-self';
|
|
||||||
tr = this.$t('randomchat.self');
|
|
||||||
} else {
|
|
||||||
className = 'rc-partner';
|
|
||||||
tr = this.$t('randomchat.partner');
|
|
||||||
}
|
}
|
||||||
return `<span class="${className}">${tr}: </span>${message.text}`;
|
const cls = message.type === 'self' ? 'rc-self' : 'rc-partner';
|
||||||
}
|
const who = message.type === 'self' ? this.$t('randomchat.self') : this.$t('randomchat.partner');
|
||||||
}
|
return `<span class="${cls}">${who}: </span>${message.text}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -271,5 +316,4 @@ export default {
|
|||||||
.inputline>label>input {
|
.inputline>label>input {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -157,10 +157,8 @@ const store = createStore({
|
|||||||
|
|
||||||
const retryConnection = (reconnectFn) => {
|
const retryConnection = (reconnectFn) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
console.log('Retrying Daemon WebSocket connection...');
|
|
||||||
reconnectFn();
|
reconnectFn();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
console.log('Retrying Daemon WebSocket connection...');
|
|
||||||
};
|
};
|
||||||
connectDaemonSocket();
|
connectDaemonSocket();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<h2>{{ $t('socialnetwork.forum.title') }} {{ forumName }}</h2>
|
<h2>{{ $t('socialnetwork.forum.title') }} {{ forumName }}</h2>
|
||||||
<div class="creationtoggler">
|
<div class="creationtoggler">
|
||||||
<button @click="createNewTopic">{{ $t(!inCreation ? 'socialnetwork.forum.showNewTopic' :
|
<button @click="createNewTopic">
|
||||||
'socialnetwork.forum.hideNewTopic') }}</button>
|
{{ $t(!inCreation
|
||||||
|
? 'socialnetwork.forum.showNewTopic'
|
||||||
|
: 'socialnetwork.forum.hideNewTopic') }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="inCreation">
|
<div v-if="inCreation">
|
||||||
<div>
|
<div>
|
||||||
<label class="newtitle">
|
<label class="newtitle">
|
||||||
@@ -14,13 +18,26 @@
|
|||||||
<div class="editor-container">
|
<div class="editor-container">
|
||||||
<EditorContent :editor="editor" class="editor" />
|
<EditorContent :editor="editor" class="editor" />
|
||||||
</div>
|
</div>
|
||||||
<button @click="saveNewTopic">{{ $t('socialnetwork.forum.createNewTopic') }}</button>
|
<button @click="saveNewTopic">
|
||||||
|
{{ $t('socialnetwork.forum.createNewTopic') }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else-if="titles.length > 0">
|
<div v-else-if="titles.length > 0">
|
||||||
<!-- PAGINATION + TABLE bleibt unverändert -->
|
<!-- hier kommt deine bestehende TABLE + PAGINATION hin -->
|
||||||
<!-- ... -->
|
<table>
|
||||||
|
<!-- Kopfzeile, Spalten etc. -->
|
||||||
|
</table>
|
||||||
|
<div class="pagination">
|
||||||
|
<button @click="goToPage(page-1)" :disabled="page<=1">‹</button>
|
||||||
|
<span>{{ page }} / {{ totalPages }}</span>
|
||||||
|
<button @click="goToPage(page+1)" :disabled="page>=totalPages">›</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else>
|
||||||
|
{{ $t('socialnetwork.forum.noTitles') }}
|
||||||
</div>
|
</div>
|
||||||
<div v-else>{{ $t('socialnetwork.forum.noTitles') }}</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -30,18 +47,10 @@ import apiClient from '../../utils/axios'
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ForumView',
|
name: 'ForumView',
|
||||||
components: {
|
components: { EditorContent },
|
||||||
EditorContent,
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
totalPages() {
|
|
||||||
return Math.ceil(this.numberOfItems / 25);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
forumName: 'test',
|
forumName: '',
|
||||||
forumId: 0,
|
|
||||||
page: 1,
|
page: 1,
|
||||||
numberOfItems: 0,
|
numberOfItems: 0,
|
||||||
titles: [],
|
titles: [],
|
||||||
@@ -50,57 +59,94 @@ export default {
|
|||||||
editor: null,
|
editor: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
// Neu: Forum‑ID immer direkt aus der Route ziehen
|
||||||
|
forumId() {
|
||||||
|
return this.$route.params.id
|
||||||
|
},
|
||||||
|
totalPages() {
|
||||||
|
return Math.ceil(this.numberOfItems / 25)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// Sobald sich die Route‑ID ändert, zurück auf Seite 1 und neu laden
|
||||||
|
forumId: {
|
||||||
|
handler() {
|
||||||
|
this.page = 1
|
||||||
|
this.loadForum()
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
// Wenn sich die Seite ändert, ebenfalls neu laden
|
||||||
|
page(newPage, oldPage) {
|
||||||
|
if (newPage !== oldPage) {
|
||||||
|
this.loadForum()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
this.forumId = this.$route.params.id;
|
// Editor initialisieren
|
||||||
await this.loadForum();
|
|
||||||
|
|
||||||
this.editor = new Editor({
|
this.editor = new Editor({
|
||||||
extensions: [StarterKit],
|
extensions: [StarterKit],
|
||||||
content: '',
|
content: '',
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
if (this.editor) this.editor.destroy();
|
if (this.editor) this.editor.destroy()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async loadForum() {
|
async loadForum() {
|
||||||
const response = await apiClient.get(`/api/forum/${this.forumId}/${this.page}`);
|
try {
|
||||||
this.setData(response.data);
|
const { data } = await apiClient.get(
|
||||||
|
`/api/forum/${this.forumId}/${this.page}`
|
||||||
|
)
|
||||||
|
this.forumName = data.name
|
||||||
|
this.titles = data.titles
|
||||||
|
this.numberOfItems = data.totalTopics
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Fehler beim Laden des Forums', err)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
createNewTopic() {
|
createNewTopic() {
|
||||||
this.inCreation = !this.inCreation;
|
this.inCreation = !this.inCreation
|
||||||
if (this.inCreation && this.editor) {
|
if (this.inCreation && this.editor) {
|
||||||
this.editor.commands.setContent('');
|
this.editor.commands.setContent('')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async saveNewTopic() {
|
async saveNewTopic() {
|
||||||
const content = this.editor ? this.editor.getHTML() : '';
|
const content = this.editor ? this.editor.getHTML() : ''
|
||||||
const response = await apiClient.post('/api/forum/topic', {
|
if (!this.newTitle.trim() || !content.trim()) return
|
||||||
forumId: this.forumId,
|
try {
|
||||||
title: this.newTitle,
|
const { data } = await apiClient.post(
|
||||||
content,
|
'/api/forum/topic',
|
||||||
});
|
{
|
||||||
this.setData(response.data);
|
forumId: this.forumId,
|
||||||
this.inCreation = false;
|
title: this.newTitle,
|
||||||
},
|
content
|
||||||
setData(data) {
|
}
|
||||||
this.forumName = data.name;
|
)
|
||||||
this.titles = data.titles;
|
// Neu: Server kann aktuelle Liste zurückliefern
|
||||||
this.page = data.page;
|
this.forumName = data.name
|
||||||
this.numberOfItems = data.totalTopics;
|
this.titles = data.titles
|
||||||
|
this.numberOfItems = data.totalTopics
|
||||||
|
this.page = data.page
|
||||||
|
this.inCreation = false
|
||||||
|
this.newTitle = ''
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Fehler beim Erstellen des Themas', err)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
goToPage(page) {
|
goToPage(page) {
|
||||||
if (page >= 1 && page <= this.totalPages) {
|
if (page >= 1 && page <= this.totalPages) {
|
||||||
this.page = page;
|
this.page = page
|
||||||
this.loadForum();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
openProfile(id) {
|
openProfile(id) {
|
||||||
this.$root.$refs.userProfileDialog.userId = id;
|
this.$root.$refs.userProfileDialog.userId = id
|
||||||
this.$root.$refs.userProfileDialog.open();
|
this.$root.$refs.userProfileDialog.open()
|
||||||
},
|
},
|
||||||
openTopic(topicId) {
|
openTopic(topicId) {
|
||||||
this.$router.push(`/socialnetwork/forumtopic/${topicId}`);
|
this.$router.push(`/socialnetwork/forumtopic/${topicId}`)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,17 +156,14 @@ export default {
|
|||||||
.creationtoggler {
|
.creationtoggler {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.newtitle {
|
.newtitle {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 1em;
|
gap: 1em;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.newtitle input {
|
.newtitle input {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-container {
|
.editor-container {
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
@@ -128,23 +171,19 @@ export default {
|
|||||||
min-height: 200px;
|
min-height: 200px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor {
|
.editor {
|
||||||
min-height: 150px;
|
min-height: 150px;
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination {
|
.pagination {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 0.5em;
|
gap: 0.5em;
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination button {
|
.pagination button {
|
||||||
padding: 0.5em 1em;
|
padding: 0.5em 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination span {
|
.pagination span {
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user