dynamic loaded chat and PWA
This commit is contained in:
		
							parent
							
								
									fd4fff2a78
								
							
						
					
					
						commit
						451b30c3f2
					
				
							
								
								
									
										19
									
								
								api.js
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								api.js
									
									
									
									
									
								
							| @ -27,7 +27,7 @@ wss.on('connection', (ws, req) => { | |||||||
|     console.log(`${req.socket.remoteAddress} connected`) |     console.log(`${req.socket.remoteAddress} connected`) | ||||||
|     ws.on('message', msgJSON => { |     ws.on('message', msgJSON => { | ||||||
|         let msg = JSON.parse(msgJSON) |         let msg = JSON.parse(msgJSON) | ||||||
|         console.log(`${req.socket.remoteAddress} => ${msgJSON}`) |         console.log(`${req.socket.remoteAddress} (${thisuser}) => ${msgJSON}`) | ||||||
|         if (msg.type === 'message') |         if (msg.type === 'message') | ||||||
|             if (thisuser === ""){ |             if (thisuser === ""){ | ||||||
|                 ws.send(JSON.stringify({type: "error", content: "please login before writing"})) |                 ws.send(JSON.stringify({type: "error", content: "please login before writing"})) | ||||||
| @ -37,23 +37,26 @@ wss.on('connection', (ws, req) => { | |||||||
|             else{ |             else{ | ||||||
|                 msg.content.user = thisuser |                 msg.content.user = thisuser | ||||||
|                 msg.content.text = msg.content.text.replace(/</g, "<").replace(/>/g, ">").replace(/\n/g, "<br>") |                 msg.content.text = msg.content.text.replace(/</g, "<").replace(/>/g, ">").replace(/\n/g, "<br>") | ||||||
|                 wss.clients.forEach(client => { |                 wss.clients.forEach(client => client.send(JSON.stringify(msg))) | ||||||
|                     if (client !== ws) client.send(JSON.stringify(msg))}) |  | ||||||
|             } |             } | ||||||
|         else if (msg.type === 'login' && msg.content.user !== ""){ |         else if (msg.type === 'login' && msg.content.user !== ""){ | ||||||
|             if (msg.content.user >= 20) ws.send(JSON.stringify({type: "error", content: "username is too long"})) |             if (msg.content.user.length >= 20) ws.send(JSON.stringify({type: "error", content: "username is too long"})) | ||||||
|             else if (function(){ |             else if (msg.content.user === "you" || user.indexOf(msg.content.user) !== -1) | ||||||
|                 for (let i = 0; i < user.length; i++) if (user[i] === msg.content.user) return true |                 ws.send(JSON.stringify({type: "error", content: "username already exist"})) | ||||||
|                 return false |  | ||||||
|             }() === true) ws.send(JSON.stringify({type: "error", content: "username already exist"})) |  | ||||||
|             else{ |             else{ | ||||||
|                 thisuser = msg.content.user |                 thisuser = msg.content.user | ||||||
|                 user.push(msg.content.user) |                 user.push(msg.content.user) | ||||||
|                 ws.send('{"type":"route","path":"/chat"}') |                 ws.send('{"type":"route","path":"/chat"}') | ||||||
|  |                 ws.send(JSON.stringify({type: "info", username: thisuser})) | ||||||
|                 wss.clients.forEach(client => |                 wss.clients.forEach(client => | ||||||
|                     client.send(JSON.stringify({type: "room", name: "open chat", user: user}))) |                     client.send(JSON.stringify({type: "room", name: "open chat", user: user}))) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     }) |     }) | ||||||
|  |     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"})) |     ws.send(JSON.stringify({type: "info", time: Date.now(), content: "connected"})) | ||||||
| }) | }) | ||||||
| @ -3,6 +3,10 @@ | |||||||
|   <head> |   <head> | ||||||
|     <meta charset="utf-8" /> |     <meta charset="utf-8" /> | ||||||
|     <meta http-equiv="X-UA-Compatible" content="IE=edge"/> |     <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'/> |     <meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0'/> | ||||||
|     <link rel="icon" href="<%= BASE_URL %>favicon.ico"/> |     <link rel="icon" href="<%= BASE_URL %>favicon.ico"/> | ||||||
|     <title><%= htmlWebpackPlugin.options.title %></title> |     <title><%= htmlWebpackPlugin.options.title %></title> | ||||||
|  | |||||||
							
								
								
									
										9
									
								
								public/manifest.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								public/manifest.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | { | ||||||
|  |   "name": "open chat", | ||||||
|  |   "short_name": "open chat", | ||||||
|  |   "start_url": "/", | ||||||
|  |   "display": "standalone", | ||||||
|  |   "background_color": "#14181b", | ||||||
|  |   "theme_color": "#00BCD4", | ||||||
|  |   "orientation": "portrait-primary" | ||||||
|  | } | ||||||
| @ -32,5 +32,6 @@ export default { | |||||||
|     background-color: #42b983; |     background-color: #42b983; | ||||||
|     border-radius: 1rem 1rem 1rem 0; |     border-radius: 1rem 1rem 1rem 0; | ||||||
|     text-align: left; |     text-align: left; | ||||||
|  |     word-break: break-word; | ||||||
|   } |   } | ||||||
| </style> | </style> | ||||||
| @ -22,16 +22,6 @@ export default { | |||||||
|       if (this.msg.content.text !== "") { |       if (this.msg.content.text !== "") { | ||||||
|         this.msg.time = Date.now() |         this.msg.time = Date.now() | ||||||
|         main.methods.sendWebSocket(this.msg) |         main.methods.sendWebSocket(this.msg) | ||||||
|         //just for now, ik it's dirty |  | ||||||
|         document.getElementById('messages').innerHTML += |  | ||||||
|             `<div class="messageContainer" data-v-032da2b2=""> |  | ||||||
|             <div class="message" data-v-032da2b2=""> |  | ||||||
|                 ${this.msg.content.text |  | ||||||
|                 .replace(/</g, "<") |  | ||||||
|                 .replace(/>/g, ">") |  | ||||||
|                 .replace(/\n/g, "<br>")} |  | ||||||
|             </div> |  | ||||||
|         </div>`; |  | ||||||
|         this.msg.content.text = "" |         this.msg.content.text = "" | ||||||
|         document.getElementById("messagesContainer").style.height = "calc(100% - 7rem)" |         document.getElementById("messagesContainer").style.height = "calc(100% - 7rem)" | ||||||
|         document.getElementById("newMessageInput").style.height = "1.25rem" |         document.getElementById("newMessageInput").style.height = "1.25rem" | ||||||
| @ -54,9 +44,11 @@ export default { | |||||||
|         type: "message", |         type: "message", | ||||||
|         time: Date.now(), |         time: Date.now(), | ||||||
|         content: { |         content: { | ||||||
|  |           user: "you", | ||||||
|           text: "" |           text: "" | ||||||
|         } |         } | ||||||
|       } |       }, | ||||||
|  |       chatroom: main.data().chatroom | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -6,8 +6,8 @@ | |||||||
|       </router-link> |       </router-link> | ||||||
|       <icon class="smallIcon" id="picTop" ic="./sym/supervisor_account-24px.svg" /> |       <icon class="smallIcon" id="picTop" ic="./sym/supervisor_account-24px.svg" /> | ||||||
|       <div id="container"> |       <div id="container"> | ||||||
|         <div id="chatName">{{roomInfo.name}}</div> |         <div id="chatName">{{chatroom.name}}</div> | ||||||
|         <div id="users">{{roomInfo.user.length}} members</div> |         <div id="users">{{chatroom.user.length}} members</div> | ||||||
|       </div> |       </div> | ||||||
|       <icon class="smallIcon" id="icon-menu" ic="./sym/menu-24px.svg" /> |       <icon class="smallIcon" id="icon-menu" ic="./sym/menu-24px.svg" /> | ||||||
|     </div> |     </div> | ||||||
| @ -15,6 +15,7 @@ | |||||||
| </template> | </template> | ||||||
| <script> | <script> | ||||||
| import icon from '@/components/icon.vue'; | import icon from '@/components/icon.vue'; | ||||||
|  | import main from '@/main.js'; | ||||||
| 
 | 
 | ||||||
| export default { | export default { | ||||||
|   name: "topBanner", |   name: "topBanner", | ||||||
| @ -23,10 +24,7 @@ export default { | |||||||
|   }, |   }, | ||||||
|   data(){ |   data(){ | ||||||
|     return { |     return { | ||||||
|       roomInfo: { |       chatroom: main.data().chatroom | ||||||
|         name: "open chat", |  | ||||||
|         user: [] |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @ -37,7 +35,7 @@ export default { | |||||||
|   width: 100%; |   width: 100%; | ||||||
|   height: 3rem; |   height: 3rem; | ||||||
|   background-color: #1d1d1d; |   background-color: #1d1d1d; | ||||||
|   box-shadow: 0 3px 10px #111; |   box-shadow: 0 0px 5px #111; | ||||||
| } | } | ||||||
| .smallIcon{ | .smallIcon{ | ||||||
|   top: 0.25rem; |   top: 0.25rem; | ||||||
|  | |||||||
							
								
								
									
										45
									
								
								src/main.js
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								src/main.js
									
									
									
									
									
								
							| @ -27,12 +27,12 @@ const router = new VueRouter({ | |||||||
|   ] |   ] | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| new Vue({ | let chatroom = { | ||||||
|   el: '#app', |   name: "open chat", | ||||||
|   router, |   user: [], | ||||||
|   template: '<App/>', |   username: "you", | ||||||
|   components: {App} |   messages: [] | ||||||
| }).$mount('#app') | }; | ||||||
| 
 | 
 | ||||||
| export default { | export default { | ||||||
|   mounted() { |   mounted() { | ||||||
| @ -40,10 +40,7 @@ export default { | |||||||
|   }, |   }, | ||||||
|   data(){ |   data(){ | ||||||
|     return { |     return { | ||||||
|       roomInfo: { |       chatroom: chatroom | ||||||
|         name: "open chat", |  | ||||||
|         user: [] |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
| @ -63,9 +60,22 @@ export default { | |||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const wsurl = 'ws://127.0.0.1:8090' | new Vue({ | ||||||
| const socket = new WebSocket(wsurl) |   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)} | function element(id){ return document.getElementById(id)} | ||||||
| 
 | 
 | ||||||
| socket.onopen = () => { | socket.onopen = () => { | ||||||
| @ -86,16 +96,11 @@ socket.onmessage = (e) => { | |||||||
|   if (msg.type === 'error') show_error(msg.content) |   if (msg.type === 'error') show_error(msg.content) | ||||||
|   else if (msg.type === 'route') router.push({path: msg.path}) |   else if (msg.type === 'route') router.push({path: msg.path}) | ||||||
|   else if (msg.type === 'room'){ |   else if (msg.type === 'room'){ | ||||||
|     this.roomInfo.user = msg.user |     chatroom.user = msg.user | ||||||
|   } |   } | ||||||
|  |   else if (msg.type === "info") chatroom.username = msg.username | ||||||
|   else if (msg.type === 'message'){ |   else if (msg.type === 'message'){ | ||||||
|     //just for now, ik it's dirty
 |     chatroom.messages.push(msg) | ||||||
|     element('messages').innerHTML += |  | ||||||
|         `<div class="messageContainer" data-v-a1576e28="">
 |  | ||||||
|             <div class="message" data-v-a1576e28=""> |  | ||||||
|                 ${msg.content.text} |  | ||||||
|             </div> |  | ||||||
|         </div>`; |  | ||||||
|     let msgContainer = document.getElementById("messagesContainer") |     let msgContainer = document.getElementById("messagesContainer") | ||||||
|     if (msgContainer.scrollHeight < msgContainer.scrollTop + 1000) msgContainer.scrollTo(0, msgContainer.scrollHeight) |     if (msgContainer.scrollHeight < msgContainer.scrollTop + 1000) msgContainer.scrollTo(0, msgContainer.scrollHeight) | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -2,9 +2,15 @@ | |||||||
|   <div> |   <div> | ||||||
|     <div ref="msgContainer" id="messagesContainer" class="messagesContainer"> |     <div ref="msgContainer" id="messagesContainer" class="messagesContainer"> | ||||||
|       <div id="messages" class="messages"> |       <div id="messages" class="messages"> | ||||||
|         <p style="margin-left: 1rem; font-style: italic;">You entered the chat</p> |         <p style="text-align: center; font-style: italic;">you entered the chat</p> | ||||||
|         <message style="display: none;" /> |         <div v-for="(message, i) in chatroom.messages" :key="message.time"> | ||||||
|         <messageReceive style="display: none;" /> |           <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> | ||||||
|       </div> |       </div> | ||||||
|     </div> |     </div> | ||||||
|     <newMessage /> |     <newMessage /> | ||||||
| @ -16,7 +22,8 @@ | |||||||
| import message from '@/components/message.vue'; | import message from '@/components/message.vue'; | ||||||
| import messageReceive from '@/components/messageReceive.vue'; | import messageReceive from '@/components/messageReceive.vue'; | ||||||
| import newMessage from '@/components/newMessage.vue'; | import newMessage from '@/components/newMessage.vue'; | ||||||
| import topBanner from "@/components/topBanner"; | import topBanner from '@/components/topBanner.vue'; | ||||||
|  | import main from '@/main.js'; | ||||||
| 
 | 
 | ||||||
| export default { | export default { | ||||||
|   name: 'chat', |   name: 'chat', | ||||||
| @ -25,6 +32,11 @@ export default { | |||||||
|     messageReceive, |     messageReceive, | ||||||
|     newMessage, |     newMessage, | ||||||
|     topBanner |     topBanner | ||||||
|  |   }, | ||||||
|  |   data(){ | ||||||
|  |     return { | ||||||
|  |       chatroom: main.data().chatroom | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user