mirror of
https://github.com/danbulant/Nertivia-Client
synced 2026-07-05 11:00:50 +00:00
desktop notification
This commit is contained in:
parent
8904a9254b
commit
012a0b08f8
11 changed files with 219 additions and 14 deletions
|
|
@ -22,7 +22,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const remote = window.require("electron").remote;
|
const {remote} = window.require("electron");
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -54,12 +54,11 @@ export default {
|
||||||
}
|
}
|
||||||
.frame-buttons div {
|
.frame-buttons div {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 5px;
|
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
height: 15px;
|
height: 100%;
|
||||||
width: 15px;
|
width: 50px;
|
||||||
border-radius: 5px;
|
border-radius: 2px;
|
||||||
margin: 3px;
|
margin: 1px;
|
||||||
color: white;
|
color: white;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,11 @@
|
||||||
<div
|
<div
|
||||||
class="member"
|
class="member"
|
||||||
@click="openUserInformation()"
|
@click="openUserInformation()"
|
||||||
|
@mouseover="hover = true" @mouseleave="hover = false"
|
||||||
>
|
>
|
||||||
<Profile-picture
|
<Profile-picture
|
||||||
class="avatar"
|
class="avatar"
|
||||||
:url="userAvatar"
|
:url="`${userAvatar}${hover ? '' : '?type=png'}`"
|
||||||
size="35px"
|
size="35px"
|
||||||
:unique-i-d="user.uniqueID"
|
:unique-i-d="user.uniqueID"
|
||||||
:status="presense"
|
:status="presense"
|
||||||
|
|
@ -31,6 +32,11 @@ import config from '@/config';
|
||||||
export default {
|
export default {
|
||||||
components: { ProfilePicture },
|
components: { ProfilePicture },
|
||||||
props: ['user', 'avatar', 'type'],
|
props: ['user', 'avatar', 'type'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
hover: false
|
||||||
|
}
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
userAvatar() {
|
userAvatar() {
|
||||||
return config.domain + "/avatars/" + this.avatar
|
return config.domain + "/avatars/" + this.avatar
|
||||||
|
|
|
||||||
|
|
@ -580,9 +580,6 @@ export default {
|
||||||
editMessage() {
|
editMessage() {
|
||||||
let editMessage = this.$store.getters.popouts.editMessage;
|
let editMessage = this.$store.getters.popouts.editMessage;
|
||||||
if (!editMessage) return null;
|
if (!editMessage) return null;
|
||||||
editMessage = Object.assign({}, editMessage);
|
|
||||||
const messages = this.$store.getters.messages[editMessage.channelID];
|
|
||||||
editMessage.message = messages.find(m => m.messageID === editMessage.messageID).message
|
|
||||||
return editMessage;
|
return editMessage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ export default {
|
||||||
},
|
},
|
||||||
editMessage() {
|
editMessage() {
|
||||||
this.dropDownVisable = false;
|
this.dropDownVisable = false;
|
||||||
this.$store.dispatch("setEditMessage", {channelID: this.channelID, messageID: this.messageID});
|
this.$store.dispatch("setEditMessage", {channelID: this.channelID, messageID: this.messageID, message: this.message});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,9 @@ export default {
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
transition: 0.2s;
|
transition: 0.2s;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.item:hover {
|
.item:hover {
|
||||||
background: rgb(46, 46, 46);
|
background: rgb(46, 46, 46);
|
||||||
|
|
|
||||||
|
|
@ -32,12 +32,14 @@ import { bus } from "@/main";
|
||||||
const MyProfile = () => import("./SettingsPanels/MyProfile.vue");
|
const MyProfile = () => import("./SettingsPanels/MyProfile.vue");
|
||||||
const ManageEmojis = () => import("./SettingsPanels/ManageEmojis.vue");
|
const ManageEmojis = () => import("./SettingsPanels/ManageEmojis.vue");
|
||||||
const MessageDesign = () => import("./SettingsPanels/MessageDesign.vue");
|
const MessageDesign = () => import("./SettingsPanels/MessageDesign.vue");
|
||||||
|
const Notifications = () => import("./SettingsPanels/Notifications.vue");
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
MyProfile,
|
MyProfile,
|
||||||
ManageEmojis,
|
ManageEmojis,
|
||||||
MessageDesign
|
MessageDesign,
|
||||||
|
Notifications
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -60,6 +62,12 @@ export default {
|
||||||
tabName: "Manage Emojis",
|
tabName: "Manage Emojis",
|
||||||
icon: "face",
|
icon: "face",
|
||||||
component: "manage-emojis"
|
component: "manage-emojis"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Notifications",
|
||||||
|
tabName: "Notifications",
|
||||||
|
icon: "message",
|
||||||
|
component: "notifications"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,127 @@
|
||||||
|
<template>
|
||||||
|
<div class="my-profile-panel">
|
||||||
|
|
||||||
|
<div class="switches">
|
||||||
|
<div class="checkbox"
|
||||||
|
@click="toggleNotification()">
|
||||||
|
<div class="checkbox-box" :class="{selected: !notificationSettings.disableDesktopNotification}" />
|
||||||
|
<div class="checkbox-name">
|
||||||
|
Desktop Notifications
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import config from "@/config.js";
|
||||||
|
|
||||||
|
import SettingsService from '@/services/settingsService.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isElectron: window && window.process && window.process.type
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleSetting(key) {
|
||||||
|
const setting = this.notificationSettings[key];
|
||||||
|
if ( !setting || setting === false )
|
||||||
|
this.$store.dispatch('settingsModule/updateNotification', {[key]: true})
|
||||||
|
else
|
||||||
|
this.$store.dispatch('settingsModule/updateNotification', {[key]: false})
|
||||||
|
},
|
||||||
|
toggleNotification(){
|
||||||
|
const _this = this;
|
||||||
|
const setting = this.notificationSettings['disableDesktopNotification'];
|
||||||
|
if (setting && setting === true && !this.isElectron) {
|
||||||
|
if (Notification.permission === "denied") {
|
||||||
|
alert("Notifications blocked. Please enable them in your browser.");
|
||||||
|
}
|
||||||
|
Notification.requestPermission().then(function(result) {
|
||||||
|
if (result === 'denied' || result === 'default') return;
|
||||||
|
_this.$store.dispatch('settingsModule/updateNotification', {disableDesktopNotification: false})
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.toggleSetting('disableDesktopNotification');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (!this.isElectron && this.notificationSettings.disableDesktopNotification === undefined) {
|
||||||
|
this.$store.dispatch('settingsModule/updateNotification', {disableDesktopNotification: true})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
notificationSettings() {
|
||||||
|
return this.$store.getters['settingsModule/settings'].notification;
|
||||||
|
},
|
||||||
|
user() {
|
||||||
|
return this.$store.getters.user
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
.switches {
|
||||||
|
display: flex;
|
||||||
|
margin: 20px;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.checkbox-box {
|
||||||
|
background: rgba(88, 88, 88, 0.74);
|
||||||
|
height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
margin: auto;
|
||||||
|
margin-right: 10px;
|
||||||
|
transition: 0.3s;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-box.selected {
|
||||||
|
background: rgba(66, 122, 244, 0.74);
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-box.selected:hover {
|
||||||
|
background: rgba(66, 122, 244, 0.94);
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-box:hover {
|
||||||
|
background: rgba(88, 88, 88, 0.94);
|
||||||
|
}
|
||||||
|
.checkbox-name {
|
||||||
|
max-width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-example{
|
||||||
|
padding: 10px;
|
||||||
|
background: rgba(88, 88, 88, 0.44);
|
||||||
|
border-radius: 10px;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
.title{
|
||||||
|
font-size: 20px;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.my-profile-panel {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin-top: 10px;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -9,6 +9,7 @@ const state = {
|
||||||
GDriveLinked: false,
|
GDriveLinked: false,
|
||||||
customEmojis: [],
|
customEmojis: [],
|
||||||
recentEmojis: JSON.parse(localStorage.getItem('recentEmojis')) || [],
|
recentEmojis: JSON.parse(localStorage.getItem('recentEmojis')) || [],
|
||||||
|
notification: JSON.parse(localStorage.getItem('notificationSettings')) || {},
|
||||||
apperance: {}
|
apperance: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,6 +29,12 @@ const actions = {
|
||||||
setGDriveLinked(context, status) {
|
setGDriveLinked(context, status) {
|
||||||
context.commit('GoogleDriveLinked', status)
|
context.commit('GoogleDriveLinked', status)
|
||||||
},
|
},
|
||||||
|
updateNotification(context, data) {
|
||||||
|
let notificationSettings = JSON.parse(localStorage.getItem('notificationSettings')) || {};
|
||||||
|
Object.assign(notificationSettings, data);
|
||||||
|
localStorage.setItem("notificationSettings", JSON.stringify(notificationSettings));
|
||||||
|
context.commit('updateNotification', notificationSettings)
|
||||||
|
},
|
||||||
addRecentEmoji(context, shortcode) {
|
addRecentEmoji(context, shortcode) {
|
||||||
const recentEmojis = JSON.parse(localStorage.getItem('recentEmojis')) || [];
|
const recentEmojis = JSON.parse(localStorage.getItem('recentEmojis')) || [];
|
||||||
let filter = recentEmojis.filter(function (item) {
|
let filter = recentEmojis.filter(function (item) {
|
||||||
|
|
@ -85,6 +92,9 @@ const actions = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const mutations = {
|
const mutations = {
|
||||||
|
updateNotification(state, data) {
|
||||||
|
Vue.set(state, 'notification', data)
|
||||||
|
},
|
||||||
setApperance(state, data) {
|
setApperance(state, data) {
|
||||||
Vue.set(state.apperance, Object.keys(data)[0], data[Object.keys(data)[0]])
|
Vue.set(state.apperance, Object.keys(data)[0], data[Object.keys(data)[0]])
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
|
import config from '@/config';
|
||||||
import {bus} from '../../main'
|
import {bus} from '../../main'
|
||||||
import {router} from './../../router'
|
import {router} from './../../router'
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import DesktopNotification from '@/utils/ElectronJS/DesktopNotification'
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
|
|
||||||
|
|
@ -151,6 +152,8 @@ const actions = {
|
||||||
}
|
}
|
||||||
if (context.rootState.channelModule.selectedChannelID == data.message.channelID && document.hasFocus()) {
|
if (context.rootState.channelModule.selectedChannelID == data.message.channelID && document.hasFocus()) {
|
||||||
this._vm.$socket.emit('notification:dismiss', {channelID: data.message.channelID});
|
this._vm.$socket.emit('notification:dismiss', {channelID: data.message.channelID});
|
||||||
|
} else {
|
||||||
|
desktopNotification();
|
||||||
}
|
}
|
||||||
// send notification if other users message the recipient
|
// send notification if other users message the recipient
|
||||||
if (data.message.creator.uniqueID === context.getters.user.uniqueID) return;
|
if (data.message.creator.uniqueID === context.getters.user.uniqueID) return;
|
||||||
|
|
@ -160,6 +163,28 @@ const actions = {
|
||||||
sender: data.message.creator
|
sender: data.message.creator
|
||||||
}
|
}
|
||||||
context.dispatch('messageCreatedNotification', notification);
|
context.dispatch('messageCreatedNotification', notification);
|
||||||
|
function desktopNotification() {
|
||||||
|
// send desktop notification
|
||||||
|
const disableDesktopNotification = context.rootGetters['settingsModule/settings'].notification.disableDesktopNotification;
|
||||||
|
if (disableDesktopNotification === true) return
|
||||||
|
const channel = context.getters.channels[data.message.channelID];
|
||||||
|
if (channel.server_id) {
|
||||||
|
const server = context.getters['servers/servers'][channel.server_id]
|
||||||
|
DesktopNotification.serverMessage({
|
||||||
|
serverName: server.name,
|
||||||
|
channelName: channel.name,
|
||||||
|
username: data.message.creator.username,
|
||||||
|
avatarURL: config.domain + '/avatars/' + server.avatar,
|
||||||
|
message: data.message.message
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
DesktopNotification.directMessage({
|
||||||
|
username: data.message.creator.username,
|
||||||
|
avatarURL: config.domain + '/avatars/' + data.message.creator.avatar,
|
||||||
|
message: data.message.message
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
socket_userStatusChange(context, data) {
|
socket_userStatusChange(context, data) {
|
||||||
if (context.rootState.user.user.uniqueID === data.uniqueID) return;
|
if (context.rootState.user.user.uniqueID === data.uniqueID) return;
|
||||||
|
|
|
||||||
30
src/utils/ElectronJS/DesktopNotification.js
Normal file
30
src/utils/ElectronJS/DesktopNotification.js
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
module.exports = {
|
||||||
|
directMessage({username, avatarURL, message}) {
|
||||||
|
let myNotification = new Notification(`${username}`, {
|
||||||
|
body: message,
|
||||||
|
icon: avatarURL,
|
||||||
|
silent: true
|
||||||
|
})
|
||||||
|
myNotification.onclick = () => {
|
||||||
|
console.log("CLICK")
|
||||||
|
}
|
||||||
|
myNotification.onclose = () => {
|
||||||
|
myNotification = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
serverMessage({serverName, channelName, username, avatarURL, message}) {
|
||||||
|
let myNotification = new Notification(`${username} in ${serverName}#${channelName}`, {
|
||||||
|
body: message,
|
||||||
|
icon: avatarURL,
|
||||||
|
silent: true
|
||||||
|
})
|
||||||
|
myNotification.onclick = () => {
|
||||||
|
console.log("CLICK")
|
||||||
|
}
|
||||||
|
myNotification.onclose = () => {
|
||||||
|
myNotification = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -256,7 +256,7 @@ export default {
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
max-width: 495px;
|
max-width: 560px;
|
||||||
flex-basis: auto; /* default value */
|
flex-basis: auto; /* default value */
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
-webkit-app-region: no-drag;
|
-webkit-app-region: no-drag;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue