// ==UserScript== // @id OpenPeriscope@pmmlabs.ru // @name Periscope Web Client // @namespace https://greasyfork.org/users/23 // @description Periscope client based on API requests. Visit example.net for launch. // @include https://api.twitter.com/oauth/authorize // @include http*://example.net/* // @version 2.0 // @author Pmmlabs@github // @grant GM_xmlhttpRequest // @connect periscope.tv // @connect twitter.com // @connect digits.com // @require https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.js // @require https://github.com/brix/crypto-js/raw/master/crypto-js.js // @require http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js // @require http://leaflet.github.io/Leaflet.markercluster/dist/leaflet.markercluster-src.js // @require https://github.com/iamcal/js-emoji/raw/master/lib/emoji.js // @require https://github.com/zenorocha/clipboard.js/raw/v2.0.0/dist/clipboard.min.js // @require https://github.com/le717/jquery-spoiler/raw/master/jquery.spoiler.min.js // @require https://github.com/nathancahill/Split.js/raw/master/split.min.js // @downloadURL https://github.com/Pmmlabs/OpenPeriscope/raw/master/Periscope_Web_Client.user.js // @updateURL https://github.com/Pmmlabs/OpenPeriscope/raw/master/Periscope_Web_Client.meta.js // @icon https://github.com/Pmmlabs/OpenPeriscope/raw/master/images/openperiscope.png // @noframes // @grant GM_addStyle // @grant GM_getResourceText // @resource CSS style.css // ==/UserScript== var emoji = new EmojiConvertor(); NODEJS = typeof GM_xmlhttpRequest === 'undefined'; var IMG_PATH = 'https://raw.githubusercontent.com/Pmmlabs/OpenPeriscope/master'; var settings = JSON.parse(localStorage.getItem('settings')) || {}; if (NODEJS) { // for NW.js const https = require('https'); const url = require('url'); GM_xmlhttpRequest = function (options) { var onload = options.onload; options.onload = null; var u = url.parse(options.url); options.host = u.host; options.hostname = u.hostname; options.path = u.path; options.protocol = u.protocol; var chunks = ''; var req = https.request(options, function (res) { res.setEncoding('utf8'); res.on('data', function (chunk) { chunks += chunk; }); res.on('end', function() { onload({ status: res.statusCode, responseText: chunks }); }); }); req.on('error', function (e) { console.error(e); }); if (options.data) req.write(options.data); req.end(); return req; }; IMG_PATH = ''; // Back & Forward hotkeys $(window).on('keydown', function (e) { if (e.keyCode == 8 && e.target == document.body) { //backspace if (e.shiftKey) history.forward(); else history.back(); } else if (e.keyCode == 116) //F5 location.href='/index.html'; }); // default download path = executable path if (!settings.downloadPath) setSet('downloadPath', process.execPath.substring(0, process.execPath.lastIndexOf(process.platform === 'win32' ? '\\' : '/'))); if (settings.windowSize) window.resizeTo(settings.windowSize.width, settings.windowSize.height); setTimeout(function(){ $(window).resize(function (e) { setSet('windowSize', { width: $(this).width(), height: $(this).height() }); }) }, 1000); } if (location.href == 'https://api.twitter.com/oauth/authorize') { location.href = $('meta[http-equiv="refresh"]').attr('content').substr(6).replace('twittersdk://openperiscope/index.html', 'http://example.net/'); } else { $('style').remove(); $(document.head).append(''); if (NODEJS) { $(document.head).append('') } else { var resourceText = GM_getResourceText("CSS").replace(/url\("/g, 'url("' + IMG_PATH); GM_addStyle(resourceText); } document.title = 'OpenPeriscope'; var oauth_token = localStorage.getItem('oauth_token'), oauth_verifier = localStorage.getItem('oauth_verifier'), session_key = localStorage.getItem('session_key'), session_secret = localStorage.getItem('session_secret'), loginTwitter = localStorage.getItem('loginTwitter'); $(function() { if (loginTwitter) { loginTwitter = JSON.parse(loginTwitter); Ready(loginTwitter); refreshProfile(); } else if (session_key && session_secret) { SignIn3(session_key, session_secret); } else if (oauth_token && oauth_verifier) { SignIn2(oauth_token, oauth_verifier); } else if ((oauth_token = getParameterByName('oauth_token')) && (oauth_verifier = getParameterByName('oauth_verifier'))) { localStorage.setItem('oauth_token', oauth_token); localStorage.setItem('oauth_verifier', oauth_verifier); SignIn2(oauth_token, oauth_verifier); } else { var signInButton = $('Sign in with twitter').click(SignIn1); var signInSMSButton = $('Sign in with SMS').click(SignInSMS); $(document.body).html('
').append(signInButton, signInSMSButton); } $(document.body).append(Progress.elem); }); } function getParameterByName(name) { name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), results = regex.exec(location.search); return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); } function lazyLoad(parent) { var right = $('#right'); $(parent).on('scroll', function () { clearTimeout($.data(this, 'scrollTimer')); // for preventing dozens of firing $.data(this, 'scrollTimer', setTimeout(function () { var windowHeight = $(window).height(); var scrollTop = $(window).scrollTop(); right.find('img[lazysrc]:visible').each(function () { var el = $(this); var top = el.offset().top; if (scrollTop < top + el.height() + 100 && scrollTop + windowHeight + 100 > top) { // 100 is handicap el.attr('src', el.attr('lazysrc')); el.removeAttr('lazysrc'); } }) }, 100)); }); } var selfAvatar; function Ready(loginInfo) { console.log('ready! ', loginInfo); var signOutButton = $('Sign out'); signOutButton.click(SignOut); var userLink = $('@' + (loginInfo.user.username || loginInfo.user.twitter_screen_name) + '').click(switchSection.bind(null, 'User', loginInfo.user.id)); var userEdit = $(' ').click(switchSection.bind(null, 'Edit')); loginInfo.user.profile_image_urls.sort(function (a, b) { return a.width * a.height - b.width * b.height; }); selfAvatar = $(''); // toolbar var backButton = $('🡄'); backButton.click(function(){history.back()}); var forwardButton = $('🡆'); forwardButton.click(function(){history.forward()}); var addressBar = $('') .val(location.href) .mousemove(function () {return false}) .dblclick(function () {return false}) .keypress(function (e) { if (e.keyCode == 13) location.href = $(this).val(); }); window.onpopstate = function(event) { addressBar.val(document.location); } var toolbar = $('
').append(backButton, forwardButton, addressBar).hide(); var left = $('
').append(signOutButton, selfAvatar, userEdit, '
' + emoji.replace_unified(loginInfo.user.display_name) + '
', userLink); $(document.body).html(toolbar).append(left, '