Initial commit
This commit is contained in:
277
frontend/src/dialogues/chat/RandomChatDialog.vue
Normal file
277
frontend/src/dialogues/chat/RandomChatDialog.vue
Normal file
@@ -0,0 +1,277 @@
|
||||
<template>
|
||||
<DialogWidget ref="dialog" title="randomchat.title" icon="dice24.png" :show-close="true" :buttons="buttons"
|
||||
:modal="false" :isTitleTranslated="true" @close="closeDialog">
|
||||
<div v-if="chatIsRunning" class="randomchat">
|
||||
<div class="headline">
|
||||
{{ $t("randomchat.agerange") }}
|
||||
<input type="number" v-model="agefromsearch" min="18" max="150" size="5" />
|
||||
-
|
||||
<input type="number" v-model="agetosearch" min="18" max="150" size="5" />
|
||||
<span class="multiselect">
|
||||
{{ $t("randomchat.gendersearch") }}
|
||||
<div>
|
||||
<label><input type="checkbox" v-model="searchmale" />{{ $t("randomchat.gender.male") }}</label>
|
||||
<label><input type="checkbox" v-model="searchfemale" />{{ $t("randomchat.gender.female")
|
||||
}}</label>
|
||||
</div>
|
||||
</span>
|
||||
<label><input type="checkbox" v-model="camonlysearch" />{{ $t("randomchat.camonly") }}</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')" />
|
||||
<label><input type="checkbox" v-model="autosearch" />{{ $t("randomchat.autosearch") }}</label>
|
||||
<button @click="nextUser" v-if="partner != null">{{ $t("randomchat.jumptonext") }}</button>
|
||||
<button @click="startSearch" v-if="partner == null && !searching">{{ $t("randomchat.startsearch") }}</button>
|
||||
</div>
|
||||
<div class="output">
|
||||
<div v-for="message in messages" v-html="renderMessage(message)">
|
||||
</div>
|
||||
</div>
|
||||
<div class="inputline">
|
||||
<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/dice16.png" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div>
|
||||
<label>{{ $t("randomchat.age") }} <input type="number" v-model="age" min="18" max="150"
|
||||
value="18" /></label>
|
||||
</div>
|
||||
<div>
|
||||
<label>{{ $t("randomchat.gender.title") }} <select v-model="gender">
|
||||
<option value="f">{{ $t("randomchat.gender.female") }}</option>
|
||||
<option value="m">{{ $t("randomchat.gender.male") }}</option>
|
||||
</select></label>
|
||||
</div>
|
||||
<div>
|
||||
<button @click="startRandomChat()">{{ $t("randomchat.start") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</DialogWidget>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DialogWidget from '@/components/DialogWidget.vue';
|
||||
import { mapGetters } from 'vuex';
|
||||
import axios from 'axios';
|
||||
|
||||
export default {
|
||||
name: 'RandomChatDialog',
|
||||
components: {
|
||||
DialogWidget,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['isLoggedIn']),
|
||||
buttons() {
|
||||
return [{ text: this.$t("randomchat.close")}];
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
chatIsRunning: false,
|
||||
age: 18,
|
||||
gender: "f",
|
||||
agefromsearch: 18,
|
||||
agetosearch: 150,
|
||||
searchmale: true,
|
||||
searchfemale: true,
|
||||
autosearch: false,
|
||||
inputtext: '',
|
||||
searching: false,
|
||||
userId: null,
|
||||
searchInterval: null,
|
||||
messages: [],
|
||||
partner: null,
|
||||
messagesInterval: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async open() {
|
||||
this.$refs.dialog.open();
|
||||
},
|
||||
async registerUser() {
|
||||
try {
|
||||
const response = await axios.post('/api/chat/register', {
|
||||
gender: this.gender,
|
||||
age: this.age
|
||||
});
|
||||
this.userId = response.data.id;
|
||||
} catch (error) {
|
||||
console.error('Error registering user:', error);
|
||||
}
|
||||
},
|
||||
async closeDialog() {
|
||||
this.$refs.dialog.close();
|
||||
await axios.push('/api/chat/exit', { id: this.userId })
|
||||
await this.removeUserFromChat();
|
||||
},
|
||||
async startRandomChat() {
|
||||
this.chatIsRunning = true;
|
||||
await this.registerUser();
|
||||
await this.startSearch();
|
||||
},
|
||||
async startSearch() {
|
||||
this.searching = true;
|
||||
await this.findMatch();
|
||||
this.messages.push({ type: "system", tr: "randomchat.waitingForMatch" })
|
||||
this.searchInterval = setInterval(this.findMatch, 500);
|
||||
},
|
||||
async findMatch() {
|
||||
try {
|
||||
const response = await axios.post('/api/chat/findMatch', {
|
||||
genders: this.getSearchGenders(),
|
||||
age: {
|
||||
min: this.agefromsearch,
|
||||
max: this.agetosearch
|
||||
},
|
||||
id: this.userId
|
||||
});
|
||||
if (response.data.status && response.data.status === 'matched') {
|
||||
this.searching = false;
|
||||
if (this.searchInterval) {
|
||||
console.log('clear interval');
|
||||
clearInterval(this.searchInterval);
|
||||
this.searchInterval = null;
|
||||
}
|
||||
const initText = this.$t("randomchat.chatpartner")
|
||||
.replace("<gender>", this.$t(`randomchat.partnergender${response.data.user.gender}`))
|
||||
.replace("<age>", response.data.user.age);
|
||||
this.messages = [];
|
||||
this.messages.push({ "type": "system", text: initText })
|
||||
this.partner = response.data.user;
|
||||
this.messagesInterval = setInterval(this.getNewMessages, 250);
|
||||
} else {
|
||||
if (this.autosearch && !this.searching && ! this.searchInterval) {
|
||||
this.searchInterval = setInterval(this.findMatch, 500);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error finding match:', error);
|
||||
}
|
||||
},
|
||||
getSearchGenders() {
|
||||
const genders = [];
|
||||
if (this.searchmale) genders.push('m');
|
||||
if (this.searchfemale) genders.push('f');
|
||||
return genders;
|
||||
},
|
||||
async sendMessage() {
|
||||
if (this.inputtext.trim() !== '') {
|
||||
console.log('Sending message:', this.inputtext);
|
||||
const response = await axios.post('/api/chat/sendMessage', { from: this.userId, to: this.partner.id, text: this.inputtext });
|
||||
this.messages.push({ type: "self", text: response.data.text });
|
||||
this.inputtext = '';
|
||||
}
|
||||
},
|
||||
async getNewMessages() {
|
||||
if (!this.partner) {
|
||||
return;
|
||||
}
|
||||
const response = await axios.post('/api/chat/getMessages', { to: this.userId, from: this.partner.id });
|
||||
const messages = response.data.filter(item => !item.activity);
|
||||
const activities = response.data.filter(item => item.activity);
|
||||
for (let i = 0; i < activities.length; ++i) {
|
||||
const activity = activities[i];
|
||||
if (activity.activity === 'otheruserleft') {
|
||||
this.partner = null;
|
||||
this.messages.push({ type: 'system', tr: 'randomchat.userleftchat' });
|
||||
}
|
||||
}
|
||||
this.messages.push(...messages);
|
||||
},
|
||||
async removeUserFromChat() {
|
||||
try {
|
||||
await axios.post('/api/chat/remove', { id: this.userId });
|
||||
} catch (error) {
|
||||
console.error('Error removing user from chat:', error);
|
||||
}
|
||||
},
|
||||
async nextUser() {
|
||||
await axios.post('/api/chat/leave', { id: this.userId });
|
||||
this.partner = null;
|
||||
this.messages.push({ type: 'system', tr: 'randomchat.selfstopped' });
|
||||
if (this.autosearch) {
|
||||
this.searchInterval = setInterval(this.findMatch, 500);
|
||||
this.messages.push({ type: "system", tr: "randomchat.waitingForMatch" })
|
||||
}
|
||||
},
|
||||
renderMessage(message) {
|
||||
let className = '';
|
||||
let tr = '';
|
||||
if (message.type === 'system') {
|
||||
const text = message.tr ? this.$t(message.tr) : message.text;
|
||||
return `<span class="rc-system">${text}</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}`;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.randomchat {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
gap: 0.5em;
|
||||
}
|
||||
|
||||
.randomchat>div {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.randomchat>.headline {
|
||||
gap: 1.5em;
|
||||
}
|
||||
|
||||
.multiselect {
|
||||
border: 1px solid black;
|
||||
position: relative;
|
||||
padding: 0.1em;
|
||||
}
|
||||
|
||||
.multiselect>div {
|
||||
border: 1px solid black;
|
||||
position: absolute;
|
||||
top: 1.5em;
|
||||
left: -1px;
|
||||
text-align: left;
|
||||
background-color: rgba(256, 256, 256, 0.9);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.multiselect:hover>div {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.output {
|
||||
border: 1px solid #909090;
|
||||
padding: 0.2em;
|
||||
overflow: auto;
|
||||
flex: 1;
|
||||
flex-direction: column !important;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.inputline {
|
||||
display: flex;
|
||||
gap: 0.5em;
|
||||
}
|
||||
|
||||
.inputline>label {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.inputline>label>input {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
</style>
|
||||
63
frontend/src/dialogues/standard/DataPrivacyDialog.vue
Normal file
63
frontend/src/dialogues/standard/DataPrivacyDialog.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<DialogWidget
|
||||
ref="dialog"
|
||||
title="dataPrivacy.title"
|
||||
isTitleTranslated=true
|
||||
icon="privacy24.png"
|
||||
:show-close="true"
|
||||
:buttons="[{ text: 'Ok' }]"
|
||||
:modal="false"
|
||||
@close="closeDialog"
|
||||
@ok="handleOk"
|
||||
>
|
||||
<div v-html="dataPrivacyContent"></div>
|
||||
</DialogWidget>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DialogWidget from '../../components/DialogWidget.vue';
|
||||
import content from '../../content/content.js';
|
||||
|
||||
export default {
|
||||
name: 'DataPrivacyDialog',
|
||||
components: {
|
||||
DialogWidget
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataPrivacyContent: content.dataPrivacy[this.$i18n.locale]
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
'$i18n.locale'(newLocale) {
|
||||
this.dataPrivacyContent = content.dataPrivacy[newLocale];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.$refs.dialog.open();
|
||||
},
|
||||
closeDialog() {
|
||||
this.$refs.dialog.close();
|
||||
},
|
||||
handleOk() {
|
||||
this.closeDialog();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
63
frontend/src/dialogues/standard/ImprintDialog.vue
Normal file
63
frontend/src/dialogues/standard/ImprintDialog.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<DialogWidget
|
||||
ref="dialog"
|
||||
title="imprint.title"
|
||||
isTitleTranslated=true
|
||||
icon="imprint24.png"
|
||||
:show-close="true"
|
||||
:buttons="[{ text: 'Ok' }]"
|
||||
:modal="false"
|
||||
@close="closeDialog"
|
||||
@ok="handleOk"
|
||||
>
|
||||
<div v-html="imprintContent"></div>
|
||||
</DialogWidget>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DialogWidget from '../../components/DialogWidget.vue';
|
||||
import content from '../../content/content.js';
|
||||
|
||||
export default {
|
||||
name: 'ImprintDialog',
|
||||
components: {
|
||||
DialogWidget
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
imprintContent: content.imprint[this.$i18n.locale]
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
'$i18n.locale'(newLocale) {
|
||||
this.imprintContent = content.imprint[newLocale];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.$refs.dialog.open();
|
||||
},
|
||||
closeDialog() {
|
||||
this.$refs.dialog.close();
|
||||
},
|
||||
handleOk() {
|
||||
this.closeDialog();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user