// ==UserScript==
// @name RomeoEnhancer
// @version 1.10.21
// @author braveguy (Romeo: braveguy / Gruppe RomeoEnhancer)
// @description Ergänzungen für die Romeo-Website
// @require https://code.jquery.com/jquery-3.6.4.min.js
// @match https://*.romeo.com/*
// @match https://83.98.143.20/*
// @match https://www.hunqz.com/*
// @run-at document-body
// @copyright braveguy 12.10.2016 / 01.04.2023
// @namespace https://greasyfork.org/users/139428
// ==/UserScript==
/**
* Copyright(c) braveguy (Romeo: braveguy / Gruppe 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 / group 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
*/
// ***** Use RE_addStyle instead of GM_addStyle to work with both Gear Browser and Userscripts *****
if (typeof RE_addStyle == 'undefined') {
this.RE_addStyle = (aCss) => {
'use strict';
let head = document.getElementsByTagName('head')[0];
if (head) {
let style = document.createElement('style');
style.setAttribute('type', 'text/css');
style.textContent = aCss;
head.appendChild(style);
return style;
}
return null;
};
}
// ***** CSS *****
//background colors
let color1 = '', color2 = '', color3 = '', color4 = '', color5 = '', color6 = '', color7 = '', color8 = '', color9 = '';
//localStorage.setItem('REcolorScheme', 'retroBlue')
switch (localStorage.getItem('REcolorScheme')) {
case 'sexyDark': // Romeo default - Sexy Dark
break;
case 'lighterGrey': // Lighter Grey
color1 = '#1f1f1f', color2 = '#1f1f1f', color3 = '#000', color4 = '#101010', color5 = '#1a1a1a', color6 = '#f0f0f0', color7 = '#cc2d2d', color8 = '#2a2a2a', color9 = '#2a2a2a';
break;
case 'retroBlue': // Retro Blue
color1 = '#102c54', color2 = '#102c54', color3 = '#000', color4 = '#101010', color5 = '#122646', color6 = '#f0f0f0', color7 = '#f0f0f0', color8 = 'rgba(255,255,255,.08)', color9 = '#30415d';
break;
case 'fineGrey': // RE default - Fine Grey
default:
color1 = '#1a1a1a', color2 = '#171717', color3 = '#000', color4 = '#101010', color5 = '#232323', color6 = '#f0f0f0', color7 = '#cc2d2d', color8 = '#2a2a2a', color9 = '#2a2a2a';
break;
}
RE_addStyle (
//tweak dark design
`html.js body, .js-main-stage, .stream__content, .layer__column--background, .layer__column--detail, #group-preview .layer__container, .profile .below-fold, .profile-section {background-color:${color1} !important}` +
`div.js-wrapper section[class^="Section"], div.js-wrapper div[class^="slider_wrapper-"]:before, div.js-wrapper div[class^="slider_wrapper-"]:after {background-color:${color1} !important}` +
`.content-nav, .content-nav__actions, .ui-navbar--app, .filter-container {background-color:${color2} !important}` +
`.listitem--selected > div {background-color:${color9} !important}` +
`li[class^="stat-bar__item--"] {background-color:${color2}}` +
`.listresult {background-color:${color2}}` +
`.listresult:hover, :is(.js-chat, .js-contacts) .reactView > div:hover {background-color:${color8} !important}` +
`.js-profile-footprints section {background-color:${color8}}` +
`.listresult .list-stat-bar__item, .icon-circular.icon-u {background-color:transparent}` +
`.js-groups .reactView > button {background-color:${color9} !important}` +
`:is(.js-post-edit, .js-post-list, #post, #group-post) textarea {background-color:${color4} !important}` +
`.js-post-edit button[class*="ActionButton"] {background-color:${color1}}` +
`.js-post-edit div[class*="Wrapper-"] {background-color:${color5} !important}` +
`.js-post-list div[class^="Container"], :is(#group-post, #post) :is(.js-post, .js-post div[class^="Container"], div.js-comment) {background-color:${color5} !important}` +
`section.js-main-stage div[class^="Grid-"] div[class*="Wrapper-"], section.js-main-stage div[class^="Grid-"] + div[class^="Wrapper-"] {background-color:${color5} !important}` +
`.messages-list__content, .messages-send {background-color:${color2}!important}` +
`:is(.js-profile-contact, #messenger .js-detail) > div > div, :is(.js-profile-contact, .js-detail) > div > div > div > div:last-child {background-color:${color2}!important}` +
`.messages-send__form-input {background-color:${color3}!important}` +
`:is(.js-groups, .js-main .js-navigation li) svg[class^="Icon__Svg-sc-"] {color:${color7}}` +
`:is(.search-results--list-style > div, .grouped-tiles-list .refreshable) > div:nth-child(odd) .reactView > div {background-color:${color5}}` +
`:is(.search-results--list-style > div, .grouped-tiles-list .refreshable) > div:nth-child(even) .reactView > div {background-color:${color1}}` +
//bigger text in messages, groups, profiles; wrap long links
':is(#messages-list div.reactView, :is(.js-post-list, .js-post, .js-profile-text, .js-description) div[class^="TruncateBlock__Content-"]) > p[class^="BaseText-sc-"],' +
'.profile section.profile__stats details > div > p[class^="BaseText-sc-"],' +
':is(.stream__content, .js-chat, .js-correspondence, .js-contacts, .js-username, .js-groups, .js-actions, #manage, .js-profile-reviews) [class^="BodyText-sc-"],' +
'[class^="ResponsiveBodyText-"] {font-size:.9375rem !important; letter-spacing:normal !important; line-height:1.375 !important; word-break:break-word !important}' +
//icons, links
'a.re-icon {position:relative; top:.1em; font-size:.9em}' +
':is(div.BIG, div.SMALL, div.LIST, .js-contacts) a.re-icon {position:relative; top:0}' +
':is(div.LIST, .js-contacts, .js-username) a.re-icon {font-size:.825em}' +
'a.re-idle, a.re-idle-no-hover, a.re-idle-no-hover:hover {color:inherit !important}' +
':is(a.re-icon:hover, a.re-idle, Xa.re-icon-visitor, Xa.re-icon visited):hover {color:rgba(102,215,255,.8) !important}' +
'a.re-link, a.re-link-no-hover {color:#00bdff}' +
'[class*="hunqz"] a.re-link {color:#fc193c}' +
'a.re-link-idle {color:unset !important}' +
':is(a.re-link, a.re-link-idle, .js-report-icon svg):hover {color:#66d7ff !important}' +
'[class*="hunqz"] :is(a.re-link, a.re-link-idle, a.re-icon, .js-report-icon svg):hover {color:#fd5871 !important}' +
//filter icon, bookmark name
'.re-filter-bookmark-name {position:absolute; right:0}' +
'.is-filter-collapsed .re-filter-bookmark-name {display:none!important}' +
'.is-filter-opened .re-filter-options-text, .is-filter-opened div.js-filter-button svg + span + span:not(.re-filter-bookmark-name) {display:none!important}' +
//expand truncated location names on hover
'.typo-small.txt-truncate:hover {white-space:normal; word-break:break-all}' +
//big tiles
'div.tile--plus span[class^="SpecialText"] {background-color:rgb(38,38,38)}' +
'div.tile p[class^="SpecialText"] {word-break:break-word}' +
'div.tile p[class^="SpecialText"]:hover {white-space:normal}' +
//messenger
'#messenger .message__content--attachment {max-width:80%}' +
'#messenger .message--sent .message__content--attachment {max-width:15rem}' +
'#messenger .message__content a {word-break:break-word}' +
'.message:not(.message--sent) .message__text {background:hsla(0,0%,100%,.125)}' +
'.message__status {color:rgba(255,255,255,.5)!important}' +
':is(.js-chat, #manage) div[class^="OnlineStatus"] > div > svg {height:13px; width:13px}' +
':is(.js-chat, #manage) div[class^="OnlineStatus"] > div > svg[viewBox="0 0 10 12"] {height:15px; width:15px}' +
'p[class*="OnlineStatus__TimeString"] {line-height:1}' +
'.js-chat .js-scrollable {max-height:1270px !important}' +
'.js-chat .typo-headline-small {font-size:inherit}' +
'.fQIYNa {font-weight:550}' +
'.online-favourites__item {margin:0 .475rem !important}' +
'.online-favourites__itemName {width:4rem; margin:0 -.125rem}' +
'section.emoji-mart button.emoji-mart-anchor:hover {color:rgba(255,255,255,.5)}' +
'.js-chat p[class^="BodyText-sc-"] {opacity:.87; column-gap:.25rem}' +
'.js-chat a[href^="/messenger"] > div > span {opacity:.87}' +
'.js-chat a > span > span svg[viewBox="0 0 9 7"] {height:9px; width:11px; opacity:.66}' +
'.js-chat a > span > span svg[viewBox="0 0 12 12"] {height:15px; width:15px}' +
'#messenger .js-header-region > div > div {padding-top:1.25rem}' +
'#messenger .js-header-region .reactView > div > div > :is(div, a) {position:absolute; top:-1.2rem}' +
'#messenger .re-login-location {position:absolute; top:0; width:100%}' +
'#messenger .re-login-location > div {position:absolute; font-size:.75rem; font-weight:500; opacity:.8; background-color:transparent}' +
'#messenger .re-msg-location {top:0; width:100%; padding:.25rem 0 0 3rem}' +
'#messenger .re-msg-location a {padding-top:3px}' +
'#messenger .re-msg-login {top:2.7rem; left:4rem; line-height:.85rem; min-width:10rem; padding-left:3rem; margin-right:5rem}' +
'#messenger .re-msg-offline {top:2.7rem; left:3rem; line-height:.85rem}' +
'.messages-send__form textarea.input--chat {padding-right:.5rem}' +
':is(.js-correspondence .js-header-region, #manage) div[class*="ContextMenu__"] ul {width:15.25rem; max-width:15.25rem !important}' +
'.js-contacts div > div > button > svg {height:21px; width:21px}' +
'ul[class^="TagCloud__UnstyledList"] button {font-size:.875rem; line-height:1.25}' +
':is(.js-detail, .js-profile-contact) p[class^="ResponsiveBodyText-"] + :is(span, p) {font-size:.875rem !important; padding-bottom:.25rem}' +
//stream
'div.stream__content div.tile div[class^="OnlineStatus"] {position:absolute; left:-8px; top:-8px}' +
'div.stream__content div.tile div[class^="OnlineStatus"] > div {display:flex; align-items:center; justify-content:center; background-color:#1f1f1f; border-radius:50%; height:19px; width:19px; margin-top:0!important}' +
'div.stream__content div.tile div[class^="OnlineStatus"] svg {height:12px; width:12px}' +
'div.stream__content div.tile div[class^="OnlineStatus"] svg[viewBox="0 0 10 12"] {height:13px; width:13px}' +
'.listitem .emoji:hover {font-size:1.5rem; line-height:1.33rem; margin-left:-.4rem; position:relative; right:-.2rem; padding-bottom:.33rem}' +
//profile stats, separators, icons
'.profile__info p {word-break:break-word}' +
'.profile div[aria-label] > div[role="figure"] {border-color:rgba(255,255,255,0.33)}' +
'.profile .re-profile-stats {font-size:.825rem; color:rgba(255,255,255,0.6)}' +
'.re-img-count {position:absolute; bottom:.5rem; left:.5rem; display:flex; align-items:center; justify-items:center}' +
'.re-img-count div {color:rgba(255,255,255,.87); background-color:rgb(18,18,18); border-radius:.125rem; padding:0 .25rem; height:1.125rem; line-height:1rem}' +
'.profile__image-strip .re-img-count {margin-left:.5rem}' +
'.js-profile-footprints > div > .reactView > div > div {padding-top:7.5rem}' +
'.js-profile-footprints > div > .reactView > div > section + div {padding-top:0}' +
'.js-profile-footprints.re-zoom .reactView > div > div {grid-template-columns:repeat(3,33%)}' +
'.js-profile-footprints.re-zoom .reactView > div > div button {background-size:72px 72px; height:77px; width:72px; border-bottom-width:5px}' +
'.js-profile-footprints.re-zoom .reactView > div > div label p {max-width:14ch}' +
//slideshow
'div.swiper-wrapper {margin-top:2rem}' +
'#metadata-bar > div > div > a {margin-left:0}' +
'#metadata-bar > div > div a + p > a {margin-left:.33em}' +
'#metadata-bar > div:first-child > div + p {margin:0 0 .5rem 0; font-size:.8125rem !important; color:rgba(255,255,255,.66); text-transform:uppercase}' +
'#metadata-bar > div:first-child > div:first-child + p[class^="SpecialText"] {text-transform:none}' +
'#metadata-bar > div > div > p[class^="ResponsiveBodyText"] {font-size:.875rem !important}' +
'#metadata-bar > div > div:nth-last-child(-n+2) {flex-direction:row}' +
'#metadata-bar > div > div:nth-last-child(-n+2) button > svg + p {display:none}' +
'#metadata-bar > div > div:nth-last-child(-n+2) > button {margin:0 .25rem .25rem 0; order:2}' +
'#metadata-bar > div > div:nth-last-child(-n+2) > p {margin:.25rem 0; order:3}' +
'#metadata-bar > div > div:last-child {margin-bottom:.25rem}' +
'#metadata-bar > div > div:last-child > p {color:rgb(255,255,255,.66)}' +
//group tiles
'div[class*="Tile__BaseTile-"] > p + div {position:absolute; bottom:2rem; left:.475rem}' +
'div[class*="Tile__BaseTile-"] > p + div > p {background-color:#121212 !important}' +
'div[class*="Tile__BaseTile-"] > p {margin:0 0 -.125rem}' +
'.profile div[class*="Tile__BaseTile-"] > p {margin:0; font-size:.925rem}' +
'.re-common-group p:last-child {color:#6ddc00}' +
//groups
'div.Container--3h4tt div.js-groups > div.pt- {display:none}' +
'.js-date .reactView span {font-size:.85em}' +
'.js-post-list button[class*="ShowMoreButton"].is-hidden {display:block!important}' +
'.js-post-list p[class^="BaseText"] > button {margin-top:.25rem}' +
'div[class^="CommentsArea"] div[class^="TruncateBlock__Content"] {-webkit-line-clamp:unset}' +
'div[class^="CommentsArea"] div[class^="TruncateBlock__Container"] p button {display:none}' +
'.js-main .js-sidebar {max-height:inherit !important}' +
'.js-main .js-sidebar .js-groups {padding-bottom:1rem}' +
//groups list
'span.re-posts-view {font-family: "Gibson Bold"; font-weight:500; text-transform:uppercase; background-color:transparent; color:#fff; height:auto; cursor:pointer; padding-left:2rem;}' +
'span.re-list-head, span.re-list-view, span.re-list-load {font-family:Inter,Helvetica,Arial,"Open Sans",sans-serif; text-transform:uppercase; user-select:none; color:rgb(255,255,255,.5); height:auto}' +
'span.re-list-view, span.re-list-load {font-family: "Gibson Bold"; font-weight:500; color:rgb(250,250,250); cursor:pointer;}' +
'span.re-list-load:before {display:inline-block; transform:scaleX(-1)}' +
'.re-groups-listitem {font-family:Inter,Helvetica,Arial,"Open Sans",sans-serif; display:flex; align-items:center; border:0; border-radius:.25em; padding:.5em; width:100%}' +
`.re-groups-listitem:hover {background-color:${color8}}` +
'.re-groups-tile {display:flex; flex-shrink:0; margin-right:1em; background-size:cover; border-radius:50%; height:3em; width:3em}' +
'.re-groups-entry {flex-grow:1; flex-shrink:1; min-width:0; display:flex; align-items:center}' +
'.re-groups-text {font-size:1em; font-weight:500; line-height:1.375em; word-break:break-word; margin-right:.25em; display:block; overflow:hidden}' +
'.re-groups-name {font-size:.9375rem; color:rgb(0,163,228); font-weight:500; display:inline-block; overflow:hidden; text-overflow:ellipsis; word-wrap:normal}' +
'.re-groups-time {font-size:.825em; color:rgba(250,250,250,.625)}' +
'.re-groups-admin {display:flex; align-items:center; color:rgb(0,0,0,.8); background-color:rgb(0,189,255); padding:0 .25rem; border-radius:.25rem; font-size:0.625rem}' +
'.re-groups-new {display:flex; align-items:center; color:rgb(250,250,250,.8); font-size:0.8em}' +
'.re-groups-new svg {display:inline-block; height:1em; width:1.125em; vertical-align:middle}' +
'.re-groups-new svg path {fill:currentcolor}' +
'.re-groups-selected .re-groups-name {color:rgba(255,255,255,.925)}' +
'.re-groups-selected .re-groups-new {color:rgba(250,250,250,.425)}' +
'.re-groups-selected .re-groups-admin {background-color:rgba(255,255,255,.87)}' +
'.re-groups-visited :is(.re-groups-name, .re-groups-new) {color:rgba(250,250,250,.425)}' +
'.re-groups-visited .re-groups-time {color:rgba(250,250,250,.375)}' +
'.re-groups-visited .re-groups-admin {background-color:rgba(250,250,250,.425)}' +
//travel
'.re-member-travel, .re-radar-travel, .re-edit-travel {color:#00bdff; text-transform:initial; line-height:inherit !important; cursor:pointer}' +
'.re-member-travel:hover, .re-radar-travel:hover, .re-edit-travel:hover {color:#66d7ff}' +
'.re-member-travel.re-selected, .re-radar-travel.re-selected {color:#fff}' +
//visitor icons
'a.re-icon-visitor, a.re-icon-visited {font-size:1.1em; color:#fff}' +
'a.re-icon-visitor:before, a.re-icon-visited:before {position:relative; top:1px}' +
'a.re-icon-visited:before {transform:scaleX(-1)}' +
//picture rating
'.re-rating-date {position:absolute; top:2.5rem; font-size:.85em; cursor:default}' +
//more big tiles per page
'@media screen and (min-width:55rem) {' +
'.search-results--big-tiles .search-results__item {padding-bottom:25% !important; width:25% !important}' +
':is(.is-filter-opened, .is-stream-opened) .search-results--big-tiles .search-results__item {padding-bottom:33.33333% !important; width:33.33333% !important}' +
'.is-stream-opened .is-filter-opened div.search-results--big-tiles div.search-results__item {padding-bottom:50% !important; width:50% !important} }' +
'@media screen and (min-width:75rem) {' +
'.search-results--big-tiles .search-results__item {padding-bottom:20% !important; width:20% !important}' +
':is(.is-filter-opened, .is-stream-opened) .search-results--big-tiles .search-results__item {padding-bottom:25% !important; width:25% !important}' +
'.is-stream-opened .is-filter-opened div.search-results--big-tiles div.search-results__item {padding-bottom:33.33333% !important; width:33.33333% !important} }' +
'@media screen and (min-width:95rem) {' +
'.search-results--big-tiles .search-results__item {padding-bottom:16.66666% !important; width:16.66666% !important}' +
':is(.is-filter-opened, .is-stream-opened) .search-results--big-tiles .search-results__item {padding-bottom:20% !important; width:20% !important}' +
'.is-stream-opened .is-filter-opened div.search-results--big-tiles div.search-results__item {padding-bottom:25% !important; width:25% !important} }' +
'@media screen and (min-width:120rem) {' +
'.search-results--big-tiles .search-results__item {padding-bottom:12.5% !important; width:12.5% !important}' +
':is(.is-filter-opened, .is-stream-opened) .search-results--big-tiles .search-results__item {padding-bottom:16.66666% !important; width:16.66666% !important}' +
'.is-stream-opened .is-filter-opened div.search-results--big-tiles div.search-results__item {padding-bottom:20% !important; width:20% !important} }' +
'@media screen and (min-width:140rem) {' +
'.search-results--big-tiles .search-results__item {padding-bottom:12.5% !important; width:12.5% !important}' +
':is(.is-filter-opened, .is-stream-opened) .search-results--big-tiles .search-results__item {padding-bottom:12.5% !important; width:12.5% !important}' +
'.is-stream-opened .is-filter-opened div.search-results--big-tiles div.search-results__item {padding-bottom:16.66666% !important; width:16.66666% !important} }' +
//*** DESKTOP ***
'@media screen and (min-width:768px) {' +
//general
'.re-mobi {display:none!important}' +
'.re-touch {visibility:hidden!important}' +
'}' +
//*** DESKTOP >= 1024px ***
'@media screen and (min-width: 1024px) {' +
//stream
'.stream {width:18.5rem!important}'+
'}' +
//*** MOBILE ***
'@media screen and (max-width:767px) {' +
//general
'.re-desk {display:none!important}' +
'.re-touch {visibility:hidden!important}' +
//tweak dark design
`.ui-navbar--app, .ui-navbar.content-nav ul {background-color:#000 !important}` +
'div.content-nav--animated {height:3rem}' +
//main menu
'header.js-header {height:4rem; padding-bottom:.25rem}' +
'.layer--nav-primary {bottom:4rem}' +
//stream
'div.stream__content {top:3.75rem}' +
//messages
'#messenger .js-header-region > div > div {padding-top:1.75rem}' +
'#messenger .re-msg-location {padding-top:.75rem}' +
'#messenger .re-msg-login {top:3.2rem}' +
'#messenger .re-msg-offline {top:3.2rem}' +
'.messages-send__form textarea.input--chat {font-size:.9375rem; letter-spacing:normal}' +
//group tiles
'div[class*="Tile__BaseTile-"] > p {margin:0; font-size:.925rem}' +
//slideshow
'div.swiper-wrapper {height:96%; margin-top:0}' +
'#metadata-bar:not(.gtvwGw) {background:linear-gradient(transparent,rgba(0,0,0,.4) 2.5rem,rgba(0,0,0,.8))}' +
'#metadata-bar:not(.gtvwGw) {backdrop-filter:blur(0px); -webkit-backdrop-filter:blur(0px)}' +
'#metadata-bar:not(.gtvwGw) > div > div {margin:0 0 .25rem 0}' +
'#metadata-bar:not(.gtvwGw) > div:first-child > div:first-child {margin-bottom:0}' +
'#metadata-bar:not(.gtvwGw) > div:first-child > div + p {margin-bottom:0}' +
'#metadata-bar:not(.gtvwGw) > div > div:nth-last-child(-n+2) > button {margin-bottom:0}' +
'#metadata-bar:not(.gtvwGw) > div > div:last-child {margin-bottom:0}' +
'aside .media-viewer-footer {height:2rem; padding-bottom:.5rem}' +
'aside .media-viewer-footer p {padding-bottom:.5rem}' +
//picture rating
'.re-rating-date {top:3rem}' +
//back arrow in group post
'#group-post .js-post button.js-back {margin:1rem 1rem 0 -.5rem}' +
'}' +
//*** TOUCH SCREEN ***
'@media screen and (hover:none) {' +
//general
'.re-touch {visibility:visible!important}' +
//icons, links
'a.re-icon {padding:.25em 0 .25rem .5em; font-size:1em}' +
'div.stream__content a.re-icon {padding:.25em .5em .25em 0}' +
//'a[class*="Tabbed-nav-link"] span {padding:0 .5em}' +
'}'
);
// ***** Clean up old settings *****
localStorage.removeItem('contactsSelection');
localStorage.removeItem('REgroupPostsView');
localStorage.removeItem('reRatingMax');
// ***** Test for mobile or touch device *****
// usage: if (mobile.matches) ...; if (touch.matches) ...
var mobile = window.matchMedia("(max-width:767px)");
var touch = window.matchMedia("(hover:none)");
// **************************************************************
// ***** 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];
var timerInterval = (document.visibilityState === "visible" ? 500 : 1500);
//--- 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
);
},
timerInterval
);
controlObj [controlKey] = timeControl;
}
}
waitForKeyElements.controlObj = controlObj;
}
// ***** end
// **************************************************************
// ***** Set AJAX headers *****
var key0 = window.atob('WC1TZXNzaW9uLUlk');
var key1 = window.atob('WC1BcGktS2V5');
var val1 = window.atob('OEpOdlBiVjNJOUtMaU5xUFNxc2NOVFllZzd1aXd2TUk=');
function ajaxHead(){
return {[key0]: JSON.parse(localStorage.getItem('PR_SETTINGS:SESSION_ID')), [key1]: val1};
}
// ***** Replace URLs with links *****
// ***** Adopted from https://stackoverflow.com/questions/37684/how-to-replace-plain-urls-with-links/37687#37687 *****
function linkify(text) {
//Email addresses
var pattern1 = /(^|\s|<br>)(([-\w\.\+])+@[-\w]+?(\.[A-Z]{2,6})+)/gim;
text = text.replace(pattern1, '$1<a href="mailto:$2" class="plain-text-link">$2</a>');
//URLs starting with http:// or https://
var pattern2 = /(^|\s|<br>)(https?:\/\/[-\w+&@#\/\(\)%?=~|!:,.;]*[-\w+&@#\/\(\)%=~|])/gim;
text = text.replace(pattern2, '$1<a target="_blank" href="$2" rel="noreferrer noopener" class="plain-text-link">$2</a>');
//URLs without http:// or https://
var pattern3 = /(^|\s|<br>)([-\w]+\.[a-z][-\w+&#\/\(\)%?=~|!:,.;]*[-\w+&#\/\(\)%=~|])/gm;
text = text.replace(pattern3, '$1<a target="_blank" href="http://$2" rel="noreferrer noopener" class="plain-text-link re-link-idle">$2</a>');
//keep internal links in same window
var pattern4 = /(target="_blank" )(href="https?:\/\/(www\.)?((planet)?romeo|hunqz)\.com)/gim;
text = text.replace(pattern4, '$2');
return text;
}
// ***** Format date/time *****
function dateTime(timeStamp, dateOnly) {
// 1s...59s; 1min...59min; hh:mm; gestern hh:mm; tt.mm.jjjj, hh:mm
var timeNow = new Date();
var timeNow1 = new Date (timeNow - 1000*60*60*24);
var timeTag = "";
if (timeStamp) {
if (timeNow.toLocaleDateString() == timeStamp.toLocaleDateString()) {
timeTag = /*'heute ' + */timeStamp.toLocaleTimeString('de-DE').slice(0,-3);
} else if (timeNow1.toLocaleDateString() == timeStamp.toLocaleDateString()) {
timeTag = 'gestern ' + timeStamp.toLocaleTimeString('de-DE').slice(0,-3);
} else {
timeTag = dateOnly ? timeStamp.toLocaleDateString('de-DE') : timeStamp.toLocaleString('de-DE').slice(0,-3);
}
}
return timeTag;
}
// ***** Change URL without reloading the page *****
function changeUrl(url) {
history.pushState({}, document.title, url);
history.pushState({}, document.title, url);
history.back();
}
// ***** Add title and aria-label
jQuery.fn.titleLabel = function(text) {
return $(this).attr({'title': text, 'aria-label': text});
};
// ***** Open message thread or contact info by profile name *****
// (not working for blocked, blocking, or deactivated profiles)
function openByName(baseUrl, profileLink, profileName) {
var profileType = 'profiles';
if (profileLink.match(/^\/hunq\//)) {
profileType = 'hunqz/profiles';
/*} else if (profileLink.match(/^\/groups?\//)) {
profileType = 'groups';*/
}
$.ajax({url: `/api/v4/${profileType}?pick=items.*.(id,name)&lang=de&length=1&filter[fulltext_search_mode]=EXACT&filter[fulltext]=@${profileName}`,
headers: ajaxHead()
})
.done(function (data) {
if (data.items[0] && data.items[0].name == profileName) {
changeUrl(baseUrl + data.items[0].id);
/* } else {
$.ajax({headers: ajaxHead(), url: `/api/v4/${profileType}/${profileName}/full?lang=de&lookup_type=NAME`})
.done(function (data) {
if (data.id) {
changeUrl(baseUrl + data.id);
}
}); */
}
});
}
// ***** Hide visit *****
function hideVisit(profileId) {
if (profileId > 0) {
$.ajax({url: `/api/v4/visits/${profileId}`,
headers: ajaxHead(),
method: 'DELETE'
})
.done(function () {
$('div.profile-topnav__hide').attr('style', 'visibility:hidden');
$('.profile .top-info-header button').attr('style', 'color:rgb(168,168,168)');
})
}
}
// ***** Search profile id, open profile name directly *****
function searchInput(jNode) {
$('#search a.re-add').off('click').remove();
$(jNode).on('input click', function() {
var inputValue = $(jNode).val();
$('#search a.re-add').off('click').remove();
if (inputValue.match(/^[1-9]\d{2,}$/)) {
$('#search div.js-input').after(
`<a style="font-size:1rem" class="re-add re-link-no-hover mr-"><span class="re-desk">Profil-ID ${inputValue} anzeigen</span><span class="re-mobi">ID anzeigen</span></a>`
).next('.re-add').click(function() {
openById(inputValue);
return false;
});
} else if (inputValue.match(/^@?[-\w\/]{3,}$/)) {
inputValue = inputValue.replace(/^@/, '');
$('#search div.js-input').after(
`<a style="font-size:1rem" class="re-add re-link-no-hover mr-"><span>${inputValue}</span><span class="re-desk"> anzeigen</span></a>`
).next('.re-add').click(function() {
changeUrl(((inputValue.match(/^\//)) ? '' : '/profile/') + inputValue);
return false;
});
}
});
}
// ***** Open profile by ID *****
function openById(id) {
$.ajax({headers: ajaxHead(), url: `/api/v4/profiles/${id}?expand=partner&lang=de`})
.done(function (data) {
var type = (data.type) ? data.type : '';
var name = (data.name) ? data.name : '';
var profileType = 'profile';
if (type == 'ESCORT') {
profileType = 'hunq';
} else if (type == 'CLUB') {
profileType = 'group';
}
changeUrl(`/${profileType}/${name}`);
})
.fail(function (data) {
changeUrl('/profile/-');
});
}
// ***** Picture upload month/year *****
//init
const imgTable = [
0x00000000,0x00000000,0x000076f1,0x0000c0c2,0x000113ac,0x000193c7,0x00022adb,0x0002e59b,0x0003c274,0x0004bdda,0x0005cb8f,0x0006f792, //2003
0x00083008,0x0009e166,0x000bc399,0x000dc70d,0x000fcad1,0x001219f5,0x0014e794,0x00180a61,0x001b7a83,0x001eeaaa,0x0022a968,0x0026aaf2, //2004
0x002b6a0f,0x00313036,0x003679aa,0x003c4cb5,0x00421898,0x00489583,0x004f0bb9,0x00563896,0x005d5196,0x0064262d,0x006bc70e,0x0072db1e, //2005
0x007a330c,0x0082713d,0x0089c239,0x00920965,0x009ae25a,0x00a3fcc4,0x00ad0e2a,0x00b72f32,0x00c1ea95,0x00cb8a91,0x00d5b890,0x00df6c5b, //2006
0x00e8fe6b,0x00f428d3,0x00fe1be4,0x0108f04e,0x01140217,0x011feaa7,0x012b87a5,0x0137a5e8,0x014368b3,0x014eaa9b,0x015ae9ab,0x01666521, //2007
0x01721afe,0x017ed9a3,0x018a8ee3,0x0197cf93,0x01a3f625,0x01b1bb65,0x01bf47e7,0x01ce39de,0x01dd1952,0x01eb6283,0x01fa1c2d,0x02086e83, //2008
0x0216d64c,0x0226d437,0x0234d31f,0x02552e25,0x02677e9a,0x027aa2a8,0x028da180,0x02a15073,0x02b5f39d,0x02c9b434,0x02ddb5e1,0x02f0ec81, //2009
0x0304f1c0,0x031b489e,0x032e68b1,0x0342c8c2,0x0356cc1f,0x036cb607,0x0381b40b,0x03985a47,0x03b09c6d,0x03c679e3,0x03dd7e4e,0x03f43921, //2010
0x040ae598,0x0423e5d2,0x0439c138,0x0452752e,0x046b27d1,0x0485592a,0x04a0708c,0x04bcc54e,0x04d9b67e,0x04f52906,0x0511f368,0x052df05c, //2011
0x054a0109,0x0568a266,0x0584d23a,0x05a25176,0x05c0b77b,0x05df7ee8,0x05fe3605,0x061e623c,0x063f4240,0x065e2c95,0x067e22b7,0x069dbc58, //2012
0x06c0304b,0x06e63a8a,0x0707d372,0x072df9eb,0x0751ca91,0x077860fb,0x079beac9,0x07c1e771,0x07e86b65,0x080da891,0x08320879,0x08558ed7, //2013
0x087b78bc,0x08a21c54,0x08c4f3e4,0x08eac68d,0x0911be41,0x093996ac,0x0960c869,0x098a963b,0x09b76f87,0x09e0140c,0x0a0906c0,0x0a305fc4, //2014
0x0a80e9b2,0x0adaf553,0x0b2947ce,0x0b7d3b5d,0x0bcf0d62,0x0c24958c,0x0c75591b,0x0ccd3588,0x0d23c304,0x0d7376dc,0x0dc57294,0x0e140406, //2015
0x0e65db5f,0x0ebe6747,0x0f0cd756,0x0f607f08,0x0fb3657b,0x100b35e6,0x105e79ed,0x10b8bbbf,0x1115caaf,0x116ae5ac,0x11becc5e,0x121244b8, //2016
0x1267dfa9,0x12c46bf9,0x1315847b,0x136e2e9c,0x13c5fdbd,0x141f4e2c,0x147b0f3e,0x14ddb2a5,0x154194f4,0x159e4a36,0x1601ff5c,0x16657d11, //2017
0x16cb7cc6,0x1734ec50,0x1792a1d7,0x17fa28e5,0x185ec78c,0x18c99f6f,0x193230d2,0x19a225bd,0x1a12bd1e,0x1a797ec2,0x1ae1e760,0x1b4790fd, //2018
0x1bb4f607,0x1c23ce64,0x1c84c7c3,0x1cf2f6a5,0x1d61d7f8,0x1ddb56d8,0x1e596a40,0x1ededcb1,0x1f66d255,0x1fe26a91,0x205eca2e,0x20d26c98, //2019
0x21484431,0x21c24ba6,0x2230d2f9,0x22a6cd0e,0x2312ebbd,0x23844c83,0x23f45e42,0x246d38c1,0x24eb9338,0x255dccee,0x25d30c82,0x264389a4, //2020
0x26b9cb56,0x2730f2c2,0x279824a7,0x28072e59,0x2870c5b3,0x28e20cee,0x294ea8bd,0x29bdfadb,0x2a2f2276,0x2a987389,0x2b029033,0x2b665594, //2021
0x2bcd3a33,0x2c3819a2,0x2c95c80f,0x2cf681ad,0x2d57afa7,0x2dc0e36e,0x2e283430,0x2e94df63,0x2f016036,0x2f63046c,0x2fc3e761,0x301fadc3, //2022
0x307f54f1,0x30e47a38,0x313b627e,0x319cf8c7,0x31fb89b9,0x325d41a2,0x32bbd294,0x331d8a7d,0x337f4265,0x33ddd357,0x343facdf,0x349e3dd1, //2023
0x34fff5ba,0x3561ada3,0x35bd179e,0x361eade7,0x367d3ed8,0x36def6c1,0x373d87b3,0x379f3f9c,0x3800f785,0x385f8876,0x38c161ff,0x391ff2f0, //2024
0xffffffff];
function uploadDate(imgName) {
const monthYearIndex = (element) => element >= parseInt(imgName, 16);
let index = imgTable.findIndex(monthYearIndex) - 1;
let year = 2003 + Math.trunc(index / 12);
let month = 1 + index % 12;
if (imgTable[index] == 0x00000000) {
return '';
} else {
return `≈ ${month}.${year}${imgTable[index + 1] == 0xffffffff ? '+' : ''}`;
}
}
// ***** Copy message thread to clipboard *****
function copyMessageThread(profileId, profileName) {
var loadTime = new Date().toLocaleString('de-DE').slice(0,-3);
var msgCount = '', header = '', msgThread = '', msgTime = '', name = '';
var ownName = $('img.avatar__image').attr('alt');
var jsonParam = `lang=de&length=10000&filter[folders][]=SENT&filter[folders][]=RECEIVED&filter[partner_id]=${profileId}`;
$.ajax({headers: ajaxHead(), url: `/api/v4/messages?${jsonParam}`})
.done(function (data) {
//gather data
if (data.items_total) {
msgCount = data.items_total;
header = 'Message-Verlauf von ' + ownName + ' mit ' + profileName + ' (Profil-ID ' + profileId + ') vom ' + loadTime + '\n\n\n';
for (var i = msgCount-1; i >= 0; i--) {
msgTime = new Date(data.items[i].date.slice(0,-5)+'.000Z');
name = (data.items[i].folder == 'SENT') ? ownName : profileName;
msgThread += msgCount-i + '. ' + name + ' • ' + msgTime.toLocaleString('de-DE').slice(0,-3);
msgThread += (data.items[i].unread == true) ? ' [ungelesen]' : '';
msgThread += (data.items[i].locked == true) ? ' [gespeichert]' : '';
msgThread += (data.items[i].spam == true) ? ' [Spam]' : '';
msgThread += '\n-------------------------------------------------------------------';
msgThread += '\n' + data.items[i].text.trim() + '\n\n\n';
//handle links
if (data.items[i].attachments) {
for (var item of data.items[i].attachments) {
if (item.type == 'COMMAND') {
msgThread += `[${item.index + 1}] ${item.params?.url?.match(/^\//) ? 'https://www.romeo.com' : ''}${item.params?.url}\n`;
msgThread = msgThread.replace(`[[${item.index}]]`, `${item.params?.text} [${item.index + 1}]`);
}
}
msgThread += '\n\n'
}
}
msgThread += '\n====================\n\n';
}
//confirm copy
$('div.js-correspondence').after(
`<div class="re-bubble layout layout--h-center">
<div class="ui-bubble ui-bubble--dark" style="width:auto; top:72px">
<div class="ui-bubble__content [ js-content ] [ js-scrollable ] scrollable">
<div class="confirm-box">
<div class="txt-right" style="margin:-.5rem -.5rem -.75rem">
<a class="re-copy-cancel re-link icon icon-larger icon-cross"></a>
</div>
<div class="confirm-box__label" style="margin-bottom:1.125rem">
<p>Message-Verlauf kopieren</p>
</div>
<div class="confirm-box__actions">
<button class="re-copy-email ui-button ui-button--transparent">E-Mail-Entwurf</button>
<button class="re-copy-confirm ui-button ui-button--primary">Zwischenablage</button>
</div>
</div>
</div>
</div>
</div>
<div class="layer ui-bubble__overlay l-fancy"></div>`
);
$('button.re-copy-confirm').focus().click(function() {
copyToClipboard(header + msgThread);
$('div.re-bubble, div.ui-bubble__overlay').hide();
});
$('button.re-copy-email').click(function() {
location.href = `mailto:?subject=${encodeURIComponent(header)}&body=${encodeURIComponent(msgThread)}`;
$('div.re-bubble, div.ui-bubble__overlay').hide();
});
$('a.re-copy-cancel, div.ui-bubble__overlay').click(function() {
$('div.re-bubble, div.ui-bubble__overlay').hide();
});
});
}
// ***** copy data to clipboard *****
const copyToClipboard = msgThread => {
const el = document.createElement('textarea');
el.value = msgThread;
el.setAttribute('readonly', '');
el.style.position = 'absolute';
el.style.left = '-9999px';
document.body.appendChild(el);
const selected =
document.getSelection().rangeCount > 0
? document.getSelection().getRangeAt(0)
: false;
el.select();
document.execCommand('copy');
document.body.removeChild(el);
if (selected) {
document.getSelection().removeAllRanges();
document.getSelection().addRange(selected);
}
}
// ***** Fix scrolling on larger screens for messages list *****
function fixScroll (jNode) {
$(jNode).parents('.js-chat .js-scrollable').attr('style', 'max-height:inherit !important');
}
// ***** Add double tap to menu items, change behavior for mobile *****
function menuLinks (jNode) {
$(jNode).has('#radar-menu').off('dblclick').dblclick(function() { changeUrl('/search/romeos'); });
$(jNode).has('#visitors-menu').off('dblclick').dblclick(function() { changeUrl('/visitors/me'); });
$(jNode).has('#messages-menu').off('dblclick').dblclick(function() { changeUrl('/messenger/contacts'); });
$(jNode).has('[href="/me"]').off('dblclick').dblclick(function() { changeUrl('/stream'); });
if (mobile.matches) {
$(jNode).has('#groups-menu').off('click').click(function() { changeUrl('/groups/member'); return false; });
}
}
// ***** Add contacts etc. to navigation bar *****
function navLinks (jNode) {
//icons on radar and eyecandy
if (!mobile.matches) {
$('main nav.js-navigation ul').has('a[href^="/radar/"], a[href^="/eyecandy/"]').not(':has(li.re-add > span)').append(
'<li class="Tabbed-nav-item--2iOWw re-add"><span class="re-add re-radar-travel icon icon-airplane" title="Travel"><span></span></span></li>'
);
$('main nav.js-navigation ul').has('a[href^="/radar/"], a[href^="/eyecandy/"]').not(':has(li.re-add > a)').append(
'<li class="Tabbed-nav-item--2iOWw re-add"><a style="cursor:default">|</a></li>' +
'<li class="Tabbed-nav-item--2iOWw re-add"><a href="/messenger/contacts" class="js-nav-item Tabbed-nav-link--xyQY6" title="Kontakte"><span class="icon icon-save-contact"></span></a></li>' +
'<li class="Tabbed-nav-item--2iOWw re-add"><a href="/groups/member" class="js-nav-item Tabbed-nav-link--xyQY6" title="Meine Gruppen"><span class="icon icon-group-members"></span></a></li>'
);
} else {
$('main nav.js-navigation ul').has('a[href^="/radar/"], a[href^="/eyecandy/"]').not(':has(li.re-add)').prepend(
'<li class="Tabbed-nav-item--2iOWw re-add"><span class="re-add re-radar-travel icon icon-airplane" title="Travel"><span></span></span></li>'
);
}
//travel
if ($('main nav.js-navigation ul').has('a[href^="/radar/"], a[href^="/eyecandy/"]')) {
var viewMode = localStorage.getItem('REradarTravelLocation');
var toggleTravel = 'span.re-radar-travel';
var refreshClick = 'li.Tabbed-nav-item--2iOWw a.is-selected';
handleTravelLocation(viewMode, toggleTravel, refreshClick);
$('span.re-radar-travel').click(function() {
var viewMode = localStorage.getItem('REradarTravelLocation');
var toggleTravel = 'span.re-radar-travel';
var refreshClick = 'li.Tabbed-nav-item--2iOWw a.is-selected';
viewMode = (viewMode == 'travel') ? 'default' : 'travel';
localStorage.setItem('REradarTravelLocation', viewMode);
handleTravelLocation(viewMode, toggleTravel, refreshClick);
});
}
//icons on groups
if (!mobile.matches) {
$('div.js-navigation ul').has('a[href="/groups/discover"]').not(':has(li.re-add)').append(
'<li class="Tabbed-nav-item--2iOWw re-add"><a style="cursor:default">|</a></li>' +
'<li class="Tabbed-nav-item--2iOWw re-add"><a href="/messenger/contacts" class="js-nav-item Tabbed-nav-link--xyQY6" title="Kontakte"><span class="icon icon-save-contact"></span></a></li>'
);
}
$('div.js-navigation ul li').not('.re-add').find('a[href="/groups/member"]').titleLabel(`${commonGroupsList.length.toLocaleString()} Gruppen abonniert`);
//remove GR-Tools hint
$('li.re-grtools').remove();
}
// ***** Show versions and online users in menu, selected bookmark in filter icon title and text *****
function handleVersionBookmark (jNode) {
//menu
if ($('#offcanvas-nav div[class^="Version"]').length) {
var reVersion = `${(typeof GM_info != 'undefined') ? `${GM_info.script.name} ${GM_info.script.version}` : 'RomeoEnhancer'}`;
var onlineAll = '';
$.ajax({url: `/api/services/landing/online-count`}).done(function (data) {
if (data.online_count) {
onlineAll = `${data.online_count.toLocaleString()} Profile online`;
}
$('#offcanvas-nav div[class^="Version"] .re-add').remove();
$('#offcanvas-nav div[class^="Version"]').addClass('txt-preserve').append(`<div class="re-add">${reVersion}\n${onlineAll}</div>`);
var profileType = ($('li.is-selected, li[class*="list__item--active"]').find('a[href*="/hunqz"]').length) ? '/hunqz/profiles' : '/profiles';
var users = '', online = '';
$.ajax({headers: ajaxHead(), url: `/api/v4${profileType}?pick=items_total&lang=de&length=1`}).done(function (data) {
if (data.items_total) {
users = `${data.items_total.toLocaleString()} User`;
}
$.ajax({headers: ajaxHead(), url: `/api/v4${profileType}?pick=items_total&lang=de&length=1&filter[online_status][]=ONLINE&filter[online_status][]=DATE&filter[online_status][]=SEX`}).done(function (data) {
if (data.items_total) {
online = `${data.items_total.toLocaleString()} online`;
}
$('#offcanvas-nav div[class^="Version"]').off().on('dblclick', function() {
$('#offcanvas-nav div[class^="Version"] div').replaceWith(`<div class="re-add">${reVersion}\n${onlineAll}\n${users} • ${online}</div>`);
});
});
});
});
//display
/*if (location.pathname == '/me/display') {
console.log('Display menu');
$('#offcanvas-nav div.settings__key:first-child').not('.re-add').clone().insertBefore('#offcanvas-nav div.settings__key:first-child').first().addClass('re-add');
}*/
} else {
//filter icon title and text
var selectedBookmark = $('div[class^="js-bookmarks-list"] div[class*="item__is-selected"] a').text().trim();
if (selectedBookmark) {
$('div.js-filter-button button').attr('style', 'color:rgb(250,250,250); background-color:transparent');
$('div.js-filter-button button title').text(`Lesezeichen: ${selectedBookmark}`);
$('div.js-filter-button button span').not('.re-add').addClass('re-filter-options-text');
$('div.js-filter-button button').not(':has(.re-add)').append(`<span class="re-add re-filter-bookmark-name mr">${selectedBookmark}</span>`);
$('div.js-filter-button button span').attr('title', `Lesezeichen: ${selectedBookmark}`);
$('button.ui-navbar__button--bookmarks').attr('title', 'Lesezeichen auswählen');
} else {
$('div.js-filter-button button span.re-filter-options-text').removeClass('re-filter-options-text');
$('div.js-filter-button button span.re-add').remove();
}
}
}
// ***** Preview unread messages in title tag, delete by clicking blue badge *****
function previewMessage (jNode) {
var profileId = $(jNode).closest('a').attr('href').match(/\d{3,}/);
if (profileId) {
$(jNode).closest('a').addClass('re-id' + profileId);
var msgCount = parseInt($(jNode).text());
var jsonParam = 'lang=de&length=' + msgCount + '&filter[folders][]=RECEIVED&filter[partner_id]=' + profileId;
var msgText = '';
var thisId = '.re-id' + profileId;
$.ajax({headers: ajaxHead(), url: '/api/v4/messages?' + jsonParam}).done(function (data) {
//preview
for (var i = msgCount-1; i >= 0; i--) {
msgText += '\r' + data.items[i].text + '\r';
//handle links
if (data.items[i].attachments) {
for (var item of data.items[i].attachments) {
if (item.type == 'COMMAND') {
//console.log('attachments COMMAND');
msgText = msgText.replace(`[[${item.index}]]`, `[${item.params?.text}]`);
}
}
}
}
$(thisId).attr('title', msgText);
$(thisId).find('img').parent('div').attr('title', msgText);
//delete unread
$(jNode).attr('title', 'Löschen')/*.text(` ${msgCount} `)*/.off().click(function () {
if (confirm(msgCount + ' Message(s) ungelesen löschen?')) {
for (var i = msgCount-1; i >= 0; i--) {
$.ajax({url: '/api/v4/messages/' + data.items[i].id + '?expand=from',
headers: ajaxHead(),
method: 'DELETE'
})
.done(function (data) {
//$('#messenger li.Tabbed-nav-item--8Ou8b a').first().get(0).click();
})
}
//changeUrl('/messenger/chat');
//$('#messenger li.Tabbed-nav-item--8Ou8b.is-selected a').get(0).click();
}
})
});
//highlight profile name
$(jNode).closest('a').find('p[class^="BodyText"]').attr('style', 'color:rgba(255,255,255,1); opacity:1');
}
}
// ***** Show last login and location in message thread *****
function showLoginLocation (jNode) {
//placeholder for login and location
$('section.js-detail > div').not(':has(.re-login-location)').append(
`<div class="re-login-location re-add"></div>`
);
if ($('.js-correspondence > div').filter('.re-add').length) return;
var profileId = location.pathname.match(/\d{3,}$/);
var name = '', country = '', distance = '', sensor = '';
var loginTime = '', loginLocalTime = '', timeTag = '', lastSince = '', offlineSince ='';
$.ajax({headers: ajaxHead(), url: '/api/v4/profiles/' + profileId + '?expand=partner&lang=de'})
.done(function (data) {
$('.js-correspondence > div').addClass('re-add');
//last login
if (data.last_login && data.online_status) {
loginTime = new Date(data.last_login.slice(0,-5)+'.000Z');
loginLocalTime = dateTime(loginTime);
timeTag = dateTime(loginTime, !mobile.matches);
lastSince = `${data.online_status == 'OFFLINE' ? 'Zuletzt online:' : 'Online seit:'}`;
if (($(jNode).closest('div').parent().find('[class*="OnlineStatus"]')).length == 0) {
offlineSince = `<span class="icon icon-last-login-hours mr-- re-add" style="font-size:.75rem; color:rgba(250,250,250,.75)" title="${lastSince} ${loginLocalTime}"> ${touch.matches ? '' : timeTag}</span>`;
};
}
//location, distance
if (data.location && data.location.name) {
name = `<a class="re-link-idle" target="_blank" href="https://google.com/maps/place/${data.location.name}" rel="noreferrer noopener" title="Ort in Google Maps anzeigen">${data.location.name.trim()}</a>`;
}
if (data.location && data.location.country && (data.location.distance > 50000 || data.location.distance == null)) {
country = `, ${data.location.country}`;
}
if (data.location && data.location.distance >= 0) {
if (data.location.distance < 1000) {
distance = ' • ' + data.location.distance + 'm';
} else if (data.location.distance < 50000) {
distance = ' • ' + (Math.round(data.location.distance/100)/10).toLocaleString() + ' km';
} else {
distance = ' • ' + (Math.round(data.location.distance/1000)) + ' km';
}
}
if (data.location && data.location.sensor) {
sensor = '<span class="icon icon-gps-needle icon-badge mr-" style="font-size:.85em"></span>';
}
})
.always(function (data) {
$('section.js-detail div.re-login-location').html(`
<div class="re-msg-location">${sensor}${name}${country}${distance}</div>
<div class="re-msg-login" title="${lastSince} ${loginLocalTime}">
<span class="re-touch">${lastSince} ${loginLocalTime}</span></div>
<div class="re-msg-offline">${offlineSince}</div>`
);
});
}
// ***** Add copy to message thread options menu *****
function threadOptionsMenu (jNode) {
$(jNode).find('li').first().clone().appendTo($(jNode)).click(function() {
var profileId = '', profileName = '';
if ($(this).closest('#messenger').length) {
profileId = location.pathname.match(/\d{3,}/);
profileName = $('#messenger div.js-correspondence').find('a > p[class^="BodyText"]').first().text().trim();
} else {
profileId = xhrFull.id;
profileName = xhrFull.name;
}
copyMessageThread(profileId, profileName);
return false;
}).attr('id', 'options_copy').find('span').text('Kopieren');
}
// ***** Zoom footprints list *****
//init
let setFootprintZoom = (localStorage.getItem('REfootprintZoom') === 'true');
function handleFootprints (jNode) {
setFootprintZoom ? $('.js-profile-footprints').addClass('re-zoom') : $('.js-profile-footprints').removeClass('re-zoom');
$('.js-profile-footprints .reactView > div > span').last().not(':has(.re-add)').wrapInner(
`<a class="re-link mr re-add" style="font-size:1.2rem" title="Vergrößern" href="">- +</a>`
).click(function() {
setFootprintZoom = !setFootprintZoom;
localStorage.setItem('REfootprintZoom', setFootprintZoom);
$('.js-profile-footprints').toggleClass('re-zoom');
return false;
});
}
// ***** Filter by "no entry" *****
function handleFilterNoEntry (jNode) {
//insert button
$(jNode).not('.re-add').addClass('re-add').after(`
<div class="re-add layout mt mh++">
<a class="re-button-no-entry ui-tag ui-tag--center" href="">+ keine Angabe
<span class="icon icon-small icon-info ml-" title="Zeigt auch Profile, die zu den ausgewählten Suchoptionen keine Angabe enthalten"
aria-label="Zeigt auch Profile, die zu den ausgewählten Suchoptionen keine Angabe enthalten"></span>
</a>
</div>`
).next('div.re-add').off().click(function() {
filterNoEntry = !filterNoEntry;
localStorage.setItem('REfilterNoEntry', filterNoEntry);
//toggle button
$('.re-button-no-entry').toggleClass('ui-tag--selected');
//reload radar tab
$('section.js-main-stage div.js-navigation').find('a.is-selected, div.js-nav-item').get(0).click();
return false;
});
if (filterNoEntry) $('.re-button-no-entry').addClass('ui-tag--selected');
}
// ***** Link contact icons in messages list entries *****
function handleMessage (jNode) {
var profileId = new Array;
profileId = $(jNode).attr('href').match(/\d{3,}/);
if (! profileId) profileId = location.pathname.match(/\d{3,}/);
$(jNode).not(':has(a.re-add)').find('p > span > svg').not('[label="HUNQZ"], .cObeIS').wrap(
`<a href="/messenger/contacts/all/${profileId}" class="re-add"></a>`
);
$(jNode).not(':has(a.re-add)').find('svg.cObeIS').wrap(
`<a href="/messenger/contacts/blocked/${profileId}" class="re-add"></a>`
);
}
// ***** Add message icons to contact list entries *****
function handleContacts (jNode) {
var profileId = new Array;
profileId = $(jNode).attr('href').match(/\d{3,}$/);
if (! profileId) profileId = location.pathname.match(/\d{3,}$/);
//console.log(profileId);
$(jNode).find('p[class^="BodyText-"] > span, span > span').last().not(':has(a)').prepend(
`<a class="icon icon-chat re-icon re-idle ml-- mr-" title="Messages" href="/messenger/chat/${profileId}"></a>`
);
}
// ***** Link user names on discover page to messages *****
function handleContactStrip (jNode) {
var replacePattern = /(.*\/(profile|hunq|group)\/)([-\w]*)(.*)/;
var profileLink = $(jNode).attr('href');
$(jNode).attr('href', profileLink.replace(/\/group\//, '/profile/'));
var profileName = profileLink.replace(replacePattern, '$3');
//console.log(profileName);
var baseUrl = '/messenger/chat/';
$(jNode).find('div[class^="Name-"]').attr('title', profileName)/*.wrapInner(
`<a class="re-link-idle" title="${profileName} | Messages" href="${baseUrl}${profileName}"></a>`
).children()*/.off().click(function() {
openByName(baseUrl, profileLink, profileName);
return false;
}).attr('style', `${profileLink.match(/^\/hunq\//) ? 'color:#fc193c' : ''}`);
}
// ***** Mark common groups *****
function handleGroupTiles (jNode) {
var jNodeGroupTiles = $(jNode).closest('a');
if (jNodeGroupTiles.attr('href') && jNodeGroupTiles.attr('href').match(/^\/group\//)) {
const profileName = jNodeGroupTiles.attr('href').match(/[-\w]+$/);
const nameIndex = (item) => item.name == profileName;
if (commonGroupsList.findIndex(nameIndex) > -1) {
jNodeGroupTiles.addClass('re-common-group');
jNodeGroupTiles.find('p').last().attr('title', 'Du bist Mitglied in dieser Gruppe');
}
//show full group name in title
jNodeGroupTiles.find('p').first().attr('title', $(jNode).find('p').first().text().trim());
}
}
// ***** Add message icons to discover, visitor list, search results, and group member list, link contact icons *****
function handleTiles (jNode) {
var jNodeTiles = $(jNode).closest('a');
var replacePattern = /(.*\/(profile|hunq|group)\/)([-\w]*)(.*)/;
var profileLink = jNodeTiles.attr('href');
var profileName = profileLink.replace(replacePattern, '$3');
//console.log(profileName);
//add + to distance if travel
if (travelMode && location.pathname.match(/^\/(radar|groups|explore)\//)) {
if (jNodeTiles.find('svg + p[class^="SpecialText"]').not('.re-add').text().match(/(\d[\d\.,]*\s?(km|m|mi|ft))/)) {
var distance = `+${jNodeTiles.find('svg + p[class^="SpecialText"]').html()}`;
jNodeTiles.find('svg + p[class^="SpecialText"]').html(distance).addClass('re-add');
}
}
//add visitor icon
var visitTime, visitedTime = '';
const nameIndex = (item) => item.name == profileName;
if (location.pathname == '/visitors/me') {
if (visitorsList.findIndex(nameIndex) > -1) {
var index1 = visitorsList.findIndex(nameIndex);
visitTime = new Date(visitorsList[index1].date_visited);
jNodeTiles.find('div > div > div + div > p').first().not('.re-add').addClass('re-add').append(
`<a class="icon icon-visitor re-icon re-icon-visitor ml--" title="Besucher ${dateTime(visitTime)}" href="/visitors"></a>`
);
}
}
if (location.pathname == '/visitors') {
if (visitsList.findIndex(nameIndex) > -1) {
var index2 = visitsList.findIndex(nameIndex);
visitedTime = new Date(visitsList[index2].date_visited);
jNodeTiles.find('div > div > div + div > p').first().not('.re-add').addClass('re-add').prepend(
`<a class="icon icon-visitor re-icon re-icon-visited mr--" title="Besucht ${dateTime(visitedTime)}" href="/visitors/me"></a>`
);
}
}
//add message icon
var baseUrl = '/messenger/chat/';
$(jNode).parent().not(':has(.re-icon)').append(
`<a class="icon icon-chat re-icon re-idle ml-" title="Messages" href="${baseUrl}${profileName}"></a>`
).children().last().click(function() {
openByName(baseUrl, profileLink, profileName);
return false;
});
//link contact icon
jNodeTiles.find('svg').has('path[d^="M4 8a4"]').not('.re-contact').addClass('re-contact').wrap(
`<a class="re-idle-no-hover re-contact" title="Kontakt bearbeiten" href="/messenger/contacts/all/${profileName}"></a>`
);
jNodeTiles.find('a.re-contact').off().click(function() {
openByName('/messenger/contacts/all/', profileLink, profileName);
//console.log(profileLink, profileName);
return false;
});
jNodeTiles.find('svg').has('path[d^="M8.039"]').not('.re-contact-blocked').addClass('re-contact-blocked').wrap(
`<a class="re-idle-no-hover re-contact-blocked" title="Kontakt bearbeiten" href="/messenger/contacts/blocked/${profileName}"></a>`
);
jNodeTiles.find('a.re-contact-blocked').off().click(function() {
openByName('/messenger/contacts/blocked/', profileLink, profileName);
return false;
});
}
// ***** Add message icons and preview links to radar entries, link contact icons *****
function handleRadar (jNode) {
//console.log('handleRadar');
var jNodeRadar = $(jNode).closest('a');
var replacePattern = /(.*\/(profile|hunq|group)\/)([-\w]*)(.*)/;
var profileLink = jNodeRadar.attr('href');
var profileName = profileLink.replace(replacePattern, '$3');
// TEST
if ($('#profiles div.search-results__item').length > 200) {
//$('#profiles div.search-results__item').eq(0).remove();
}
//add visitor icon
const nameIndex = (element) => element.name == profileName;
if (visitorsList.findIndex(nameIndex) > -1) {
var index = visitorsList.findIndex(nameIndex);
var visitTime = new Date(visitorsList[index].date_visited);
jNodeRadar.find('div > div > div + div').first().not('.re-add').addClass('re-add').append(
`<a class="icon icon-visitor re-icon re-icon-visitor ml--" title="Besucher ${dateTime(visitTime)}" href="/visitors"></a>`
);
}
//add message icon
var baseUrl = '/messenger/chat/';
$(jNode).parent().not(':has(.re-icon)').append(
`<a class="icon icon-chat re-icon re-idle ml-" title="Messages" href="${baseUrl}${profileName}"></a>`
).children().last().click(function() {
openByName(baseUrl, profileLink, profileName);
return false;
});
//add + to distance if travel
if (travelMode || location.pathname.match(/^\/explore\//)) {
if (location.pathname.match(/^\/(radar|groups|explore|eyecandy)\//)) {
if (jNodeRadar.find('svg + p[class^="SpecialText"]').not('.re-add').text().match(/(\d[\d\.,]*\s?(km|m|mi|ft))/)) {
var distance = `+${jNodeRadar.find('svg + p[class^="SpecialText"]').html()}`;
jNodeRadar.find('svg + p[class^="SpecialText"]').html(distance).addClass('re-add');
}
}
}
//link username to preview
if ($(jNode).closest('.search-results--big-tiles, .search-results--list-style').length) {
$(jNode).not(':has(.re-link-idle)').wrapInner(
`<a class="re-link-idle" title="${profileName} | Vorschau" href="${profileLink.replace(replacePattern, '$1$3/preview')}"></a>`
);
}
//link contact icon
jNodeRadar.find('svg').has('path[d^="M4 8a4"]').not('.re-contact').addClass('re-contact').wrap(
`<a class="re-idle-no-hover re-contact" title="Kontakt bearbeiten" href="/messenger/contacts/all/${profileName}"></a>`
);
jNodeRadar.find('a.re-contact').off().click(function() {
openByName('/messenger/contacts/all/', profileLink, profileName);
return false;
});
jNodeRadar.find('svg').has('path[d^="M8.039"]').not('.re-contact-blocked').addClass('re-contact-blocked').wrap(
`<a class="re-idle-no-hover re-contact-blocked" title="Kontakt bearbeiten" href="/messenger/contacts/blocked/${profileName}"></a>`
);
jNodeRadar.find('a.re-contact-blocked').off().click(function() {
openByName('/messenger/contacts/blocked/', profileLink, profileName);
return false;
});
//show count of profiles, Plus, travelling, and GPS in title tag of selected tab
var loadTime = new Date().toLocaleTimeString() + ' aktualisiert';
var profiles = $('#profiles :is(div.BIG, div.SMALL, div.LIST)').length;
var profilesPlus = '';
var percentPlus = '';
if ($('#profiles .search-results--mixed-tiles').length) {
profilesPlus = $('#profiles .search-results--mixed-tiles div.tile--plus, #profiles .search-results--big-tiles').length;
percentPlus = (profiles > 0 ? ' (' + (Math.round(profilesPlus/profiles*1000)/10).toLocaleString() + ' %)' : '');
profilesPlus = ' • ' + profilesPlus + ' Plus' + percentPlus;
}
var profilesTravel = '';
var percentTravel = '';
profilesTravel = $('#profiles svg > path[d^="M10.0452"]').length;
percentTravel = (profiles > 0 ? ' (' + (Math.round(profilesTravel/profiles*1000)/10).toLocaleString() + ' %)' : '');
profilesTravel = `${profilesTravel} ${(profilesTravel == 1 ? 'Reisender' : 'Reisende')}${percentTravel}`;
var profilesGPS = '';
var percentGPS = '';
profilesGPS = $('#profiles svg > path[d^="M11.94"]').length;
percentGPS = (profiles > 0 ? ' (' + (Math.round(profilesGPS/profiles*1000)/10).toLocaleString() + ' %)' : '');
profilesGPS = ' • ' + profilesGPS + ' GPS' + percentGPS;
profiles += ` ${(profiles == 1 ? 'Profil' : 'Profile')} geladen`;
$('ul.Tabbed-nav--2c5l9 li.is-selected, ul[class^="list--"] li[class*="list__item--active--"], div.js-nav-item').attr(
'title', `${loadTime}\r${profiles}${profilesPlus}\r${profilesTravel}${profilesGPS}`
);
}
// ***** Add message icons to non-message Activity Stream entries; handle group related entries; add icon to settings *****
function handleStream (jNode) {
var jNodeStream = $(jNode).closest('a');
var bodyLink = jNodeStream.attr('href');
if (bodyLink != undefined) {
var replacePattern = /(.*\/(profile|hunq|groups)\/)([-\w]*)(.*)/;
var profileLink = '' + jNodeStream.parent().find('a').attr('href');
var profileName = profileLink.replace(replacePattern, '$3');
//console.log(profileName);
var baseUrl = '/messenger/chat/';
//link contact icon
jNodeStream.find('svg').has('path[d^="M4 8a4"]').not('.re-contact').addClass('re-contact').wrap(
`<a class="re-idle-no-hover re-contact" title="Kontakt bearbeiten" href="/messenger/contacts/all/${profileName}"></a>`
);
jNodeStream.find('a.re-contact').off().click(function() {
openByName('/messenger/contacts/all/', profileLink, profileName);
return false;
});
jNodeStream.find('svg').has('path[d^="M8.039"]').not('.re-contact-blocked').addClass('re-contact-blocked').wrap(
`<a class="re-idle-no-hover re-contact-blocked" title="Kontakt bearbeiten" href="/messenger/contacts/blocked/${profileName}"></a>`
);
jNodeStream.find('a.re-contact-blocked').off().click(function() {
openByName('/messenger/contacts/blocked/', profileLink, profileName);
return false;
});
}
if (bodyLink != undefined && ! bodyLink.match('/messenger/chat/')) {
//add message icon
if (profileName) {
jNodeStream.find('p[class^="BodyText-"]').not(':has(a,img)').prepend(
`<a class="icon icon-chat re-icon mr-" title="Messages" href="${baseUrl}${profileName}"></a>`
).children().last().click(function() {
openByName(baseUrl, profileLink, profileName);
return false;
});
}
//italic if system text
jNodeStream.find('span.listitem__text, span.ui-status-description').attr('style', 'font-style:italic');
//add icon if group picture, hide group pictures in small stream
var jNodeGroupPicture = jNodeStream.has('img.thumbnail').not(':has(span.icon-heart, span.icon-camera-icon, .re-add)');
jNodeGroupPicture.find('span.listitem__timestamp').after(
`<span class="clr-ui-text listitem__highlight--expanded re-add"><span class="icon icon-group-members"></span></span>`
);
if (! location.pathname.match(/^\/stream/)) {
/*jNodeGroupPicture.find('span.listitem__text').first().hide();
jNodeGroupPicture.attr('title', jNodeGroupPicture.find('span.listitem__text').first().text().trim());
$(jNodeGroupPicture).parent().addClass('re-group-item');*/
$(jNodeGroupPicture).parent().addClass('re-group-item').hide();
} else {
//hide group pictures of blocked users
$(jNodeGroupPicture).has('path[d^="M8.039"]').parent().addClass('re-group-item').hide();
}
}
//add enlarge and settings
$('div.stream__content div.js-list').not(':has(div.re-add)').prepend(`
<div class="re-add mt-- mb- mh" style="display:flex; justify-content:space-between; align-items:center; height:.875rem">
<div class="layout">${(!location.pathname.match(/^\/stream$/)) ? `<a href="/stream" class="icon icon-back re-icon re-link p0 re-stream-group-items" title="Erweitern"></a>` : ``}</div>
<a href="/me/notifications" class="icon icon-settings re-icon re-link p0"><span class="ml--">Anpassen</span></a>
</div>`
);
var groupItems = $('section.js-stream .re-group-item').not(':has(svg.fSgjsY)').length;
if (groupItems) {
$('.re-stream-group-items').html(`<span class="ml-">${groupItems}<span class="icon icon-group-members" style="margin-left:.15rem"></span></span>`).attr('title', `Erweitern • Neue Bilder in ${groupItems} Gruppe${(groupItems == 1) ? '' : 'n'}`);
}
}
// ***** Profiles: show profile id, visits since; link URLs *****
function handleProfile (jNode) {
var profileName = $('div.top-info-header p[class^="BodyText"]').first().text().trim();
var profileType = ($('div.is-profile-loaded').hasClass('profile--hunqz')) ? '/hunqz/profiles' : '/profiles';
var profilePath = ($('div.is-profile-loaded').hasClass('profile--hunqz')) ? 'hunq' : 'profile';
var profileId = '', profileIdInfo = '', visits = '', since = '', known = '', known1st = '', known2nd = '', verified = '';
var albums = 0, profilePictures = 0, albumPictures = 0, quickSharePictures = 0;
var name = '', country = '', distance = '';
var loginTime = '', loginLocalTime = '', timeTag = '', lastSince ='';
var sinceMonthYear = $('section.profile__stats section > p').last().contents().filter(function(){ return this.TEXT_NODE; }).first().text();
var data = xhrFull;
if (data.id) {
profileId = data.id;
profileIdInfo = `Profil-ID: ${data.id}`;
}
if (data.visits_count) { // not 0 or undefined
visits = `<br>Besucher: ${data.visits_count.toLocaleString()}`;
}
if (data.creation_date) {
since = new Date(data.creation_date.slice(0,-5)+'.000Z').toLocaleDateString();
since = 'Mitglied seit: ' + since;
} else {
since = sinceMonthYear;
}
//known by
if (data.known_by && data.known_by.first_degree > 0) {
known1st = data.known_by.first_degree;
known2nd = data.known_by.second_degree;
known = `Bekannt bei ${known1st.toLocaleString()} ${known1st == 1 ? 'Nutzer (dieser' : 'Nutzern (diese'} bekannt bei ${known2nd.toLocaleString()})`;
} else {
known = `Noch nicht bei anderen bekannt`;
}
//online time
if (data.last_login && data.online_status) {
loginTime = new Date(data.last_login.slice(0,-5)+'.000Z');
loginLocalTime = dateTime(loginTime);
timeTag = dateTime(loginTime, 'dateOnly');
lastSince = `${data.online_status == 'OFFLINE' ? 'Zuletzt online:' : 'Online seit:'}`;
}
//show pictures count
if (data.albumsV2.items_total) {
for (var item of data.albumsV2.items) {
if (item.id == 'PROFILE') {
if (item.pictures) {
profilePictures += item.pictures.items_total;
}
} else if (item.access_policy == 'SHARED') {
quickSharePictures += item.items_total;
} else {
if (item.pictures) {
albumPictures += item.pictures.items_total;
//albums += (item.items_total) ? 1 : 0;
}
}
}
if (profilePictures > 1) {
$('section.profile__image-strip').not(':has(.re-add)').append(
`<div class="re-add re-img-count"><div><p>${profilePictures}</p></div></div>`
).children().last().click(function(){
changeUrl(`/${profilePath}/${profileName}/gallery`);
}).attr('style', 'cursor:pointer').titleLabel('Alle Alben anzeigen');
}
if (quickSharePictures) {
$('section.js-profile-stats section > div > a > div > div').first().has('svg').not(':has(.re-add)').append(
`<div class="re-add re-img-count"><div><p>${quickSharePictures}</p></div></div>`
);
}
if (quickSharePictures || albumPictures) {
$('section.profile__stats section > div[class^="InfoText-"] p[class^="BaseText"]').first().not(':has(.re-add)').append(
`<span class="re-add" style="font-size:.925em; color:rgba(255,255,255,.6)"> • ${quickSharePictures + albumPictures} Bilder</span>`
);
}
}
//link location name to maps
if (data.location.name) {
name = `<a target="_blank" href="https://google.com/maps/place/${data.location.name}" rel="noreferrer noopener" class="re-link-idle" title="Ort in Google Maps anzeigen">${data.location.name.trim()}</a>`;
}
if (data.location.country && (data.location.distance > 50000 || data.location.distance == null)) {
country = `, ${data.location.country}`;
}
if (data.location.distance != null) {
if (data.location.distance < 1000) {
distance = ' • ' + data.location.distance + 'm';
} else if (data.location.distance < 50000) {
distance = ' • ' + (Math.round(data.location.distance/100)/10).toLocaleString() + ' km';
} else {
distance = ' • ' + (Math.round(data.location.distance/1000)) + ' km';
}
}
//location, country, distance
$('div.profile__info svg + p[class^="BodyText"]').first().html(name + country + distance);
//since, id, known by, visits, online
$('section.profile__stats section > p').last().addClass('re-profile-stats mb-').html(`${since}<br>${profileIdInfo}<br>${known}${visits}<br>${lastSince} ${timeTag}`);
//authenticity
var title = $('.top-info-header p + div > button').attr('title');
$('.top-info-header p + div > button').not('.re-add').addClass('re-add').find('title').text(`${title}${(known1st) ? ` (${(known1st <= 30) ? known1st : '30+'})` : ''}\n${sinceMonthYear}\n${lastSince} ${timeTag}`);
//hide visit
$('.profile--romeo .top-info-header p[class^="BodyText"]').first().attr('title', 'Profilbesuch verstecken').off().click(function(){
hideVisit(profileId);
});
//link to albums
$('section.profile__stats section').first().find('div[class^="InfoText-"] p[class^="BaseText"]').click(function(){
changeUrl(`/${profilePath}/${profileName}/gallery`);
}).attr('style', 'cursor:pointer').titleLabel('Alle Alben anzeigen');
//complete headline
if (data.headline && data.headline.length > 50) {
$('div.profile__info p[class^="BodyText"]').last().text(data.headline);
}
//URLs in headline and profile text
$('div.profile__info div.reactView > div > p[class^="BodyText"], section.profile__stats details > div > p[class^="BaseText-sc-"]').each(function() {
var replacedText = linkify($(this).html());
$(this).html(replacedText);
});
//link travel locations to maps
$('section.profile__stats details').has('#travel-list').find('div:not([role="heading"]) > p:first-child').not(':has(.re-add)').each(function() {
$(this).wrapInner(
`<a target="_blank" href="https://google.com/maps/place/${$(this).text().trim()}" rel="noreferrer noopener" class="re-link-idle re-add" title="Ort in Google Maps anzeigen"></a>`
)
});
//move Travel Date and Looking For to top, keeping Albums and B&B at top
$('section.profile__stats details').not('.re-add').has('summary :contains("Ich suche"), summary :contains("Looking For"), summary :contains("Recherche")').each(function() {
$(this).addClass('re-add').prependTo('section.profile__stats > div > div.reactView > div');
});
$('section.profile__stats details').has('#travel-list').not('.re-add').addClass('re-add').prependTo('section.profile__stats > div > div.reactView > div');
$('section.profile__stats section').not('.re-add').has('img + div > p').addClass('re-add').prependTo('section.profile__stats > div > div.reactView > div');
$('section.profile__stats section').not('.re-add').first().has('div[class^="InfoText-"]').addClass('re-add').prependTo('section.profile__stats > div > div.reactView > div');
}
// ***** Handle error page *****
function linksError (jNode) {
//...
$(jNode).append(
`<div style="font-size:0.9em"><br/>...</div>`
);
}
// ***** Sort groups list by active posts *****
//init
var groupsList = [];
var counter = 0;
var groupsCount = 0;
var refresh = false;
var groupsListloadTime = 0;
var lastGroupUrl = '';
var atoz = false;
var linkTextActive = 'Aktive Beiträge', linkTextDefault = 'Standard';
function recentPosts (jNode) {
//console.log('recentPosts');
//insert menu
var viewMode = localStorage.getItem('REgroupsListView');
//var linkTextActive = 'Aktive Beiträge', linkTextDefault = 'Standard';
var linkText = (viewMode == 'active') ? linkTextActive : linkTextDefault;
$('div.Container--3h4tt div.js-groups').not(':has(span.re-list-head)').prepend(`
<div class="mt- mb- pv-" style="font-size:.85rem; border-bottom:1px solid rgba(255,255,255,.125)">
<span class="re-list-head">Sortierung</span>
<span class="re-list-view ml-" title="Umschalten" role="button" aria-label="Sortierung ändern">${linkText}</span>
<span class="re-list-load icon icon-stathistory pl- pr-" title="Aktualisieren">
<span class="re-list-head ml--"></span>
</span>
</div>`
);
//toggle sort mode (recent posts <-> a-z)
$('.re-list-head').off().on('dblclick', function() {
if (viewMode == 'active') {
atoz = !atoz;
linkText = linkTextActive = (atoz) ? 'A - Z' : 'Aktive Beiträge';
$('.re-list-view').text(linkText);
refresh = true;
insertPostsList (groupsList);
}
});
if (mobile.matches) {
$('div.Container--3h4tt div.js-header').removeClass('l-hidden-sm');
$('div.Container--xbtQn').hide();
}
if (viewMode !== 'active') {
$('span.re-list-load').hide();
}
//register toggle menu click
$('span.re-list-view').click(function() {
if (counter == groupsCount) { //not while building groupsList
var oldViewMode = localStorage.getItem('REgroupsListView');
if (oldViewMode == 'active') {
linkText = linkTextDefault;
viewMode = 'default';
$('span.re-list-load').hide();
lastGroupUrl = '';
} else {
linkText = linkTextActive;
viewMode = 'active';
$('span.re-list-load').show();
}
localStorage.setItem('REgroupsListView', viewMode);
$('span.re-list-view').text(linkText);
handlePostsList(viewMode);
}
});
//register refresh list click
$('span.re-list-load').click(function() {
if (counter == groupsCount) { //not while building groupsList
groupsList.length = 0;
counter = 0;
refresh = true;
groupsListloadTime = new Date().toLocaleTimeString();
$('div.Container--3h4tt div.js-groups div.re-add').remove();
$('div.Container--3h4tt div.js-groups > div.pt-').hide();
handlePostsList(viewMode);
}
});
handlePostsList(viewMode);
}
// ***** Handle posts list *****
function handlePostsList (viewMode) {
if (viewMode !== 'active') {
$('div.Container--3h4tt div.js-groups div.re-add').remove();
$('div.Container--3h4tt div.js-groups > div.pt-').show();
var highlighted = 'div.Container--3h4tt div.js-groups button';
if ($(highlighted).length) {
if (typeof $(highlighted)[0].scrollIntoViewIfNeeded === 'function') {
$(highlighted)[0].scrollIntoViewIfNeeded(true);
} else {
$(highlighted)[0].scrollIntoView({block: 'center'});
}
}
} else {
$('div.Container--3h4tt div.js-groups > div.pt-').hide();
if (groupsList.length > 0) {
insertPostsList(groupsList);
} else {
refresh = true;
groupsListloadTime = new Date().toLocaleTimeString('de-DE');
$('div.Container--3h4tt div.js-groups').not(':has(.re-add)').append(
'<div class="spinner-container re-add"><div class="spinner"></div></div>'
);
$.ajax({headers: ajaxHead(), url: '/api/v4/profiles/me/groups?expand=items.*.(membership,activity)&lang=de&length=1000&pick=items.*.(id,name,display_name,membership.is_admin,is_forum_enabled,activity.posts.*,activity.photos.*,preview_pic.url_token),items_total'})
.done(function (data) {
groupsList = [];
counter = 0;
groupsCount = data.items_total;
var ajaxUrl = '', name = '', displayName = '', isAdmin = false, picToken = '', actPosts = 0, countPosts = 0, actPhotos = 0, countPhotos = 0;
for (var item of data.items) {
// loop "posts" for all groups
if (item) {
name = item.name;
displayName = item.display_name;
isAdmin = item.membership.is_admin;
picToken = (item.preview_pic) ? item.preview_pic.url_token : '';
if (item.activity) {
actPosts = (item.activity.posts) ? item.activity.posts.last_accessed : 0;
countPosts = (item.activity.posts) ? item.activity.posts.count : 0;
actPhotos = (item.activity.photos) ? item.activity.photos.last_accessed : 0;
countPhotos = (item.activity.photos) ? item.activity.photos.count : 0;
} else {
actPosts = 0;
countPosts = 0;
actPhotos = 0;
countPhotos = 0;
}
if (item.is_forum_enabled) {
ajaxUrl = `/api/v4/groups/${item.id}/posts?pick=items.*.(date_created,comments.items.*.(date_created))&expand=items.*.(comments)&lang=de&length=5&sort_criteria=COMMENTED_AT_DESC`;
} else {
ajaxUrl = `/api/v4/groups/${item.id}/posts?pick=items.*.(date_created)&lang=de&length=5&sort_criteria=COMMENTED_AT_DESC`;
}
$.ajax({headers: ajaxHead(),
url: ajaxUrl,
custom: {name: name, displayName: displayName, isAdmin: isAdmin, picToken: picToken, actPosts: actPosts, countPosts: countPosts, actPhotos: actPhotos, countPhotos: countPhotos} })
.done(function (data) {
//save name, timestamp, etc. to array (most recent post or comment)
var timeList = [], name = '', displayName = '', time = 0, isComment = false, picToken = '', actPosts = 0, countPosts = 0, actPhotos = 0, countPhotos = 0;
for (var item of data.items) {
if (item.comments && item.comments.items[0]) {
time = item.comments.items[0].date_created;
isComment = true;
} else {
time = item.date_created;
isComment = false;
}
if (time != 0) time = new Date(time.slice(0,-2) + ':00');
timeList.push({time: time, isComment: isComment});
}
//sort by most recent post or comment
timeList.sort(function (a,b) {
return b.time - a.time;
});
if (timeList[0]) time = timeList[0].time;
if (timeList[0]) isComment = timeList[0].isComment;
name = this.custom.name;
displayName = this.custom.displayName.trim();
isAdmin = this.custom.isAdmin;
picToken = this.custom.picToken;
actPosts = this.custom.actPosts;
countPosts = this.custom.countPosts;
actPhotos = this.custom.actPhotos;
countPhotos = this.custom.countPhotos;
if (actPosts != 0) actPosts = new Date(actPosts);
if (actPhotos != 0) actPhotos = new Date(actPhotos);
//console.log(displayName, timeList);
//add to array
groupsList.push({time: time, name: name, displayName: displayName, isAdmin: isAdmin, picToken: picToken, isComment: isComment, actPosts: actPosts, countPosts: countPosts, actPhotos: actPhotos, countPhotos: countPhotos, visited: false});
})
.always(function (data) {
counter++;
if (counter >= groupsCount) {
insertPostsList(groupsList);
return;
}
});
} else {
counter++;
if (counter >= groupsCount) {
insertPostsList(groupsList);
return;
}
}
}
});
}
$('span.re-list-load span').text(groupsListloadTime.slice(0,-3));
$('ul.Container--1I9Gx button').click();
}
}
// ***** Insert posts list *****
function insertPostsList (groupsList) {
//sort by most recent
groupsList.sort(function (a,b) {
if (atoz) {
return b.isAdmin - a.isAdmin || a.displayName.localeCompare(b.displayName);
} else {
return b.time - a.time;
}
});
//console.log(groupsList);
//insert list elements on top of MY GROUPS
$('div.Container--3h4tt div.js-groups div.re-add').remove();
$('div.Container--3h4tt div.js-groups > div.pt-').hide();
$('div.Container--3h4tt div.js-groups').append('<div class="mb re-add"></div>');
var thumbnail = '';
for (var item of groupsList) {
thumbnail = (item.picToken == '') ? '/assets/f3b077168d98a575e8960e70c59f5d78.svg' : `/img/usr/squarish/212x212/${item.picToken}.jpg`;
$('div.Container--3h4tt div.js-groups').append(`
<div class="reactView re-add">
<a href="/groups/member/${item.name}" class="re-groups-listitem">
<div class="re-groups-tile" style="background-image:url(${thumbnail})"></div>
<div class="re-groups-entry">
<span class="re-groups-text">
<span>
<span lang="" title="${item.displayName}" class="re-groups-name">${item.displayName}<br>
<span class="re-groups-time" title="${(item.isComment) ? 'Letzter Kommentar' : 'Letzter Beitrag'} vom ${item.time.toLocaleString('de-DE').slice(0,-3)}">${dateTime(item.time, !touch.matches)}</span>
</span>
</span>
</span>
</div>
</a>
</div>`
);
if (item.isComment) {
$('div.Container--3h4tt div.js-groups div.re-add a').last().append(`
<div class="re-groups-new ml-" style="margin-right:.1em" title="Aktueller Kommentar vom ${item.time.toLocaleString('de-DE').slice(0,-3)}">
<svg label="Aktueller Kommentar" role="img" aria-hidden="false" viewBox="0 0 1024 1024">
<path d="M943.3 408.7c-49.9-49.9-118.9-80.7-195-80.7H222.7l.1-183.5L0 367.4l222.8 222.8.1-183.5h525.4c54.4 0 103.6 22.1 139.3 57.7 35.6 35.7 57.6 84.9 57.6 139.3 0 54.4-22 103.6-57.7 139.3-35.7 35.7-84.9 57.7-139.3 57.7H616.3c-14.2 0-25.7 11.5-25.7 25.7v27.5c0 14.2 11.5 25.7 25.7 25.7h131.9c76.2 0 145.1-30.9 195-80.7 49.9-49.9 80.7-118.9 80.7-195 .1-76.3-30.8-145.3-80.6-195.2z"></path>
</svg>
</div>`
);
}
if (item.actPosts) {
$('div.Container--3h4tt div.js-groups div.re-add a').last().append(`
<div class="re-groups-new ml-" title="${item.countPosts} ${(item.countPosts == 1) ? 'neuer Beitrag' : 'neue Beiträge'} seit ${item.actPosts.toLocaleString('de-DE').slice(0,-3)}">
<span style="margin-right:.25em">${item.countPosts}</span>
<svg label="Neue Beiträge" style="font-size:.675em" role="img" aria-hidden="false" viewBox="0 0 100 100">
<path d="M50 0a50 50 0 100 100A50 50 0 1050 0z"></path>
</svg>
</div>`
);
}
if (item.actPhotos) {
$('div.Container--3h4tt div.js-groups div.re-add a').last().append(`
<div class="re-groups-new ml-" title="${item.countPhotos} ${(item.countPhotos == 1) ? 'neues Bild' : 'neue Bilder'} seit ${item.actPhotos.toLocaleString('de-DE').slice(0,-3)}">
<span style="margin-right:.25em">${item.countPhotos}</span>
<svg label="Neue Bilder" role="img" aria-hidden="false" viewBox="0 0 1024 1024">
<path d="M656 579c0 80-64 145-144 145s-144-65-144-145 64-145 144-145 144 65 144 145zM512 808c-63 0-120-26-161-68s-67-98-67-162c0-63 26-120 67-162s98-67 161-67 120 25 161 67 67 99 67 162c0 64-26 120-67 162s-98 68-161 68zm449-589H762L644 107c-7-7-16-11-27-11H407c-11 0-20 4-27 11L262 219H63c-35 0-63 28-63 63v583c0 35 28 63 63 63h898c35 0 63-28 63-63V282c0-35-28-63-63-63z"></path>
</svg>
</div>`
);
}
if (item.isAdmin) {
$('div.Container--3h4tt div.js-groups div.re-add a').last().append(`
<div class="re-groups-admin ml-" title="Du verwaltest diese Gruppe" aria-label="Du verwaltest diese Gruppe"s>
<span>ADMIN</span>
</div>`
);
}
}
//highlight selected item, dim visited items
$('div.Container--3h4tt div.js-groups div.re-add a').each(function() {
var index = $('div.Container--3h4tt div.js-groups div.re-add a').index(this);
if (location.href.match(this.href) || (mobile.matches && lastGroupUrl.match(this.href))) {
if (!refresh) $(this)[0].scrollIntoView({block: 'center'});
$(this).addClass('re-groups-selected');
$(this).attr('style', `background-color:${color9}`);
groupsList[index].visited = true;
//if (mobile.matches) $(this).find('div.re-groups-new').remove();
} else if (groupsList[index].visited == true) {
$(this).addClass('re-groups-visited');
}
});
//refresh content on re-click, remove indicators on first click
$('div.Container--3h4tt div.js-groups div.re-add a').click(function() {
lastGroupUrl = this.href;
if (location.href.match(this.href)) {
$('ul.Container--1I9Gx button').click();
return false;
} else {
return true;
}
});
refresh = false;
//insert separators admin/member if needed
if (atoz && $('div.Container--3h4tt div.js-groups div.re-add a').not(':has(.re-groups-admin)').length) {
$('div.Container--3h4tt div.js-groups div.re-add a').has('.re-groups-admin').first().before(
`<h4 class="bjIHpu m--">Admin</h4>`
);
$('div.Container--3h4tt div.js-groups div.re-add a').has('.re-groups-admin').last().after(
`<h4 class="bjIHpu m-- mt">Mitglied</h4>`
);
}
}
// ***** Toggle group manage mode *****
function groupManageMode (jNode) {
if (resigned) $(jNode).not(':has(.re-add)').prepend('<span class="re-add">!</span>');
$(jNode).off().on('dblclick', function() {
$(this).find('.re-add').remove();
resigned = !resigned;
if (resigned) $(this).prepend('<span class="re-add">!</span>');
});
}
// ***** Compact view for group posts *****
function groupPostsViewMode (jNode) {
var viewMode = localStorage.getItem('REgroupPostsView');
var linkTextCompact = 'Kompakt', linkTextDefault = 'Mit Kommentaren';
var linkText = (viewMode == 'compact') ? linkTextCompact : linkTextDefault;
$('div.Container--1cJVr').append(
'<span class="re-posts-view" title="Umschalten">' + linkText + '</span>' +
'<span class="layout-item icon icon-dropdown dropdown__arrow"></span>'
);
$('span.re-posts-view').click(function() {
var oldViewMode = localStorage.getItem('REgroupPostsView');
var linkText = linkTextCompact, viewMode = 'compact';
if (oldViewMode == 'compact') {
linkText = linkTextDefault;
viewMode = 'default';
}
localStorage.setItem('REgroupPostsView', viewMode);
$('span.re-posts-view').text(linkText);
$('span.CommentCount--3uCNR').each(function() {
handleGroupComment(this);
});
});
}
// ***** Show/hide group comments *****
function refreshGroupComments (jNode) {
var thisNode = $(jNode).find('span.CommentCount--3uCNR'); // span.CommentCount--1Eef2
handleGroupComment(thisNode);
}
// ***** Handle a single group post *****
function handleGroupComment (thisNode) {
var viewMode = localStorage.getItem('REgroupPostsView');
var timestamp = $(thisNode).parent().parent().nextAll().find('span.PostDate--2LVzF').last().text();
if (viewMode == 'compact') {
$(thisNode).parent().parent().nextAll().hide();
if (timestamp == '') {
$(thisNode).text('Kommentar schreiben');
} else {
$(thisNode).after(
'<span class="ml--"> • ' + timestamp + '</span>'
);
}
$(thisNode).not(':has(a)').wrapInner('<a></a>').off('click').click(function() {
$(thisNode).parent().parent().nextAll().toggle();
});
} else {
$('div.CommentsArea--3iSoQ, div.js-add-comment').show();
$(thisNode).find('a').contents().unwrap('a');
$(thisNode).off('click');
$(thisNode).next('span').remove();
if (timestamp == '') {
$(thisNode).text('0 Kommentare');
}
}
}
// ***** Group posts *****
function handleGroupPosts (jNode) {
//...
}
// ***** Sort group members by distance from travel location *****
//init
var travelName = '';
sessionStorage.setItem('PR_SETTINGS:groups:members:sorting', localStorage.getItem('PR_SETTINGS:groups:members:sorting'));
function groupTravelLocation (jNode) {
var viewMode = localStorage.getItem('REgroupTravelLocation');
var toggleTravel = 'span.re-member-travel';
var refreshClick = 'ul.Container--1I9Gx button';
$('div.Container--e53RO div.Container--13Nkp .re-add').remove();
$('div.Container--e53RO div.Container--13Nkp').has('div:contains("Entf"), div:contains("Dist")').append(
`<span class="re-add re-member-travel icon icon-airplane ml- pl" style="cursor:pointer" title="Travel" role="img" aria-label="Travel"><span class="pl-"></span></span>`
);
handleTravelLocation(viewMode, toggleTravel, refreshClick);
$('span.re-member-travel').click(function() {
var viewMode = localStorage.getItem('REgroupTravelLocation');
var toggleTravel = 'span.re-member-travel';
var refreshClick = 'ul.Container--1I9Gx button';
viewMode = (viewMode == 'travel') ? 'default' : 'travel';
localStorage.setItem('REgroupTravelLocation', viewMode);
handleTravelLocation(viewMode, toggleTravel, refreshClick);
});
//save sorting permanently
localStorage.setItem('PR_SETTINGS:groups:members:sorting', sessionStorage.getItem('PR_SETTINGS:groups:members:sorting'));
}
function handleTravelLocation (viewMode, toggleTravel, refreshClick) {
if (viewMode == 'travel') {
$(toggleTravel).addClass('re-selected');
if (xhrTravelLat) {
$.ajax({headers: ajaxHead(), url: `/api/geocoder/private/name?lat=${xhrTravelLat}&lon=${xhrTravelLong}&lang=de`})
.done(function (data) {
if (data[0].name) {
travelName = data[0].name;
}
var travelEdit = '<a href="/explore/edit" class="re-edit-travel icon icon-pen pl-" style="line-height:inherit" title="Reiseziel in TRAVEL ändern"></a>';
$(toggleTravel).find('span').html(travelName).attr('title', travelName).addClass('pl-');
$(toggleTravel).next('a.re-edit-travel').remove();
$(toggleTravel).after(travelEdit);
travelMode = true;
$(refreshClick).get(0).click();
});
} else {
$.ajax({headers: ajaxHead(), url: `/api/v4/locations/travel`})
.done(function (data) {
var travelEdit = '';
if (data.length) {
var last = data.length -1;
xhrTravelLat = data[last].lat;
xhrTravelLong = data[last].long;
travelName = data[last].name;
travelMode = true;
travelEdit = '<a href="/explore/edit" class="re-edit-travel icon icon-pen pl-" title="Reiseziel in TRAVEL ändern"></a>';
} else {
travelMode = false;
travelEdit = '<a href="/explore/new" class="re-edit-travel">Füge in TRAVEL dein Reiseziel hinzu!</a>';
}
$(toggleTravel).find('span').html(travelName).attr('title', travelName).addClass('pl-');
$(toggleTravel).next('a.re-edit-travel').remove();
$(toggleTravel).after(travelEdit);
$(refreshClick).get(0).click();
});
}
} else {
$(toggleTravel).removeClass('re-selected');
$(toggleTravel).find('span').text('').removeAttr('title').removeClass('pl-');
$(toggleTravel).next('a.re-edit-travel').remove();
travelMode = false;
$(refreshClick).get(0).click();
}
}
// ***** Show picture info in slide show *****
//init
let imgNameOld = '';
function imgInfo (jNode) {
//don't handle repeatedly within 500ms
let imgName = $('div.swiper-slide-active img').attr('src');
if (imgName === imgNameOld) return;
//new picture or after 500ms
imgNameOld = imgName;
setTimeout(() => {
imgNameOld = '';
}, 500);
//handle picture
let jNodeSlide = $('div.swiper-slide-active img').closest('main');
$(jNodeSlide).find('.re-add').remove();
if (imgName && imgName.match(/^\/img\//)) {
let imgNameTxt = uploadDate(`${imgName.substr(imgName.lastIndexOf('/') + 1, 8)}`);
info = `<a class="re-add" style="font-size:.8125rem; color:rgba(255,255,255,.5); cursor:default" title="Upload-Datum" href="${imgName}">${imgNameTxt}</a>`;
$(jNodeSlide).children('section').children('div').first().children('button').after(info);
}
//report button
$(jNodeSlide).children('section').children('div').first().children('p').attr('style', 'font-size:.9375rem');
//URLs in picture caption
$('#metadata-bar p[class^="ResponsiveBodyText"]').each(function() {
let replacedText = linkify($(this).text());
$(this).html(replacedText);
});
//localize picture date
let imgDate = $('#metadata-bar > div > div > p').last().text().trim();
if (imgDate.match(/\d+\w{2} \w+ \d{4}/)) {
imgDate = imgDate.replace(/(^|: )(\d+)(\w{2}) (\w+ \d{4})/, '$2 $4');
imgDate = new Date(imgDate).toLocaleDateString();
if (imgDate != 'Invalid Date') $('#metadata-bar > div > div > p').last().text(imgDate);
}
}
// ***** Show picture info in picture rating *****
function ratingInfo (jNode) {
$('#picture-rating .re-add').remove();
$('#picture-rating button').blur();
var imgName = $('#picture-rating img').attr('src');
if (imgName) {
var imgNameTxt = `${imgName.substr(imgName.lastIndexOf('/') + 1, 5)}...`;
var imgDate = uploadDate(`${imgName.substr(imgName.lastIndexOf('/') + 1, 8)}`);
var imgNameMax = sessionStorage.getItem('REratingMax');
imgNameMax = (imgNameMax ? imgNameMax : imgNameTxt);
if (imgNameTxt >= imgNameMax) {
sessionStorage.setItem('REratingMax', imgNameTxt);
}
var color = (parseInt(imgNameTxt,16) + 1 < parseInt(imgNameMax,16)) ? 'rgba(255,0,0,.8)' : 'rgba(255,255,255,.375)';
$('#picture-rating button').has('p').after(
`<a class="re-rating-date re-add" style="color:${color}" title="Upload-Datum" href="${imgName}">${imgDate}</a>`
);
}
//set focus on skip or reload button
if (!touch.matches) {
$('#picture-rating p + button, #picture-rating button[class^="TertiaryButton__Element-"]').focus();
}
}
// ***** Handle prompt *****
function handlePrompt (jNode) {
$(jNode).off().on('dblclick', function() {
$('div.ui-bubble__overlay, div.ui-bubble--fullscreen').remove();
});
}
// ***** Relogin after timeout *****
function reLogin (jNode) {
if ($(jNode).not('.re-add').addClass('re-add').children('span').filter(':contains("Erneut einloggen"), :contains("Log in again"), :contains("Reconnexion")').length) {
$(jNode).closest('section').find('div > button').hide();
//setTimeout(() => {
$(jNode).closest('section').find('h1').text('');
$(jNode).closest('section').find('div > img').replaceWith('<div class="spinner-container"><div class="spinner"></div></div>');
$(jNode).closest('section').children('p').text('Erneut einloggen ...');
//}, 500);
setTimeout(() => {
location.reload();
}, 800);
}
}
// ***** XHR *****
//test
//localStorage.setItem('REpostFromDeleted', 'true')
localStorage.setItem('REtestMode', 'false')
//init
let xhrTravelLat = '', xhrTravelLong = '';
let travelMode = false;
let resigned = false;
let xhrFull ='';
let filterNoEntry = (localStorage.getItem('REfilterNoEntry') === 'true');
let postFromDeleted = (localStorage.getItem('REpostFromDeleted') === 'true');
let testMode = (localStorage.getItem('REtestMode') === 'true');
(function() {
let oldXHROpen = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
if (url.match(/v4\/messages\//)) {
//...
}
if (url.match(/v4\/messages\/conversations\?/)) {
//url = url.replace('&length=15', '&length=120');
}
if (url.match(/v4\/contacts\?/)) {
if ($('#contacts-custom-tags a.ui-tag--selected span.ui-tag__label').text().trim() == '[ A-Z ]') {
url += '&sort_criteria=NAME_ASC';
url = url.replace(/&filter%5Btags%5D%5B%5D\=\d+/, ``);
}
if ($('#contacts-custom-tags a.ui-tag--selected span.ui-tag__label').text().trim() == '[ Login ]') {
url += '&sort_criteria=LAST_LOGIN_DESC';
url = url.replace(/&filter%5Btags%5D%5B%5D\=\d+/, ``);
}
if ($('#contacts-custom-tags a.ui-tag--selected span.ui-tag__label').text().trim() == '[ Online ]') {
url += '&filter[online]=true';
url = url.replace(/&filter%5Btags%5D%5B%5D\=\d+/, ``);
}
//url += '&sort_criteria=LAST_LOGIN_DESC';
//url += '&sort_criteria=NAME_ASC';
//url += '&filter[online]=true';
url = url.replace('/contacts?length=100&pick=items.*.profile&lang=de', '/contacts?length=999&pick=items.*.profile&lang=de');
}
if (location.pathname.match(/^\/messenger\/contacts\/name/)) {
if (url.match(/filter%5Busername%5D\=/)) {
url += '&sort_criteria=NAME_ASC';
url = url.replace(/filter%5Busername%5D\=\*/, '');
}
}
if (travelMode) {
if (location.pathname.match(/^\/radar\//)) {
url = url.replace(/filter%5Blocation%5D%5Blat%5D\=[-0-9\.]+/, `filter[location][lat]=${xhrTravelLat}`);
url = url.replace(/filter%5Blocation%5D%5Blong%5D\=[-0-9\.]+/, `filter[location][long]=${xhrTravelLong}`);
}
//url = url.replace(/filter%5Btravellers_filter%5D\=EXCLUDED/, '');
//url = url.replace(/filter%5Btravellers_filter%5D\=INCLUDED/, 'filter%5Btravellers_filter%5D=EXCLUDED');
//url = url.replace(/sort_criteria\=NEARBY_ASC/, 'sort_criteria=NEARBY_DESC');
}
if (location.pathname.match(/^\/(radar|hunqz)\//) && url.match(/filter%5Blocation%5D/)) {
var radius = $('.js-distance-radius .noUi-handle').attr('aria-valuenow');
if (radius >= 94500 && radius < 95500) { //95
url = url.replace(/filter%5Blocation%5D%5Bradius%5D\=[0-9\.]+/, `filter[location][radius]=${250000}`);
}
if (radius >= 95500 && radius < 96500) { //96
url = url.replace(/filter%5Blocation%5D%5Bradius%5D\=[0-9\.]+/, `filter[location][radius]=${500000}`);
}
if (radius >= 96500 && radius < 97500) { //97
url = url.replace(/filter%5Blocation%5D%5Bradius%5D\=[0-9\.]+/, `filter[location][radius]=${1000000}`);
}
if (radius >= 97500 && radius < 98500) { //98
url = url.replace(/filter%5Blocation%5D%5Bradius%5D\=[0-9\.]+/, `filter[location][radius]=${2000000}`);
}
if (radius >= 98500 && radius < 99500) { //99
url = url.replace(/filter%5Blocation%5D%5Bradius%5D\=[0-9\.]+/, `filter[location][radius]=${4000000}`);
}
}
if (url.match(/v4\/groups\//)) {
if (travelMode) {
url = url.replace(/filter%5Blocation%5D%5Blat%5D\=[-0-9\.]+/, `filter[location][lat]=${xhrTravelLat}`);
url = url.replace(/filter%5Blocation%5D%5Blong%5D\=[-0-9\.]+/, `filter[location][long]=${xhrTravelLong}`);
}
if (resigned) {
url = url.replace('statuses[]=REJECTED', 'statuses[]=NONE');
}
}
if (travelMode) {
if (url.match(/v4\/profiles\/popular/)) {
url = url.replace('sort_criteria=LAST_LOGIN_DESC', 'sort_criteria=NEARBY_ASC');
url = url.replace(/filter%5Blocation%5D%5Blat%5D\=[-0-9\.]+/, `filter[location][lat]=${xhrTravelLat}`);
url = url.replace(/filter%5Blocation%5D%5Blong%5D\=[-0-9\.]+/, `filter[location][long]=${xhrTravelLong}`);
}
//url = url.replace('sort_criteria=LAST_LOGIN_DESC', 'sort_criteria=SIGNUP_DESC');
}
if (location.pathname.match(/^\/explore\//) && url.match(/v4\/profiles\?lang/)) {
var loc = location.pathname.match(/[-0-9\.]+/g);
xhrTravelLat = loc[0];
xhrTravelLong = loc[1];
//var radius = $('.js-distance-radius .noUi-handle').attr('aria-valuenow');
//url = url.replace('sort_criteria=NEARBY_ASC', `sort_criteria=LAST_LOGIN_DESC&filter[location][radius]=${radius}`);
//url = url.replace('sort_criteria=NEARBY_ASC', `sort_criteria=SIGNUP_DESC&filter[location][radius]=${radius}`);
}
//include "no entry" to filter
if (filterNoEntry) {
if (url.match(/\/profiles\?/)) {
const categories = [
'&filter%5Bpersonal%5D%5Bgender_orientation%5D%5Bgender%5D%5B%5D=',
'&filter%5Bpersonal%5D%5Bgender_orientation%5D%5Borientation%5D%5B%5D=',
'&filter%5Bpersonal%5D%5Blooking_for%5D%5B%5D=',
'&filter%5Bpersonal%5D%5Bbody_type%5D%5B%5D=',
'&filter%5Bpersonal%5D%5Bbody_hair%5D%5B%5D=',
'&filter%5Bpersonal%5D%5Bhair_color%5D%5B%5D=',
'&filter%5Bpersonal%5D%5Bhair_length%5D%5B%5D=',
'&filter%5Bpersonal%5D%5Bethnicity%5D%5B%5D=',
'&filter%5Bsexual%5D%5Banal_position%5D%5B%5D=',
'&filter%5Bsexual%5D%5Bdick_size%5D%5B%5D=',
'&filter%5Bsexual%5D%5Bconcision%5D%5B%5D=',
'&filter%5Bsexual%5D%5Bsafer_sex%5D%5B%5D=',
'&filter%5Bsexual%5D%5Bfetish%5D%5B%5D=',
'&filter%5Bsexual%5D%5Bsm%5D%5B%5D=',
'&filter%5Bsexual%5D%5Bfisting%5D%5B%5D='
]
for (let item of categories) {
url = url.replace(item, item + 'NO_ENTRY' + item)
}
}
}
//full profile
if (url.match(/v4\/(hunqz\/)?profiles\/[-\w]+\/full\?/)) {
this.addEventListener('load', function() {
xhrFull = JSON.parse(this.response)
//console.log('xhrFull');
});
}
//show group posts of deleted users
if (postFromDeleted) {
if (url.match(/v4\/groups\/\d+\/posts\?/)) {
this.addEventListener('load', function() {
try {
this.xhr = JSON.parse(this.response)
for (let item of this.xhr.items) {
if (item.deleted) {
//console.log(`deleted`);
delete item.deleted;
//item.edit_status = 'NO_EDIT';
item.content = `[Gelöschter Beitrag]\n${item.content}`;
}
if (item.owner.deletion_date) {
//console.log(`deletion_date`);
delete item.owner.deletion_date;
item.content = `[Profil gelöscht]\n\n${item.content}`;
}
}
Object.defineProperty(this, 'responseText', {
writable: true
});
this.responseText = JSON.stringify(this.xhr)
} catch(e) {
}
});
}
}
return oldXHROpen.apply(this, arguments);
}
})();
// ***** Run at login *****
//init
var commonGroupsList = [], visitorsList = [], visitsList = [];
function runAtLogin (jNode) {
//init common groups
commonGroupsList = [];
$.ajax({headers: ajaxHead(), url: '/api/v4/profiles/me/groups?lang=de&length=10000&pick=items.*.(id,name,display_name)'})
.done(function (data) {
for (var item of data.items) {
commonGroupsList.push(item);
}
//console.log(commonGroupsList);
waitForKeyElements ('div[class*="Tile__BaseTile-"]', handleGroupTiles);
//DYNAMIC_TWEAKS.push({selector: 'li[class*="list__item--group-tile-"] a, .profile .js-profile-stats section > div > a, .profile .js-profile-groups ul > a, .js-list li[class*="Tile--"] a, #search div[class^="GroupThird-"] a', tweak: handleGroupTiles});
});
//visitors, visits
$.ajax({headers: ajaxHead(), url: '/api/v4/visitors?lang=de&length=10000&pick=items.*.(name,date_visited)'})
.done(function (data) {
for (var item of data.items) {
if (testMode) visitorsList.push(item);
}
console.log(visitorsList);
});
$.ajax({headers: ajaxHead(), url: '/api/v4/visits?lang=de&length=10000&pick=items.*.(name,date_visited)'})
.done(function (data) {
for (var item of data.items) {
if (testMode) visitsList.push(item);
}
console.log(visitsList);
});
}
// ***** MutationObserver *****
/*** Functions for accessibility tweaks ***/
function makeHeading(el, level) {
el.setAttribute("role", "heading");
el.setAttribute("aria-level", level);
}
function makeRegion(el, label) {
el.setAttribute("role", "main");
el.setAttribute("aria-label", label);
}
function makeButton(el, label) {
el.setAttribute("role", "button");
if (label) el.setAttribute("aria-label", label);
}
function makeButtonFromText(el, label) {
el.setAttribute("role", "button");
if (!label) label = '';
el.setAttribute("aria-label", `${label}${el.textContent.trim()}`);
}
function makeIcon(el, label) {
el.setAttribute("role", "img");
el.setAttribute("aria-label", label);
}
function makePresentational(el) {
el.setAttribute("role", "presentation");
}
function setLabel(el, label) {
el.setAttribute("aria-label", label);
}
function setLabelFromTitle(el, label) {
if (!label) label = '';
el.setAttribute("aria-label", `${label}${el.getAttribute('title')}`);
}
function setLabelFromText(el) {
el.setAttribute("aria-label", el.textContent.trim());
}
function setLabelFromChildText(el) {
el.parentNode.setAttribute("aria-label", el.textContent.trim());
}
function makeRadio(el) {
el.setAttribute("role", "radio");
el.setAttribute("aria-checked", "false");
}
function makeRadioChecked(el) {
el.setAttribute("role", "radio");
el.setAttribute("aria-checked", "true");
}
/*** Code to apply the tweaks when appropriate ***/
function applyTweaks(root, tweaks) {
for (let tweak of tweaks) {
for (let el of root.querySelectorAll(tweak.selector)) {
if (Array.isArray(tweak.tweak)) {
let [func, ...args] = tweak.tweak;
func(el, ...args);
} else {
tweak.tweak(el);
}
}
}
}
function initMutationObserver() {
applyTweaks(document, LOAD_TWEAKS);
applyTweaks(document, DYNAMIC_TWEAKS);
}
let observer = new MutationObserver(function(mutations) {
for (let mutation of mutations) {
try {
if (mutation.type === "childList") {
for (let node of mutation.addedNodes) {
if (node.nodeType != Node.ELEMENT_NODE) {
continue;
}
applyTweaks(node, DYNAMIC_TWEAKS);
}
/*for (let node of mutation.removedNodes) {
if (node.nodeType != Node.ELEMENT_NODE) {
continue;
}
applyTweaks(node, DYNAMIC_TWEAKS);
}*/
/*} else if (mutation.type === "attributes") {
if (mutation.attributeName == "class") {
applyTweaks(mutation.target, DYNAMIC_ATTRIBUTE_TWEAKS);
}*/
}
} catch (e) {
// Catch exceptions for individual mutations so other mutations are still handled
console.log(`Exception while handling mutation: ${e}`);
}
}
});
observer.observe(document, {childList: true, subtree: true});
let observerAttr = new MutationObserver(function(mutations) {
for (let mutation of mutations) {
try {
if (mutation.type === "attributes") {
if (mutation.attributeName == "class") {
applyTweaks(mutation.target, DYNAMIC_ATTRIBUTE_TWEAKS);
}
}
} catch (e) {
// Catch exceptions for individual mutations so other mutations are still handled
console.log(`Exception while handling mutation: ${e}`);
}
}
});
observerAttr.observe(document, {childList: true, attributes: true, subtree: true, attributeFilter: ["class"]});
/*** Define the actual tweaks ***/
// Tweaks to be applied on load
const LOAD_TWEAKS = [
]
// Tweaks to be applied whenever a node is added
const DYNAMIC_TWEAKS = [
//RomeoEnhancer (see also waitForKeyElements below)
//{selector: 'div#marionette.is-logged-in', tweak: runAtLogin},
{selector: '#search input', tweak: searchInput},
{selector: 'header li', tweak: menuLinks},
//{selector: 'div[class*="Central--"] ul.Tabbed-nav--2c5l9 li.is-selected', tweak: navLinks},
{selector: '#offcanvas-nav div[class^="Version"], div.js-filter-button button', tweak: handleVersionBookmark},
//{selector: '#messenger:not(.is-hidden) div[class^="Box"] div p[class^="SpecialText"]', tweak: previewMessage},
{selector: '#messenger div:is(.js-correspondence, .js-header) div.reactView div > a > p', tweak: showLoginLocation},
//{selector: 'div.js-correspondence div.js-header-region div[class*="ContextMenu__"] ul', tweak: threadOptionsMenu},
{selector: '.js-profile-footprints h1', tweak: handleFootprints},
{selector: '.js-quick-filter .js-anal-position > div', tweak: handleFilterNoEntry},
{selector: '#messenger div.js-chat .reactView a[href^="/messenger/chat"]', tweak: handleMessage},
{selector: '#messenger div.js-contacts .reactView a[href^="/messenger/contacts"]', tweak: handleContacts},
{selector: ':is(div.js-wrapper, div.js-admins, #group-preview) a.js-contact', tweak: handleContactStrip},
{selector: ':is(div.js-wrapper, #visits, #search, .js-profiles) :is(a div.BIG, a div.SMALL, a div.LIST) div > span[class^="sc-"]', tweak: handleTiles},
{selector: '#profiles :is(a div.BIG, a div.SMALL, a div.LIST) div > span[class^="sc-"]', tweak: handleRadar},
{selector: 'div.stream__content a.listitem__body .js-username, div.stream__content div.js-list', tweak: handleStream},
{selector: 'section.profile__stats section > p[class^="BaseText"], section.profile__stats ol', tweak: handleProfile},
//{selector: 'div[class^="Container--3h4tt"] > div.js-groups', tweak: recentPosts},
{selector: '#manage div[class^="FilterBar__Container"] > div > div', tweak: groupManageMode},
{selector: 'div.Container--e53RO div.Container--13Nkp button', tweak: groupTravelLocation},
{selector: '#picture-rating img, #picture-rating p[class^="Text-sc-"]', tweak: ratingInfo},
//{selector: 'div.js-chat .js-scrollable div[class="js-paging-spinner spinner-container l-fancy"]', tweak: fixScroll},
//{selector: '#spotlight-container > div.layer-container-clickable', tweak: removeFeedbackLayer},
{selector: 'div.ui-modal__content p', tweak: handlePrompt},
//{selector: 'head > title', tweak: emptyTitle},
{selector: 'section[class^="PopupWindow__Content"] button[class^="PrimaryButton__Element"]', tweak: reLogin},
{selector: '#metadata-bar p', tweak: imgInfo}, // see also DYNAMIC_ATTRIBUTE_TWEAKS below
//accessibility: navigation items with badges
{selector: '.icon-search', tweak: [makeIcon, "Suchen"]},
{selector: '.icon-visitor', tweak: [makeIcon, "Besucher"]},
{selector: '.icon-chat', tweak: [makeIcon, "Messages"]},
{selector: '.icon-notification-bell', tweak: [makeIcon, "Activity Stream"]},
{selector: '.ui-status--online', tweak: [makeIcon, "Online"]},
{selector: '.ui-status--date', tweak: [makeIcon, "Date"]},
{selector: '.ui-status--sex', tweak: [makeIcon, "Now"]},
{selector: '.icon-airplane', tweak: [makeIcon, "Travel"]},
{selector: '.icon-save-contact', tweak: [makeIcon, "Kontakte"]},
{selector: '.js-nav-item .icon-group-members', tweak: [makeIcon, "Meine Gruppen"]},
//accessibility: profile screen
{selector: '.profile--romeo', tweak: [makeRegion, "Romeo-Profil"]},
{selector: '.profile--hunqz', tweak: [makeRegion, "Hunqz-Profil"]},
{selector: '.icon-add-footprint', tweak: [makeButton, "Fußtaps vergeben"]},
{selector: '.js-remove-footprint', tweak: [setLabelFromTitle]},
{selector: '.js-quickshare-trigger', tweak: [setLabel, "QuickShare-Album teilen"]},
{selector: '.icon-default-contact', tweak: [makeIcon, "Nutzer speichern"]},
{selector: '[id^="profile-"] .icon-save-contact', tweak: [makeIcon, "Nutzer speichern"]},
{selector: '#visits > div', tweak: [makeRegion, "Besucher"]},
{selector: '.icon-back', tweak: [makeIcon, "Zurück"]},
{selector: '.icon-next', tweak: [makeIcon, "Weiter"]},
{selector: '.icon-open-menu-ver', tweak: [makeIcon, "Menü öffnen"]},
{selector: '.icon-open-stats', tweak: [makeIcon, "Profildetails"]},
{selector: '.js-attach-pictures', tweak: [setLabel, "Bilder anhängen"]},
{selector: '.js-submit', tweak: [setLabel, "Abschicken"]},
{selector: 'button[class^="Close--"], button.js-close-button, .js-close-icon button', tweak: [setLabel, "Schließen"]},
{selector: '.js-close-spotlight', tweak: [makeButton, "Schließen"]},
{selector: '.js-hide.js-plus', tweak: [setLabel, "Profilbesuch verstecken"]},
{selector: '.profile-section .reactView p[class^="BodyText"]', tweak: [makeHeading, "3"]},
{selector: '.top-info-header p[class^="BodyText"]', tweak: [makeHeading, "1"]},
{selector: 'button[class^="CollapsibleSection"] > p', tweak: [setLabelFromChildText]},
//accessibility: other
{selector: '.messages-send__select-button', tweak: [setLabel, "Templates, Standort, Bilder senden"]},
{selector: ':not(.js-nav-item) > .icon-group-members', tweak: [makeIcon, "Gruppe"]},
{selector: '.js-settings-privacy div[class*="Radio-"]', tweak: [makeRadio]},
{selector: '.js-settings-privacy div[class*="Selected-"] div[class*="Radio-"]', tweak: [makeRadioChecked]},
]
// Tweaks to be applied on attribute changes
const DYNAMIC_ATTRIBUTE_TWEAKS = [
{selector: 'div.swiper-slide-visible.swiper-slide-active div.swiper-zoom-container', tweak: imgInfo},
]
initMutationObserver();
// ***** waitForKeyElements (for nodes not handled by MutationObserver) *****
waitForKeyElements ('div#marionette.is-logged-in', runAtLogin, true);
waitForKeyElements ('div[class*="Central--"] ul.Tabbed-nav--2c5l9 li.is-selected', navLinks);
waitForKeyElements ('#messenger:not(.is-hidden) div[class^="Box"] div p[class^="SpecialText"]', previewMessage);
waitForKeyElements ('div.js-correspondence div.js-header-region div[class*="ContextMenu__"] ul', threadOptionsMenu);
waitForKeyElements ('div.js-groups', recentPosts);
waitForKeyElements ('div.js-chat .js-scrollable div[class="js-paging-spinner spinner-container l-fancy"]', fixScroll, true);