934 lines
40 KiB
JavaScript
934 lines
40 KiB
JavaScript
// I'm not a React developer. Be advised!
|
|
// If you are, and want to rewrite this the "right way", go ahead and do it :)
|
|
// This is plain Javascript and only requires basic calls to implement customizations
|
|
|
|
|
|
// Do simple XHR requests to the API on Mastodon
|
|
// make sure you control errors correctly, as a Mastodon Server might not setup CORS correctly
|
|
const fediloveMastodon = {
|
|
request: function(method, path, payload, callbk) {
|
|
payload = payload || null;
|
|
callbk = callbk || null;
|
|
const ACCESS_TOKEN = window.fediloveApi.getAccessToken();
|
|
if (ACCESS_TOKEN === undefined)
|
|
return callbk(undefined);
|
|
const API_URL = 'https://'+fediloveApi.getCurrentInstance()+path;
|
|
const oReq = new XMLHttpRequest();
|
|
oReq.addEventListener("load", function() { if (callbk) callbk(this.responseText) });
|
|
oReq.open(method, API_URL);
|
|
oReq.setRequestHeader('Authorization', 'Bearer '+ACCESS_TOKEN);
|
|
oReq.send(payload);
|
|
},
|
|
get: function(path, payload, callbk) {
|
|
return fediloveMastodon.request('GET', path, payload, callbk);
|
|
},
|
|
post: function(path, payload, callbk) {
|
|
return fediloveMastodon.request('POST', path, payload, callbk);
|
|
},
|
|
API: {
|
|
discardAccount: function(account_id, cback) {
|
|
fediloveMastodon.post(`/api/v1/accounts/${account_id}/block`, null, function(data) { cback() });
|
|
fediloveMastodon.post(`/api/v1/follow_requests/${account_id}/reject`);
|
|
},
|
|
matchAccount: function(account_id, cback) {
|
|
fediloveMastodon.post(`/api/v1/accounts/${account_id}/follow`, {'reblogs': true}, function(data) { cback() });
|
|
fediloveMastodon.post(`/api/v1/follow_requests/${account_id}/authorize`);
|
|
},
|
|
getRelationship: function(account_id, cback) {
|
|
fediloveMastodon.get(`/api/v1/accounts/relationships?id=${account_id}`, null, cback);
|
|
},
|
|
getMyFollowing: function(cback) {
|
|
fediloveMastodon.get(`/api/v1/accounts/${fediloveData.myAccountId}/following`, null, cback);
|
|
},
|
|
getMyRequestsToFollow: function(cback) {
|
|
// to-do: find out how to list my own matches (follow requests)
|
|
},
|
|
getMyFollowers: function(cback) {
|
|
fediloveMastodon.get(`/api/v1/accounts/${fediloveData.myAccountId}/followers`, null, cback);
|
|
},
|
|
getRequestsToFollowMe: function(cback) {
|
|
fediloveMastodon.get('/api/v1/follow_requests', null, cback);
|
|
},
|
|
statusFav: function(dom, status_id) {
|
|
var dislike = false;
|
|
var path = `/api/v1/statuses/${status_id}/favourite`;
|
|
if (dom.getAttribute('data-liked') === "1") {
|
|
path = `/api/v1/statuses/${status_id}/unfavourite`;
|
|
dislike = true;
|
|
}
|
|
fediloveMastodon.post(path, {}, function(data) {
|
|
if (!dislike) {
|
|
$(dom).addClass('liked-msg');
|
|
$(dom).attr('data-liked', 1);
|
|
dom.style.animation = "spin2 .5s linear 1";
|
|
} else {
|
|
$(dom).removeClass('liked-msg');
|
|
$(dom).attr('aria-label', '0 '+$(dom).attr('aria-label'));
|
|
$(dom).removeAttr('data-liked');
|
|
dom.style.animation = undefined;
|
|
}
|
|
});
|
|
},
|
|
sendMessage: function() {
|
|
// the message is composed from the current chat Acct (@user@domain) + the compose textarea value
|
|
const text = fediloveData.chatAvatarCache.acct + ' ' + $('div#chat-compose-global textarea').val();
|
|
|
|
//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);
|
|
|
|
// empty the current compose box
|
|
$('div#chat-compose-global textarea').val('');
|
|
|
|
// scroll to the end as all chat Apps do
|
|
fediloveUI.scrollChatToLastItem();
|
|
}
|
|
}
|
|
};
|
|
|
|
var fediloveUI = {
|
|
registerSwipeOnElementEvents: {
|
|
elements: [],
|
|
vars: {
|
|
startX: null, startY: null, dist: null,
|
|
threshold: 30, allowedTime: 200,
|
|
elapsedTime: 0, startTime: null
|
|
},
|
|
touchstart: function(e) {
|
|
const vars = fediloveUI.registerSwipeOnElementEvents.vars;
|
|
const touchobj = e.changedTouches[0];
|
|
|
|
vars.dist = 0; vars.startX = touchobj.pageX; vars.startY = touchobj.pageY;
|
|
vars.startTime = new Date().getTime(); e.preventDefault();
|
|
},
|
|
touchmove: function(e) { e.preventDefault() },
|
|
touchend: function(e) {
|
|
if (fediloveUI.registerSwipeOnElementEvents.touchendCallback != null) {
|
|
const vars = fediloveUI.registerSwipeOnElementEvents.vars;
|
|
const touchobj = e.changedTouches[0];
|
|
vars.dist = touchobj.pageX - vars.startX;
|
|
vars.elapsedTime = new Date().getTime() - vars.startTime;
|
|
|
|
if (Math.abs(vars.dist) < 20) { return e.preventDefault(); }
|
|
|
|
const swiperightBol = (vars.elapsedTime <= vars.allowedTime && vars.dist >= vars.threshold);
|
|
|
|
fediloveUI.registerSwipeOnElementEvents.touchendCallback(swiperightBol);
|
|
e.preventDefault();
|
|
}
|
|
},
|
|
touchendCallback: null
|
|
},
|
|
unregisterSwipeOnElement: function(selector) {
|
|
const element = document.querySelector(selector);
|
|
if (element === null || element === undefined) return;
|
|
|
|
fediloveUI.registerSwipeOnElementEvents.elements = fediloveUI.registerSwipeOnElementEvents.elements.filter(
|
|
function(item) { return item !== selector });
|
|
element.removeEventListener('touchstart', fediloveUI.registerSwipeOnElementEvents.touchstart);
|
|
element.removeEventListener('touchmove', fediloveUI.registerSwipeOnElementEvents.touchmove);
|
|
element.removeEventListener('touchend', fediloveUI.registerSwipeOnElementEvents.touchend);
|
|
},
|
|
registerSwipeOnElement: function(selector, cbackFunc) {
|
|
const element = document.querySelector(selector);
|
|
if (element === null || element === undefined) return;
|
|
|
|
if (fediloveUI.registerSwipeOnElementEvents.elements.includes(selector))
|
|
return true;
|
|
|
|
fediloveUI.registerSwipeOnElementEvents.elements.push(selector);
|
|
fediloveUI.registerSwipeOnElementEvents.touchendCallback = cbackFunc;
|
|
element.addEventListener('touchstart', fediloveUI.registerSwipeOnElementEvents.touchstart, false);
|
|
element.addEventListener('touchmove', fediloveUI.registerSwipeOnElementEvents.touchmove, false);
|
|
element.addEventListener('touchend', fediloveUI.registerSwipeOnElementEvents.touchend, false);
|
|
},
|
|
meetAccountImageDirection: function(direction) {
|
|
if (!window.location.pathname.startsWith('/accounts') ||
|
|
fediloveUI.meetAccountImageLocked) return;
|
|
fediloveUI.meetAccountImageLocked = true;
|
|
|
|
var dontMove = false;
|
|
if (direction === 'prev')
|
|
fediloveData.meetAccountCurrentImg -= 1;
|
|
else if (direction === 'next')
|
|
fediloveData.meetAccountCurrentImg += 1;
|
|
else
|
|
dontMove = true;
|
|
|
|
const last = $('div.virtual-list > div.virtual-list-item').length - 1;
|
|
if (fediloveData.meetAccountCurrentImg > last) {
|
|
fediloveData.meetAccountCurrentImg = last > 0 ? last : 0;
|
|
dontMove = true;
|
|
} else if (fediloveData.meetAccountCurrentImg < 0) {
|
|
fediloveData.meetAccountCurrentImg = 0;
|
|
dontMove = true;
|
|
}
|
|
|
|
document.querySelector('#meet-navigation > #profile-nav > #next').style = '';
|
|
document.querySelector('#meet-navigation > #profile-nav > #prev').style = '';
|
|
if (fediloveData.meetAccountCurrentImg === last)
|
|
document.querySelector('#meet-navigation > #profile-nav > #next').style = 'display: none';
|
|
else if (fediloveData.meetAccountCurrentImg === 0)
|
|
document.querySelector('#meet-navigation > #profile-nav > #prev').style = 'display: none';
|
|
|
|
const _setSelectedVisible = function() {
|
|
if ($('div.virtual-list > div.virtual-list-item')[fediloveData.meetAccountCurrentImg] !== undefined) {
|
|
$('div.virtual-list > div.virtual-list-item').attr('style', 'display: none');
|
|
$('div.virtual-list > div.virtual-list-item')[fediloveData.meetAccountCurrentImg].style = '';
|
|
}
|
|
fediloveUI.meetAccountImageLocked = false;
|
|
};
|
|
|
|
if (dontMove === false) {
|
|
if (direction === 'next')
|
|
$('div.virtual-list')[0].style.animation = 'dismissMeet .25s linear 1';
|
|
else if (direction === 'prev')
|
|
$('div.virtual-list')[0].style.animation = 'acceptMeet .25s linear 1';
|
|
setTimeout(function() {
|
|
if ($('div.virtual-list')[0] !== undefined) {
|
|
$('div.virtual-list')[0].style.animation = '';
|
|
_setSelectedVisible();
|
|
}
|
|
}, 220);
|
|
} else { _setSelectedVisible() }
|
|
|
|
},
|
|
meetPageGoToCurrentAccount: function(isRightSwipe) {
|
|
isRightSwipe = isRightSwipe || false;
|
|
const accObj = fediloveApi.getMeetAccount();
|
|
if (!isRightSwipe && accObj !== undefined) {
|
|
const elem2Anim = $('div.virtual-list > div.virtual-list-item.meetshown:visible')[0];
|
|
if (elem2Anim !== undefined)
|
|
elem2Anim.style.animation = 'dismissMeet .25s linear 1';
|
|
setTimeout(function() { fediloveApi.redirect(`/accounts/${accObj.id}`) }, 200);
|
|
}
|
|
},
|
|
scrollChatToLastItem: function() {
|
|
const startLen = $('div.the-list > div').length;
|
|
var count = 0;
|
|
var _this = setInterval(function() {
|
|
count++;
|
|
var newLen = $('div.the-list > div').length;
|
|
if (count >= 100 || newLen != startLen) {
|
|
const elem = document.querySelector('div.the-list > div:last-child');
|
|
if (elem !== null) elem.scrollIntoView();
|
|
clearInterval(_this);
|
|
}
|
|
}, 150);
|
|
},
|
|
paintChatAvatarAndName: function(accid, acct, avatar, name) {
|
|
accid = accid || null;
|
|
acct = acct || null;
|
|
avatar = avatar || null;
|
|
name = name || null;
|
|
|
|
if ((accid+acct+avatar+name) === 0) {
|
|
accid = 0;
|
|
avatar = '/missing.png';
|
|
name = '...';
|
|
} else {
|
|
fediloveData.chatAvatarCache = {
|
|
id: accid, acct: acct,
|
|
avatar: avatar, name: name
|
|
};
|
|
// add domain part on acct on painting it to be clear
|
|
if (acct.split('@').length-1 === 1) {
|
|
acct += `@${fediloveApi.getCurrentInstance()}`;
|
|
}
|
|
}
|
|
|
|
// to-do: check is it XSS safe to add it like this :) ??
|
|
$('div#chat-party-global > div#image > img').attr('src', avatar);
|
|
$('div#chat-party-global > div#name > a > span').html(name);
|
|
$('div#chat-party-global > div#name > span').text(acct);
|
|
if (accid != 0) $('div#chat-party-global > div#name > a').attr('href', `/accounts/${accid}`);
|
|
},
|
|
fillMeetRelationships: function() {
|
|
var countMax = 0;
|
|
const _this = setInterval(function() {
|
|
if (countMax > 100) {
|
|
return clearInterval(_this);
|
|
}
|
|
const items = fediloveFunctions.filterItemsForFedilove(window.__store.get().timelineItemSummaries);
|
|
if (items !== null && items.length > 0) {
|
|
var refIds = [];
|
|
for (var it of items) {
|
|
if (it.accountId !== undefined && !refIds.includes(it.accountId))
|
|
refIds.push(it.accountId);
|
|
}
|
|
if (fediloveData.pagesLoaded['meet']) {
|
|
for (var accId of refIds) {
|
|
window.__database.getRelationship(fediloveApi.getCurrentInstance(), accId+"").then(function(rel) {
|
|
if (rel !== undefined && fediloveData.meetRelationships[rel.id] === undefined)
|
|
fediloveData.meetRelationships[rel.id] = rel;
|
|
if (Object.keys(window.fediloveData.meetRelationships).length === refIds.length)
|
|
fediloveData.meetRelationshipsFilled = true;
|
|
});
|
|
}
|
|
} else {
|
|
for (var accId of refIds) {
|
|
fediloveMastodon.API.getRelationship(accId+"", function(data) {
|
|
const json = JSON.parse(data)[0];
|
|
if (json && fediloveData.meetRelationships[json.id] === undefined)
|
|
fediloveData.meetRelationships[json.id] = json;
|
|
fediloveData.meetRelationshipsFilled = true;
|
|
fediloveData.pagesLoaded['meet'] = true;
|
|
});
|
|
}
|
|
}
|
|
clearInterval(_this);
|
|
}
|
|
countMax++;
|
|
}, 100);
|
|
},
|
|
toast: function(whatToSay, time, className, renderHtml) {
|
|
if (!fediloveData.toastInitialized) return;
|
|
if (time !== undefined)
|
|
window.fediloveData.toastTime = time;
|
|
if (className !== undefined)
|
|
window.fediloveData.toastClass = className;
|
|
if (renderHtml) {
|
|
$('#theToast #plain-text')[0].style = 'display: none';
|
|
$('#theToast #html-text').html(whatToSay);
|
|
} else {
|
|
$('#theToast #plain-text')[0].style = '';
|
|
$('#theToast #html-text').html('');
|
|
}
|
|
window.__toast.say(whatToSay);
|
|
},
|
|
animateMainContentSwipe: function(animName, cback) {
|
|
$('div.virtual-list')[0].style.animation = `${animName} .25s linear 1`;
|
|
setTimeout(cback, 220);
|
|
},
|
|
onAccountNope: function() {
|
|
const accObj = fediloveApi.getMeetAccount();
|
|
if (accObj === undefined) return;
|
|
if (!fediloveData.tmpDiscardedAccounts.includes(accObj.id))
|
|
fediloveData.tmpDiscardedAccounts.push(accObj.id);
|
|
fediloveMastodon.API.discardAccount(accObj.id, function() {
|
|
fediloveUI.animateMainContentSwipe('nopeMeet', function() { window.history.back() });
|
|
});
|
|
},
|
|
onAccountMatch: function() {
|
|
const accObj = fediloveApi.getMeetAccount();
|
|
if (accObj === undefined) return;
|
|
if (fediloveData.meetRelationships[accObj.id] !== undefined)
|
|
fediloveData.meetRelationships[accObj.id] = { 'id': accObj.id, 'requested': true }
|
|
|
|
fediloveUI.toast(window.__intl.matchAction, 6000, 'match', true);
|
|
fediloveMastodon.API.matchAccount(accObj.id, function() { });
|
|
},
|
|
onAccountMaybe: function() {
|
|
const accObj = fediloveApi.getMeetAccount();
|
|
if (accObj === undefined) return;
|
|
|
|
const expire = 24 * (60*60*1000); // hours. Expire the maybe after 24 hours
|
|
var accounts = {};
|
|
if (window.localStorage.store_maybeAccounts !== undefined)
|
|
accounts = JSON.parse(window.localStorage.store_maybeAccounts);
|
|
accounts[accObj.id] = Date.now() + expire;
|
|
window.localStorage.store_maybeAccounts = JSON.stringify(accounts);
|
|
|
|
fediloveUI.toast(window.__intl.maybeAction, 2000, 'maybe');
|
|
fediloveUI.animateMainContentSwipe('acceptMeet', function() { window.history.back() });
|
|
}
|
|
};
|
|
|
|
// objects to access from React code
|
|
var fediloveApi = {
|
|
redirect: function(url) {
|
|
const _id = 'link-' + Date.now();
|
|
var a = document.createElement('a');
|
|
a.href = url; a.id = _id;
|
|
document.body.append(a);
|
|
document.getElementById(_id).click();
|
|
document.body.removeChild(a);
|
|
},
|
|
getMeetAccount: function(directlyFromStore) {
|
|
directlyFromStore = directlyFromStore || false;
|
|
if (window.localStorage.store_meetAccounts === undefined)
|
|
return undefined;
|
|
if (document.getElementById(window.fediloveData.currentIDMeetTimeline) === undefined)
|
|
return undefined;
|
|
if (directlyFromStore)
|
|
return window.__store.get().currentAccountProfile;
|
|
var accId;
|
|
if (window.location.pathname == '/meet')
|
|
accId = $(document.getElementById(window.fediloveData.currentIDMeetTimeline)).data('account');
|
|
else if (window.location.pathname.startsWith('/accounts/'))
|
|
accId = window.location.pathname.match(/^\/accounts\/(\d+)/)[1];
|
|
if (accId === undefined)
|
|
return undefined;
|
|
const aJson = JSON.parse(window.localStorage.store_meetAccounts);
|
|
if (aJson[accId] === undefined) {
|
|
if (window.__store.get().currentAccountProfile === undefined)
|
|
return undefined;
|
|
return window.__store.get().currentAccountProfile;
|
|
}
|
|
return aJson[accId];
|
|
},
|
|
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').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() {
|
|
const instance = fediloveApi.getCurrentInstance();
|
|
if (instance === undefined)
|
|
return undefined;
|
|
return JSON.parse(localStorage.store_loggedInInstances)[instance].access_token;
|
|
},
|
|
getCurrentInstance: function() {
|
|
if (localStorage.store_currentInstance === undefined)
|
|
return undefined;
|
|
return JSON.parse(localStorage.store_currentInstance);
|
|
},
|
|
getFedilovedName: function(nameTxt, emojis) {
|
|
emojis = emojis || undefined;
|
|
nameTxt = nameTxt.replace(/#fedilove/gi, '').trim();
|
|
nameTxt = nameTxt.replace(/\s+/g, ' ').trim().replace(/\s/g, ' ');
|
|
if (emojis === undefined || fediloveFunctions.emojifyText === undefined)
|
|
return nameTxt;
|
|
return fediloveFunctions.emojifyText(nameTxt, emojis);
|
|
}
|
|
};
|
|
var fediloveFunctions = {
|
|
filterItemsForFedilove: function(items) {
|
|
if (typeof items == "string")
|
|
items = JSON.parse(items);
|
|
if (items === null || items === undefined)
|
|
return null;
|
|
let newItems = [];
|
|
for (var item of items) {
|
|
if (item.display_name !== undefined) {
|
|
if (item.id != window.fediloveData.myAccountId)
|
|
newItems.push(item);
|
|
continue;
|
|
}
|
|
if (item.account === undefined) {
|
|
if (item.accountId !== undefined &&
|
|
item.accountId !== window.fediloveData.myAccountId)
|
|
newItems.push(item);
|
|
continue;
|
|
}
|
|
if (item.account.display_name.toLowerCase().includes('#fedilove') &&
|
|
item.content.replace(/<[^<>]+>/g, '').toLowerCase().includes('#fedilove') &&
|
|
item.account.id != window.fediloveData.myAccountId) {
|
|
newItems.push(item);
|
|
}
|
|
}
|
|
return newItems;
|
|
}
|
|
};
|
|
var fediloveData = {
|
|
chatAvatarCache: undefined,
|
|
meetAccountCurrentImg: 0,
|
|
meetAccountImageLocked: false,
|
|
myAccountId: undefined,
|
|
currentAccountIsEmpty: false,
|
|
currentIDMeetTimeline: null,
|
|
tmpDiscardedAccounts: [],
|
|
meetRelationships: {},
|
|
meetRelationshipsFilled: false,
|
|
gotEmojifyTextFunction: false,
|
|
composeTxtKeypressEvent: false,
|
|
toastTime: undefined,
|
|
toastClass: undefined,
|
|
toastInitialized: false,
|
|
pagesLoaded: {},
|
|
tpls: {}
|
|
};
|
|
var fediloveEvents = {
|
|
onGotEmojifyTextFunction: function() {
|
|
fediloveData.gotEmojifyTextFunction = true;
|
|
},
|
|
onChatGetData: function(data) {
|
|
// dont do anything if avatar and name is cached
|
|
if (fediloveData.chatAvatarCache !== undefined) return;
|
|
|
|
// waits for the React code to call the "onGotEmojifyTextFunction" so we can use it
|
|
var waitForEmojifyAndDo = function(accid, acct, avatar, dname, emojis) {
|
|
var count = 0;
|
|
var _this = setInterval(function() {
|
|
if (count > 100) {
|
|
clearInterval(_this);
|
|
return;
|
|
}
|
|
if (fediloveData.gotEmojifyTextFunction) {
|
|
fediloveUI.paintChatAvatarAndName(accid, acct, avatar,
|
|
fediloveApi.getFedilovedName(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 (fediloveData.myAccountId == data.account.id) {
|
|
var account_id = data.in_reply_to_account_id;
|
|
if (account_id === null && data.mentions.length > 0) {
|
|
account_id = data.mentions[0].id;
|
|
}
|
|
if (account_id === null || account_id === undefined) return;
|
|
fediloveMastodon.get(`/api/v1/accounts/${account_id}`, {}, function(newData) {
|
|
var json = JSON.parse(newData);
|
|
if (json !== undefined) {
|
|
waitForEmojifyAndDo( account_id, `@${json.acct}`, 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.id, `@${data.account.acct}`, data.account.avatar,
|
|
data.account.display_name, data.account.emojis );
|
|
}
|
|
}
|
|
},
|
|
onEmojiPicked: function(emoji) {
|
|
var $txt = $("#chat-compose-global textarea");
|
|
var caretPos = $txt[0].selectionStart;
|
|
var textAreaTxt = $txt.val();
|
|
$txt.val(textAreaTxt.substring(0, caretPos) + emoji + textAreaTxt.substring(caretPos));
|
|
},
|
|
onNewNotification: function (dataItems) {
|
|
if (window.location.pathname.startsWith('/statuses/')) {
|
|
if (fediloveFunctions.updateStatusAndThread !== undefined) {
|
|
fediloveFunctions.updateStatusAndThread( fediloveApi.getCurrentInstance(), fediloveApi.getAccessToken(),
|
|
window.location.pathname, fediloveApi.getChatMessageId() );
|
|
fediloveUI.scrollChatToLastItem();
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
// this is our URL-based customizations made by JavaScript
|
|
function fedilove_customization() {
|
|
document.body.classList = '';
|
|
document.getElementById('sapper').style = '';
|
|
|
|
if ([undefined,"undefined"].includes(localStorage.store_currentInstance)) {
|
|
$('body').addClass('not-logged-in');
|
|
if (window.location.pathname == '/') {
|
|
$('body').addClass('home');
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (fediloveData.myAccountId === undefined && window.__store.get().verifyCredentials !== undefined) {
|
|
var aCountMax = 0;
|
|
const _a = setInterval(function() {
|
|
if (aCountMax > 20)
|
|
return clearInterval(_a);
|
|
const theData = window.__store.get().verifyCredentials[fediloveApi.getCurrentInstance()];
|
|
if (theData) {
|
|
fediloveData.myAccountId = theData ? theData.id : undefined;
|
|
return clearInterval(_a);
|
|
}
|
|
aCountMax++;
|
|
}, 500);
|
|
}
|
|
|
|
if (!fediloveData.toastInitialized) {
|
|
var aCountMax = 0;
|
|
const _a = setInterval(function() {
|
|
if (aCountMax > 20)
|
|
return clearInterval(_a);
|
|
if (window.__toast) {
|
|
window.fediloveData.toastClass = 'notshown';
|
|
window.fediloveData.toastTime = 10;
|
|
window.__toast.say('...');
|
|
fediloveData.toastInitialized = true;
|
|
return clearInterval(_a);
|
|
}
|
|
aCountMax++;
|
|
}, 500);
|
|
}
|
|
|
|
if (document.querySelector('#main-nav > div#dummy-nav') != null) {
|
|
document.querySelector('#main-nav > div#dummy-nav').remove();
|
|
document.querySelector('#main-nav > ul.main-nav-ul').style = '';
|
|
}
|
|
|
|
document.querySelector('.main-content').classList = "main-content";
|
|
document.querySelector('#meet-navigation').style = 'display: none';
|
|
document.querySelector('#meet-navigation > #profile-nav').style = 'display: none';
|
|
document.querySelector('#chat-compose-global').style = 'visibility: collapse';
|
|
document.querySelector('#chat-party-hide').style = 'display: none !important';
|
|
document.querySelector('nav#main-nav > ul.main-nav-ul').style = '';
|
|
fediloveUI.unregisterSwipeOnElement('main.infinite-scroll-page');
|
|
fediloveUI.unregisterSwipeOnElement('#meet-navigation #anim-swipe');
|
|
fediloveData.currentAccountIsEmpty = false;
|
|
|
|
$('nav#main-nav li.main-nav-li svg').each(function() {
|
|
$(this).removeClass('active');
|
|
});
|
|
|
|
// add some animations ( i can't with sass D: )
|
|
if (document.getElementById('fedilove-animations') === null) {
|
|
var style = document.createElement('style');
|
|
style.id = 'fedilove-animations';
|
|
style.innerHTML = `
|
|
@keyframes spin2 {
|
|
100% { transform:rotate(-360deg); }
|
|
}
|
|
@keyframes fadeOut {
|
|
0% {opacity: 1;}
|
|
100% {opacity: 0;}
|
|
}
|
|
@keyframes dismissMeet {
|
|
0% {position: relative; left: 0}
|
|
100% {position: relative; left: -95%}
|
|
}
|
|
@keyframes acceptMeet {
|
|
0% {position: relative; left: 0}
|
|
100% {position: relative; left: 95%}
|
|
}
|
|
@keyframes nopeMeet {
|
|
0% {position: relative; top: 0}
|
|
100% {position: relative; top: 95vh}
|
|
}
|
|
@keyframes yepMeet {
|
|
0% {position: relative; top: 0}
|
|
100% {position: relative; top: -95vh}
|
|
}
|
|
`;
|
|
document.body.appendChild(style);
|
|
}
|
|
|
|
if (window.location.pathname === '/notifications') {
|
|
$('nav#main-nav li.main-nav-li svg')[1].classList += ' active';
|
|
}
|
|
else if (window.location.pathname.startsWith('/statuses/'))
|
|
{
|
|
$('div.main-content').addClass('chat');
|
|
$('body').addClass('chat');
|
|
document.querySelector('#chat-compose-global').style = '';
|
|
document.querySelector('#chat-party-hide').style = '';
|
|
document.querySelector('nav#main-nav > ul.main-nav-ul').style = 'display: none !important';
|
|
|
|
if (!fediloveData.composeTxtKeypressEvent) {
|
|
$('div#chat-compose-global textarea').keypress(function(e) {
|
|
const keycode = (e.keyCode ? e.keyCode : e.which);
|
|
if (keycode == '13') {
|
|
if (!e.ctrlKey && !e.shiftKey) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
setTimeout(function() { fediloveMastodon.API.sendMessage() }, 100);
|
|
return true;
|
|
} else {
|
|
if (!e.shiftKey && e.ctrlKey) {
|
|
$(this).val($(this).val()+'\n');
|
|
}
|
|
}
|
|
}
|
|
});
|
|
fediloveData.composeTxtKeypressEvent = true;
|
|
}
|
|
|
|
// *******
|
|
// load cached avatars or paint it empty (automated process after this will fill it)
|
|
if (fediloveData.chatAvatarCache !== undefined) {
|
|
fediloveUI.paintChatAvatarAndName( fediloveData.chatAvatarCache.id, fediloveData.chatAvatarCache.acct,
|
|
fediloveData.chatAvatarCache.avatar, fediloveData.chatAvatarCache.name );
|
|
} else {
|
|
fediloveUI.paintChatAvatarAndName();
|
|
}
|
|
|
|
// this function changes the css class on articles (messages)
|
|
// that match the given account_id
|
|
var theint = 100;
|
|
const _this = setInterval(function()
|
|
{
|
|
// interval auto-destroyer
|
|
if (!window.location.pathname.startsWith('/statuses/')) {
|
|
clearInterval(_this);
|
|
return;
|
|
}
|
|
|
|
// paint MY messages as mine
|
|
if (fediloveData.myAccountId !== undefined) {
|
|
$('div.main-content.chat article.status-article').each(function(i) {
|
|
if ($(this).find('a.status-author-name').attr('href').endsWith(`/accounts/${fediloveData.myAccountId}`)) {
|
|
$(this).addClass('mymsg');
|
|
theint = 250;
|
|
} else {
|
|
$(this).addClass('partymsg');
|
|
}
|
|
});
|
|
}
|
|
|
|
// paint LIKES
|
|
$('a.status-favs-reblogs.status-favs').each(function(i) {
|
|
// easy, aria-label contains the times this status was fav
|
|
// so, we use this as the input source to search for "0",
|
|
// if no "0" found in text, we mark element as liked so we can apply styles and "undo like" function
|
|
if ($(this).attr('aria-label').search(/0/) == -1) {
|
|
$(this).addClass('liked-msg');
|
|
$(this).attr('data-liked', 1);
|
|
}
|
|
});
|
|
|
|
// remove liking functionality from our own messages
|
|
$('div.the-list article.status-article.mymsg a.status-favs-reblogs').each(function(i) {
|
|
$(this).attr('onclick', 'return false;');
|
|
});
|
|
|
|
// resize likes acording to the outer parent
|
|
$('div.main-content.chat div.the-list article.status-article').each(function(e) {
|
|
$(this).find('div.like-div').width($(this).width());
|
|
});
|
|
|
|
}, theint);
|
|
}
|
|
else if (window.location.pathname == '/matches') {
|
|
$('div.main-content').addClass('matches');
|
|
if ($('#tpl-follow').length > 0 &&
|
|
fediloveData.tpls.accountMatches === undefined) {
|
|
var elem = $('#tpl-follow').clone();
|
|
elem[0].removeAttribute('id');
|
|
elem[0].removeAttribute('style');
|
|
fediloveData.tpls.accountMatches = elem[0].outerHTML;
|
|
}
|
|
var filledOnce = false;
|
|
const _fillAccountMatches = function(accounts) {
|
|
if (!filledOnce) {
|
|
$('#manage-matches').html('');
|
|
filledOnce = true;
|
|
}
|
|
var i = 0;
|
|
for (var account of accounts) {
|
|
var acct = account.acct;
|
|
if (acct.charAt(0) !== '@')
|
|
acct = `@${acct}`;
|
|
if (acct.split('@').length-1 === 1)
|
|
acct += `@${fediloveApi.getCurrentInstance()}`;
|
|
const dname = fediloveApi.getFedilovedName(account.display_name, account.emojis);
|
|
var htm = fediloveData.tpls.accountMatches;
|
|
htm = htm.replace(/\[userID\]/g, account.id);
|
|
htm = htm.replace(/\[userAvatar\]/g, account.avatar);
|
|
htm = htm.replace(/\[originalAccountUrl\]/g, account.url);
|
|
htm = htm.replace(/\[userHandle\]/g, acct);
|
|
htm = htm.replace(/\[displayName\]/g, dname);
|
|
$('#manage-matches').append(htm);
|
|
if (i < accounts.length -1)
|
|
$('#manage-matches').append('<div class="accsep"></div>');
|
|
else
|
|
$('#manage-matches').append('<div class="accsep-close"></div>');
|
|
i++;
|
|
}
|
|
};
|
|
fediloveMastodon.API.getRequestsToFollowMe(function(data) {
|
|
const items = fediloveFunctions.filterItemsForFedilove(data);
|
|
_fillAccountMatches(items);
|
|
});
|
|
}
|
|
else if (window.location.pathname == '/direct') {
|
|
$('div.main-content').addClass('direct');
|
|
$('body').addClass('direct');
|
|
$('nav#main-nav li.main-nav-li svg')[2].classList += ' active';
|
|
}
|
|
else if (window.location.pathname.startsWith('/settings')) {
|
|
$('nav#main-nav li.main-nav-li svg')[3].classList += ' active';
|
|
}
|
|
else if (window.location.pathname.startsWith('/accounts/') &&
|
|
window.location.pathname.match(/^\/accounts\/\d+$/) !== null)
|
|
{
|
|
$('div.main-content').addClass('account');
|
|
$('body').addClass('account');
|
|
document.querySelector('nav#main-nav > ul.main-nav-ul').style = 'display: none !important';
|
|
document.querySelector('#meet-navigation').style = '';
|
|
document.querySelector('#meet-navigation > #profile-nav').style = '';
|
|
$('#meet-navigation > #anim-swipe').html('');
|
|
|
|
// prev and next navigation
|
|
const cloneBackSvg = function(selector) {
|
|
$(selector).html('');
|
|
$(selector).append(
|
|
$('#meet-navigation > #back > svg').clone());
|
|
};
|
|
cloneBackSvg('#meet-navigation > #profile-nav > #prev');
|
|
cloneBackSvg('#meet-navigation > #profile-nav > #next');
|
|
fediloveUI.meetAccountImageDirection(null);
|
|
|
|
// clone the first element and include the account header image
|
|
var countmax = 0;
|
|
const _applyImageTo = function(selector) {
|
|
setTimeout(function()
|
|
{ // set image of first item to the account header (100ms after cloning the object)
|
|
const accObj = window.fediloveApi.getMeetAccount(true);
|
|
if (accObj !== undefined) {
|
|
if ($(selector)[0] !== undefined)
|
|
$(selector)[0].src = accObj.header;
|
|
}
|
|
}, 100);
|
|
};
|
|
const _this = setInterval(function() {
|
|
|
|
if (!window.location.pathname.startsWith('/accounts')) {
|
|
clearInterval(_this);
|
|
return;
|
|
}
|
|
|
|
// max interval time: 10 seconds
|
|
if (countmax > 50 || $('div.virtual-list > div.virtual-list-item').length > 0) {
|
|
if ($('div.virtual-list > div.virtual-list-item').length > 0) {
|
|
// clone the first element, insert it at the next position
|
|
const _e = $('div.virtual-list > div.virtual-list-item:last').clone();
|
|
$(_e).insertAfter('div.virtual-list > div.virtual-list-item:last');
|
|
|
|
_applyImageTo('div.virtual-list > div.virtual-list-item:last div.status-media img');
|
|
fediloveUI.registerSwipeOnElement('main.infinite-scroll-page', function(isRightSwipe) {
|
|
if (isRightSwipe)
|
|
fediloveUI.meetAccountImageDirection('prev');
|
|
else fediloveUI.meetAccountImageDirection('next');
|
|
});
|
|
}
|
|
|
|
clearInterval(_this);
|
|
} else if ($('div.virtual-list > div.nothing-to-show').length === 1) {
|
|
if ($('div.virtual-list > div.no-images-account').length === 0)
|
|
$('div.virtual-list').append('<div class="no-images-account"><img class="fixed-size-img"/></div>');
|
|
_applyImageTo('div.virtual-list > div.no-images-account > img.fixed-size-img');
|
|
$('#meet-navigation > #profile-nav > #next')[0].style = 'display: none !important';
|
|
|
|
clearInterval(_this);
|
|
}
|
|
countmax++;
|
|
|
|
}, 200);
|
|
}
|
|
else if (window.location.pathname == '/meet')
|
|
{
|
|
$('div.main-content').addClass('meet');
|
|
$('body').addClass('meet');
|
|
document.querySelector('nav#main-nav > ul.main-nav-ul').style = 'display: none !important';
|
|
document.querySelector('#meet-navigation').style = '';
|
|
|
|
// swipe left animation
|
|
$('#meet-navigation > #anim-swipe').html('');
|
|
for (var i of [1,2,3]) {
|
|
var elem = $('#meet-navigation > #back > svg').clone();
|
|
$('#meet-navigation > #anim-swipe').append(elem);
|
|
setTimeout(function(it) {
|
|
it.attr('style', 'animation: fadeOut .5s linear infinite');
|
|
}, (i*250), elem);
|
|
}
|
|
|
|
fediloveData.meetRelationshipsFilled = false;
|
|
fediloveUI.fillMeetRelationships();
|
|
fediloveUI.registerSwipeOnElement('#meet-navigation #anim-swipe', function(swiperightBol) {
|
|
fediloveUI.meetPageGoToCurrentAccount(swiperightBol)
|
|
});
|
|
|
|
const _discardAccountUI = function(accId) {
|
|
$('article[data-account='+accId+']').each(function() {
|
|
$(this).parent().addClass('meetnotshown');
|
|
if ($(this)[0].id === fediloveData.currentIDMeetTimeline)
|
|
fediloveData.currentIDMeetTimeline = null;
|
|
});
|
|
};
|
|
|
|
// "maybe" Accounts are stored on localStorage
|
|
// as there is no way to save this on Mastodon
|
|
const nowDate = Date.now();
|
|
const maybeAccounts = localStorage.store_maybeAccounts !== undefined ?
|
|
JSON.parse(localStorage.store_maybeAccounts) : [];
|
|
|
|
// make sure only the wanted items in timeline are shown
|
|
var prevItems;
|
|
var itemsDrawnOnce = false;
|
|
const _this = setInterval(function()
|
|
{
|
|
if (window.location.pathname !== '/meet')
|
|
return clearInterval(_this);
|
|
|
|
if (!fediloveData.meetRelationshipsFilled)
|
|
return;
|
|
|
|
// added when there is no more profiles to Meet
|
|
if ($('div#noone-to-meet').length === 0)
|
|
$('div.timeline').parent().append('<div id="noone-to-meet" style="display: none"><span>'+window.__intl.nothingToShow+'</span></div>');
|
|
|
|
// remove discarded accounts from timeline (temporal,
|
|
// if /meet is reloaded, blocked accounts won't show either)
|
|
prevItems = $('div.virtual-list > div.virtual-list-item:visible');
|
|
|
|
|
|
// discard temporary added accounts (by "Nope" action)
|
|
for (var accId of fediloveData.tmpDiscardedAccounts)
|
|
_discardAccountUI(accId);
|
|
|
|
// discard localStorage powered maybe accounts (by "Maybe" action)
|
|
for (var accId of Object.keys(maybeAccounts))
|
|
if (maybeAccounts[accId] !== undefined && maybeAccounts[accId] > nowDate)
|
|
_discardAccountUI(accId);
|
|
|
|
// discard the ones we "matched" (by "Match" action
|
|
for (var accId of Object.keys(fediloveData.meetRelationships))
|
|
if (fediloveData.meetRelationships[accId].requested)
|
|
_discardAccountUI(accId);
|
|
|
|
|
|
// paint the current Meet account, after adding classes to hide what we want
|
|
const items = $('div.virtual-list > div.virtual-list-item:visible');
|
|
if (items.length > 0) {
|
|
if (window.fediloveData.currentIDMeetTimeline === null ||
|
|
document.getElementById(window.fediloveData.currentIDMeetTimeline) === null) {
|
|
const itemToId = items.first().find('article:first');
|
|
if (itemToId[0] !== undefined) {
|
|
window.fediloveData.currentIDMeetTimeline = itemToId[0].id;
|
|
itemToId.parent().addClass('meetshown');
|
|
}
|
|
} else {
|
|
items.removeClass('meetshown');
|
|
const itemToId = $(document.getElementById(window.fediloveData.currentIDMeetTimeline));
|
|
if (itemToId.length > 0)
|
|
itemToId.parent().addClass('meetshown');
|
|
}
|
|
} else {
|
|
if (prevItems.length != items.length && $('div#noone-to-meet').length > 0)
|
|
$('div#noone-to-meet')[0].style = '';
|
|
}
|
|
|
|
}, 200);
|
|
}
|
|
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
|
|
// Watch for URL changes every 1/2 seconds (this is efficient, don't worry about it!)
|
|
// and dispatch a call to "fedilove_customization" to load page customizations depending on URL context
|
|
var __window_url = null;
|
|
var __window_url_old = null;
|
|
(function() {
|
|
const _this = setInterval(function() {
|
|
if (typeof $ !== "undefined") {
|
|
clearInterval(_this);
|
|
setInterval(function() {
|
|
const newurl = window.location.pathname;
|
|
if (newurl != __window_url) {
|
|
__window_url_old = __window_url;
|
|
__window_url = newurl;
|
|
fedilove_customization();
|
|
}
|
|
}, 100);
|
|
}
|
|
});
|
|
})();
|