summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/assets/css/tailwind.css31
-rw-r--r--src/components/group/GroupMaker.vue21
-rw-r--r--src/components/group/GroupSender.vue62
-rw-r--r--src/components/group/Message.vue20
-rw-r--r--src/components/searcher/Searcher.vue41
-rw-r--r--src/components/searcher/Sugestion.vue21
-rw-r--r--src/main.js2
-rw-r--r--src/services/ChatService.js12
-rw-r--r--src/views/Home.vue52
-rw-r--r--src/views/Login.vue12
-rw-r--r--src/views/Register.vue14
11 files changed, 182 insertions, 106 deletions
diff --git a/src/assets/css/tailwind.css b/src/assets/css/tailwind.css
new file mode 100644
index 0000000..1028353
--- /dev/null
+++ b/src/assets/css/tailwind.css
@@ -0,0 +1,31 @@
1@tailwind base;
2@tailwind components;
3@tailwind utilities;
4
5@layer base {
6 .inset-center {
7 position: absolute;
8 top: 50%;
9 left: 50%;
10 transform: translate(-50%, -50%);
11 }
12
13 kbd {
14 @apply bg-gray-600;
15 @apply p-1;
16 @apply rounded-md;
17 @apply border-gray-800;
18 @apply font-fira;
19 }
20
21 .searcher {
22 @apply inset-center;
23 @apply w-2/3;
24 @apply h-90;
25 @apply shadow-lg;
26 @apply bg-gray-900;
27 @apply p-4 rounded-lg;
28 @apply border-2;
29 @apply border-blue-900;
30 }
31}
diff --git a/src/components/group/GroupMaker.vue b/src/components/group/GroupMaker.vue
index f3da293..06963e3 100644
--- a/src/components/group/GroupMaker.vue
+++ b/src/components/group/GroupMaker.vue
@@ -1,15 +1,17 @@
1<template> 1<template>
2 <div class="group_maker"> 2 <div class="searcher">
3 Group maker 3 <div class="text-2xl p-2"> Group maker </div>
4 <form @submit="make_group"> 4 <form @submit="make_group">
5 <input 5 <input
6 v-model="group_name" 6 v-model="group_name"
7 ref='input' 7 ref='input'
8 type="text" 8 type="text"
9 placeholder="Type group name..." 9 placeholder="Nazwa grupy..."
10 class="w-full bg-gray-800 mb-2 mt-10 p-2"
11 @keydown="hotkeys"
10 /> 12 />
11 13
12 <select multiple v-model="users_selection"> 14 <select multiple class="w-full bg-gray-800 p-4 mb-10" v-model="users_selection">
13 15
14 <option 16 <option
15 v-for="user in users" 17 v-for="user in users"
@@ -19,6 +21,8 @@
19 </option> 21 </option>
20 22
21 </select> 23 </select>
24
25 <input type="submit" class="w-full p-2 bg-gray-800">
22 </form> 26 </form>
23 </div> 27 </div>
24</template> 28</template>
@@ -69,6 +73,15 @@ export default {
69 this.close() 73 this.close()
70 74
71 console.log(this.users) 75 console.log(this.users)
76 },
77
78 hotkeys(e) {
79 switch(e.code) {
80 case 'Delete':
81 e.preventDefault()
82 this.$emit('close')
83 break
84 }
72 } 85 }
73 }, 86 },
74 87
diff --git a/src/components/group/GroupSender.vue b/src/components/group/GroupSender.vue
index ba36949..a815561 100644
--- a/src/components/group/GroupSender.vue
+++ b/src/components/group/GroupSender.vue
@@ -1,12 +1,25 @@
1<template> 1<template>
2 <div class="group_view"> 2 <div
3 <h1> {{group.name}} </h1> 3 class="bg-gray-900 w-full m-2 mb-0 border-4"
4 <div class="messages"> 4 :class="{
5 'border-red-900': isFocus,
6 'border-blue-900': !isFocus
7 }"
8 >
9
10 <h1 class="text-2xl p-2 bg-blue-900"> {{group.name}} </h1>
11 <div class="overflow-auto h-64 p-2" ref="messages">
5 <Message v-for="message in messages" :key="message.id" :message="message" /> 12 <Message v-for="message in messages" :key="message.id" :message="message" />
6 </div> 13 </div>
7 14
8 <form @submit="send_message"> 15 <form @submit="send_message">
9 <input v-model="message" type="text" ref="input" /> 16 <input
17 v-model="message"
18 class="w-full bg-blue-900 p-2" placeholder="Napisz cos..." type="text" ref="input"
19 @focus="isFocus=true"
20 @blur="isFocus=false"
21 @keydown="hotkeys"
22 />
10 </form> 23 </form>
11 </div> 24 </div>
12</template> 25</template>
@@ -20,6 +33,7 @@ export default {
20 return { 33 return {
21 message: "", 34 message: "",
22 messages: [], 35 messages: [],
36 isFocus: false
23 } 37 }
24 }, 38 },
25 39
@@ -45,13 +59,38 @@ export default {
45 59
46 console.log(data) 60 console.log(data)
47 61
48 if(status===200) 62 if(status===200){
49 this.messages = data.messages 63 this.messages = data.messages
64 this.scroll_down()
65 }
50 }, 66 },
51 67
52 push_message(message) { 68 push_message(message) {
53 if(message.receiver == this.group.id) 69 if(message.receiver == this.group.id){
54 this.messages.push(message) 70 this.messages.push(message)
71 this.scroll_down()
72 }
73 },
74
75 scroll_down() {
76 this.$nextTick(function () {
77 const messages = this.$refs.messages
78 console.log(messages)
79 messages.scrollTop = messages.scrollHeight
80 })
81 },
82
83 hotkeys(e) {
84 switch(e.code) {
85 case 'Delete':
86 e.preventDefault()
87 this.$emit('close', this.group.id)
88 break
89 case 'Escape':
90 e.preventDefault()
91 this.$refs.input.blur()
92 break
93 }
55 } 94 }
56 }, 95 },
57 96
@@ -72,14 +111,3 @@ export default {
72 } 111 }
73} 112}
74</script> 113</script>
75
76<style scoped>
77.group_view {
78 width: 25%;
79}
80
81.messages {
82 overflow:auto;
83 height: 300px;
84}
85</style>
diff --git a/src/components/group/Message.vue b/src/components/group/Message.vue
index eedcc6e..556deb9 100644
--- a/src/components/group/Message.vue
+++ b/src/components/group/Message.vue
@@ -1,8 +1,8 @@
1<template> 1<template>
2 <div class="message" :class="{mine: is_message_mine}"> 2 <div class="w-full text-left mt-2" :class="{'text-right': is_message_mine}">
3 <div class="sender">{{ get_message_user }}</div> 3 <div class="">{{ get_message_user }}</div>
4 <div class="content">{{ get_message_content }}</div> 4 <div class="">{{ get_message_content }}</div>
5 <div class="date">{{ get_message_date }}</div> 5 <div class="">{{ get_message_date }}</div>
6 </div> 6 </div>
7</template> 7</template>
8 8
@@ -29,15 +29,3 @@ export default {
29 } 29 }
30} 30}
31</script> 31</script>
32
33<style scoped>
34.message {
35 width: 100%;
36 margin-bottom: 10px;
37 color: white;
38}
39
40.mine {
41 color: red;
42}
43</style>
diff --git a/src/components/searcher/Searcher.vue b/src/components/searcher/Searcher.vue
index f8dd51f..e74600a 100644
--- a/src/components/searcher/Searcher.vue
+++ b/src/components/searcher/Searcher.vue
@@ -1,7 +1,8 @@
1<template> 1<template>
2 <div id="searcher"> 2 <div class="searcher">
3 <input 3 <input
4 type="text" 4 type="text"
5 class="w-full bg-gray-800 p-2 mb-4"
5 v-model='search' 6 v-model='search'
6 ref='input' 7 ref='input'
7 @keydown="hotkeys" 8 @keydown="hotkeys"
@@ -13,7 +14,7 @@
13 v-for="sugestion in sugestions" 14 v-for="sugestion in sugestions"
14 :key="sugestion[0]" 15 :key="sugestion[0]"
15 :sugestion="sugestion" 16 :sugestion="sugestion"
16 :class="{selected: sugestion[0] === current[0]}" 17 :class="{'bg-gray-800': sugestion[0] === current[0]}"
17 /> 18 />
18 </div> 19 </div>
19</template> 20</template>
@@ -72,7 +73,11 @@ export default {
72 73
73 hotkeys(e) { 74 hotkeys(e) {
74 switch(e.code) { 75 switch(e.code) {
75 case 'Escape': 76 case 'Escape':
77 e.preventDefault()
78 this.close()
79 break
80 case 'Delete':
76 e.preventDefault() 81 e.preventDefault()
77 this.close() 82 this.close()
78 break 83 break
@@ -127,31 +132,3 @@ export default {
127 } 132 }
128} 133}
129</script> 134</script>
130
131<style scoped>
132 #searcher {
133 position: absolute;
134 width: 30%;
135 height: 80%;
136 top: 50%;
137 left: 50%;
138 background-color: #202020;
139 padding: 20px;
140 border-radius: 10px;
141 transform: translate(-50%, -50%);
142 }
143
144 #searcher input {
145 width: 100%;
146 margin-bottom: 20px;
147 padding: 10px;
148 padding-right: 0px;
149 height: 20px;
150 border: none;
151 background-color: #303030;
152 }
153
154 .selected {
155 background-color: #505050;
156 }
157</style>
diff --git a/src/components/searcher/Sugestion.vue b/src/components/searcher/Sugestion.vue
index 4721ca2..15a177d 100644
--- a/src/components/searcher/Sugestion.vue
+++ b/src/components/searcher/Sugestion.vue
@@ -1,5 +1,5 @@
1<template> 1<template>
2 <div class="sugestion"> 2 <div class="w-auto bg-gray-700 p-2 text-center mt-5">
3 <span>{{sugestion[0]}}</span> 3 <span>{{sugestion[0]}}</span>
4 </div> 4 </div>
5</template> 5</template>
@@ -9,24 +9,5 @@ export default {
9 props: { 9 props: {
10 sugestion: Array 10 sugestion: Array
11 }, 11 },
12
13 created() {
14 this.$nextTick(function () {
15 })
16 }
17
18} 12}
19</script> 13</script>
20
21<style scoped>
22 .sugestion {
23 width: 100%;
24 margin-left: auto;
25 margin-right: auto;
26 background-color: #303030;
27
28 margin-top: 10px;
29 padding: 5px;
30 padding-right: 0px;
31 }
32</style>
diff --git a/src/main.js b/src/main.js
index fd31090..50babcd 100644
--- a/src/main.js
+++ b/src/main.js
@@ -6,6 +6,8 @@ import Axios from 'axios'
6import Notifications from 'vue-notification' 6import Notifications from 'vue-notification'
7import VueHotkey from 'v-hotkey' 7import VueHotkey from 'v-hotkey'
8 8
9import '@/assets/css/tailwind.css'
10
9Vue.config.productionTip = false 11Vue.config.productionTip = false
10 12
11Axios.defaults.headers.common['Authorization'] = store.state.token !== "" && `Token ${store.state.token}`; 13Axios.defaults.headers.common['Authorization'] = store.state.token !== "" && `Token ${store.state.token}`;
diff --git a/src/services/ChatService.js b/src/services/ChatService.js
index d077e9b..d03f250 100644
--- a/src/services/ChatService.js
+++ b/src/services/ChatService.js
@@ -37,5 +37,17 @@ export default {
37 } 37 }
38 }) 38 })
39 .catch(error => error_notify(error)) 39 .catch(error => error_notify(error))
40 },
41
42 async get_group_detail(group_pk) {
43 return await axios
44 .get(url+`groups/detail/${group_pk}/`)
45 .then(res => {
46 return {
47 status: res.status,
48 data: res.data
49 }
50 })
51 .catch(error => error_notify(error))
40 } 52 }
41} 53}
diff --git a/src/views/Home.vue b/src/views/Home.vue
index d85760b..205a260 100644
--- a/src/views/Home.vue
+++ b/src/views/Home.vue
@@ -1,11 +1,19 @@
1<template> 1<template>
2 <div class="home" v-hotkey="keymap"> 2 <div class="home" v-hotkey="keymap">
3 Hi {{get_username}}! 3 <div class="inset-center">
4 <div class="text-center bg-gray-900 p-5 rounded-lg">
5 <p class="text-3xl capitalize">Witaj, {{get_username}}!</p>
6 <p class="mt-5"><kbd>Ctl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> </p>
7 </div>
8 </div>
4 9
5 <div v-for="group in groups" :key="group.name" > 10 <div class="flex flex-row justify-around">
6 <GroupSender 11 <GroupSender
12 v-for="group in groups"
7 :group="group" 13 :group="group"
8 :socket="socket" 14 :socket="socket"
15 :key="group.name"
16 @close="closeGroupSender"
9 /> 17 />
10 </div> 18 </div>
11 19
@@ -27,6 +35,7 @@
27import Searcher from '@/components/searcher/Searcher.vue' 35import Searcher from '@/components/searcher/Searcher.vue'
28import GroupMaker from '@/components/group/GroupMaker.vue' 36import GroupMaker from '@/components/group/GroupMaker.vue'
29import GroupSender from '@/components/group/GroupSender.vue' 37import GroupSender from '@/components/group/GroupSender.vue'
38import ChatService from '@/services/ChatService.js'
30import io from 'socket.io-client' 39import io from 'socket.io-client'
31 40
32const popups = { 41const popups = {
@@ -62,12 +71,29 @@ export default {
62 let groups = this.groups.slice() 71 let groups = this.groups.slice()
63 let index = groups.findIndex(o => o.name===group.name) 72 let index = groups.findIndex(o => o.name===group.name)
64 73
74 if(groups.length >=3)
75 groups.shift()
76
65 if(index >= 0) 77 if(index >= 0)
66 groups.splice(index, 1) 78 groups.splice(index, 1)
67 else 79 else
68 groups.push(group) 80 groups.push(group)
69 81
70 this.groups = groups 82 this.groups = groups
83 },
84
85 async joinAllGroupsSocket() {
86 const {data, status} = await ChatService.get_all_user_groups()
87
88 if(status === 200)
89 data.forEach(group => {
90 this.socket.emit("join_group", {group_id: group.id})
91 })
92 },
93
94 closeGroupSender(group_id) {
95 const index = this.groups.findIndex(group => group.id === group_id)
96 this.groups.splice(index, 1)
71 } 97 }
72 }, 98 },
73 99
@@ -82,7 +108,7 @@ export default {
82 'ctrl+shift+p': this.toogleSearcherShow, 108 'ctrl+shift+p': this.toogleSearcherShow,
83 'esc': this.hideGroup 109 'esc': this.hideGroup
84 } 110 }
85 } 111 },
86 }, 112 },
87 113
88 components: { 114 components: {
@@ -99,6 +125,7 @@ export default {
99 this.socket = io() 125 this.socket = io()
100 this.socket.auth = { token: this.$store.getters.get_token }; 126 this.socket.auth = { token: this.$store.getters.get_token };
101 this.socket.connect(); 127 this.socket.connect();
128 this.joinAllGroupsSocket()
102 129
103 this.socket.on("connect", () => { 130 this.socket.on("connect", () => {
104 console.log("Socket connected!") 131 console.log("Socket connected!")
@@ -107,7 +134,24 @@ export default {
107 this.socket.on("disconnect", () => { 134 this.socket.on("disconnect", () => {
108 console.log("Scoket dsiconected") 135 console.log("Scoket dsiconected")
109 }) 136 })
137
138 this.socket.on("receive_group_message", async ({message}) => {
139 const index = this.groups.findIndex(group => {return group.id === message.receiver})
140
141 if(index<0) {
142 const {status, data} = await ChatService.get_group_detail(message.receiver)
143 if(status!==200)
144 return
145
146 this.$notify({
147 type: 'success',
148 title: `Groupa: ${data.name}`,
149 text: `${message.sender.username}, napisal "${message.message}"`,
150 duration: -1
151 })
152 }
153 })
110 } 154 }
111 155
112} 156}
113</script> 157</script>
diff --git a/src/views/Login.vue b/src/views/Login.vue
index cb5c8d8..2763840 100644
--- a/src/views/Login.vue
+++ b/src/views/Login.vue
@@ -1,13 +1,13 @@
1<template> 1<template>
2 <div id="login"> 2 <div id="login" class="inset-center bg-gray-900 p-4 rounded-lg shadow-lg">
3 <form @submit="log_in"> 3 <form @submit="log_in">
4 <input type="text" placeholder="Login" v-model="login"> 4 <input type="text" placeholder="Login" v-model="login" class="w-full bg-gray-800 p-2 mb-2">
5 <input type="password" placeholder="Password" v-model="password"> 5 <input type="password" placeholder="Password" v-model="password" class="w-full bg-gray-800 p-2 mb-4">
6 6
7 <input type="submit" value="Login!"> 7 <input type="submit" value="Login!" class="w-full bg-gray-800 p-2 mb-2">
8 </form> 8 </form>
9 9
10 <router-link to="/register"> Still don't have an account? </router-link> 10 <router-link to="/register"> Nadal nie masz konta? </router-link>
11 11
12 </div> 12 </div>
13</template> 13</template>
@@ -54,4 +54,4 @@ export default {
54 54
55<style> 55<style>
56 56
57</style> \ No newline at end of file 57</style>
diff --git a/src/views/Register.vue b/src/views/Register.vue
index eb382c5..fa8822b 100644
--- a/src/views/Register.vue
+++ b/src/views/Register.vue
@@ -1,14 +1,14 @@
1<template> 1<template>
2 <div id="register"> 2 <div id="register" class="inset-center bg-gray-900 p-4 rounded-lg shadow-lg">
3 <form @submit="register"> 3 <form @submit="register">
4 <input type="text" placeholder="Login" v-model="login"> 4 <input type="text" placeholder="Login" v-model="login" class="w-full bg-gray-800 p-2 mb-2">
5 <input type="password" placeholder="Password" v-model="password"> 5 <input type="password" placeholder="Password" v-model="password" class="w-full bg-gray-800 p-2 mb-2">
6 <input type="password" placeholder="Repeat password" v-model="repeat_password"> 6 <input type="password" placeholder="Repeat password" v-model="repeat_password" class="w-full bg-gray-800 p-2 mb-4">
7 7
8 <input type="submit" value="Register!"> 8 <input type="submit" value="Register!" class="w-full bg-gray-800 p-2 mb-2">
9 </form> 9 </form>
10 10
11 <router-link to="/login">Already have an account?</router-link> 11 <router-link to="/login">Juz masz konto?</router-link>
12 12
13 </div> 13 </div>
14</template> 14</template>
@@ -66,4 +66,4 @@ export default {
66 66
67<style> 67<style>
68 68
69</style> \ No newline at end of file 69</style>