OctoSpaccHub/static/MBViewer/js/telegram-web.js

380 lines
12 KiB
JavaScript

(function($) {
$.fn.redraw = function() {
return this.map(function(){ this.offsetTop; return this; });
};
$.fn.scrollIntoView = function(options) {
options = options || {}
return this.first().each(function() {
var position = options.position || 'auto',
padding = options.padding || 0,
duration = options.duration || 0;
var $item = $(this),
$cont = $item.scrollParent(),
scrollTop = $cont.scrollTop(),
positionTop = 0,
paddingTop = 0,
itemHeight = $item.outerHeight(),
isBody = false;
if ($cont.get(0) === document) {
isBody = true;
$cont = $(window);
positionTop = $item.offset().top;
paddingTop = $('header').height() + 1;
} else {
positionTop = $item.offset().top - $cont.offset().top + scrollTop;
}
if (options.slidedEl) {
if (options.slidedEl === 'this') {
options.slidedEl = this;
}
$(options.slidedEl, this).each(function() {
itemHeight += (this.scrollHeight - this.clientHeight);
});
}
var itemTop = positionTop,
itemBottom = itemTop + itemHeight,
contHeight = $cont.height(),
contTop = scrollTop + padding + paddingTop,
contBottom = scrollTop + contHeight - padding,
scrollTo = null;
if (position == 'auto') {
if (itemTop < contTop) {
scrollTo = itemTop - padding - paddingTop;
} else if (itemBottom > contBottom) {
if (itemHeight > contHeight - padding - padding) {
scrollTo = itemTop - padding - paddingTop;
} else {
scrollTo = itemBottom - contHeight + padding;
}
}
} else if (position == 'top' || position == 'center') {
if (contHeight > itemHeight) {
padding = (contHeight - paddingTop - itemHeight) / 2;
}
scrollTo = itemTop - padding - paddingTop;
} else if (position == 'bottom') {
if (itemHeight > contHeight - padding - padding) {
scrollTo = itemTop - padding - paddingTop;
} else {
scrollTo = itemBottom - contHeight + padding;
}
}
if (scrollTo) {
if (duration) {
if (isBody) {
$cont = $('html');
}
$cont.stop().animate({scrollTop: scrollTo}, duration);
} else {
$cont.scrollTop(scrollTo);
}
}
});
};
})(jQuery);
function doesSupportThinBoxShadow() {
if (!window.getComputedStyle) return;
var div = document.createElement('div');
div.style.boxShadow = '0 0 0 0.5px black';
div.style.display = 'none';
document.body.appendChild(div);
var box_shadow = window.getComputedStyle(div).boxShadow;
document.body.removeChild(div);
return box_shadow.indexOf('0.5') >= 0;
}
function formatDate(datetime) {
var date = new Date(datetime);
var cur_date = new Date();
var j = date.getDate();
var M = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'][date.getMonth()];
var Y = date.getFullYear();
if (cur_date.getFullYear() == date.getFullYear()) {
return M + ' ' + j;
}
if (!j && !M && !Y) {
return 'Undefined';
}
return M + ' ' + j + ', ' + Y;
}
function getCssProperty(el, prop) {
if (window.getComputedStyle) {
return window.getComputedStyle(el, '').getPropertyValue(prop) || null;
} else if (el.currentStyle) {
return el.currentStyle[prop] || null;
}
return null;
}
function isVisible(el, padding) {
var node = el, val;
var visibility = getCssProperty(node, 'visibility');
if (visibility == 'hidden') return false;
while (node) {
if (node === document.documentElement) break;
var display = getCssProperty(node, 'display');
if (display == 'none') return false;
var opacity = getCssProperty(node, 'opacity');
if (opacity !== null && opacity < 0.1) return false;
node = node.parentNode;
}
if (el.getBoundingClientRect) {
padding = +padding || 0;
var rect = el.getBoundingClientRect();
var html = document.documentElement;
if (rect.bottom < padding ||
rect.right < padding ||
rect.top > (window.innerHeight || html.clientHeight) - padding ||
rect.left > (window.innerWidth || html.clientWidth) - padding) {
return false;
}
}
return true;
}
var TWeb = {
init: function(options) {
options = options || {};
if (!doesSupportThinBoxShadow()) {
$('body').addClass('thin_box_shadow');
}
$('.js-widget_message').each(function() {
TPost.init(this);
});
TWeb.updateServiceDate($('.js-widget_message_wrap'));
if (options.scrollToPost) {
TWeb.highlightPost(options.scrollToPost, true);
} else {
$('.js-widget_message_wrap').last().scrollIntoView({position: 'top'});
}
$('body').removeClass('no_transitions');
$('.js-header_search').on('focus', function() {
$('header.tgme_header').removeClass('search_collapsed');
$(this).select();
});
$('.js-header_search').on('blur', function() {
$('header.tgme_header').addClass('search_collapsed');
});
TWeb.initScroll();
TWeb.initViews();
if (window.matchMedia) {
var darkMedia = window.matchMedia('(prefers-color-scheme: dark)');
TWeb.toggleTheme(darkMedia.matches);
darkMedia.addListener(function(e) {
TWeb.toggleTheme(e.matches);
});
}
if (true) { // wallpaper supported
$('body').addClass('twallpaper');
TWallpaper.init($('#tgme_background').get(0));
$(window).on('focus', function() { // chrome fix
TWallpaper.update();
});
var reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
reduceMotion.addEventListener('change', function() {
TWallpaper.scrollAnimate(!reduceMotion.matches);
});
TWallpaper.scrollAnimate(!reduceMotion.matches);
}
},
toggleTheme: function(dark) {
$('html').toggleClass('theme_dark', dark);
},
initScroll: function() {
var $document = $(document);
$document.on('scroll', function() {
$before = $('.js-messages_more[data-before]');
$after = $('.js-messages_more[data-after]');
var wheight = $(window).height();
var scrollTop = $(window).scrollTop();
if ($before.length) {
var bottom = $before.offset().top + $before.height() - scrollTop;
if (bottom > -wheight * 3) {
TWeb.loadMore($before);
}
}
if ($after.length) {
var top = $after.offset().top - scrollTop;
if (top < wheight * 3) {
TWeb.loadMore($after);
}
}
});
$document.on('click', '.js-messages_more', function() {
var $el = $(this);
TWeb.loadMore($el);
});
},
initViews: function() {
TWeb.viewsMap = {};
TWeb.viewsQueue = [];
TWeb.viewsLastLoad = 0;
var $document = $(document), $window = $(window);
$document.ready(function() {
$window.on('scroll resize', TWeb.checkVisiblePosts);
TWeb.checkVisiblePosts();
});
},
checkVisiblePosts: function() {
$('.js-widget_message[data-view]').each(function() {
if (isVisible(this, 50)) {
var view = this.getAttribute('data-view');
if (view) {
TWeb.addViewToQueue(view);
}
this.removeAttribute('data-view');
}
});
},
addViewToQueue: function(view) {
if (!TWeb.viewsMap[view]) {
TWeb.viewsMap[view] = true;
TWeb.viewsQueue.push(view);
TWeb.sendViewsMaybe();
}
},
sendViewsMaybe: function() {
var now = +(new Date);
if (now - TWeb.viewsLastLoad < 10000 && TWeb.viewsQueue.length < 50) {
return setTimeout(TWeb.sendViewsMaybe, 10000);
}
if (TWeb.viewsQueue.length > 0) {
var views = TWeb.viewsQueue.join(';');
TWeb.viewsQueue = [];
$.ajax('/v/', {type: 'POST', data: {views: views}});
TWeb.viewsLastLoad = now;
}
},
highlightPost: function(post_id, scroll) {
var $postWrap = $('.js-widget_message[data-post="' + post_id + '"]').parents('.js-widget_message_wrap');
if (scroll) {
$postWrap.scrollIntoView({position: 'top'});
}
$postWrap.addClass('prepare_highlight').redraw().addClass('highlight');
setTimeout(function() {
$postWrap.removeClass('highlight');
setTimeout(function() {
$postWrap.removeClass('prepare_highlight');
}, 300);
}, 1500);
},
updateServiceDate: function($wrapEls, skip_first) {
$wrapEls.each(function() {
if (!$(this).data('msg_date')) {
var datetime = $('time[datetime]', this).attr('datetime');
if (datetime) {
var date_formatted = formatDate(datetime);
$('<div class="tgme_widget_message_service_date_wrap"><div class="tgme_widget_message_service_date">' + date_formatted + '</div></div>').appendTo(this);
$(this).data('msg_date', date_formatted);
}
}
});
var len = $wrapEls.size();
for (var i = len - 1; i >= 0; i--) {
var $wrapEl = $wrapEls.eq(i);
var $prevWrapEl = i > 0 ? $wrapEls.eq(i - 1) : null;
if (!$prevWrapEl && skip_first) continue;
var date_visible = !$prevWrapEl || $prevWrapEl.data('msg_date') != $wrapEl.data('msg_date');
$wrapEl.toggleClass('date_visible', date_visible);
}
},
loadMore: function($moreEl, dataOverride) {
var loading = $moreEl.data('loading');
if (loading) {
return false;
}
var wrapType = '';
var after = $moreEl.attr('data-after');
var before = $moreEl.attr('data-before');
if (after !== undefined) {
wrapType = 'after';
} else if (before !== undefined) {
wrapType = 'before';
}
var url = $moreEl.attr('href');
$moreEl.data('loading', true);
$moreEl.addClass('dots-animated');
var _load = function(url, before, after) {
if (dataOverride) {
_loadContinue(dataOverride);
} else if (url) {
$.ajax(url, {
success: function(data) { _loadContinue(data) },
error: function(data) {
var timeout = $moreEl.data('timeout') || 1000;
$moreEl.data('timeout', timeout > 60000 ? timeout : timeout * 2);
setTimeout(function(){ _load(url, before, after); }, timeout);
}
});
}
};
var _loadContinue = async function(data) {
var messageHistoryCountBefore = $('section.tgme_channel_history.js-message_history .tgme_widget_message_wrap.js-widget_message_wrap').length;
var [initialHtmlScroll, initialHtmlHeight] = [$('html').scrollTop(), $('html').height()];
var $data = $(await MakeMbHtml(data, wrapType));
var $helper = $('<div class="tgme_widget_messages_helper"></div>');
$helper.append($data);
$('.js-message_history').append($helper);
$helper.find('.js-widget_message').each(function() {
TPost.init(this);
});
$helper.remove();
var wrapEls = $data.filter('.js-widget_message_wrap').get();
var $moreElWrap = $moreEl.parents('.js-messages_more_wrap');
if (before) {
var firstWrapEl = $moreElWrap.next('.js-widget_message_wrap').get();
var $wrapEls = $(wrapEls.concat(firstWrapEl));
TWeb.updateServiceDate($wrapEls);
var y = $moreElWrap.offset().top + $moreElWrap.outerHeight(true) - $(document).scrollTop();
$data.insertBefore($moreElWrap);
var st = $moreElWrap.offset().top - y;
$moreElWrap.remove();
$(window).scrollTop(st);
} else {
var lastWrapEl = $moreElWrap.prev('.js-widget_message_wrap').get();
var $wrapEls = $(lastWrapEl.concat(wrapEls));
TWeb.updateServiceDate($wrapEls, lastWrapEl.length > 0);
$data.insertBefore($moreElWrap);
$moreElWrap.remove();
}
// load more messages if the current viewport is not tall enough to be scrolled
if (!IsScrollableY($('html')[0])) {
MbState.wasEverNonScrollable = true;
MbState.lastMustScroll = true;
TWeb.loadMore($('.js-messages_more_wrap > a'));
return;
}
if (MbState.lastMustScroll) {
return _scrollToLastMessage();
}
if (MbState.wasEverNonScrollable) {
return _scrollToLastMessage();
}
if (wrapType === 'before') {
$('html').scrollTop(initialHtmlScroll + $('html').height() - initialHtmlHeight);
}
if (MbState.startingPost && messageHistoryCountBefore === 1) {
TWeb.highlightPost(MbState.startingPost?.id || MbState.startingPost?.ID);
}
};
var _scrollToLastMessage = function() {
//$('#BottomAnchor')[0].scrollIntoView();
var lastMessageElem = $('.tgme_widget_message_wrap').last()[0];
lastMessageElem.scrollIntoView();
// scroll a bit more to show the message nicely if it's taller than viewport
if (lastMessageElem.clientHeight > ($('html')[0].clientHeight - 48)) {
$('html')[0].scrollTop -= 48;
}
MbState.lastMustScroll = false;
};
// avoid automatic infinite upscrolling
if ($('html')[0].scrollTop === 0) {
$('html')[0].scrollTop = 16;
}
_load(url, before, after);
},
}
window.TWeb = TWeb;