fixed formatter

This commit is contained in:
supertiger1234 2019-07-24 13:55:09 +01:00
parent aa76b15a31
commit 7f801ccdbd
17 changed files with 294 additions and 51 deletions

View file

@ -0,0 +1,74 @@
<template>
<div class="edit-panel" v-if="selectedChannelID === data.channelID">
<div class="title">Edit Message:</div>
<div class="message">{{data.message}}</div>
<div class="close-button" @click="close">Cancel</div>
</div>
</template>
<script>
export default {
props: ['data'],
methods: {
close() {
this.$store.dispatch("setEditMessage", null);
},
keyDownEvent(event) {
if(event.keyCode !== 27) return; // 27 = escape
this.close();
}
},
created() {
document.addEventListener('keydown', this.keyDownEvent)
},
destroyed() {
this.$store.dispatch("setEditMessage", null);
document.removeEventListener('keydown', this.keyDownEvent)
},
computed: {
selectedChannelID() {
return this.$store.getters.selectedChannelID;
},
}
}
</script>
<style scoped>
.edit-panel {
padding: 10px;
color: white;
background: rgba(23, 112, 255, 0.877);
display: flex;
flex-direction: column;
z-index: 99999;
border-radius: 10px;
margin: 10px;
margin-bottom: 0;
}
.top{
display: flex;
}
.title {
flex: 1;
}
.close-button {
color: white;
background: rgba(0, 0, 0, 0.199);
padding: 2px;
border-radius: 3px;
align-self: flex-end;
transition: 0.3s;
user-select: none;
cursor: pointer;
}
.close-button:hover {
background: rgba(0, 0, 0, 0.431);
}
.message {
color: rgb(214, 214, 214);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>

View file

@ -26,6 +26,7 @@
:messageID="msg.messageID"
:channelID="msg.channelID"
:type="msg.type"
:timeEdited="msg.timeEdited"
/>
<uploadsQueue v-if="uploadQueue !== undefined" :queue="uploadQueue"/>
</div>
@ -40,6 +41,7 @@
<emoji-panel v-if="showEmojiPanel" @close="showEmojiPanel = false"/>
</div>
<edit-panel v-if="editMessage" :data='editMessage' />
<div class="message-area">
<input type="file" ref="sendFileBrowse" @change="attachmentChange" class="hidden">
<div class="attachment-button" @click="attachmentButton">
@ -62,9 +64,9 @@
</button>
<button
:class="{'send-button': true, 'error-send-button': messageLength > 5000}"
@click="sendMessage"
@click="editMessage ? updateMessage() : sendMessage()"
>
<i class="material-icons">send</i>
<i class="material-icons">{{editMessage ? 'edit' : 'send'}}</i>
</button>
</div>
<div class="info">
@ -98,6 +100,7 @@ import emojiParser from "@/utils/emojiParser.js";
import statuses from "@/utils/statuses";
const emojiPanel = () => import("@/components/app/EmojiPanels/emojiPanel.vue");
const EditPanel = () => import("@/components/app/EditPanel.vue");
export default {
components: {
@ -107,7 +110,8 @@ export default {
uploadsQueue,
emojiSuggestions,
emojiPanel,
heading
heading,
EditPanel
},
data() {
return {
@ -187,9 +191,49 @@ export default {
console.log(error);
}
},
async updateMessage() {
const editMessage = this.editMessage;
this.$refs["input-box"].focus();
this.message = this.message.trim();
if (this.message === this.editMessage.message){
this.$store.dispatch("setEditMessage", null);
this.message = "";
return;
}
if (this.message == "") return;
if (this.message.length > 5000) return;
this.$store.dispatch("setEmojiArray", null);
clearInterval(this.postTimerID);
this.postTimerID = null;
this.messageLength = 0;
const msg = emojiParser.replaceShortcode(this.message);
this.$store.dispatch('updateMessage', {
channelID: editMessage.channelID,
messageID: editMessage.messageID,
message: {message: msg, status: 0}
})
this.$store.dispatch("setEditMessage", null);
this.message = "";
const {ok, error, result} = await messagesService.update(editMessage.messageID, editMessage.channelID, {
message: msg
})
if (ok) {
this.$store.dispatch('updateMessage', {
channelID: editMessage.channelID,
messageID: editMessage.messageID,
message: {status: 1}
})
} else {
this.$store.dispatch('updateMessage', {
channelID: editMessage.channelID,
messageID: editMessage.messageID,
message: {message: msg, status: 2}
})
}
},
async postTimer() {
this.postTimerID = setTimeout(async () => {
if (this.message.trim() == "") {
clearInterval(this.postTimerID);
@ -202,7 +246,6 @@ export default {
this.postTimer()
}
}, 2000)
},
resize(event) {
@ -321,9 +364,26 @@ export default {
this.enterEmojiSuggestion();
return;
}
this.sendMessage();
if (this.editMessage) {
return this.updateMessage()
} else {
this.sendMessage();
}
}
}
if (event.keyCode === 38){ //38 = up arrow
if (this.message !== "") return;
if (this.editMessage) return;
const messagesFiltered = this.selectedChannelMessages.filter(m => m.creator.uniqueID === this.user.uniqueID);
if (!messagesFiltered.length) return;
event.preventDefault();
const lastMessage = messagesFiltered[messagesFiltered.length - 1];
this.$store.dispatch("setEditMessage", {
messageID: lastMessage.messageID,
channelID: lastMessage.channelID
});
}
},
invertScroll(event) {
if (event.deltaY) {
@ -451,6 +511,15 @@ export default {
window.removeEventListener('focus', this.onFocus)
delete this.$options.sockets.typingStatus;
},
watch: {
editMessage(editMessage) {
if (!editMessage) {
this.message = ""
} else {
this.message = editMessage.message
}
}
},
computed: {
uploadQueue() {
const allUploads = this.$store.getters.getAllUploads;
@ -507,6 +576,14 @@ export default {
status = presences[channel.recipients[0].uniqueID] || 0;
}
return statuses[status].color;
},
editMessage() {
let editMessage = this.$store.getters.popouts.editMessage;
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;
}
}
};

View file

@ -1,5 +1,5 @@
<template>
<div class="container">
<div class="container" @mouseover="hover = true" @mouseleave="hover = false">
<div
v-if="!type || type === 0"
:class="{message: true, ownMessage: user.uniqueID === $props.uniqueID, ownMessageLeft: user.uniqueID === $props.uniqueID && (apperance && apperance.own_message_right === true)} "
@ -7,7 +7,7 @@
<div class="avatar">
<profile-picture
:admin="$props.admin"
:url="userAvatar"
:url="`${userAvatar}${hover ? '' : '?type=png'}`"
size="50px"
:hover="true"
@click.native="openUserInformation"
@ -38,9 +38,7 @@
<i class="material-icons">insert_drive_file</i>
</div>
<div class="information">
<div class="info">
{{ getFile.fileName }}
</div>
<div class="info"> {{ getFile.fileName }}</div>
<a
:href="getFile.url"
target="_blank"
@ -58,17 +56,18 @@
@click="imageClicked"
>
</div>
<message-embed-template v-if="embed" :embed="embed"/>
<message-embed-template v-if="embed && Object.keys(embed).length" :embed="embed"/>
</div>
<div class="other-information">
<div class="drop-down-button" ref="drop-down-button" @click="dropDownVisable = !dropDownVisable"><i class="material-icons">more_vert</i></div>
<div class="drop-down-menu" v-click-outside="closeDropDown" v-if="dropDownVisable">
<!-- <div class="drop-item">Edit</div> -->
<div class="drop-item" @click="editMessage" v-if="user.uniqueID === uniqueID">Edit</div>
<div class="drop-item warn" @click="deleteMessage">Delete</div>
</div>
<div class="sending-status" v-if="status === 0"><i class="material-icons">hourglass_full</i></div>
<div class="sending-status" v-if="status === 1"><i class="material-icons">done</i></div>
<div class="sending-status" v-if="status === 2"><i class="material-icons">close</i> Failed</div>
<div class="sending-status" v-if="timeEdited && (status === undefined || status === 1)" :title="`Edited ${getEditedDate}`"><i class="material-icons">edit</i></div>
<div class="sending-status" v-else-if="status === 0"><i class="material-icons">hourglass_full</i></div>
<div class="sending-status" v-else-if="status === 1"><i class="material-icons">done</i></div>
<div class="sending-status" v-else-if="status === 2"><i class="material-icons">close</i> Failed</div>
</div>
</div>
@ -113,7 +112,8 @@ export default {
},
data() {
return {
dropDownVisable: false
dropDownVisable: false,
hover: false
}
},
props: [
@ -128,7 +128,8 @@ export default {
"type",
"embed",
"messageID",
"channelID"
"channelID",
"timeEdited"
],
methods: {
openUserInformation() {
@ -146,6 +147,10 @@ export default {
this.dropDownVisable = false;
const {ok, error, result} = await messagesService.delete(this.messageID, this.channelID);
},
editMessage() {
this.dropDownVisable = false;
this.$store.dispatch("setEditMessage", {channelID: this.channelID, messageID: this.messageID});
}
},
computed: {
@ -158,7 +163,7 @@ export default {
const filetypes = /jpeg|jpg|gif|png/;
const extname = filetypes.test(path.extname(file.fileName).toLowerCase());
if (!extname) return undefined;
return config.domain + "/files/" + file.fileID;
return config.domain + "/media/" + file.fileID;
},
getFile() {
if (!this.$props.files || this.$props.files.length === 0)
@ -177,6 +182,9 @@ export default {
getDate() {
return friendlyDate(this.$props.date);
},
getEditedDate() {
return friendlyDate(this.timeEdited);
},
userAvatar() {
return config.domain + "/avatars/" + this.$props.avatar;
},

View file

@ -2,10 +2,12 @@
<div
class="my-mini-information"
:style="{backgroundColor: getStatusColor}"
@mouseover="hover = true" @mouseleave="hover = false"
>
<div class="profile-pic-outer">
<profile-picture
:url="avatar"
:url="`${avatar}${hover ? '' : '?type=png'}`"
:admin="user.admin"
size="50px"
:hover="true"
@ -73,7 +75,8 @@ export default {
return {
status: {
isPoppedOut: false
}
},
hover: false
};
},
computed: {

View file

@ -1,5 +1,5 @@
<template>
<div :class="{channel: true, notifyAnimation: hasNotifications}">
<div class="channel" :class="{notifyAnimation: hasNotifications, selected: selectedChannelID === channelData.channelID}">
<i class="material-icons">storage</i>
<div class="channel-name">
{{ channelData.name }}
@ -15,7 +15,10 @@ export default {
const notifications = this.$store.getters.notifications;
const find = notifications.find(n => n.channelID === this.channelData.channelID)
return find
}
},
selectedChannelID() {
return this.$store.getters.selectedChannelID;
},
}
};
</script>
@ -62,6 +65,9 @@ export default {
.channel:hover {
background: rgba(139, 139, 139, 0.288);
}
.selected {
background: rgba(139, 139, 139, 0.288);
}
.channel-name {
overflow: hidden;
text-overflow: ellipsis;

View file

@ -1,7 +1,7 @@
<template>
<div class="embed" :class="{article: embed.type === 'article' || embed.type === 'video.other'}">
<div class="right">
<div class="image"><img v-if="embed.image" :src="`//images.weserv.nl/?url=${embed.image}`" alt=""></div>
<div class="image" v-if="embed.image" @click="embedImgClicked"><img :src="`//images.weserv.nl/?url=${embed.image}`" alt=""></div>
</div>
<div class="left">
<div class="title" v-if="embed.url"><a target=”_blank” :href="embed.url">{{embed.title}}</a></div>
@ -13,7 +13,12 @@
<script>
export default {
props: ["embed"]
props: ["embed"],
methods: {
embedImgClicked() {
this.$store.dispatch("setImagePreviewURL", "//images.weserv.nl/?url=" + this.embed.image);
},
}
}
</script>

View file

@ -3,10 +3,12 @@
:class="{friend: true, notifyAnimation: (notifications && notifications > 0) }"
:style="`background: ${status.bgColor};`"
@click="openChat"
@mouseover="hover = true"
@mouseleave="hover = false"
>
<div
class="profile-picture"
:style="`border-color: ${status.statusColor}; background-image: url(${userAvatar})`"
:style="`border-color: ${status.statusColor}; background-image: url(${userAvatar}${hover ? '' : '?type=png'})`"
@click="openUserInformation"
>
<div
@ -45,6 +47,11 @@ import {bus} from '@/main'
export default {
props: ['username', 'tag', 'channelID', 'uniqueID', 'recipient'],
data() {
return {
hover: false
}
},
computed: {
notifications () {
const channelID = this.$props.channelID;

View file

@ -46,7 +46,6 @@ export default {
return -1
if (notificationB)
return 1
if (a.lastMessaged === undefined)
return 1
if (b.lastMessaged === undefined)

View file

@ -9,12 +9,8 @@
<i class="material-icons">insert_drive_file</i>
</div>
<div class="information">
<div class="info">
{{ upload.name }}
</div>
<div class="info size">
{{ upload.size }}
</div>
<div class="info"> {{ upload.name }} </div>
<div class="info size"> {{ upload.size }} </div>
<div class="progress">
<div class="progress-bar">
<div

View file

@ -8,6 +8,9 @@ export default {
delete ( messageID, channelID ) {
return wrapper(instance().delete(`messages/${messageID}/channels/${channelID}`));
},
update ( messageID, channelID, data ) {
return wrapper(instance().patch(`messages/${messageID}/channels/${channelID}`, data));
},
post (channelID, data, onProgress) {
const url = `messages/channels/${channelID}`;

View file

@ -29,6 +29,13 @@ const actions = {
removeChannel(context, {channelID}) {
context.commit('removeChannel', channelID)
},
removeChannels(context, channelsArr){
for (let index = 0; index < channelsArr.length; index++) {
const element = channelsArr[index];
context.commit('removeChannel', element)
}
},
updateChannel(context, data) {
const update = Object.assign({}, context.state.channels[data.channelID], data);
context.commit('channel', update)
@ -58,7 +65,7 @@ const mutations = {
Vue.set(state.channels[channelID], "lastMessaged", Date.now());
},
addAllChannels(state, channels) {
const test = Object.assign(state.channels, channels);
const test = Object.assign({}, state.channels, channels);
Vue.set(state, "channels", test);
},
channel(state, channel) {

View file

@ -27,7 +27,8 @@ const state = {
serverSettings:{
serverID: null,
index: null
}
},
editMessage: null
}
const getters = {
@ -57,10 +58,16 @@ const actions = {
},
setGenericMessage(context, message) {
context.commit('setGenericMessage', message);
},
setEditMessage(context, data){
context.commit('setEditMessage', data)
}
}
const mutations = {
setEditMessage(state, data){
Vue.set(state, 'editMessage', data);
},
setGenericMessage(state, message){
Vue.set(state, 'genericMessage', message)
},

View file

@ -64,17 +64,29 @@ const actions = {
}
},
removeServerChannel (context, {server_id, channelID}) {
const filter = context.state.channelsIDs[server_id].filter(c => {
return c !== channelID
})
const filter = context.state.channelsIDs[server_id].filter(c => c !== channelID )
context.commit('SET_CHANNEL_IDs', {serverID: server_id, channelIDs: filter})
}
},
removeAllServerChannels(context, server_id) {
const serverChannels = context.state.channelsIDs[server_id]
context.dispatch('removeChannels', serverChannels, {root: true})
context.commit('DELETE_CHANNELS', server_id)
},
removeNotifications(context, server_id) {
const serverChannels = context.state.channelsIDs[server_id]
const filteredNotifications = context.rootState.notificationsModule.notifications.filter(n => !serverChannels.includes(n.channelID));
context.dispatch('addAllNotifications', filteredNotifications, {root:true});
},
};
const mutations = {
SET_CHANNEL_IDs(state, {serverID, channelIDs}) {
Vue.set(state.channelsIDs, serverID, channelIDs)
},
DELETE_CHANNELS(state, server_id) {
Vue.delete(state.channelsIDs, server_id);
},
ADD_CHANNELS_IDS(state, {serverID, channelsIDs}) {
const previousChannels = state.channelsIDs[serverID] || []
Vue.set(state.channelsIDs, serverID, [...new Set([...previousChannels, ...channelsIDs])]);

View file

@ -30,7 +30,6 @@ const actions = {
},
addRecentEmoji(context, shortcode) {
const recentEmojis = JSON.parse(localStorage.getItem('recentEmojis')) || [];
let filter = recentEmojis.filter(function (item) {
return item !== shortcode
})
@ -49,6 +48,15 @@ const actions = {
const emojiID = customEmoji.emoji.emojiID;
const customEmojiList = context.state.customEmojis;
// remove from recents
const recentEmojis = JSON.parse(localStorage.getItem('recentEmojis')) || [];
let filter = recentEmojis.filter(function (item) {
return item !== customEmoji.emoji.name
})
localStorage.setItem("recentEmojis", JSON.stringify(filter));
context.commit('setRecentEmojis', filter)
for (let index = 0; index < customEmojiList.length; index++) {
const element = customEmojiList[index];
if (element.emojiID === emojiID){

View file

@ -222,6 +222,8 @@ const actions = {
['socket_server:leave'](context, {server_id}) {
context.dispatch('servers/removePresences', server_id);
context.dispatch('servers/removeServer', server_id)
context.dispatch('servers/removeNotifications', server_id)
context.dispatch('servers/removeAllServerChannels', server_id)
},
['socket_server:memberAdd'](context, {serverMember, presence}) { // member_add
let sm = Object.assign({}, serverMember);
@ -232,12 +234,9 @@ const actions = {
context.dispatch('members/updatePresence', {uniqueID: member.uniqueID, status: presence})
context.dispatch('members/addMember', member)
context.dispatch('servers/addServerMember', sm)
console.log("someone joined")
},
['socket_server:memberRemove'](context, {uniqueID, server_id}) { // member_remove
context.dispatch('servers/removeServerMember', {uniqueID, server_id})
console.log("Someone left")
},
['socket_server:members'](context, {serverMembers, memberPresences}) { // members
let serverMembersArr = [];
@ -266,7 +265,7 @@ const actions = {
},
['socket_server:removeChannel'](context, {server_id, channelID}) {
context.dispatch('servers/removeServerChannel', {server_id, channelID});
context.dispatch('dismissNotification', channelID);
},
['socket_server:updateServer'](context, data) {
context.dispatch('servers/updateServer', {server_id: data.server_id, server: data});

View file

@ -14,10 +14,44 @@
const config = [
{
version: 5.4,
title: "Bug Fixes!",
shortTitle: "",
date: "24/07/2019",
headColor: "rgba(15, 65, 70, 0.77)",
fix: [
'Fixed a bug where when pressing the up arrow key to edit while there is text in the text box, it would discard the message and edit.',
'Fixed a bug where when editing a message and going to a different tab, the message is still editing.',
'Fixed a bug where if an emoji is in the recents, and then removed in the settings, the emoji would stay in the recents.',
'Fixed bugs with html escape :scream:',
],
},
{
version: 5.3,
title: "Edit messages, More performance!",
shortTitle: "",
date: "23/07/2019",
headColor: "rgba(15, 89, 70, 0.77)",
new: [
"You can now edit your own messages!",
"Avatar and message pictures should now be disk cached.",
"Gif avatars will now only animate when being hovered. This will improve performance.",
"You can now click on embed images to get a full screen preview.",
"Server channels now show a gray background when selected.",
],
fix: [
'Fixed a bug where when deleting a server channel, the notification would still stay.',
'Fixed a bug where when sending a message, the friend wouldnt go at the top in the recents list.',
],
next: ["HTML channel for servers", "Change username, email and password."],
},
{
version: 5.2,
title: "Delete messages, URL Embeds",

View file

@ -13,12 +13,12 @@ emojiFormatter.addTransformer({
symbol: ':',
padding: false,
recursive: false,
validate: text => /.+?&(.+?)/.test(text),
validate: text => /.+?&amp;(.+?)/.test(text),
transformer: owo
})
function owo (text) {
const split = escapeHTML(text).split('&');
const split = escapeHTML(text).split('&amp;');
if (!split || split.length <= 1) return `:${text}:`;
const url = split[split.length - 1].slice(4);
return `<img class="emoji" draggable="false" alt=":${split[0]}:" src="${config.domain + "/files/" + url}">`
@ -29,7 +29,7 @@ futoji.addTransformer({
symbol: ':',
padding: false,
recursive: false,
validate: text => /.+?&(.+?)/.test(text),
validate: text => /.+?&amp;(.+?)/.test(text),
transformer: text => {
const formattedInner = emojiFormatter.format(text);
return owo(formattedInner);
@ -85,7 +85,6 @@ futoji.addTransformer({
symbol: '```',
recursive: false,
transformer: text => {
//TODO: use https://github.com/atom/highlights instead.
let formatted = formatCode(text)
let highlighted
@ -109,10 +108,9 @@ futoji.addTransformer({
})
export default (message) => {
message = futoji.format(message + ' ').trim();
message = futoji.format(escapeHtml(message + ' ')).trim();
message = emojiParser.replaceEmojis(message);
return message;
}