Compare commits

..

No commits in common. "07117763bfb1944df09c7ddb719c39cd589c3b57" and "49791b52762e3a9a864842a872396b5bf34fb180" have entirely different histories.

11 changed files with 94 additions and 151 deletions

41
api.js
View File

@ -21,42 +21,17 @@ const wss = new ws.Server({
});
//WS handler
let user = [];
wss.on('connection', (ws, req) => {
let thisuser = ""
console.log(`${req.socket.remoteAddress} connected`)
ws.on('message', msgJSON => {
let msg = JSON.parse(msgJSON)
console.log(`${req.socket.remoteAddress} (${thisuser}) => ${msgJSON}`)
if (msg.type === 'message')
if (thisuser === ""){
ws.send(JSON.stringify({type: "error", content: "please login before writing"}))
ws.send('{"type":"route","path":"/login"}')
}else if (msg.content.text === "")
ws.send(JSON.stringify({type: "error", content: "your message was empty"}))
else{
msg.content.user = thisuser
msg.content.text = msg.content.text.replace(/</g, "&lt").replace(/>/g, "&gt").replace(/\n/g, "<br>")
wss.clients.forEach(client => client.send(JSON.stringify(msg)))
}
else if (msg.type === 'login' && msg.content.user !== ""){
if (msg.content.user.length >= 20) ws.send(JSON.stringify({type: "error", content: "username is too long"}))
else if (msg.content.user === "you" || user.indexOf(msg.content.user) !== -1)
ws.send(JSON.stringify({type: "error", content: "username already exist"}))
else{
thisuser = msg.content.user
user.push(msg.content.user)
ws.send('{"type":"route","path":"/chat"}')
ws.send(JSON.stringify({type: "info", username: thisuser}))
wss.clients.forEach(client =>
client.send(JSON.stringify({type: "room", name: "open chat", user: user})))
}
}
console.log(`${req.socket.remoteAddress} => ${msgJSON}`)
if (msg.type === 'message') wss.clients.forEach(client => client.send(msgJSON))
})
ws.on('close', () => {
user.splice(user.indexOf(thisuser), 1);
console.log(`${req.socket.remoteAddress} (${thisuser}) closed`)
})
ws.send(JSON.stringify({type: "info", time: Date.now(), content: "connected"}))
let msg = {
type: "info",
time: Date.now(),
content: "connected"
}
ws.send(JSON.stringify(msg))
})

View File

@ -3,10 +3,6 @@
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<!-- PWA support -->
<link rel="manifest" href="./manifest.json"/>
<meta name="theme-color" content="#2F3BA2"/>
<meta name="description" content="open chat"/>
<meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0'/>
<link rel="icon" href="<%= BASE_URL %>favicon.ico"/>
<title><%= htmlWebpackPlugin.options.title %></title>

View File

@ -1,9 +0,0 @@
{
"name": "open chat",
"short_name": "open chat",
"start_url": "/",
"display": "standalone",
"background_color": "#14181b",
"theme_color": "#00BCD4",
"orientation": "portrait-primary"
}

