diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..6b61141 --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,6 @@ +{ + "ExpandedNodes": [ + "" + ], + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000..5a1a079 Binary files /dev/null and b/.vs/slnx.sqlite differ diff --git a/src/components/ProfilePictureTemplate.vue b/src/components/ProfilePictureTemplate.vue index 2ba4812..9e01d6e 100644 --- a/src/components/ProfilePictureTemplate.vue +++ b/src/components/ProfilePictureTemplate.vue @@ -39,6 +39,7 @@ export default { name: "cute", emotePath: this.flower }; + return "" } } }; @@ -75,38 +76,16 @@ export default { margin-left: 0; flex-shrink: 0; margin: auto; - background: linear-gradient( - 45deg, - #ffd828 1%, - #ffd828 40%, - #ffd828 50%, - #ffe87f 60%, - #ffd828 99%, - #ffd828 100%, - #ffd828 100% - ); - background-size: 400% 400%; + background: #ffd828 100%; + - animation: Anime 4s ease infinite; } .cute { margin-right: 5px; margin-left: 0; flex-shrink: 0; margin: auto; - background: linear-gradient( - 45deg, - #ffb7ed 1%, - #ffb7ed 40%, - #ffb7ed 50%, - #ffe2f8 60%, - #ffb7ed 99%, - #ffb7ed 100%, - #ffb7ed 100% - ); - background-size: 400% 400%; - - animation: Anime 4s ease infinite; + background: #ffb7ed; } .cute .emote { z-index: 999; @@ -114,17 +93,6 @@ export default { left: -3px; } -@keyframes Anime { - 0% { - background-position: 0% 50%; - } - 50% { - background-position: 100% 50%; - } - 100% { - background-position: 0% 50%; - } -} .emote { position: absolute; height: 20px; diff --git a/src/components/app/MembersList.vue b/src/components/app/MembersList.vue new file mode 100644 index 0000000..3de407e --- /dev/null +++ b/src/components/app/MembersList.vue @@ -0,0 +1,32 @@ + + + + + diff --git a/src/components/app/MessagePanel.vue b/src/components/app/MessagePanel.vue index 02c94f1..b6e259e 100644 --- a/src/components/app/MessagePanel.vue +++ b/src/components/app/MessagePanel.vue @@ -1,20 +1,11 @@ @@ -24,6 +25,7 @@ const GDriveLinkMenu = () => import('./Popouts/GDriveLinkMenu.vue'); const imageLargePreview = () => import('./Popouts/imageLargePreview.vue'); const DragDropFileUploadDialog = () => import('./Popouts/DragDropFileUploadDialog.vue'); + const ServerInvitePopout = () => import('./Popouts/ServerInvitePopout.vue'); @@ -36,7 +38,8 @@ export default { DragDropFileUploadDialog, imageLargePreview, TakeSurveyPopout, - AddServer + AddServer, + ServerInvite: ServerInvitePopout }, data() { return { diff --git a/src/components/app/Popouts/Popouts/AddServer.vue b/src/components/app/Popouts/Popouts/AddServer.vue index 9b01ddf..7db8f43 100644 --- a/src/components/app/Popouts/Popouts/AddServer.vue +++ b/src/components/app/Popouts/Popouts/AddServer.vue @@ -1,20 +1,76 @@ diff --git a/src/components/app/Popouts/Popouts/ServerInvitePopout.vue b/src/components/app/Popouts/Popouts/ServerInvitePopout.vue new file mode 100644 index 0000000..ee94f06 --- /dev/null +++ b/src/components/app/Popouts/Popouts/ServerInvitePopout.vue @@ -0,0 +1,141 @@ + + + + + + + diff --git a/src/components/app/Popouts/Popouts/SettingsPanels/MyProfile.vue b/src/components/app/Popouts/Popouts/SettingsPanels/MyProfile.vue index e2dc91a..5ac4c6e 100644 --- a/src/components/app/Popouts/Popouts/SettingsPanels/MyProfile.vue +++ b/src/components/app/Popouts/Popouts/SettingsPanels/MyProfile.vue @@ -145,6 +145,7 @@ export default { display: flex; width: 100%; margin-top: 20px; + flex-shrink: 0; } .avatar { display: flex; @@ -233,11 +234,11 @@ export default { } @media (max-width: 815px) { .general-information { - display: block; flex-direction: column; } .avatar{ - margin: auto; + align-self: center; + margin: 0; margin-bottom: 10px; } .information { diff --git a/src/components/app/ServerList.vue b/src/components/app/ServerList.vue index 35e6219..7a56f43 100644 --- a/src/components/app/ServerList.vue +++ b/src/components/app/ServerList.vue @@ -1,10 +1,9 @@ @@ -20,54 +19,30 @@ export default { }, data() { return { - openedServer: null, - serverData: { - "67574563576897": { - name: "DevHelp", - channels: [ - { name: "General", channelID: 3563567574767467 }, - { name: "NodeJS", channelID: 758546746747378 }, - { name: "Java", channelID: 57355675747875 }, - { name: "C#", channelID: 45656764765676 } - ] - }, - "24325587980787": { - name: "Musica", - channels: [ - { name: "General", channelID: 3563567574767467 }, - { name: "NodeJS", channelID: 758546746747378 }, - { name: "Java", channelID: 57355675747875 }, - { name: "C#", channelID: 45656764765676 } - ] - }, - "3468636435": { - name: "IDK", - channels: [ - { name: "General", channelID: 3563567574767467 }, - { name: "NodeJS", channelID: 758546746747378 }, - { name: "Java", channelID: 57355675747875 }, - { name: "C#", channelID: 45656764765676 } - ] - }, - "63575764574645": { - name: "OWO", - channels: [ - { name: "General", channelID: 3563567574767467 }, - { name: "NodeJS", channelID: 758546746747378 }, - { name: "Java", channelID: 57355675747875 }, - { name: "C#", channelID: 45656764765676 } - ] - } - } + openedServer: null }; }, methods: { - toggleChannel(index, event) { - if (!event.target.closest('.small-view')) return; - if (this.openedServer === index) + openAddServer() { + this.$store.dispatch("setPopoutVisibility", { + name: "addServer", + visibility: true + }); + }, + toggleChannel(serverID, event) { + if (!event.target.closest('.small-view') || event.target.closest('.options-context-button') || event.target.closest('.options-context-menu')) return; + if (this.openedServer === serverID) this.openedServer = null; else - this.openedServer = index; + this.openedServer = serverID; + } + }, + computed: { + servers() { + const data = this.$store.getters['servers/servers']; + return Object.keys(data).map(key => { + return data[key]; + }).slice().reverse() } } }; diff --git a/src/components/app/ServerTemplate/ChannelsList.vue b/src/components/app/ServerTemplate/ChannelsList.vue new file mode 100644 index 0000000..01a8846 --- /dev/null +++ b/src/components/app/ServerTemplate/ChannelsList.vue @@ -0,0 +1,69 @@ + + + + + + + diff --git a/src/components/app/ServerTemplate/ServerTemplate.vue b/src/components/app/ServerTemplate/ServerTemplate.vue index 115d368..20b9f27 100644 --- a/src/components/app/ServerTemplate/ServerTemplate.vue +++ b/src/components/app/ServerTemplate/ServerTemplate.vue @@ -1,44 +1,89 @@ @@ -54,14 +99,13 @@ export default { transition: 0.3s; } - .server:hover { background: rgba(0, 0, 0, 0.288); } .material-icons { transition: 0.3s; } -.add-server:hover .material-icons{ +.add-server:hover .material-icons { color: rgba(20, 255, 39, 0.726); } @@ -70,23 +114,18 @@ export default { display: flex; transition: 0.3s; position: relative; - overflow: hidden; align-items: center; padding: 5px; } -.channel-list { - background: rgba(0, 0, 0, 0.288); - display: flex; - flex-direction: column; -} - .server-name { overflow: hidden; text-overflow: ellipsis; margin-left: 5px; + flex: 1; + white-space: nowrap; } -.add-icon{ +.add-icon { height: 56px; display: flex; align-items: center; @@ -97,4 +136,38 @@ export default { .add-icon .material-icons { font-size: 40px; } +.options-context-button { + display: flex; + align-items: center; + margin-right: 5px; + color: rgba(255, 255, 255, 0.623); + border-radius: 50%; + transition: 0.3s; +} +.options-context-button .material-icons:hover { + color: white; +} + +.options-context-menu { + position: absolute; + background: rgba(0, 0, 0, 0.692); + border-radius: 10px; + z-index: 9999; + padding: 5px; + right: 40px; + top: 20px; +} +.menu-button { + padding: 5px; + margin: 2px; + border-radius: 5px; + transition: 0.3s; +} +.menu-button:hover { + background: rgb(47, 47, 47); +} + +.warn { + color: red; +} diff --git a/src/components/app/Tabs/DirectMessage.vue b/src/components/app/Tabs/DirectMessage.vue index c8152f0..f424fac 100644 --- a/src/components/app/Tabs/DirectMessage.vue +++ b/src/components/app/Tabs/DirectMessage.vue @@ -65,6 +65,8 @@ export default { .left-panel { position: absolute; background-color: rgba(39, 39, 39, 0.97); + bottom: 0; + height: calc(100% - 40px); } } diff --git a/src/components/app/Tabs/Servers.vue b/src/components/app/Tabs/Servers.vue index 1be0bb1..6414bcd 100644 --- a/src/components/app/Tabs/Servers.vue +++ b/src/components/app/Tabs/Servers.vue @@ -8,6 +8,7 @@ /> + @@ -16,11 +17,13 @@ import { bus } from "@/main"; import ServerList from "@/components/app/ServerList.vue"; import MessagePanel from "@/components/app/MessagePanel.vue"; +import MembersList from "@/components/app/MembersList.vue"; export default { components: { ServerList, - MessagePanel + MessagePanel, + MembersList }, data() { return { diff --git a/src/components/app/TypingStatus.vue b/src/components/app/TypingStatus.vue index a092218..5db49f2 100644 --- a/src/components/app/TypingStatus.vue +++ b/src/components/app/TypingStatus.vue @@ -1,22 +1,82 @@ diff --git a/src/components/app/relationships/RecentFriends.vue b/src/components/app/relationships/RecentFriends.vue index c015893..0794022 100644 --- a/src/components/app/relationships/RecentFriends.vue +++ b/src/components/app/relationships/RecentFriends.vue @@ -24,7 +24,7 @@ export default { const keys = Object.keys(json); let result = []; keys.forEach(function(key){ - if (json[key].recipients.length > 0) + if (json[key].recipients.length > 0 && !json[key].servers) result.push(json[key]); }); diff --git a/src/components/app/uploadsQueue.vue b/src/components/app/uploadsQueue.vue index 8b8a35b..8b17309 100644 --- a/src/components/app/uploadsQueue.vue +++ b/src/components/app/uploadsQueue.vue @@ -35,6 +35,7 @@ export default { margin-left: 70px; display: flex; padding: 10px; + border-radius: 10px; } .icon .material-icons { font-size: 40px; diff --git a/src/services/ServerService.js b/src/services/ServerService.js new file mode 100644 index 0000000..04a1a78 --- /dev/null +++ b/src/services/ServerService.js @@ -0,0 +1,26 @@ +import {instance, wrapper} from './Api'; + +export default { + post ( data ) { + return wrapper(instance().post('/server', data)); + }, + getChannels(serverID) { + return wrapper(instance().get(`/server/channels/${serverID}`)); + }, + postInvite (serverID) { + return wrapper (instance().post(`/server/${serverID}/invite`)) + }, + getInvites (serverID) { + return wrapper (instance().get(`/server/${serverID}/invites`)) + }, + getInviteDetail (inviteCode) { + return wrapper (instance().get(`/server/invite/${inviteCode}`)) + }, + joinServer (inviteCode) { + return wrapper (instance().post(`/server/invite/${inviteCode}`)) + }, + leaveServer (serverID) { + return wrapper (instance().delete(`/server/${serverID}`)) + }, + +} \ No newline at end of file diff --git a/src/store/index.js b/src/store/index.js index 4b23379..6987d90 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -9,6 +9,7 @@ import settingsModule from './modules/settingsModule'; import uploadFilesModule from './modules/uploadFilesModule'; import popoutsModule from './modules/popoutsModule/popoutsModule.js'; import emojiSuggestionModule from './modules/emojiSuggestionModule'; +import serversModule from './modules/serversModule'; import { router } from './../router' @@ -25,7 +26,8 @@ export const store = new Vuex.Store({ settingsModule, uploadFilesModule, popoutsModule, - emojiSuggestionModule + emojiSuggestionModule, + servers: serversModule }, state: { diff --git a/src/store/modules/messageModule.js b/src/store/modules/messageModule.js index 795c298..c00548c 100644 --- a/src/store/modules/messageModule.js +++ b/src/store/modules/messageModule.js @@ -15,6 +15,14 @@ const getters = { }; const actions = { + async openChannel(context, channel) { + context.commit("setChannelName", channel.name); + const messages = context.state.messages[channel.channelID]; + if (messages) return context.commit("selectedChannelID", channel.channelID); + context.commit("selectedChannelID", "loading") + getMessages(context, channel.channelID); + + }, async openChat(context, { uniqueID, channelID, channelName }) { if (channelName) context.commit("setChannelName", channelName); @@ -33,65 +41,21 @@ const actions = { } if (messages) return; - if (channel && !messages) return getMessages(channelID); + if (channel && !messages) return getMessages(context, channelID); const { ok, error, result } = await channelService.post(uniqueID); if (ok) { context.commit("channel", result.data.channel); - getMessages(result.data.channel.channelID); + getMessages(context, result.data.channel.channelID); } else { // TODO handle this console.log(error); } - async function getMessages(channelID) { - const { ok, error, result } = await messagesService.get(channelID); - if (ok) { - context.commit("selectedChannelID", channelID); - context.commit("messages", { - channelID: result.data.channelID, - messages: result.data.messages.reverse() - }); - } else { - // TODO handle this - console.log(error.response); - } - } + }, - // OLD STUFF - async openddChat(context, { channelID, channelName }) { - context.commit("selectedChannelID", channelID); - if (channelName) context.commit("setChannelName", channelName); - - const messages = context.state.messages[channelID]; - const channel = context.rootState.channelModule.channels[channelID]; - if (messages) return; - if (channel && !messages) return getMessages(); - - const { ok, error, result } = await channelService.post(channelID); - if (ok) { - context.commit("channel", result.data.channel); - getMessages(); - } else { - // TODO handle this - console.log(error); - } - - async function getMessages() { - const { ok, error, result } = await messagesService.get(channelID); - if (ok) { - context.commit("messages", { - channelID: result.data.channelID, - messages: result.data.messages.reverse() - }); - } else { - // TODO handle this - console.log(error.response); - } - } - }, messages(context, data) { context.commit("messages", data); }, @@ -110,6 +74,21 @@ const actions = { } }; +async function getMessages(context, channelID) { + const { ok, error, result } = await messagesService.get(channelID); + if (ok) { + context.commit("selectedChannelID", channelID); + context.commit("messages", { + channelID: result.data.channelID, + messages: result.data.messages.reverse() + }); + } else { + // TODO handle this + console.log(error.response); + } +} + + const mutations = { messages(state, data) { Vue.set(state.messages, data.channelID, data.messages); diff --git a/src/store/modules/popoutsModule/popoutsModule.js b/src/store/modules/popoutsModule/popoutsModule.js index d06d407..b481acf 100644 --- a/src/store/modules/popoutsModule/popoutsModule.js +++ b/src/store/modules/popoutsModule/popoutsModule.js @@ -11,12 +11,16 @@ const state = { uploadDialog: false, ImagePreviewURL: null, + serverIDContextMenu: null, + showServerInviteMenu: false, + userInformationPopoutID: null, surveyPopout: false, dragDropFileUploadDialog: false, settings: false, GDLinkMenu: false, + addServer: false, } const getters = { @@ -37,6 +41,9 @@ const actions = { }, setImagePreviewURL(context, url) { context.commit('setImagePreviewURL', url); + }, + setServerIDContextMenu(context, serverID) { + context.commit('setServerIDContextMenu', serverID); } } @@ -52,6 +59,9 @@ const mutations = { }, setImagePreviewURL(state, url) { Vue.set(state, 'ImagePreviewURL', url); + }, + setServerIDContextMenu(state, serverID) { + Vue.set(state, 'serverIDContextMenu', serverID); } } diff --git a/src/store/modules/serversModule.js b/src/store/modules/serversModule.js new file mode 100644 index 0000000..79f167a --- /dev/null +++ b/src/store/modules/serversModule.js @@ -0,0 +1,55 @@ +import { bus } from "../../main"; +import { router } from "./../../router"; +import Vue from "vue"; + +const state = { + servers: {}, + channelsIDs: {} +}; + +const getters = { + servers(state) { + return state.servers; + }, + channelsIDs(state) { + return state.channelsIDs; + } +}; + +const actions = { + setChannelsIDs(context, {serverID, channelsIDs}) { + context.commit('SET_CHANNELS_IDS', {serverID, channelsIDs}); + }, + setServers(context, servers) { + context.commit('SET_SERVERS', servers); + }, + setServer(context, server) { + context.commit('SET_SERVER', server); + }, + removeServer(context, serverID) { + context.commit('REMOVE_SERVER', serverID); + }, +}; + +const mutations = { + SET_CHANNELS_IDS(state, {serverID, channelsIDs}) { + Vue.set(state.channelsIDs, serverID, channelsIDs); + }, + SET_SERVERS(state, servers) { + state.servers = servers; + }, + SET_SERVER(state, server) { + Vue.set(state.servers, server.server_id, server); + }, + REMOVE_SERVER(state, serverID) { + Vue.delete(state.servers, serverID); + }, +}; + +export default { + namespaced: true, + state, + actions, + mutations, + getters +}; diff --git a/src/store/modules/socketIOModule.js b/src/store/modules/socketIOModule.js index 57f9380..3692e2c 100644 --- a/src/store/modules/socketIOModule.js +++ b/src/store/modules/socketIOModule.js @@ -34,9 +34,20 @@ const actions = { } } } - data.user.friends = friendObject; } + let servers = user.servers || []; + //convert array to object for servers + servers = servers.reduce((obj, item) => { + obj[item.server_id] = item + return obj + }, {}) + + context.dispatch('servers/setServers', servers) + + data.user.servers = undefined; + data.user.friends = friendObject; + context.commit('user', data.user) // convert dms array to object @@ -123,7 +134,13 @@ const actions = { }, ['socket_survey:completed'](context) { context.dispatch('surveyCompleted'); - } + }, + ['socket_server:joined'](context, server) { + context.dispatch('servers/setServer', server) + }, + ['socket_server:leave'](context, {server_id}) { + context.dispatch('servers/removeServer', server_id) + }, } export default { diff --git a/src/views/App.vue b/src/views/App.vue index 3426808..78681a9 100644 --- a/src/views/App.vue +++ b/src/views/App.vue @@ -32,8 +32,8 @@
- -
+ +
cached
@@ -56,8 +56,9 @@ import Spinner from "./../components/Spinner.vue"; const ElectronFrameButtons = () => import("./../components/ElectronJS/FrameButtons.vue"); - -const News = () => import(/* webpackChunkName: "News" */"./../components/app/Tabs/News.vue"); + +const News = () => + import(/* webpackChunkName: "News" */ "./../components/app/Tabs/News.vue"); //const DirectMessage = () => import('./../components/app/Tabs/DirectMessage.vue'); const DirectMessage = () => ({ component: import("./../components/app/Tabs/DirectMessage.vue"), @@ -233,7 +234,6 @@ export default {