mirror of
https://github.com/chylex/Discord-History-Tracker.git
synced 2025-06-13 22:02:18 +03:00
Track and view replies (#133)
* Track and view replies * Tweaks to reply saving (PR #133) Co-authored-by: chylex <contact@chylex.com>
This commit is contained in:
parent
8c825aeb86
commit
183094ad63
@ -28,6 +28,7 @@ e
|
|||||||
a
|
a
|
||||||
t
|
t
|
||||||
d
|
d
|
||||||
|
r
|
||||||
te
|
te
|
||||||
tag
|
tag
|
||||||
avatar
|
avatar
|
||||||
@ -50,10 +51,13 @@ embeds
|
|||||||
attachments
|
attachments
|
||||||
title
|
title
|
||||||
description
|
description
|
||||||
|
reply
|
||||||
toDate
|
toDate
|
||||||
memoizedProps
|
memoizedProps
|
||||||
props
|
props
|
||||||
children
|
children
|
||||||
channel
|
channel
|
||||||
messages
|
messages
|
||||||
msSaveBlob
|
msSaveBlob
|
||||||
|
messageReference
|
||||||
|
message_id
|
||||||
|
@ -56,7 +56,8 @@
|
|||||||
* {
|
* {
|
||||||
* url: <attachment url>
|
* url: <attachment url>
|
||||||
* }, ...
|
* }, ...
|
||||||
* ]
|
* ],
|
||||||
|
* r: <reply message id> // only present if referencing another message (reply)
|
||||||
* }, ...
|
* }, ...
|
||||||
* }, ...
|
* }, ...
|
||||||
* }
|
* }
|
||||||
@ -234,6 +235,10 @@ class SAVEFILE{
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (discordMessage.messageReference !== null){
|
||||||
|
obj.r = discordMessage.messageReference.message_id;
|
||||||
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,36 @@ var DISCORD = (function(){
|
|||||||
var templateEmbedRichUnsupported;
|
var templateEmbedRichUnsupported;
|
||||||
var templateEmbedDownload;
|
var templateEmbedDownload;
|
||||||
|
|
||||||
|
var processMessageContents = function(contents){
|
||||||
|
var processed = DOM.escapeHTML(contents.replace(REGEX.formatUrlNoEmbed, "$1"));
|
||||||
|
|
||||||
|
if (STATE.settings.enableFormatting){
|
||||||
|
var escapeHtmlMatch = (full, match) => "&#"+match.charCodeAt(0)+";";
|
||||||
|
|
||||||
|
processed = processed
|
||||||
|
.replace(REGEX.specialEscapedBacktick, "`")
|
||||||
|
.replace(REGEX.formatCodeBlock, (full, ignore, match) => "<code class='block'>"+match.replace(REGEX.specialUnescaped, escapeHtmlMatch)+"</code>")
|
||||||
|
.replace(REGEX.formatCodeInline, (full, ignore, match) => "<code class='inline'>"+match.replace(REGEX.specialUnescaped, escapeHtmlMatch)+"</code>")
|
||||||
|
.replace(REGEX.specialEscapedSingle, escapeHtmlMatch)
|
||||||
|
.replace(REGEX.specialEscapedDouble, full => full.replace(/\\/g, "").replace(/(.)/g, escapeHtmlMatch))
|
||||||
|
.replace(REGEX.formatBold, "<b>$1</b>")
|
||||||
|
.replace(REGEX.formatItalic, (full, pre, match) => pre === '\\' ? full : (pre || "")+"<i>"+match+"</i>")
|
||||||
|
.replace(REGEX.formatUnderline, "<u>$1</u>")
|
||||||
|
.replace(REGEX.formatStrike, "<s>$1</s>");
|
||||||
|
}
|
||||||
|
|
||||||
|
var animatedEmojiExtension = STATE.settings.enableAnimatedEmoji ? "gif" : "png";
|
||||||
|
|
||||||
|
processed = processed
|
||||||
|
.replace(REGEX.formatUrl, "<a href='$1' target='_blank' rel='noreferrer'>$1</a>")
|
||||||
|
.replace(REGEX.mentionChannel, (full, match) => "<span class='link mention-chat'>#"+STATE.getChannelName(match)+"</span>")
|
||||||
|
.replace(REGEX.mentionUser, (full, match) => "<span class='link mention-user' title='#"+(STATE.getUserTag(match) || "????")+"'>@"+STATE.getUserName(match)+"</span>")
|
||||||
|
.replace(REGEX.customEmojiStatic, "<img src='https://cdn.discordapp.com/emojis/$2.png' alt=':$1:' title=':$1:' class='emoji'>")
|
||||||
|
.replace(REGEX.customEmojiAnimated, "<img src='https://cdn.discordapp.com/emojis/$2."+animatedEmojiExtension+"' alt=':$1:' title=':$1:' class='emoji'>");
|
||||||
|
|
||||||
|
return "<p>"+processed+"</p>";
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
setup: function(){
|
setup: function(){
|
||||||
templateChannelServer = new TEMPLATE([
|
templateChannelServer = new TEMPLATE([
|
||||||
@ -59,18 +89,22 @@ var DISCORD = (function(){
|
|||||||
|
|
||||||
templateMessageNoAvatar = new TEMPLATE([
|
templateMessageNoAvatar = new TEMPLATE([
|
||||||
"<div>",
|
"<div>",
|
||||||
|
"<div>{reply}</div>",
|
||||||
"<h2><strong class='username' title='#{user.tag}'>{user.name}</strong><span class='info time'>{timestamp}</span>{edit}{jump}</h2>",
|
"<h2><strong class='username' title='#{user.tag}'>{user.name}</strong><span class='info time'>{timestamp}</span>{edit}{jump}</h2>",
|
||||||
"<div class='message'>{contents}{embeds}{attachments}</div>",
|
"<div class='message'>{contents}{embeds}{attachments}</div>",
|
||||||
"</div>"
|
"</div>"
|
||||||
].join(""));
|
].join(""));
|
||||||
|
|
||||||
templateMessageWithAvatar = new TEMPLATE([
|
templateMessageWithAvatar = new TEMPLATE([
|
||||||
|
"<div>",
|
||||||
|
"<div class='reply-message'>{reply}</div>",
|
||||||
"<div class='avatar-wrapper'>",
|
"<div class='avatar-wrapper'>",
|
||||||
"<div class='avatar'>{avatar}</div>",
|
"<div class='avatar'>{avatar}</div>",
|
||||||
"<div>",
|
"<div>",
|
||||||
"<h2><strong class='username' title='#{user.tag}'>{user.name}</strong><span class='info time'>{timestamp}</span>{edit}{jump}</h2>",
|
"<h2><strong class='username' title='#{user.tag}'>{user.name}</strong><span class='info time'>{timestamp}</span>{edit}{jump}</h2>",
|
||||||
"<div class='message'>{contents}{embeds}{attachments}</div>",
|
"<div class='message'>{contents}{embeds}{attachments}</div>",
|
||||||
"</div>",
|
"</div>",
|
||||||
|
"</div>",
|
||||||
"</div>"
|
"</div>"
|
||||||
].join(""));
|
].join(""));
|
||||||
|
|
||||||
@ -128,37 +162,7 @@ var DISCORD = (function(){
|
|||||||
return getHumanReadableTime(value);
|
return getHumanReadableTime(value);
|
||||||
}
|
}
|
||||||
else if (property === "contents"){
|
else if (property === "contents"){
|
||||||
if (value == null || value.length === 0){
|
return value == null || value.length === 0 ? "" : processMessageContents(value);
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
var processed = DOM.escapeHTML(value.replace(REGEX.formatUrlNoEmbed, "$1"));
|
|
||||||
|
|
||||||
if (STATE.settings.enableFormatting){
|
|
||||||
var escapeHtmlMatch = (full, match) => "&#"+match.charCodeAt(0)+";";
|
|
||||||
|
|
||||||
processed = processed
|
|
||||||
.replace(REGEX.specialEscapedBacktick, "`")
|
|
||||||
.replace(REGEX.formatCodeBlock, (full, ignore, match) => "<code class='block'>"+match.replace(REGEX.specialUnescaped, escapeHtmlMatch)+"</code>")
|
|
||||||
.replace(REGEX.formatCodeInline, (full, ignore, match) => "<code class='inline'>"+match.replace(REGEX.specialUnescaped, escapeHtmlMatch)+"</code>")
|
|
||||||
.replace(REGEX.specialEscapedSingle, escapeHtmlMatch)
|
|
||||||
.replace(REGEX.specialEscapedDouble, full => full.replace(/\\/g, "").replace(/(.)/g, escapeHtmlMatch))
|
|
||||||
.replace(REGEX.formatBold, "<b>$1</b>")
|
|
||||||
.replace(REGEX.formatItalic, (full, pre, match) => pre === '\\' ? full : (pre || "")+"<i>"+match+"</i>")
|
|
||||||
.replace(REGEX.formatUnderline, "<u>$1</u>")
|
|
||||||
.replace(REGEX.formatStrike, "<s>$1</s>");
|
|
||||||
}
|
|
||||||
|
|
||||||
var animatedEmojiExtension = STATE.settings.enableAnimatedEmoji ? "gif" : "png";
|
|
||||||
|
|
||||||
processed = processed
|
|
||||||
.replace(REGEX.formatUrl, "<a href='$1' target='_blank' rel='noreferrer'>$1</a>")
|
|
||||||
.replace(REGEX.mentionChannel, (full, match) => "<span class='link mention-chat'>#"+STATE.getChannelName(match)+"</span>")
|
|
||||||
.replace(REGEX.mentionUser, (full, match) => "<span class='link mention-user' title='#"+(STATE.getUserTag(match) || "????")+"'>@"+STATE.getUserName(match)+"</span>")
|
|
||||||
.replace(REGEX.customEmojiStatic, "<img src='https://cdn.discordapp.com/emojis/$2.png' alt=':$1:' title=':$1:' class='emoji'>")
|
|
||||||
.replace(REGEX.customEmojiAnimated, "<img src='https://cdn.discordapp.com/emojis/$2."+animatedEmojiExtension+"' alt=':$1:' title=':$1:' class='emoji'>");
|
|
||||||
|
|
||||||
return "<p>"+processed+"</p>";
|
|
||||||
}
|
}
|
||||||
else if (property === "embeds"){
|
else if (property === "embeds"){
|
||||||
if (!value){
|
if (!value){
|
||||||
@ -200,6 +204,17 @@ var DISCORD = (function(){
|
|||||||
else if (property === "jump"){
|
else if (property === "jump"){
|
||||||
return STATE.hasActiveFilter ? "<span class='info jump' data-jump='" + value + "'>Jump to message</span>" : "";
|
return STATE.hasActiveFilter ? "<span class='info jump' data-jump='" + value + "'>Jump to message</span>" : "";
|
||||||
}
|
}
|
||||||
|
else if (property === "reply"){
|
||||||
|
if (value === null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = "<span class='reply-username' title='#" + (value.user.tag ? value.user.tag : "????") + "'>" + value.user.name + "</span>";
|
||||||
|
var avatar = value.avatar ? "<span class='reply-avatar'>" + templateUserAvatar.apply(value.avatar) + "</span>" : "";
|
||||||
|
var contents = value.contents ? "<span class='reply-contents'>" + processMessageContents(value.contents) + "</span>" : "";
|
||||||
|
|
||||||
|
return "<span class='jump' data-jump='" + value.id + "'>Jump to reply</span><span class='user'>" + avatar + user + "</span>" + contents;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -37,7 +37,7 @@ var STATE = (function(){
|
|||||||
ROOT.onChannelsRefreshed = function(callback){
|
ROOT.onChannelsRefreshed = function(callback){
|
||||||
eventOnChannelsRefreshed = callback;
|
eventOnChannelsRefreshed = callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
ROOT.onMessagesRefreshed = function(callback){
|
ROOT.onMessagesRefreshed = function(callback){
|
||||||
eventOnMessagesRefreshed = callback;
|
eventOnMessagesRefreshed = callback;
|
||||||
};
|
};
|
||||||
@ -147,7 +147,17 @@ var STATE = (function(){
|
|||||||
var message = messages[key];
|
var message = messages[key];
|
||||||
var user = FILE.getUser(message.u);
|
var user = FILE.getUser(message.u);
|
||||||
var avatar = user.avatar ? { id: FILE.getUserId(message.u), path: user.avatar } : null;
|
var avatar = user.avatar ? { id: FILE.getUserId(message.u), path: user.avatar } : null;
|
||||||
|
|
||||||
|
var reply = ("r" in message && message.r in messages) ? messages[message.r] : null;
|
||||||
|
var replyUser = reply ? FILE.getUser(reply.u) : null;
|
||||||
|
var replyAvatar = replyUser && replyUser.avatar ? { id: FILE.getUserId(reply.u), path: replyUser.avatar } : null;
|
||||||
|
var replyObj = reply ? {
|
||||||
|
"id": message.r,
|
||||||
|
"user": replyUser,
|
||||||
|
"avatar": replyAvatar,
|
||||||
|
"contents": reply.m
|
||||||
|
} : null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"user": user,
|
"user": user,
|
||||||
"avatar": avatar,
|
"avatar": avatar,
|
||||||
@ -156,7 +166,8 @@ var STATE = (function(){
|
|||||||
"embeds": message.e,
|
"embeds": message.e,
|
||||||
"attachments": message.a,
|
"attachments": message.a,
|
||||||
"edit": ("te" in message) ? message.te : (message.f & 1) === 1,
|
"edit": ("te" in message) ? message.te : (message.f & 1) === 1,
|
||||||
"jump": key
|
"jump": key,
|
||||||
|
"reply": replyObj
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -154,3 +154,65 @@
|
|||||||
vertical-align: -30%;
|
vertical-align: -30%;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reply-message {
|
||||||
|
margin: 0 0 -2px 52px;
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
line-height: 120%;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-message .jump {
|
||||||
|
color: rgba(255, 255, 255, 0.4);
|
||||||
|
font-size: 12px;
|
||||||
|
text-underline-offset: 1px;
|
||||||
|
margin-right: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-message .emoji {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
vertical-align: -20%;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-message .user {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-avatar {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-avatar img {
|
||||||
|
width: 16px;
|
||||||
|
border-radius: 50%;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-username {
|
||||||
|
color: #FFF;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-contents {
|
||||||
|
display: inline-block;
|
||||||
|
color: rgba(255, 255, 255, 0.7);
|
||||||
|
font-size: 12px;
|
||||||
|
max-width: calc(80%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-contents p {
|
||||||
|
margin: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-contents a {
|
||||||
|
color: #0096CF;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user