BIN
public/sym/placeholder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -1,23 +1,28 @@
<template>
<div id="chatInformation">
<div class="chatInformation">
<h1>open chat</h1>
<icon class="closeBtn" onclick="this.parentNode.style.display = 'none'" ic="./sym/ic_close_white_24px.svg" />
<div id="box">
<div class="informationBox">
<div class="picBoxBig"><div class="placeholderBig"><p>{{chatroom.name.substr(0,2)}}</p></div></div>
<div class="picBoxBig"><div class="placeholderBig"><p>O P</p></div></div>
<div class="roomInformation">
<div class="roomName">{{chatroom.name}}</div>
<div class="users">{{chatroom.user.length}} members</div>
<div class="roomName">Open Chat room</div>
<div class="users">2 members</div>
</div>
</div>
<h2 v-if="chatroom.user.length !== 0">members</h2>
<div v-for="user in chatroom.user" :key="user">
<div class="contentBox">
<div class="picBox"><div class="picPlaceholder"><p>{{user.substr(0,2)}}</p></div></div>
<div class="information">
<div class="userName">{{user}}</div>
<div class="status">online</div>
</div>
<div id="textMembers">Members</div>
<div class="contentBox">
<div class="picBox"><div class="picPlaceholder"><p>O P</p></div></div>
<div class="information">
<div class="userName">TechCrafter07</div>
<div class="status">Online</div>
</div>
</div>
<div class="contentBox">
<div class="picBox"><div class="picPlaceholder"><p>O P</p></div></div>
<div class="information">
<div class="userName">Alban</div>
<div class="status">Online</div>
</div>
</div>
</div>
@ -25,38 +30,30 @@
</template>
<script>
import icon from './icon.vue';
import main from '@/main.js'
export default {
name: "chatInformation",
components:{
icon
},
data(){
return {
chatroom: main.data().chatroom
}
}
}
</script>
<style scoped>
#chatInformation{
.chatInformation{
position: absolute;
left: 50%;
transform: translate(-50%, 0);
top: 5rem;
width: calc(100% - 8rem);
max-width: 30rem;
height: calc(100% - 10rem);
background-color: #1d1d1d;
box-shadow: 6px 6px 20px #111;
border-radius: 1rem;
text-align: center;
display: none;
}
@media (max-width: 30rem) {
#chatInformation{
.chatInformation{
transform: unset;
top: 0;
left: 0;
@ -74,14 +71,16 @@ export default {
#box{
position: relative;
width: calc(100% - 2rem);
background-color: #2d2d2d;
padding: 0.001rem 1rem 1rem;
overflow-y: auto;
overflow: auto;
max-height: calc(100% - 8rem);
}
.informationBox{
margin-top: 0.2rem;
height: 5rem;
padding: 0.2rem;
border-bottom: 2px solid #9c9c9c;
}
.picBoxBig{
text-align: center;
@ -108,9 +107,17 @@ export default {
font-size: 1.2rem;
color: #9c9c9c;
}
#textMembers{
font-size: 1.5rem;
text-align: left;
margin-left: 0.2rem;
margin-top: 0.3rem;
margin-bottom: 0.2rem;
}
.contentBox{
margin-top: 0.2rem;
height: 3.2rem;
border-bottom: 2px solid #9c9c9c ;
padding: 0.2rem;
max-height: 48px;
}

View File

@ -32,6 +32,5 @@ export default {
background-color: #42b983;
border-radius: 1rem 1rem 1rem 0;
text-align: left;
word-break: break-word;
}
</style>

View File

@ -9,8 +9,8 @@
</template>
<script>
import icon from '@/components/icon.vue';
import main from '@/main.js';
import icon from './icon.vue';
import main from '../main.js';
export default {
name: "newMessage",
@ -23,10 +23,7 @@ export default {
this.msg.time = Date.now()
main.methods.sendWebSocket(this.msg)
this.msg.content.text = ""
document.getElementById("messagesContainer").style.height = "calc(100% - 7rem)"
document.getElementById("newMessageInput").style.height = "1.25rem"
let msgContainer = document.getElementById("messagesContainer")
msgContainer.scrollTo(0, msgContainer.scrollHeight)
this.resizeMessageBanner()
}
},
resizeMessageBanner(){
@ -36,6 +33,7 @@ export default {
let msgContainer = document.getElementById("messagesContainer")
msgContainer.style.height
= `calc(100% - ${id.parentElement.clientHeight}px - 3rem)`
//msgContainer.scrollTo(0, msgContainer.scrollHeight)
}
},
data(){
@ -44,11 +42,9 @@ export default {
type: "message",
time: Date.now(),
content: {
user: "you",
text: ""
}
},
chatroom: main.data().chatroom
}
}
}
}
@ -71,7 +67,7 @@ export default {
margin-bottom: 1rem;
left: 2rem;
min-height: 1.25rem;
max-height: 10rem;
max-height: 14rem;
width: calc(100% - 7rem);
height: 1.25rem;
background-color: #fff0;

View File

@ -1,13 +1,11 @@
<template>
<div class="topBanner">
<div>
<router-link to="login">
<icon class="smallIcon" id="icon-arrow" ic="./sym/arrow_back-24px.svg" />
</router-link>
<icon class="smallIcon" id="icon-arrow" ic="./sym/arrow_back-24px.svg" />
<icon class="smallIcon" id="picTop" ic="./sym/supervisor_account-24px.svg" />
<div id="container">
<div id="chatName">{{chatroom.name}}</div>
<div id="users">{{chatroom.user.length}} members</div>
<div id="chatName">{{roomInfo.name}}</div>
<div id="users">{{roomInfo.user.length}} members</div>
</div>
<icon v-on:click.native="showChatInfo()" class="smallIcon" id="icon-menu" ic="./sym/menu-24px.svg" />
</div>
@ -15,7 +13,6 @@
</template>
<script>
import icon from '@/components/icon.vue';
import main from '@/main.js';
export default {
name: "topBanner",
@ -29,7 +26,10 @@ export default {
},
data(){
return {
chatroom: main.data().chatroom
roomInfo: {
name: "open chat",
user: []
}
}
}
}
@ -40,7 +40,7 @@ export default {
width: 100%;
height: 3rem;
background-color: #1d1d1d;
box-shadow: 0 0px 5px #111;
box-shadow: 0 3px 10px #111;
}
.smallIcon{
top: 0.25rem;

View File

@ -27,22 +27,17 @@ const router = new VueRouter({
]
})
let chatroom = {
name: "open chat",
user: [],
username: "you",
messages: []
};
new Vue({
el: '#app',
router,
template: '<App/>',
components: {App}
}).$mount('#app')
export default {
mounted() {
sendMessage()
},
data(){
return {
chatroom: chatroom
}
},
methods: {
sendMessage(message){
let msg = {
@ -60,22 +55,9 @@ export default {
}
}
new Vue({
el: '#app',
router,
template: '<App/>',
components: {App},
data(){
return {
chatroom: chatroom
}
}
}).$mount('#app')
const wsurl = 'ws://127.0.0.1:8090'
//const wsurl = 'wss://chat.adb.sh:8080'
const socket = new WebSocket(wsurl)
function element(id){ return document.getElementById(id)}
socket.onopen = () => {
@ -94,15 +76,14 @@ socket.onmessage = (e) => {
console.log(`data received => ${e.data}`)
let msg = JSON.parse(e.data)
if (msg.type === 'error') show_error(msg.content)
else if (msg.type === 'route') router.push({path: msg.path})
else if (msg.type === 'room'){
chatroom.user = msg.user
}
else if (msg.type === "info") chatroom.username = msg.username
else if (msg.type === 'message'){
chatroom.messages.push(msg)
let msgContainer = document.getElementById("messagesContainer")
if (msgContainer.scrollHeight < msgContainer.scrollTop + 1000) msgContainer.scrollTo(0, msgContainer.scrollHeight)
//just for now, ik it's dirty
element('messages').innerHTML +=
`<div class="messageContainer" data-v-032da2b2="">
<div class="message" data-v-032da2b2="">
${msg.content.text}
</div>
</div>`;
}
}

View File

@ -2,15 +2,27 @@
<div>
<div ref="msgContainer" id="messagesContainer" class="messagesContainer">
<div id="messages" class="messages">
<p style="text-align: center; font-style: italic;">you entered the chat</p>
<div v-for="(message, i) in chatroom.messages" :key="message.time">
<div v-if="message.content.user !== chatroom.username && function(){
return i===0 || chatroom.messages[i-1].content.user!==message.content.user;}()"
style="margin-left: 2rem; margin-top: 1rem">{{message.content.user}}
</div>
<messageReceive v-if="message.content.user !== chatroom.username" :msg=message.content.text />
<message v-if="message.content.user === chatroom.username" :msg=message.content.text />
</div>
<message msg="Hey :D" />
<message msg="Du bist blööööd xD" />
<messageReceive msg="Du auch" />
<message msg="lol" />
<messageReceive msg="Du bist voll blöd, ich hasse dich, warum tust du das?!" />
<message msg="Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Ut imperdiet vel risus tristique mollis. Proin aliquam felis non vehicula ornare.
Fusce scelerisque pellentesque erat quis sollicitudin.
Quisque aliquet, ligula ut volutpat vulputate, ligula lorem dictum velit, et aliquam sapien orci sed magna.
Nam suscipit ex eget urna accumsan pulvinar. Pellentesque fringilla placerat feugiat.
Aenean aliquam vestibulum metus. Nulla augue turpis, consectetur vitae quam ac, porttitor rhoncus nunc.
Nullam non turpis consequat, placerat lectus nec, ornare orci.
Fusce lorem tortor, viverra ac suscipit sit amet, scelerisque id eros.
Suspendisse et ultricies elit, vitae pretium ipsum. Suspendisse vel ex in turpis pulvinar feugiat. "
/>
<messageReceive msg="Du hast Pizza!" />
<message msg="und Kuchen :P" />
<message msg="und Kuchen :P" />
<message msg="und Kuchen :P" />
<message msg="und Kuchen :P" />
<message msg="und Kuchen :P" />
</div>
</div>
<newMessage />
@ -23,23 +35,17 @@
import message from '@/components/message.vue';
import messageReceive from '@/components/messageReceive.vue';
import newMessage from '@/components/newMessage.vue';
import topBanner from '@/components/topBanner.vue';
import main from '@/main.js';
import ChatInformation from "@/components/chatInformation";
import topBanner from "@/components/topBanner";
import chatInformation from "@/components/chatInformation";
export default {
name: 'chat',
components: {
ChatInformation,
message,
messageReceive,
newMessage,
topBanner
},
data(){
return {
chatroom: main.data().chatroom
}
topBanner,
chatInformation
}
}
</script>

View File

@ -5,31 +5,23 @@
<label for="longurl-input"></label>
<input v-model="session.content.user" class="input" id="longurl-input" type="text" autocomplete="off" maxlength="20" placeholder="chose nickname">
</div>
<textbtn v-on:click.native="login()" text="login" />
<input type="hidden" value="search" name="login">
<textbtn text="login" />
</div>
</template>
<script>
import textbtn from '@/components/textbtn';
import main from "@/main";
export default {
name: "login.vue",
components: {
textbtn
},
methods: {
login() {
if (this.session.content.user !== "") {
this.session.time = Date.now()
main.methods.sendWebSocket(this.session)
}
}
},
data(){
return {
session: {
type: "login",
type: "session",
time: Date.now(),
content: {
user: ""