mirror of
https://github.com/danbulant/Nertivia-Client
synced 2026-06-18 05:51:11 +00:00
bic changes
This commit is contained in:
parent
3ce91179b2
commit
f80b7e4276
15 changed files with 173 additions and 18 deletions
17
package-lock.json
generated
17
package-lock.json
generated
|
|
@ -3291,7 +3291,7 @@
|
|||
},
|
||||
"get-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
|
||||
"resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
|
||||
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
|
||||
"dev": true
|
||||
}
|
||||
|
|
@ -3372,7 +3372,7 @@
|
|||
"dependencies": {
|
||||
"globby": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
|
||||
"resolved": "http://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
|
||||
"integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
|
@ -3385,7 +3385,7 @@
|
|||
"dependencies": {
|
||||
"pify": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
||||
"dev": true
|
||||
}
|
||||
|
|
@ -5251,6 +5251,11 @@
|
|||
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
|
||||
"dev": true
|
||||
},
|
||||
"futoji": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/futoji/-/futoji-0.2.0.tgz",
|
||||
"integrity": "sha512-V3q7YwYGisBmr9J0/24yBafW4ClSjbLok/WztF/GtpfVO6K36DCyWMD++68TlyiDN5xxcA+LNue6Zo4iON2BRQ=="
|
||||
},
|
||||
"get-caller-file": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
|
||||
|
|
@ -5713,7 +5718,7 @@
|
|||
},
|
||||
"http-proxy-middleware": {
|
||||
"version": "0.18.0",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz",
|
||||
"resolved": "http://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz",
|
||||
"integrity": "sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
|
@ -7461,7 +7466,7 @@
|
|||
},
|
||||
"p-is-promise": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
|
||||
"resolved": "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
|
||||
"integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=",
|
||||
"dev": true
|
||||
},
|
||||
|
|
@ -10934,7 +10939,7 @@
|
|||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
"dependencies": {
|
||||
"@vue/eslint-plugin": "^4.2.0",
|
||||
"axios": "^0.18.0",
|
||||
"futoji": "^0.2.0",
|
||||
"jquery": "^3.3.1",
|
||||
"socket.io": "^2.2.0",
|
||||
"socket.io-client": "^2.2.0",
|
||||
|
|
|
|||
BIN
src/assets/sounds/FriendRequest.mp3
Normal file
BIN
src/assets/sounds/FriendRequest.mp3
Normal file
Binary file not shown.
BIN
src/assets/sounds/Notification.mp3
Normal file
BIN
src/assets/sounds/Notification.mp3
Normal file
Binary file not shown.
|
|
@ -1,4 +1,23 @@
|
|||
const config = [
|
||||
{
|
||||
title: 'Notifications are finally here!',
|
||||
shortTitle: 'Notifications',
|
||||
date: '18/02/2019',
|
||||
new: [
|
||||
'When you get a notification, you will now be notified by the red flashing Indicator.',
|
||||
'When you get a new friend request, you will notified by a sound.',
|
||||
'Added a new Recents tab to easily see who messaged you last.',
|
||||
'Adjusted the padding and size in some places such as the friends list.',
|
||||
'Messages can now be formated (e.g. **Hello**)'
|
||||
],
|
||||
fix: [
|
||||
'Performance improvements were made in some places.',
|
||||
'Yesterday is now spelt with a capital "Y" in the timestamp.'
|
||||
],
|
||||
next: [
|
||||
'Uploading images or any files.',
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Typing Indicator',
|
||||
shortTitle: 'Typing Indicator',
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<div class="username">{{this.$props.username}}</div>
|
||||
<div class="date">{{getDate}}</div>
|
||||
</div>
|
||||
<div class="content-message">{{this.$props.message}}</div>
|
||||
<div class="content-message" v-html="formatMessage"></div>
|
||||
</div>
|
||||
<div class="sending-status">{{statusMessage}}</div>
|
||||
</div>
|
||||
|
|
@ -17,11 +17,15 @@
|
|||
|
||||
|
||||
<script>
|
||||
import messageFormatter from '@/messageFormatter.js'
|
||||
import config from '@/config.js'
|
||||
import friendlyDate from '@/date'
|
||||
export default {
|
||||
props: ['message', 'status', 'username', 'avatar', 'date', 'uniqueID'],
|
||||
computed: {
|
||||
formatMessage() {
|
||||
return messageFormatter(this.$props.message)
|
||||
},
|
||||
getDate() {
|
||||
return friendlyDate(this.$props.date);
|
||||
},
|
||||
|
|
@ -67,6 +71,7 @@ export default {
|
|||
background: rgba(184, 184, 184, 0.219);
|
||||
|
||||
}
|
||||
|
||||
@keyframes showMessage {
|
||||
from {
|
||||
transform: translate(0px, 9px);
|
||||
|
|
@ -162,3 +167,11 @@ export default {
|
|||
|
||||
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.codeblock{
|
||||
background-color: rgba(0, 0, 0, 0.397);
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -170,6 +170,15 @@ export default {
|
|||
}, 2500);
|
||||
}
|
||||
bus.$on('newMessage', this.hideTypingStatus)
|
||||
//dismiss notification on focus
|
||||
window.onfocus = () => {
|
||||
bus.$emit('title:change', "Nertivia");
|
||||
if (!this.$store.getters.selectedChannelID) return;
|
||||
const find = this.$store.getters.notifications.find(notification => {return notification.channelID === this.$store.getters.selectedChannelID});
|
||||
if (find && find.count >= 1) {
|
||||
this.$socket.emit('notification:dismiss', {channelID: this.$store.getters.selectedChannelID});
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
bus.$off('newMessage', this.hideTypingStatus);
|
||||
|
|
@ -190,7 +199,7 @@ export default {
|
|||
},
|
||||
channelName() {
|
||||
return this.$store.getters.channelName;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div :class="{friend: true, notifyAnimation: (notificationss && notificationss > 0) }" :style="`background: ${status.bgColor};`" @click="openChat">
|
||||
<div :class="{friend: true, notifyAnimation: (notifications && notifications > 0) }" :style="`background: ${status.bgColor};`" @click="openChat">
|
||||
<div class="profile-picture" :style="`border-color: ${status.statusColor}; background-image: url(${userAvatar})`">
|
||||
<div class="status" :style="`background-image: url(${status.statusURL})`" ></div>
|
||||
</div>
|
||||
|
|
@ -7,9 +7,9 @@
|
|||
<div class="username">{{$props.username}}</div>
|
||||
<div class="status-name" :style="`color: ${status.statusColor}`">{{status.statusName}}</div>
|
||||
</div>
|
||||
<div class="notification" v-if="notificationss && notificationss >0">
|
||||
<div class="notification" v-if="notifications && notifications >0">
|
||||
<div class="notification-inner">
|
||||
{{notificationss}}
|
||||
{{notifications}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -36,6 +36,10 @@ export default {
|
|||
},
|
||||
async openChat() {
|
||||
bus.$emit('closeLeftMenu');
|
||||
// dismiss notification if exists
|
||||
if (this.notifications && this.notifications >= 1 && document.hasFocus()) {
|
||||
this.$socket.emit('notification:dismiss', {channelID: this.channelID});
|
||||
}
|
||||
this.$store.dispatch('selectedChannelID', this.$props.channelID);
|
||||
this.$store.dispatch('setChannelName', this.$props.username);
|
||||
if (this.$store.getters.channels[this.$props.channelID] && !this.$store.getters.messages[this.$props.channelID]) return this.getMessages();
|
||||
|
|
@ -50,12 +54,12 @@ export default {
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
notificationss () {
|
||||
notifications () {
|
||||
const channelID = this.$props.channelID;
|
||||
const notifications = this.$store.getters.notifications.find(function(e) {
|
||||
return e.channelID == channelID
|
||||
})
|
||||
if (!notifications) return;
|
||||
if (!notifications || (this.$props.channelID === this.$store.getters.selectedChannelID && document.hasFocus())) return;
|
||||
return notifications.count;
|
||||
},
|
||||
user() {
|
||||
|
|
|
|||
56
src/messageFormatter.js
Normal file
56
src/messageFormatter.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
import futoji from 'futoji'
|
||||
|
||||
export default (message) => {
|
||||
message = escapeHtml(message)
|
||||
|
||||
futoji.addTransformer({
|
||||
name: 'bold-and-italic',
|
||||
symbol: '***',
|
||||
transformer: text => `<strong><em>${text}</em></strong>`
|
||||
})
|
||||
|
||||
futoji.addTransformer({
|
||||
name: 'bold',
|
||||
symbol: '**',
|
||||
transformer: text => `<strong>${text}</strong>`
|
||||
})
|
||||
|
||||
futoji.addTransformer({
|
||||
name: 'italic',
|
||||
symbol: '*',
|
||||
transformer: text => `<em>${text}</em>`
|
||||
})
|
||||
|
||||
futoji.addTransformer({
|
||||
name: 'underline',
|
||||
symbol: '__',
|
||||
transformer: text => `<u>${text}</u>`
|
||||
})
|
||||
futoji.addTransformer({
|
||||
name: 'srike',
|
||||
symbol: '~~',
|
||||
transformer: text => `<s>${text.trim()}</s>`
|
||||
})
|
||||
|
||||
futoji.addTransformer({
|
||||
name: 'code-block',
|
||||
symbol: '``\`',
|
||||
transformer: text => `<div class="codeblock"><code>${text.trim()}</code></div>`
|
||||
})
|
||||
|
||||
futoji.addTransformer({
|
||||
name: 'code',
|
||||
symbol: '`',
|
||||
transformer: text => `<code>${text}</code>`
|
||||
})
|
||||
return futoji.format(message);
|
||||
}
|
||||
|
||||
function escapeHtml(unsafe) {
|
||||
return unsafe
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
13
src/notificationSound.js
Normal file
13
src/notificationSound.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import notificationSound from '@/assets/sounds/Notification.mp3';
|
||||
import newFriendSound from '@/assets/sounds/FriendRequest.mp3';
|
||||
|
||||
export default {
|
||||
notification: () => {
|
||||
const audio = new Audio(notificationSound);
|
||||
audio.play();
|
||||
},
|
||||
newFriend: () => {
|
||||
const audio = new Audio(newFriendSound);
|
||||
audio.play();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import {bus} from '../../main'
|
||||
import {router} from './../../router'
|
||||
import Vue from 'vue';
|
||||
import NotificationSounds from '@/notificationSound';
|
||||
|
||||
const state = {
|
||||
notifications: []
|
||||
|
|
@ -18,8 +19,13 @@ const actions = {
|
|||
},
|
||||
messageCreatedNotification(context, notification) {
|
||||
const {guildID, channelID, lastMessageID, sender} = notification;
|
||||
|
||||
|
||||
if (!document.hasFocus())
|
||||
bus.$emit('title:change', "Someone sent a message.");
|
||||
|
||||
// dont display a notification if the channel is selected.
|
||||
if (context.rootState.channelModule.selectedChannelID !== channelID || !document.hasFocus()) {
|
||||
NotificationSounds.notification();
|
||||
}
|
||||
let find = context.state.notifications.find(item => {
|
||||
return item.channelID === channelID
|
||||
})
|
||||
|
|
@ -28,10 +34,22 @@ const actions = {
|
|||
}
|
||||
context.commit('messageCreatedNotification', {exists: false, notification: {channelID, lastMessageID, sender, count: 1}});
|
||||
|
||||
},
|
||||
dismissNotification(context, channelID) {
|
||||
const notifications = context.state.notifications
|
||||
for (let index = 0; index < notifications.length; index++) {
|
||||
if (notifications[index].channelID === channelID){
|
||||
context.commit('dismissNotification', index)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
dismissNotification(state, index) {
|
||||
Vue.delete(state.notifications, index)
|
||||
},
|
||||
addAllNotifications(state, notifications){
|
||||
Vue.set(state, 'notifications', notifications);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import {bus} from '../../main'
|
||||
import {router} from './../../router'
|
||||
import Vue from 'vue';
|
||||
|
||||
const state = {
|
||||
|
||||
|
|
@ -64,6 +65,9 @@ const actions = {
|
|||
tempID: data.tempID
|
||||
})
|
||||
}
|
||||
if (context.rootState.channelModule.selectedChannelID == data.message.channelID && document.hasFocus()) {
|
||||
this._vm.$socket.emit('notification:dismiss', {channelID: data.message.channelID});
|
||||
}
|
||||
// send notification if other users message the recipient
|
||||
if (data.message.creator.uniqueID === context.getters.user.uniqueID) return;
|
||||
const notification = {
|
||||
|
|
@ -92,6 +96,10 @@ const actions = {
|
|||
const {channel} = data;
|
||||
// rename to 'channel' to setchannel
|
||||
context.dispatch('channel', channel);
|
||||
},
|
||||
['socket_notification:dismiss'](context, data){
|
||||
const {channelID} = data;
|
||||
context.dispatch('dismissNotification', channelID);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import axios from 'axios'
|
|||
import Vue from 'vue'
|
||||
import {bus} from '../../main'
|
||||
import VueRouter from 'vue-router';
|
||||
import NotificationSounds from '@/notificationSound';
|
||||
|
||||
const state = {
|
||||
token: localStorage.getItem('hauthid') || null,
|
||||
|
|
@ -77,6 +78,10 @@ const mutations = {
|
|||
friends[friend.recipient.uniqueID] = friend;
|
||||
|
||||
state.user.friends = Object.assign({}, friends)
|
||||
|
||||
if (friend.status == 1) {
|
||||
NotificationSounds.newFriend();
|
||||
}
|
||||
},
|
||||
removeFriend(state, uniqueID) {
|
||||
const friends = state.user.friends;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div id="app">
|
||||
<vue-headful title="Nertivia"/>
|
||||
<vue-headful :title="title" description="Nertivia Chat Client"/>
|
||||
<div class="background-image"></div>
|
||||
<transition name="fade-between-two" appear >
|
||||
<ConnectingScreen v-if="!loggedIn" />
|
||||
|
|
@ -37,7 +37,8 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
showLeftPanel: false,
|
||||
showSettings: false
|
||||
showSettings: false,
|
||||
title: "Nertivia"
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -62,6 +63,9 @@ export default {
|
|||
bus.$on('closeSettings', () => {
|
||||
this.showSettings = false;
|
||||
})
|
||||
bus.$on('title:change', (title) => {
|
||||
this.title = title;
|
||||
})
|
||||
},
|
||||
computed: {
|
||||
loggedIn() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div id="app">
|
||||
<vue-headful title="Nertivia" />
|
||||
<vue-headful title="Nertivia" description="Nertivia Chat Client"/>
|
||||
<div class="background-image"></div>
|
||||
<div class="layout">
|
||||
<div class="small-view-nav-bar">
|
||||
|
|
|
|||
Loading…
Reference in a new issue