Improved message send on chat feature + caching and UI improvements
This commit is contained in:
parent
34a9411d32
commit
719b9f21f0
|
@ -103,3 +103,7 @@ export function setReplyVisibility (realm, replyVisibility) {
|
|||
: defaultVisibility
|
||||
store.setComposeData(realm, { postPrivacy: visibility })
|
||||
}
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
window.fediloveFunctions.postStatus = postStatus;
|
||||
}
|
||||
|
|
|
@ -5,9 +5,6 @@ export async function postStatus (instanceName, accessToken, text, inReplyToId,
|
|||
sensitive, spoilerText, visibility, poll) {
|
||||
const url = `${basename(instanceName)}/api/v1/statuses`
|
||||
|
||||
// hack to override toots text :)
|
||||
text = $('textarea#the-compose-box-input-'+inReplyToId).val();
|
||||
|
||||
const body = {
|
||||
status: text,
|
||||
in_reply_to_id: inReplyToId,
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<textarea type="text" placeholder="Send your message"></textarea>
|
||||
</td>
|
||||
<td>
|
||||
<button id="send" onclick="return api_send_message(this);" class="primary compose-box-button" aria-label="Send!">
|
||||
<button id="send" onclick="return api_send_message();" class="primary compose-box-button" aria-label="Send!">
|
||||
<svg xlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" height="24" width="24">
|
||||
<path d="M0 0h24v24H0z" fill="none"/><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
|
||||
</svg>
|
||||
|
|
|
@ -40,52 +40,23 @@ function api_status_fav(dom, status_id) {
|
|||
});
|
||||
}
|
||||
|
||||
// We use the already polished compose system to trick it to send messages using our custom UI
|
||||
// instead of the reply compose box show in every message when you hit "reply"
|
||||
function api_send_message(dom) {
|
||||
// The api to send a message on the current chat thread has been improved a lot
|
||||
// and now is much more rock-solid, and we reuse the React functions
|
||||
function api_send_message() {
|
||||
|
||||
// the status_id is the last part of our current URL
|
||||
const status_id = fediloveApi.getChatStatusId();
|
||||
const msgText = $('div#chat-compose-global textarea').val();
|
||||
if (msgText.trim() === '') {
|
||||
return false;
|
||||
}
|
||||
// the message is composed from the current chat Acct (@user@domain) + the compose textarea value
|
||||
const text = fediloveData.chatCurrentAcct + ' ' + $('div#chat-compose-global textarea').val();
|
||||
|
||||
// search for the reply on status_id, dictated by URL
|
||||
$('button[id*=reply-]').each(function(i) {
|
||||
if ($(this).attr('id').includes('//'+status_id))
|
||||
{
|
||||
// click the reply button on the current status, dictated by URL
|
||||
if ($('#the-compose-box-input-'+status_id).length == 0) {
|
||||
$(this).click();
|
||||
}
|
||||
//async function postStatus(realm, text, inReplyToId, mediaIds, sensitive, spoilerText, visibility, mediaDescriptions, inReplyToUuid, poll, mediaFocalPoints)
|
||||
const lastStatus = fediloveApi.getChatLastMessageId(true);
|
||||
fediloveFunctions.postStatus(lastStatus.id, text, lastStatus.id, [], false, undefined,
|
||||
'direct', undefined, lastStatus.uuid, undefined, undefined);
|
||||
|
||||
// wait for the button event to make the compose layer "visible"
|
||||
var _this = setInterval(function()
|
||||
{
|
||||
if ($('#the-compose-box-input-'+status_id).length > 0) {
|
||||
// search for the user ID in the title attribute
|
||||
$('a[id*=status-author-name-]').each(function(i2) {
|
||||
if ($(this).attr('id').includes('//'+status_id))
|
||||
{
|
||||
// title contains the user ID on this server
|
||||
var text = $(this).attr('title')+' '+msgText;
|
||||
// empty the current compose box
|
||||
$('div#chat-compose-global textarea').val('');
|
||||
|
||||
// set the text on thie invisible compose box of the status_id
|
||||
$('textarea#the-compose-box-input-'+status_id).val(text);
|
||||
// hit send :)
|
||||
$('div#list-item-'+status_id+' div.status-article-compose-box > div.compose-box-button-wrapper button.compose-box-button').click();
|
||||
// empty our message box
|
||||
$('div#chat-compose-global textarea').val('');
|
||||
fediloveUI.scrollChatToLastItem();
|
||||
}
|
||||
});
|
||||
|
||||
clearInterval(_this);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
// scroll to the end as all chat Apps do
|
||||
fediloveUI.scrollChatToLastItem();
|
||||
}
|
||||
|
||||
var fediloveUI = {
|
||||
|
@ -108,6 +79,8 @@ var fediloveUI = {
|
|||
if (avatar === null || name === null) {
|
||||
avatar = '/missing.png';
|
||||
name = '...';
|
||||
} else {
|
||||
fediloveData.chatAvatarCache = { avatar: avatar, name: name };
|
||||
}
|
||||
|
||||
// to-do: check is it XSS safe to add it like this :) !!
|
||||
|
@ -118,29 +91,45 @@ var fediloveUI = {
|
|||
|
||||
// objects to access from React code
|
||||
var fediloveApi = {
|
||||
getChatMessageId: function() {
|
||||
var parts = window.location.pathname.split('/');
|
||||
return parts[parts.length-1];
|
||||
},
|
||||
getChatLastMessageId: function(andUuid) {
|
||||
andUuid = andUuid || false;
|
||||
const lastUuid = $('div.the-list article.status-article.partymsg').last().attr('id');
|
||||
if (lastUuid === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
const parts = lastUuid.split('/');
|
||||
return andUuid? { id: parts[parts.length-1], uuid: lastUuid } : parts[parts.length-1];
|
||||
},
|
||||
getAccessToken: function() {
|
||||
var instance = fediloveApi.getCurrentInstance();
|
||||
return JSON.parse(localStorage.store_loggedInInstances)[instance].access_token;
|
||||
},
|
||||
getCurrentInstance: function() {
|
||||
return JSON.parse(localStorage.store_currentInstance);
|
||||
},
|
||||
getChatStatusId: function() {
|
||||
var parts = window.location.pathname.split('/');
|
||||
return parts[parts.length-1];
|
||||
}
|
||||
};
|
||||
var fediloveReact = {};
|
||||
var fediloveFunctions = {};
|
||||
var fediloveData = {
|
||||
chatAvatarCache: undefined,
|
||||
chatCurrentAcct: undefined,
|
||||
gotEmojifyTextFunction: false
|
||||
};
|
||||
var fediloveEvents = {
|
||||
onGotEmojifyTextFunction: function() {
|
||||
fediloveData.gotEmojifyTextFunction = true;
|
||||
},
|
||||
onChatGetData: function(data) {
|
||||
if (data) {
|
||||
onChatGetData: function(data) {
|
||||
// dont do anything if avatar and name is cached
|
||||
if (fediloveData.chatAvatarCache !== undefined) return;
|
||||
|
||||
fediloveData.chatCurrentAcct = `@${data.account.acct}`;
|
||||
|
||||
// waits for the React code to call the "onGotEmojifyTextFunction" so we can use it
|
||||
var waitForEmojifyAndDo = function(avatar, dname, emojis) {
|
||||
var count = 0;
|
||||
var _this = setInterval(function() {
|
||||
if (count > 100) {
|
||||
|
@ -148,12 +137,26 @@ var fediloveEvents = {
|
|||
return;
|
||||
}
|
||||
if (fediloveData.gotEmojifyTextFunction) {
|
||||
fediloveUI.paintChatAvatarAndName( data.account.avatar,
|
||||
fediloveFunctions.emojifyText(data.account.display_name, data.account.emojis) );
|
||||
fediloveUI.paintChatAvatarAndName(avatar, fediloveFunctions.emojifyText(dname, emojis));
|
||||
clearInterval(_this);
|
||||
}
|
||||
count++;
|
||||
}, 150);
|
||||
};
|
||||
if (data) {
|
||||
// if the message is mine, search which account is doing it for,
|
||||
// and do the same with the party's data
|
||||
if (localStorage.store_userAccountId === data.account.id) {
|
||||
mastodon_get(`/api/v1/accounts/${data.in_reply_to_account_id}`, {}, function(newData) {
|
||||
var json = JSON.parse(newData);
|
||||
if (json !== undefined) {
|
||||
waitForEmojifyAndDo( json.avatar, json.display_name, json.emojis );
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// this means the message we are loading is from the other party, so we continue as normal
|
||||
waitForEmojifyAndDo( data.account.avatar, data.account.display_name, data.account.emojis );
|
||||
}
|
||||
}
|
||||
},
|
||||
onEmojiPicked: function(emoji) {
|
||||
|
@ -191,7 +194,13 @@ function fedilove_customization() {
|
|||
document.querySelector('#chat-party-hide').style = '';
|
||||
document.querySelector('nav#main-nav > ul.main-nav-ul').style = 'display: none !important';
|
||||
|
||||
fediloveUI.paintChatAvatarAndName();
|
||||
// *******
|
||||
// load cached avatars or paint it empty (automated process after this will fill it)
|
||||
if (fediloveData.chatAvatarCache !== undefined) {
|
||||
fediloveUI.paintChatAvatarAndName( chatAvatarData.avatar, chatAvataData.name );
|
||||
} else {
|
||||
fediloveUI.paintChatAvatarAndName();
|
||||
}
|
||||
|
||||
// add some animations
|
||||
var style = document.createElement('style');
|
||||
|
@ -256,6 +265,10 @@ function fedilove_customization() {
|
|||
else if (window.location.pathname.startsWith('/notifications/mentions')) {
|
||||
$('nav.notification-filters li > a.focus-fix').attr('onclick', 'return false;');
|
||||
}
|
||||
|
||||
if (!window.location.pathname.startsWith('/statuses/')) {
|
||||
fediloveData.chatAvatarCache = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// we inject this script.js into the React framework at timelines.js
|
||||
|
|
Loading…
Reference in New Issue