// ==UserScript==
// @name RomeoEnhancer
// @version 0.961
// @author braveguy (Romeo: braveguy / Romeo-Club: RomeoEnhancer)
// @description Ergänzungen für die neue Romeo-Seite
// @include https://www.planetromeo.com/*
// @include https://bluebird.planetromeo.com/*
// @require https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js
// @grant GM_addStyle
/*- The @grant directive is needed to work around a design change
introduced in GM 1.0. It restores the sandbox.
*/
// @copyright braveguy 12.10.2016 / 04.09.2017
// @namespace https://greasyfork.org/users/139428
// ==/UserScript==
/**
* Copyright(c) braveguy (Romeo: braveguy / Romeo-Club: RomeoEnhancer)
*
* Änderungen oder die Wiederverwendung von Code von RomeoEnhancer
* erfordern meine ausdrückliche Zustimmung. Es ist nicht gestattet,
* geänderte Versionen von RomeoEnhancer zu veröffentlichen.
*
* Das Skript wurde mit Tampermonkey in aktuellen Versionen von Safari, Chrome
* und Firefox getestet. Dennoch geschieht die Benutzung auf eigenes Risiko.
*
* ** Datenschutz **
* RomeoEnhancer enthält keinerlei Code, um Nutzer zu identifizieren
* oder Daten auszuspähen. Es besteht keinerlei geschäftliches Interesse.
*
* Die aktuelle Version von RomeoEnhancer ist verfügbar unter:
* https://greasyfork.org/scripts/31282-romeoenhancer
*
*
* ****** English version *****
*
* Copyright(c) by braveguy (Romeo: braveguy / Romeo-Club: RomeoEnhancer)
*
* Modifications and/or reuse of RomeoEnhancer code require my explicit consent.
* You are NOT allowed to publish any changed version of RomeoEnhancer!
*
* All code has been tested with Tampermonkey in a recent Safari, Chrome,
* and Firefox browser. However, the use of this script is at your own risk.
*
* ** Privacy **
* RomeoEnhancer does NOT and never will include any code to identify you
* or spy on your data. There is no commercial interest.
*
* The latest version of RomeoEnhancer is available on:
* https://greasyfork.org/scripts/31282-romeoenhancer
*/
// ***** CSS *****
GM_addStyle (
//icons
'a.re-icon {margin-left:0.25em; font-size:0.85em; color:rgba(255,255,255,0.8)}' +
'a:hover.re-icon {color:rgba(102,215,255,0.8)}' +
//separators
'.separator--dark, .gallery__info, .footprint-separator {color:rgba(255,255,255,0.33)}' +
//more big tiles per page
'@media screen and (min-width:60rem){' +
'.search-results--big-tiles.search-results--filter-open .search-results__item, ' +
'.search-results--big-tiles.search-results--stream-open .search-results__item {padding-bottom:33.33333% !important; width:33.33333% !important} }' +
'@media screen and (min-width:80rem){' +
'.search-results--big-tiles.search-results--filter-open .search-results__item, ' +
'.search-results--big-tiles.search-results--stream-open .search-results__item {padding-bottom:25% !important; width:25% !important} }' +
'@media screen and (min-width:100rem){' +
'.search-results--big-tiles.search-results--filter-open .search-results__item, ' +
'.search-results--big-tiles.search-results--stream-open .search-results__item {padding-bottom:20% !important; width:20% !important} }' +
'@media screen and (min-width:120rem){' +
'.search-results--big-tiles.search-results--filter-open .search-results__item, ' +
'.search-results--big-tiles.search-results--stream-open .search-results__item {padding-bottom:16.66666% !important; width:16.66666% !important} }' +
'@media screen and (min-width:140rem){' +
'.search-results--big-tiles.search-results--filter-open .search-results__item, ' +
'.search-results--big-tiles.search-results--stream-open .search-results__item {padding-bottom:12.5% !important; width:12.5% !important} }'
);
// **************************************************************
// ***** The following function is taken from:
// ***** https://gist.github.com/BrockA
// ***** https://gist.github.com/raw/2625891/waitForKeyElements.js
/*--- waitForKeyElements(): A utility function, for Greasemonkey scripts,
that detects and handles AJAXed content.
Usage example:
waitForKeyElements (
"div.comments"
, commentCallbackFunction
);
//--- Page-specific function to do what we want when the node is found.
function commentCallbackFunction (jNode) {
jNode.text ("This comment changed by waitForKeyElements().");
}
IMPORTANT: This function requires your script to have loaded jQuery.
*/
function waitForKeyElements (
selectorTxt, /* Required: The jQuery selector string that
specifies the desired element(s).
*/
actionFunction, /* Required: The code to run when elements are
found. It is passed a jNode to the matched
element.
*/
bWaitOnce, /* Optional: If false, will continue to scan for
new elements even after the first match is
found.
*/
iframeSelector /* Optional: If set, identifies the iframe to
search.
*/
) {
var targetNodes, btargetsFound;
if (typeof iframeSelector == "undefined")
targetNodes = $(selectorTxt);
else
targetNodes = $(iframeSelector).contents ()
.find (selectorTxt);
if (targetNodes && targetNodes.length > 0) {
btargetsFound = true;
/*--- Found target node(s). Go through each and act if they
are new.
*/
targetNodes.each ( function () {
var jThis = $(this);
var alreadyFound = jThis.data ('alreadyFound') || false;
if (!alreadyFound) {
//--- Call the payload function.
var cancelFound = actionFunction (jThis);
if (cancelFound)
btargetsFound = false;
else
jThis.data ('alreadyFound', true);
}
} );
}
else {
btargetsFound = false;
}
//--- Get the timer-control variable for this selector.
var controlObj = waitForKeyElements.controlObj || {};
var controlKey = selectorTxt.replace (/[^\w]/g, "_");
var timeControl = controlObj [controlKey];
//--- Now set or clear the timer as appropriate.
if (btargetsFound && bWaitOnce && timeControl) {
//--- The only condition where we need to clear the timer.
clearInterval (timeControl);
delete controlObj [controlKey];
}
else {
//--- Set a timer, if needed.
if ( ! timeControl) {
timeControl = setInterval ( function () {
waitForKeyElements ( selectorTxt,
actionFunction,
bWaitOnce,
iframeSelector
);
},
300
);
controlObj [controlKey] = timeControl;
}
}
waitForKeyElements.controlObj = controlObj;
}
// ***** end
// **************************************************************
// ***** Insert layer *****
function iframeLoad(iframeId, iframeUrl) {
$('#spotlight-container').append(
'<div id="' + iframeId + '" class="layer layer--spotlight"><div class="js-layer-content layer__container layer__container--spotlight l-fancy">' +
'<div class="js-profile-error"><div><iframe style="border:0;width:928px;height:688px;" src="' + iframeUrl + '"></iframe>' +
'<a class="js-close-spotlight icon icon-large icon-cross layer__closingx l-tappable--big l-hidden-sm"></a>' +
'</div></div></div></div>'
);
}
// ***** Calculate time *****
function timeDiff(loginTime) {
var timeTag = loginTime;
// 1s...59s; 1min...59min; hh:mm; gestern hh:mm; tt.mm.jjjj, hh:mm
return timeTag;
}
// ***** Open last selected contacts instead of favourites *****
function keepContacts (jNode) {
if (window.location.hash.match(/#\/module\/contacts\/\w*$/)) {
localStorage.setItem('contactsSelection', window.location.hash);
}
var contactsPath = localStorage.getItem('contactsSelection');
contactsPath = (contactsPath ? contactsPath : '#/module/contacts/favourites');
$('#contacts-menu, a.contacts__search-close').attr('href', contactsPath);
}
// ***** Display selected bookmark in bookmark icon title, versions in header logo title *****
function bookmarkTitle (jNode) {
var selectedBookmark = $('li.js-bookmarks li.is-selected a').text();
$('li.js-bookmarks').attr('title', selectedBookmark);
$('header.site-header h1').attr('title','PlanetRomeo ' + APP_VERSION + '\rRomeoEnhancer ' + GM_info.script.version);
}
// ***** Add forums and classic to radar navigation bar *****
function forumsLink (jNode) {
$('ul.content-nav__vers-list, ul.search-nav__vers-list').append(
'<li class="ui-navbar__actions-item txt-truncate"><a class="ui-navbar__actions-link" style="cursor:default">|</a></li>' +
'<li class="ui-navbar__actions-item txt-truncate"><a id="re-forums-link" href="/#/profile/-forums" class="js-nav-item js-vers-list-link ui-navbar__actions-link">Foren</a></li>' +
'<li class="ui-navbar__actions-item txt-truncate"><a target="romeoclassic" href="https://classic.planetromeo.com" class="js-nav-item ui-navbar__actions-link">Classic</a></li>'
);
/*$('#re-forums-link').click(function() {
iframeLoad('re-forums','https://classic.planetromeo.com/myuser/?page=club&subPage=forum');
});*/
}
// ***** Add statistics to visitors navigation bar *****
function statisticsLink (jNode) {
$('#visitors ul.ui-navbar__actions').append(
'<li class="ui-navbar__actions-item txt-truncate"><a class="ui-navbar__actions-link" style="cursor:default">|</a></li>' +
'<li class="js-navigation txt-truncate ui-navbar__actions-item"><a href="/#/profile/-statistics" class="ui-navbar__actions-link">Statistik</a></li>'
);
}
// ***** Display classic forums page in a layer *****
function loadForum (jNode) {
var frameW = 'width:' + $('#profile--forums section').width() + 'px;';
var frameH = 'height:' + $('#profile--forums section').height() + 'px;';
$('#profile--forums section').replaceWith(
'<iframe style="border:0;' + frameW + frameH + '" src="https://classic.planetromeo.com/myuser/?page=club&subPage=forum"></iframe>'
);
$('ul.search-nav__vers-list li a[href="/#/profile/-forums"]').parent().removeClass('is-selected');
}
// ***** Display classic statistics page in a layer *****
function loadStatistics (jNode) {
var frameW = 'width:' + $('#profile--statistics section').width() + 'px;';
var frameH = 'height:' + $('#profile--statistics section').height() + 'px;';
$('#profile--statistics section').replaceWith(
'<iframe style="border:0;' + frameW + frameH + '" src="https://classic.planetromeo.com/settings/visitorStatistics.php"></iframe>'
);
$('ul.search-nav__vers-list li a[href="/#/profile/-statistics"]').parent().removeClass('is-selected');
}
// ***** Preview unread messages in title tag *****
function previewMessage (jNode) {
var profileId, jsonParam;
$('#messages span.txt-pill--mini').each(function(){
profileId = $(this).parent().parent().parent().attr('href').match(/\d{3,}/);
$(this).parent().parent().parent().addClass('re-id' + profileId);
var msgCount = parseInt($(this).text());
jsonParam = 'lang=de&length=' + msgCount + '&filter%5Bfolders%5D%5B%5D=RECEIVED&filter%5Bpartner_id%5D=' + profileId;
var msgText = '';
var thisId = '.re-id' + profileId;
$.get('/api/v4/messages?' + jsonParam).done(function (data) {
for (var i = msgCount-1; i >= 0; i--) {
msgText = msgText + '\r' + data.items[i].text+ '\r';
}
$(thisId).attr('title', msgText);
});
});
}
// ***** Show last login and location in message thread *****
function messageLastLogin (jNode) {
var profileId, thisId;
$('#messages div.profile__title').each(function(){
profileId = $(this).find('a').attr('href').match(/\d{3,}/);
thisId = this;
$.get('/api/v4/profiles/' + profileId + '?expand=partner&lang=de').done(function (data) {
if (data.last_login) {
var loginTime = new Date(data.last_login.slice(0,19)).toLocaleString("de-de");
var timeTag = timeDiff(loginTime);
//var timeTag = loginTime;
$(thisId).not(':has(span.icon)').append(
'<span class="icon icon-last-login-hours txt-raise" style="font-size:0.85em" title="Zuletzt online ' + loginTime + '"> ' + timeTag +'</span>'
);
}
var name = '', distance = '', sensor = '';
if (data.location.name) {
name = data.location.name;
}
if (data.location.distance >= 0) {
if (data.location.distance < 1000) {
distance = ' – ' + data.location.distance + 'm';
} else {
distance = data.location.distance.toString();
distance = ' – ' + distance.slice(0, -3) + ',' + distance.slice(-3, -2) + ' km';
}
}
if (data.location.sensor) {
sensor = ' ' + '<span class="icon icon-gps-needle icon-badge"></span>';
}
$(thisId).after(
'<div style="text-align:center" class="typo-small lh-heading txt-truncate">' + name + distance + sensor + '</div>'
);
});
});
}
// ***** Add select all to attach picture list *****
function messageAllPictures (jNode) {
/* //alert('Select');
$('#messages div.js-attachment-region div.ui-navbar').append(
'<span style="text-align:right">Alle</span>'
).click(function() {
$('div.pictures-list div.tile').addClass('tile--selected');
}); */
}
// ***** Add message bubbles to contact list entries *****
function messageContacts (jNode) {
var profileId;
$('#contacts a.js-preview.listitem__body').each(function() {
profileId = $(this).attr('href').match(/\d{3,}/);
$(this).find('span.plain-text-link').not(':has(a)').append(
'<a class="icon icon-chat re-icon" title="Messages" href="/#/module/messages/'+ profileId + '"></a>'
);
});
}
// ***** Add message bubbles to visitor list entries *****
function messageVisitors (jNode) {
var profileId;
$('#visitors a.tile__link, #visitors a.listresult').each(function() {
profileId = $(this).attr('href').match(/\d{3,}/);
$(this).find('div.info').not(':has(a)').append(
'<a class="icon icon-chat re-icon" title="Messages" href="/#/module/messages/' + profileId + '"></a>'
);
$(this).find('span.icon-save-contact').replaceWith(
'<a class="tile__badge icon icon-save-contact" title="Kontakt bearbeiten" href="/#/module/contacts/all/' + profileId + '"</a>'
);
$(this).find('span.icon-block-contact').replaceWith(
'<a class="tile__badge icon icon-block-contact" title="Kontakt bearbeiten" href="/#/module/contacts/blocked/' + profileId + '"</a>'
);
});
}
// ***** Add message bubbles to radar tiles and list entries *****
function messageRadar (jNode) {
var profileId;
$('#profiles a.tile__link, #profiles a.listresult').each(function() {
profileId = $(this).attr('href').match(/\d{3,}/);
$(this).find('div.info, span.info__body').not(':has(a)').append(
'<a class="icon icon-chat re-icon" title="Messages" href="/#/module/messages/' + profileId + '"></a>'
);
$(this).find('span.icon-save-contact').replaceWith(
'<a class="tile__badge icon icon-save-contact" title="Kontakt bearbeiten" href="/#/module/contacts/all/' + profileId + '"</a>'
);
$(this).find('span.icon-block-contact').replaceWith(
'<a class="tile__badge icon icon-block-contact" title="Kontakt bearbeiten" href="/#/module/contacts/blocked/' + profileId + '"</a>'
);
// BMI ...
/* var stats = new Array($(this).find('.stat-bar__item, .list-stat-bar__item').text());
console.info(stats[0]);
/* var bmiPos;
$(this).find('.stat-bar__item, .list-stat-bar__item').each(function(i) {
stats[i] = $(this).text();
console.info(stats[i]);
bmiPos = (stats[i].match(/\d{2,3}kg/)) ? i : 0;
});
console.info(stats[bmiPos], bmiPos);
/* //calcBMI(stats);
var weight = parseInt($(this).find('.stat-bar__item, .list-stat-bar__item').text());
var height = parseInt($(this).find('.stat-bar__item, .list-stat-bar__item').text());
//var weight = parseInt($(this).find('.stat-bar__item, .list-stat-bar__item').text().match(/\d{2,3}kg/));
//var height = parseInt($(this).find('.stat-bar__item, .list-stat-bar__item').text().match(/\d{2,3}cm/));
console.info (height + 'cm, ' + weight + 'kg');
//BMI = calcBMI (height, weight);
BMI = '00';
//$(this).find('stat-bar__item, list-stat-bar__item')[bmiPos].text(weight + 'kg (' + BMI + ')'); */
});
}
// ***** Add message bubbles to Activity Stream entries (online and footprints only) *****
function messageActivity (jNode) {
var bodyLink, profileId;
$('div.stream div.listitem').each(function() {
bodyLink = $(this).find('a.listitem__body').attr('href');
if (bodyLink.search('/module/messages/') == -1) {
profileId = $(this).find('a.tile__link').attr('href').match(/\d{3,}/);
$(this).find('div.layout-item').not(':has(a)').find('span.listitem__text, span.ui-status-description').last().append(
'<a class="icon icon-chat re-icon" title="Messages" href="/#/module/messages/' + profileId + '"></a>'
);
$(this).find('span.listitem__text, span.ui-status-description').attr('style','font-style:italic');
}
});
}
// ***** Add links to profiles: clubs, guestbook, save user *****
function linksProfile (jNode) {
var profileId = $('#spotlight-container div.layer.layer--spotlight').attr('id').match(/\d{3,}/);
var linkClubs = '<a target="_blank" href="https://classic.planetromeo.com/gemeinsam/php/links/index.php?set=' + profileId + '">Clubs</a>';
var linkGuestbook = '<a target="_blank" href="https://classic.planetromeo.com/gemeinsam/php/guestbook/lesen.php?empfaenger=' + profileId + '">Gästebuch</a>';
var linkMarket = '<a target="_blank" href="https://classic.planetromeo.com/market/view.php?userId=' + profileId + '">Anzeigen</a>';
var linkSaveUser = '<a target="_blank" href="https://classic.planetromeo.com/gemeinsam/php/myuser/index.php?partnerId=' + profileId + '">User speichern</a>';
$('section.profile__stats > div').prepend(
'<div style="padding-left:1rem;font-size:0.9em"><br/>Classic: ' + linkClubs + ' | ' + linkGuestbook + ' | ' + linkMarket + ' | ' + linkSaveUser + '</div>'
);
}
// ***** Add links to error page: save profile etc. *****
function linksError (jNode) {
var profileId = $('#spotlight-container div.layer.layer--spotlight').attr('id').match(/\d{3,}/);
var linkClubs = '<a target="_blank" href="https://classic.planetromeo.com/gemeinsam/php/links/index.php?set=' + profileId + '">Clubs</a>';
var linkGuestbook = '<a target="_blank" href="https://classic.planetromeo.com/gemeinsam/php/guestbook/lesen.php?empfaenger=' + profileId + '">Gästebuch</a>';
var linkMarket = '<a target="_blank" href="https://classic.planetromeo.com/market/view.php?userId=' + profileId + '">Anzeigen</a>';
var linkAlbum = '<a target="_blank" href="https://classic.planetromeo.com/auswertung/album/?set=' + profileId + '&user=">Fotoalbum</a>';
var linkSaveUser = '<a target="_blank" href="https://classic.planetromeo.com/gemeinsam/php/myuser/index.php?partnerId=' + profileId + '">Profil speichern</a>';
$('div.profile__container--error').append(
'<div style="font-size:0.9em"><br/>' + linkClubs + ' | ' + linkGuestbook + ' | ' + linkMarket + ' | ' + linkAlbum + ' | ' + linkSaveUser + '</div>'
);
}
// ***** Add links to contact edit page and message thread: save profile etc. *****
function linksContacts (jNode) {
var profileId = $('#spotlight-container div.layer.layer--spotlight').attr('id').match(/\d{3,}/);
var linkClubs = '<a target="_blank" href="https://classic.planetromeo.com/gemeinsam/php/links/index.php?set=' + profileId + '">Clubs</a>';
var linkGuestbook = '<a target="_blank" href="https://classic.planetromeo.com/gemeinsam/php/guestbook/lesen.php?empfaenger=' + profileId + '">Gästebuch</a>';
var linkAlbum = '<a target="_blank" href="https://classic.planetromeo.com/auswertung/album/?set=' + profileId + '&user=">Fotoalbum</a>';
var linkSaveUser = '<a target="_blank" href="https://classic.planetromeo.com/gemeinsam/php/myuser/index.php?partnerId=' + profileId + '">Profil speichern</a>';
$('div.profile__container--error').append(
'<div style="font-size:0.9em"><br/>' + linkClubs + ' | ' + linkGuestbook + ' | ' + linkAlbum + ' | ' + linkSaveUser + '</div>'
);
}
// ***** Insert BMI to profile, big radar tiles, and list view *****
function insertBMI (jNode) {
// ;
}
// ***** Show picture info in slide show *****
function imgInfo (jNode) {
var imgName;
var eq = ($('div.swipe__element').length == 1) ? 0 : 1;
imgName = $('div.swipe__element:eq(' + eq + ') img.picture__image').attr('src');
if (imgName) {
var imgNameTxt = imgName.substr(imgName.lastIndexOf('/')+1, 5) + '...';
$('#swipe div.swipe__header div.js-counter').not(':has(a)').append(
'<a target="_blank" style="color:rgba(255,255,255,0.5); font-size:0.85em" class="ml" href="' + imgName + '">' + imgNameTxt + '</a>'
);
}
}
// ***** Show picture info in picture rating *****
function ratingInfo (jNode) {
var color;
var imgName = $('#picture-rating img.picture-rating__image').attr('src');
var imgNameTxt = imgName.substr(imgName.lastIndexOf('/')+1, 5) + '...';
var imgNameMax = localStorage.getItem('reRatingMax');
imgNameMax = (imgNameMax ? imgNameMax : imgNameTxt);
if (imgNameTxt >= imgNameMax) {
localStorage.setItem('reRatingMax', imgNameTxt);
}
if (parseInt(imgNameTxt,16) + 1 >= parseInt(imgNameMax,16)) {
color = 'rgba(255,255,255,0.5)';
} else {
color = 'rgba(255,0,0,0.8)';
}
$('#picture-rating div.layer-header__title').append(
'<a target="_blank" style="color:' + color + '; font-size:0.85em" class="ml" href="' + imgName + '">' + imgNameTxt + '</a>'
);
}
// ***** Picture Search *****
function pictureSearch (jNode) {
// ;
}
// ***** Relogin after timeout *****
function reLogin (jNode) {
if (document.cookie.match(/PHPSESSID\=/)) {
location.reload();
} else {
location.replace('https://www.planetromeo.com/#/auth/login');
}
}
waitForKeyElements ("#contacts-menu, #trigger-region div div, a.contacts__search-close", keepContacts);
waitForKeyElements ("li.js-bookmarks li.is-selected, header.site-header h1", bookmarkTitle);
waitForKeyElements ("ul.content-nav__vers-list, ul.search-nav__vers-list", forumsLink);
waitForKeyElements ("#visitors ul.ui-navbar__actions", statisticsLink);
waitForKeyElements ("#profile--forums section", loadForum);
waitForKeyElements ("#profile--statistics section", loadStatistics);
waitForKeyElements ("#messages span.txt-pill--mini, #messages div.listitem a.js-preview span.txt-bold--medium", previewMessage); // #messages div.listitem a.js-preview span.txt-bold--medium
waitForKeyElements ("#messages div.profile__title", messageLastLogin);
waitForKeyElements ("#messages div.js-pictures.pictures-list", messageAllPictures);
waitForKeyElements ("#contacts span.plain-text-link", messageContacts);
waitForKeyElements ("#visitors div.tile__info", messageVisitors); // handleVisitors();
waitForKeyElements ("#profiles div.info__username, #profiles a.listresult", messageRadar);
waitForKeyElements ("div.stream a.listitem__body", messageActivity);
waitForKeyElements ("div.is-profile-loaded", linksProfile);
waitForKeyElements ("div.profile__container--error", linksError);
waitForKeyElements ("#swipe div.swipe__element", imgInfo);
waitForKeyElements ("#picture-rating img.picture-rating__image", ratingInfo);
waitForKeyElements ("div.layer--error", reLogin);