[Make DTF Great Again] UserScript показывающий ленту "Сейчас обсуждают" (последние комментарии на сайте)

Для пользователей десктопной версии без плюса.

Видео ускорено в 30 раз
// ==UserScript== // @name DTF Right Aside Redesign Edition // @namespace ¯\_(ツ)_/¯ // @match https://dtf.ru/* // @version 0.2.0 // @author ¯\_(ツ)_/¯ // @description ¯\_(ツ)_/¯ // @require https://cdn.socket.io/socket.io-2.3.1.js // ==/UserScript== (() => { //Сортировать ли комментарии по юзерам в подписке? //вверху списка будут юзеры, на которых подписан пользователь этого скрипта const SORT_COMMENTS_BY_SUBSCRIPTIONS = true; //Время обновления ленты комментариев в секундах const UPDATE_TIME = 20; const DEBUG = false; const LOG_NAME = `DTF Right Aside Redesign Edition`; const _log = DEBUG ? function(d) { console.log(`${LOG_NAME}:`); console.log(d); } : ()=>{}; let last_comments = []; let right_aside_html = ''; let aside__right__elem; let subscriptions_user_ids = []; async function get_subscriptions_user_ids__by_cache() { const ts = localStorage.getItem('aside_re__get_subscriptions__last_ts'); if (!ts) return false; if ((new Date().getTime()-parseInt(ts))>24*60*60*1000) return false; let user_ids_string = localStorage.getItem('aside_re__get_subscriptions__user_ids'); if (!user_ids_string) return false; let user_ids = JSON.parse(user_ids_string); if (!user_ids) return false; subscriptions_user_ids = user_ids; return true; } async function get_subscriptions_user_ids() { if (await get_subscriptions_user_ids__by_cache()) return; let ls_user = localStorage.getItem('user'); if (!ls_user) return; let user = JSON.parse(ls_user); if (!user || !user.id) return; const response = await fetch('https://api.dtf.ru/v2.5/subsite/subscriptions?subsiteId=' + user.id); const response_json = await response.json(); for (let k = 0; k < response_json.result.items.length; k++) { if (response_json.result.items[k]) { subscriptions_user_ids.push(response_json.result.items[k].id); } } localStorage.setItem('aside_re__get_subscriptions__user_ids', JSON.stringify(subscriptions_user_ids)); localStorage.setItem('aside_re__get_subscriptions__last_ts', new Date().getTime()); } async function add_right_aside() { if (last_comments.length === 0) return; //удаляем комменты старше 2 минут last_comments = last_comments.filter(last_comment => ((new Date().getTime() - last_comment.timestamp) < 120000)) //ставим приоритет по наличию юзеров в подписке и по времени last_comments.forEach(function callback(last_comment) { last_comment.priority = 0; if (SORT_COMMENTS_BY_SUBSCRIPTIONS && subscriptions_user_ids.includes(last_comment.user_id)) { last_comment.priority += 1000000; } last_comment.priority += 120000 - (new Date().getTime() - last_comment.timestamp); }); last_comments.sort(function(comment_1, comment_2){ return comment_2.priority - comment_1.priority; }); last_comments.slice(0,25); _log(last_comments); get_right_aside_html(); aside__right__elem.innerHTML = right_aside_html; } function get_right_aside_html() { let html = ` <div id="player"></div> <div class="live"> <div class="live__title">Сейчас обсуждают <button class="icon-button live__title-pause" type="button"> <svg class="icon icon--play_small" width="8" height="8"> <use xlink:href="#play_small"></use> </svg> </button> </div> <div class="live__main" data-scrollable=""> <div></div>`; last_comments.forEach(function(comment) { html+= ` <div class="live-item"> <div class="author" > <a class="author__avatar" style="height:36px;" href="https://dtf.ru/u/${comment.user_id}" targer_"_blank" > <div data-loaded="true" class="andropov-media andropov-media--rounded andropov-media--bordered andropov-media--has-preview andropov-image" style="aspect-ratio: 1 / 1; width: 36px; height: 36px; max-width: none; --background-color: #dddddd;"> <picture> <source srcSet="${comment.user_avatar}-/format/webp, ${comment.user_avatar}-/format/webp 2x" type="image/webp"> <img src="${comment.user_avatar}" srcSet="${comment.user_avatar}, ${comment.user_avatar} 2x" alt="" loading="lazy"> </picture> </div> </a> <div class="author__main"> <a class="author__name" href="https://dtf.ru/u/${comment.user_id}">${comment.user_name}</a> <div class="live-item__in-post">в посте</div> </div> <div class="author__details"> <a class="live-item__entry-title" title="Запись в посте &quot;${comment.content_title}&quot;" href="${comment.content_url}">${comment.content_title} </a> </div> </div> <a class="live-item__main" href="${comment.comment_url}"> <div class="live-item__text"><p>${comment.comment_text}</p></div> </a> </div>`; }); html+= ` </div> </div> </div>`; right_aside_html=html; } function add_css() { let css = ` .live-item{--max-text-lines-count: 3;padding:14px 0}.live-item__in-post{color:var(--theme-color-text-secondary)}.live-item__entry-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:500}@media (hover: hover){.live-item__main:hover{opacity:.72}}.live-item__main{display:block}.live-item__text{font-size:15px;line-height:22px;margin-top:7px;display:-webkit-box;-webkit-line-clamp:var(--max-text-lines-count);-webkit-box-orient:vertical;overflow:hidden}.live-item__text a{color:var(--theme-color-signal-active-default);cursor:pointer}@media (hover: hover){.live-item__text a:hover{color:var(--theme-color-signal-active-dark)}}.live-item__text a{pointer-events:none}.live-item__text .quote{--line-width: 4px;--offset-x: 12px;--offset-y: 8px;display:block;position:relative;padding-left:calc(var(--line-width) + var(--offset-x));margin-bottom:var(--offset-y);margin-top:var(--offset-y)}.live-item__text .quote:before{content:"";flex-shrink:0;width:var(--line-width);position:absolute;top:4px;bottom:4px;left:0;background-color:var(--theme-color-border);border-radius:var(--line-width)}.live-item__text .quote{--offset-y: 4px }.live-item__text .quote:before{background-color:var(--theme-color-border-over-background)}.live-item__media{--border-radius: 10px;display:flex;margin-top:9px}.live-item__media:first-child{margin-top:11px}.live-item .author{gap:0 8px}.live-item .author__avatar{transform:none}.live-item .author__main{font-size:13px;line-height:18px}.live-item .author__details{color:var(--theme-color-text-primary)}:root{--safe-tabbar-height: calc(var(--layout-tabbar-height) + env(safe-area-inset-bottom)) }@keyframes underlay-in{0%{opacity:0}to{opacity:1}}@keyframes modal-enter{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:none}}@keyframes modal-enter-slide{0%{opacity:0;transform:translate3d(0,100%,0)}to{opacity:1;transform:translateZ(0)}}.live{height:100%;display:grid;grid-template-rows:auto 1fr;overflow:hidden;position:relative;z-index:1}.live__title{font-weight:500;padding:0 var(--layout-right-aside-offset) 16px;background-color:var(--theme-color-background);display:flex;align-items:center;justify-content:flex-start}.live__title:after{content:"";position:absolute;top:24px;left:50%;width:100%;height:12px;border-radius:100%;transform:translate(-50%);box-shadow:0 4px 20px var(--theme-color-shadow-over-background);z-index:-1;opacity:0}.live__title--with-shadow:after{opacity:1}.live__title-pause{flex-shrink:0;background-color:var(--theme-color-button-secondary);margin-left:8px;padding:6px;will-change:transform}@media (hover: hover){.live__title-pause:hover{filter:brightness(.94)}}.live__title-pause--animated{animation:button-touched .2s cubic-bezier(.4,0,.2,1) forwards}.live__main{padding:0 var(--layout-right-aside-offset);min-height:0;overflow-x:hidden;overflow-y:auto;scrollbar-width:none}.live__main::-webkit-scrollbar{display:none}@keyframes live-item-in{0%{opacity:0}}@keyframes button-touched{50%{transform:scale(1.2)}} .author { --avatar-size: 36px !important;} `; const styleSheet = document.createElement("style"); styleSheet.innerText = css; document.head.appendChild(styleSheet); } window.addEventListener('load', async () => { add_css(); if (SORT_COMMENTS_BY_SUBSCRIPTIONS) { await get_subscriptions_user_ids(); } aside__right__elem = document.querySelector('.aside--right'); setInterval(add_right_aside, UPDATE_TIME * 1000); }) const socket = io('https://ws-sio.dtf.ru', { transports: ['websocket'] }); socket.emit('subscribe', {'channel': 'live'}); socket.on('connect', () => { _log('Connected to Socket'); }); socket.on('disconnect', (reason) => { _log("client disconnected"); if (reason === 'io server disconnect') { _log("server disconnected the client, trying to reconnect"); socket.connect(); } else { _log("trying to reconnect again with server"); } }); socket.on('connect_error', (err) => { _log(`connect_error due to ${err.message}`); }); socket.on('error', (error) => { _log(error); }); socket.on('event', (event) => { socket_event(event); }); function socket_event(event) { _log(event); if (!(event && event.data && event.data.type && event.data.type === 'comment_add')) return false; let comment_text = event.data.text; if (comment_text.length>90) { comment_text = comment_text.substring(0, 90) + ' ...'; } let post_title = event.data.content.title; if (post_title.length>60) { post_title = post_title.substring(0, 60) + ' ...'; } let new_data = { comment_id : event.data.comment_id, comment_date : event.data.date, comment_text : comment_text, comment_url : event.data.url, user_id : event.data.user.id, user_url : event.data.user.url, user_name : event.data.user.name, user_avatar : 'https://leonardo.osnova.io/' + event.data.user.avatar+ '/-/scale_crop/72x72/', content_url : event.data.content.url, content_title : post_title, timestamp : new Date().getTime(), priority : 0 } last_comments.push(new_data); } })();

Лента последних комментариев обновляется раз в 20 секунд (можно изменить).
По умолчанию комментарии сортируются по пользователям, на которых подписан пользователь скрипта. Если такая сортировка не нужна, то замените в скрипте:

const SORT_COMMENTS_BY_SUBSCRIPTIONS = false;

Как установить:

  • Установить плагин для работы UsersScript для браузера: ViolentMonkey, TamperMonkey, GreaseMonkey.
  • В настройках плагина добавить этот скрипт копированием и вставкой. Сохранить.

Благодарю юзера mr2zeek за помощь в написании скрипта.

1414
19 комментариев

Не знаю зачем вообще возвращать ленту комментариев, юзлесс же

3
Ответить

Тут все стремились избавиться от нее, зачем возвращать

1
Ответить

Избавиться слишком просто:
(() => {
window.addEventListener('load', async () => {
var aside_right = document.querySelector('.aside--right')
aside_right.parentNode.removeChild(aside_right)
})
})();

А вот вернуть пользователям скрытую за пейволлом подписки фичу - это идейно.

2
Ответить

@mr2zeek мамкин программист

1
Ответить