From e0a74abae6030ca6ab0af5c8fd438f5e448364fc Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Sun, 31 Jul 2016 01:52:37 +0500 Subject: [PATCH 01/54] fix of wrong twistdays which was based on unfiltered promoted twists --- js/interface_home.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/js/interface_home.js b/js/interface_home.js index e59ad6e..5b1984f 100644 --- a/js/interface_home.js +++ b/js/interface_home.js @@ -268,7 +268,9 @@ function refreshTwistdayReminder() { }); for (var i = 0; i < posts.length; i++) { - if (followingUsers.indexOf(posts[i].userpost.n) > -1) { + if (followingUsers.indexOf(posts[i].userpost.n) > -1 + && posts[i].userpost.height !== posts[i].userpost.k) // to filter possible promoted twists which may appear suddenly (shame on you Miguel!) + { d.setTime(0); d.setUTCSeconds(posts[i].userpost.time); if (d.getMonth() === curMonth && d.getDate() === curDate) { @@ -333,7 +335,7 @@ function initWebTorrent() { console.log("onget:", torrentId, err, data) if (err || data === null) { // error reading blob, just add torrentId - console.log("WebTorrent auto-download: " + torrentId + + console.log("WebTorrent auto-download: " + torrentId + " (previously seeded as: " + twister.torrentIds[torrentId] + ")" ); WebTorrentClient.add(torrentId); } else { From 50a3ef327253e2e1b224d23b542edbc812321c31 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Sun, 31 Jul 2016 02:37:52 +0500 Subject: [PATCH 02/54] fix of 'followers' link in peer profile modal --- home.html | 2 +- js/interface_common.js | 12 +++++++----- js/twister_following.js | 3 ++- js/twister_io.js | 6 ++++-- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/home.html b/home.html index 2fe864a..82ce2f7 100644 --- a/home.html +++ b/home.html @@ -655,7 +655,7 @@
diff --git a/js/interface_common.js b/js/interface_common.js index 87aaf80..d7e33dd 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -449,6 +449,8 @@ function openUserProfileModalWithNameHandler(peerAlias) { content.find('.tox-ctc').attr('title', polyglot.t('Copy to clipboard')); content.find('.bitmessage-ctc').attr('title', polyglot.t('Copy to clipboard')); + content.find('.open-followers').on('mouseup', {route: '#followers?user=' + peerAlias}, routeOnClick); + var modal = openModal({ classAdd: 'profile-modal', content: content, @@ -952,7 +954,7 @@ function applyShortenedURI(short, uriAndMimetype) { previewContainer.append(startTorrentLink); } } else { - var enableWebTorrentWarning = $('' + + var enableWebTorrentWarning = $('' + polyglot.t('Enable WebTorrent support in options page to display this content') + ''); previewContainer.append(enableWebTorrentWarning); @@ -972,7 +974,7 @@ function startTorrentDownloadAndPreview(torrentId, previewContainer, isMedia) { function _startTorrentDownloadAndPreview(torrentId, previewContainer, isMedia) { var torrent = WebTorrentClient.get(torrentId); - if( torrent === null ) + if( torrent === null ) torrent = WebTorrentClient.add(torrentId); previewContainer.empty(); @@ -1003,7 +1005,7 @@ function webtorrentFilePreview(file, previewContainer, isMedia) { // try guessing by filename extension isMedia = /^[^?]+\.(?:jpe?g|gif|png|mp4|webm|mp3|ogg|wav|)$/i.test(file.name) } - + if (isMedia) { var imagePreview = $('
'); previewContainer.append(imagePreview); @@ -1724,7 +1726,7 @@ function replyTextUpdateRemaining(ta) { return false; } }); - if (!disable && c >= 0 && c < $.Options.MaxPostEditorChars.val && + if (!disable && c >= 0 && c < $.Options.MaxPostEditorChars.val && textArea.val() !== textArea.attr('data-reply-to')) { remainingCount.removeClass('warn'); $.MAL.enableButton(buttonSend); @@ -2354,7 +2356,7 @@ function initInterfaceCommon() { closePrompt(event); }); - $('.open-followers').on('mouseup', {route: '#followers'}, routeOnClick); + $('.module.mini-profile .open-followers').on('mouseup', {route: '#followers'}, routeOnClick); $('.post-text').on('click', 'a', muteEvent); $('.post-reply').on('click', postReplyClick); diff --git a/js/twister_following.js b/js/twister_following.js index a45cd89..3ea7ba9 100644 --- a/js/twister_following.js +++ b/js/twister_following.js @@ -145,7 +145,8 @@ TwisterFollowing.prototype = { .find('li[data-peer-alias="' + args.fu + '"]').remove(); } } - $(".open-followers").attr("title", args.tf.knownFollowers.length.toString()); + $('.module.mini-profile .open-followers') + .attr('title', args.tf.knownFollowers.length.toString()); var ctime = new Date().getTime() / 1000; if (typeof(args.tf.followingsFollowings[args.fu]) === 'undefined' || diff --git a/js/twister_io.js b/js/twister_io.js index 9ab1ac3..5b6a8d8 100644 --- a/js/twister_io.js +++ b/js/twister_io.js @@ -279,7 +279,8 @@ function getFullname(peerAlias, elem) { twisterFollowingO.knownFollowers.push(req.peerAlias); twisterFollowingO.save(); addPeerToFollowersList(getElem('.followers-modal .followers-list'), req.peerAlias, true); - $('.open-followers').attr('title', twisterFollowingO.knownFollowers.length.toString()); + $('.module.mini-profile .open-followers') + .attr('title', twisterFollowingO.knownFollowers.length.toString()); } req.elem.addClass('isFollowing'); req.elem.attr('title', polyglot.t('follows you')); @@ -291,7 +292,8 @@ function getFullname(peerAlias, elem) { if (twisterFollowingO.knownFollowers.indexOf(req.peerAlias) === -1) { twisterFollowingO.knownFollowers.push(req.peerAlias); addPeerToFollowersList(getElem('.followers-modal .followers-list'), req.peerAlias, true); - $('.open-followers').attr('title', twisterFollowingO.knownFollowers.length.toString()); + $('.module.mini-profile .open-followers') + .attr('title', twisterFollowingO.knownFollowers.length.toString()); } req.elem.addClass('isFollowing'); req.elem.attr('title', polyglot.t('follows you')); From b83616b5cc48299ecf99ad8cf4d3bd3f9d8a9c3a Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Sun, 31 Jul 2016 03:12:16 +0500 Subject: [PATCH 03/54] add exit from routeOnClick() if we got LMB event and some text is selected --- js/interface_common.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/js/interface_common.js b/js/interface_common.js index d7e33dd..0402b78 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -1041,6 +1041,9 @@ function routeOnClick(event) { if (!event || !event.data || !event.data.route) return; + if (event.button === 0 && window.getSelection().toString() !== '') + return; + event.stopPropagation(); event.preventDefault(); From 95654edaf5bac5e92ddf972e5b31aa2c51342a1f Mon Sep 17 00:00:00 2001 From: erqan Date: Tue, 2 Aug 2016 18:05:37 +0300 Subject: [PATCH 04/54] update tr... --- js/interface_localization.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/js/interface_localization.js b/js/interface_localization.js index 9911d10..1ed0e4f 100644 --- a/js/interface_localization.js +++ b/js/interface_localization.js @@ -3604,7 +3604,7 @@ if(preferredLanguage == "tr"){ "Group Messages — Join Group": "Grup Mesajları — Gruba katıl", "direct_messages_with": "%{username} ile Direk Mesajlar", "Disable": "Kullanılmaz", - "display_mentions": "@ adının geçtiği gönderiler", // FIXME + "display_mentions": "Bahsedenleri göster", "Display retransmissions": "Tekrar iletimleri göster", "DNS to obtain list of peers:": "Eş listesini almak için DNS:", "downloading_block_chain": "Blok zinciri indiriliyor, devam edebilmek için lütfen bekleyiniz (blok zinciri %{days} günlük).", @@ -3663,12 +3663,12 @@ if(preferredLanguage == "tr"){ "new_group_messages": "%{smart_count} yeni grup mesajı |||| %{smart_count} yeni grup mesajı", "nobody": "hiçkimse", // used to promote a post without attaching the user "Not available": "Kullanılamaz", // username is not available - "warn_following_not_any": "Not following any twisters!\nSearch and follow someone.", - "warn_followers_not_all": "Well, currently here's no easy way to obtain all your followers.\n" - + "The counter indicates only a number of known peers sharing your torrent.\n" - + "In the list below are included ones, mostly, who are followed by you.", - "warn_followers_not_all_of": "Well, currently here's no easy way to obtain all followers of whoever.\n" - + "In the list below are included only few, perhaps, of ones who follow @%{alias} publicly.", + "warn_following_not_any": "Hiç kimseyi takip etmiyorsun!\nAra ve birilerini takip et.", + "warn_followers_not_all": "Tüm takipçilerini belirlemenin kolay bir yolu bulunmuyor.\n" + + "Takipçi sayacı torrent'ini paylaşan eşlerin sayısından ibaret ve\n" + + "aşağıdaki liste çoğunlukla takip ettiklerinden seni takip edenleri içerir.", + "warn_followers_not_all_of": "Tüm takipçilerini belirlemenin kolay bir yolu bulunmuyor.\n" + + "Aşağıdaki liste takipçilerin bir kısmını ve çoğunlukla takip ettiklerinden @%{alias} kullanıcısını gizlemeden takip edenleri içerir.", "notify_desktop_error": "Twister masaüstü uyarısını gösterimiyor: bilimeyen bir hata oluştu.", "notify_desktop_perm_denied": "Twister masaüstü uyarısını gösteremiyor: yetkilendirme hatası.\n\nUyarıları almak istiyorsanız, tarayıcı ayarlarında %{this_domain} alan adı için izin veriniz.", "notify_desktop_test": "Kasırga her yanı saracak\nBu karnavala hoşgeldin!", @@ -3705,10 +3705,10 @@ if(preferredLanguage == "tr"){ "send_DM": "Direk Mesaj Gönder", "Sent Post to @": "@ Kullanıcıya Gönder", "Setup account": "Hesap ayarları", - "shorten_URI": "Shorten URL", - "shorten_URI_enter_link": "Enter the long link.\n" - + "Note: shortening an URL will produce an 'empty' twist on your behalf containing the full URL.\n" - + "This special twist is not displayed by twister clients, but your twist counter will increase.", + "shorten_URI": "URL kısalt", + "shorten_URI_enter_link": "Uzun bağlantıyı yazın.\n" + + "Not: URL kısaltma işlemi tam URL'i barındıran 'boş' bir twist oluşturacak.\n" + + "Bu özel twist görüntülenmeyecek, fakat gönderi sayınızda hesaba katılacak.", "shorten_URI_its_public_is_it_ok": "Your link will be public available! Are you OK with that?", "The File APIs are not fully supported in this browser.": "Dosya API'si tarayıcınızda tam olarak desteklenmiyor.", "time_ago": "%{time} önce", // 5 minutes ago @@ -3752,8 +3752,8 @@ if(preferredLanguage == "tr"){ "Terminate Daemon:": "Servisi Durdur:", "Exit": "Çıkış", "Save Changes": "Değişiklikleri Kaydet", - "profile_saved": "Profile data has been saved to DHT.", - "profile_not_saved": "Profile data has been not saved.", + "profile_saved": "Profil bilgileri DHT'ye kaydedildi.", + "profile_not_saved": "Profil bilgileri kaydedilmedi.", "Secret key:": "Gizli anahtar:", "Options": "Ayarlar", "Switch to Promoted posts": "Destekli Mesajlara Geç", @@ -3829,7 +3829,7 @@ if(preferredLanguage == "tr"){ "not analyzed": "incelenmedi", "Reason: this": "Sebep: %{this}", "this doesnt contain that": "%{that} %{this} tarafından kapsanmıyor", - "this is undefined": "%{this} is undefined", + "this is undefined": "%{this} tanımsız", "blacklist": "beyaz liste", "whitelist": "kara liste", "language of this": "dili", From c95cdeac187e842068cc64a84b03d6bb04528e57 Mon Sep 17 00:00:00 2001 From: erqan Date: Sat, 3 Sep 2016 15:36:30 +0300 Subject: [PATCH 05/54] adding max-width for large images... --- css/style.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/css/style.css b/css/style.css index c42a4be..7cc5502 100644 --- a/css/style.css +++ b/css/style.css @@ -1305,6 +1305,10 @@ ol.toptrends-list { { width: 100%; } +.image-preview img +{ + max-width: 100%; +} .preview-container { max-height: 500px; From fed0b5e81ae54ecade85be819a7c00e77623fc0d Mon Sep 17 00:00:00 2001 From: erqan Date: Sat, 3 Sep 2016 17:25:40 +0300 Subject: [PATCH 06/54] makes video controls usable --- js/interface_common.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/js/interface_common.js b/js/interface_common.js index 0402b78..514de0b 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -1014,7 +1014,9 @@ function webtorrentFilePreview(file, previewContainer, isMedia) { elem.pause(); } }); - imagePreview.find("video").removeAttr("autoplay"); + var $vid = imagePreview.find("video"); + $vid.removeAttr("autoplay"); + $vid.on('click mouseup', muteEvent); } else { file.getBlobURL(function (err, url) { if (err) return console.error(err) From 36155be0cf0f999e897db1dcab710c2e87e82f80 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Tue, 6 Sep 2016 13:54:11 +0500 Subject: [PATCH 07/54] add URI shortener modal window with shortened URIs list --- css/style.css | 36 +++++++++++++++++ home.html | 12 ++++++ js/interface_common.js | 78 +++++++++++++++++++++++++++++++++++- js/interface_localization.js | 40 ++++++++++++++++++ theme_calm/css/style.css | 36 +++++++++++++++++ theme_nin/css/style.css | 51 +++++++++++++++++++++++ 6 files changed, 252 insertions(+), 1 deletion(-) diff --git a/css/style.css b/css/style.css index 7cc5502..283d0dc 100644 --- a/css/style.css +++ b/css/style.css @@ -1935,6 +1935,42 @@ ol.toptrends-list { color: rgba( 0, 0, 0, .6 ); } +/************************************* +********* URI SHORTENER MODAL ******** +**************************************/ + +.uri-shortener-modal .uris-list { + font-size: 12px; + overflow-x: hidden; +} + +.uri-shortener-modal .uris-list li { + padding-left: 2%; + padding-right: 2%; + margin-bottom: 4px; +} + +.uri-shortener-modal .uris-list li:last-child { + margin-bottom: 16px; +} + +.uri-shortener-modal .uris-list li.highlighted, +.uri-shortener-modal .uris-list li:hover { + background-color: #FEFEDF; +} + +.uri-shortener-modal .uris-list .short { + background-color: #F0EFCC; + display: inline-block; + width: 26%; + padding-left: 2px; + padding-right: 2px; +} + +.uri-shortener-modal .uris-list .long { + margin-left: 4px; +} + /************************************* ************ POPUP PROMPT ************ **************************************/ diff --git a/home.html b/home.html index 82ce2f7..89e5136 100644 --- a/home.html +++ b/home.html @@ -793,6 +793,18 @@
+ +
+
+ + +
+
    +
    + +
    +
  1. +
    diff --git a/js/interface_common.js b/js/interface_common.js index 514de0b..90d9c8e 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -737,6 +737,30 @@ function openWhoToFollowModal() { fillWhoToFollowModal(tmplist, hlist, 0); } +function openModalUriShortener() +{ + var modal = openModal({ + classAdd: 'uri-shortener-modal', + content: twister.tmpl.uriShortenerMC.clone(true), + title: polyglot.t('URI_shortener') + }); + + modal.content.find('.uri-shortener-control .shorten-uri').text(polyglot.t('shorten_URI')); + modal.content.find('.uri-shortener-control .clear-cache').text(polyglot.t('clear_cache')); + + var urisList = modal.content.find('.uris-list'); + //var i = 0; + for (var short in twister.URIs) { + //i++; + var long = twister.URIs[short] instanceof Array ? twister.URIs[short][0] : twister.URIs[short]; + var item = twister.tmpl.uriShortenerUrisListItem.clone(true); + item.find('.short').text(short); + item.find('.long').text(long).attr('href', long); + item.appendTo(urisList); + } + //i + URIs are cached +} + function newConversationModal(peerAlias, resource) { var content = $('#hashtag-modal-template').children().clone(true); @@ -1148,6 +1172,8 @@ function loadModalFromHash() { openGroupMessagesJoinGroupModal(); else if (hashstring === '#whotofollow') openWhoToFollowModal(); + else if (hashstring === '#/uri-shortener') + openModalUriShortener(); } function initHashWatching() { @@ -2343,6 +2369,56 @@ function replaceDashboards() { function initInterfaceCommon() { twister.tmpl.commonDMsList = extractTemplate('#template-direct-messages-list'); + twister.tmpl.uriShortenerMC = extractTemplate('#template-uri-shortener-modal-content'); + twister.tmpl.uriShortenerMC + .find('.shorten-uri').on('click', + {cbFunc: + function (long, short) { + if (short) { + var urisList = getElem('.uri-shortener-modal .uris-list'); + if (urisList.length) { + var item = urisList.find('.short:contains("' + short + '")').closest('li'); + if (!item.length) { + item = twister.tmpl.uriShortenerUrisListItem.clone(true); + item.find('.short').text(short); + item.find('.long').text(long).attr('href', long); + item.appendTo(urisList); + } + urisList.children('.highlighted').removeClass('highlighted'); + item.addClass('highlighted'); + var mc = urisList.closest('.modal-content'); + mc.scrollTop(item.offset().top - mc.offset().top + mc.scrollTop()); + } + showURIPair(long, short); + } else + showURIShortenerErrorRPC(short); + } + }, + function (event) { + muteEvent(event); + openRequestShortURIForm(event); + } + ) + .siblings('.clear-cache').on('click', + function () { + confirmPopup({ + txtMessage: polyglot.t('confirm_uri_shortener_clear_cache'), + cbConfirm: function () { + twister.URIs = {}; + $.localStorage.set('twistaURIs', twister.URIs); + getElem('.uri-shortener-modal .uris-list').empty(); + } + }); + } + ) + ; + twister.tmpl.uriShortenerUrisListItem = extractTemplate('#template-uri-shortener-uris-list-item') + .on('click', function (event) { + var elem = $(event.target); + elem.closest('.uris-list').children('.highlighted').removeClass('highlighted'); + elem.addClass('highlighted'); + }) + ; $('.modal-close, .modal-blackout').not('.prompt-close').on('click', closeModal); @@ -2445,7 +2521,7 @@ function initInterfaceCommon() { $('.tox-ctc').on('click', promptCopyAttrData); $('.bitmessage-ctc').on('click', promptCopyAttrData); - $('.uri-shortener').on('click', openRequestShortURIForm); // FIXME implement Uri Shortener Center with links library etc + $('.uri-shortener').on('mouseup', {route: '#/uri-shortener'}, routeOnClick); $('.post-area-new textarea') .on('focus', diff --git a/js/interface_localization.js b/js/interface_localization.js index 1ed0e4f..a90e3ed 100644 --- a/js/interface_localization.js +++ b/js/interface_localization.js @@ -45,6 +45,7 @@ if(preferredLanguage == "en"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "Cancel", + "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", "сonfirm_group_leaving_body": "Are you sure want to leave %{alias} group?", @@ -54,6 +55,7 @@ if(preferredLanguage == "en"){ "Do you want to check [Network Status page](%{page}) instead?", "confirm_terminate_daemon": "Are you sure you want to exit the daemon?\nThe Twister client will stop working.", "confirm_unfollow_@": "Are you sure you want to unfollow @%{alias}?", + "confirm_uri_shortener_clear_cache": "Are you sure you want to clear browser cache of shortened URIs?", "Change user": "Change user", "Checking...": "Checking...", // checking if username is available "Collapse": "Collapse", // smaller view of a post @@ -175,6 +177,7 @@ if(preferredLanguage == "en"){ + "Note: shortening an URL will produce an 'empty' twist on your behalf containing the full URL.\n" + "This special twist is not displayed by twister clients, but your twist counter will increase.", "shorten_URI_its_public_is_it_ok": "Your link will be public available! Are you OK with that?", + "URI_shortener": "URI Shortener", "The File APIs are not fully supported in this browser.": "The File APIs are not fully supported in this browser.", "time_ago": "%{time} ago", // 5 minutes ago "Time of the last block:": "Time of the last block: ", @@ -379,6 +382,7 @@ if(preferredLanguage == "es"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "Cancelar", + "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", "сonfirm_group_leaving_body": "Are you sure want to leave %{alias} group?", @@ -388,6 +392,7 @@ if(preferredLanguage == "es"){ "¿Quieres comprobar la [página de estado de la red](%{page}) en su lugar?", "confirm_terminate_daemon": "Are you sure you want to exit the daemon?\nThe Twister client will stop working.", "confirm_unfollow_@": "Are you sure you want to unfollow @%{alias}?", + "confirm_uri_shortener_clear_cache": "Are you sure you want to clear browser cache of shortened URIs?", "Change user": "Cambiar de usuario", "Checking...": "Comprobando ...", // checking if username is available "Collapse": "Colapsar", // smaller view of a post @@ -509,6 +514,7 @@ if(preferredLanguage == "es"){ + "Note: shortening an URL will produce an 'empty' twist on your behalf containing the full URL.\n" + "This special twist is not displayed by twister clients, but your twist counter will increase.", "shorten_URI_its_public_is_it_ok": "Your link will be public available! Are you OK with that?", + "URI_shortener": "URI Shortener", "The File APIs are not fully supported in this browser.": "Las API de archivos no son totalmente compatibles con este navegador.", "time_ago": "hace %{time}", // 5 minutes ago "Time of the last block:": "Hora del último bloque: ", @@ -697,6 +703,7 @@ if(preferredLanguage == "uk"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "Відміна", + "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", "сonfirm_group_leaving_body": "Are you sure want to leave %{alias} group?", @@ -706,6 +713,7 @@ if(preferredLanguage == "uk"){ "Чи бажаєте ви перевірити [сторінку зі статусом мережі](%{page})?", "confirm_terminate_daemon": "Ви впевнені, що бажаєте завершити роботу?\nКлієнт Twister буде зупинено допоки ви не запустите його знову.", "confirm_unfollow_@": "Are you sure you want to unfollow @%{alias}?", + "confirm_uri_shortener_clear_cache": "Are you sure you want to clear browser cache of shortened URIs?", "Change user": "Змінити користувача", "Checking...": "Перевірка...", // checking if username is available "Collapse": "Згорнути", // smaller view of a post @@ -828,6 +836,7 @@ if(preferredLanguage == "uk"){ + "Note: shortening an URL will produce an 'empty' twist on your behalf containing the full URL.\n" + "This special twist is not displayed by twister clients, but your twist counter will increase.", "shorten_URI_its_public_is_it_ok": "Your link will be public available! Are you OK with that?", + "URI_shortener": "URI Shortener", "The File APIs are not fully supported in this browser.": "File APIs не повністю підтримується браузером.", "time_ago": "%{time} тому", // 5 minutes ago "Time of the last block:": "Час останнього блоку: ", @@ -1014,6 +1023,7 @@ if(preferredLanguage == "zh-CN"){ "busted_avowal": "系统检测到此用户试图在这里注入恶意代码", "btn_ok": "Okay", "Cancel": "取消", + "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", "сonfirm_group_leaving_body": "Are you sure want to leave %{alias} group?", @@ -1023,6 +1033,7 @@ if(preferredLanguage == "zh-CN"){ "你要跳转到[网络状态页](%{page})吗?", "confirm_terminate_daemon": "你确定要退出后台进程?\nTwister 客户端将停止工作。", "confirm_unfollow_@": "Are you sure you want to unfollow @%{alias}?", + "confirm_uri_shortener_clear_cache": "Are you sure you want to clear browser cache of shortened URIs?", "Change user": "切换用户", "Checking...": "检查中...", // checking if username is available "Collapse": "折叠", // smaller view of a post @@ -1144,6 +1155,7 @@ if(preferredLanguage == "zh-CN"){ + "Note: shortening an URL will produce an 'empty' twist on your behalf containing the full URL.\n" + "This special twist is not displayed by twister clients, but your twist counter will increase.", "shorten_URI_its_public_is_it_ok": "Your link will be public available! Are you OK with that?", + "URI_shortener": "URI Shortener", "The File APIs are not fully supported in this browser.": "这个浏览器不能完全支持 File API。", "time_ago": "%{time} 之前", // 5 minutes ago "Time of the last block:": "最新区块的时间:", @@ -1348,6 +1360,7 @@ if(preferredLanguage == "nl"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "Annuleren", + "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", "сonfirm_group_leaving_body": "Are you sure want to leave %{alias} group?", @@ -1357,6 +1370,7 @@ if(preferredLanguage == "nl"){ "Do you want to check [Network Status page](%{page}) instead?", "confirm_terminate_daemon": "Are you sure you want to exit the daemon?\nThe Twister client will stop working.", "confirm_unfollow_@": "Are you sure you want to unfollow @%{alias}?", + "confirm_uri_shortener_clear_cache": "Are you sure you want to clear browser cache of shortened URIs?", "Change user": "Gebruiker wijzigen", "Checking...": "Controleren...", // checking if username is available "Collapse": "Uitklappen", // smaller view of a post @@ -1478,6 +1492,7 @@ if(preferredLanguage == "nl"){ + "Note: shortening an URL will produce an 'empty' twist on your behalf containing the full URL.\n" + "This special twist is not displayed by twister clients, but your twist counter will increase.", "shorten_URI_its_public_is_it_ok": "Your link will be public available! Are you OK with that?", + "URI_shortener": "URI Shortener", "The File APIs are not fully supported in this browser.": "The File APIs are not fully supported in this browser.", "time_ago": "%{time} geleden", // 5 minutes ago "Time of the last block:": "Tijd van de laatste block: ", @@ -1666,6 +1681,7 @@ if(preferredLanguage == "it"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "Cancella", + "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", "сonfirm_group_leaving_body": "Are you sure want to leave %{alias} group?", @@ -1675,6 +1691,7 @@ if(preferredLanguage == "it"){ "Vuoi controllare lo [stato della rete Twister](%{page}), invece?", "confirm_terminate_daemon": "Are you sure you want to exit the daemon?\nThe Twister client will stop working.", "confirm_unfollow_@": "Are you sure you want to unfollow @%{alias}?", + "confirm_uri_shortener_clear_cache": "Are you sure you want to clear browser cache of shortened URIs?", "Change user": "Cambia utente", "Checking...": "Controllo in corso...", // checking if username is available "Collapse": "Chiudi", // smaller view of a post @@ -1796,6 +1813,7 @@ if(preferredLanguage == "it"){ + "Note: shortening an URL will produce an 'empty' twist on your behalf containing the full URL.\n" + "This special twist is not displayed by twister clients, but your twist counter will increase.", "shorten_URI_its_public_is_it_ok": "Your link will be public available! Are you OK with that?", + "URI_shortener": "URI Shortener", "The File APIs are not fully supported in this browser.": "Le API File non sono interamente supportate da questo browser.", "time_ago": "%{time} fa", // 5 minutes ago "Time of the last block:": "Orario del blocco più recente: ", @@ -1982,6 +2000,7 @@ if(preferredLanguage == "fr"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "Annuler", + "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", "сonfirm_group_leaving_body": "Are you sure want to leave %{alias} group?", @@ -1991,6 +2010,7 @@ if(preferredLanguage == "fr"){ "Voulez-vous consulter la [page d'état du réseau](%{page}) à la place?", "confirm_terminate_daemon": "Are you sure you want to exit the daemon?\nThe Twister client will stop working.", "confirm_unfollow_@": "Are you sure you want to unfollow @%{alias}?", + "confirm_uri_shortener_clear_cache": "Are you sure you want to clear browser cache of shortened URIs?", "Change user": "Changer d'utilisateur", "Checking...": "Vérification...", // checking if username is available "Collapse": "Fermer", // smaller view of a post @@ -2112,6 +2132,7 @@ if(preferredLanguage == "fr"){ + "Note: shortening an URL will produce an 'empty' twist on your behalf containing the full URL.\n" + "This special twist is not displayed by twister clients, but your twist counter will increase.", "shorten_URI_its_public_is_it_ok": "Your link will be public available! Are you OK with that?", + "URI_shortener": "URI Shortener", "The File APIs are not fully supported in this browser.": "L'API de fichier n'est pas entièrement pris en charge dans votre navigateur.", "time_ago": "Il y a %{time}", // 5 minutes ago "Time of the last block:": "Heure du dernier bloc: ", @@ -2302,6 +2323,7 @@ if(preferredLanguage == "ru"){ "busted_avowal": "я пойман на попытке вставить этот подозрительный код здесь", "btn_ok": "Лады́", "Cancel": "Отмена", + "clear_cache": "Очистить кэш", "Confirm": "Несомненно", "сonfirm_group_leaving_header": "Подтверждение ухода из группы", "сonfirm_group_leaving_body": "Воистину покинуть группу %{alias}?", @@ -2311,6 +2333,7 @@ if(preferredLanguage == "ru"){ "Не хотите перейти на [страницу настройки сети](%{page})?", "confirm_terminate_daemon": "Вы уверены, что хотите выключить демон?\nTwister клиент перестанет работать.", "confirm_unfollow_@": "Действительно отписаться от @%{alias}?", + "confirm_uri_shortener_clear_cache": "В самом деле очистить кэш сокращённых URI в браузере?", "Change user": "Сменить пользователя", "Checking...": "Проверка...", "Collapse": "Свернуть", @@ -2432,6 +2455,7 @@ if(preferredLanguage == "ru"){ + "Примечание: в результате сокращения URL получается 'пустой' твист, содержащий эту URL.\n" + "Этот особый твист не отображается клиентами твистера, но учитывается в числе твоих твистов.", "shorten_URI_its_public_is_it_ok": "Ссылка будет общедоступной! Это приемлимо для тебя?", + "URI_shortener": "Сокращалка URI", "The File APIs are not fully supported in this browser.": "File APIs не полностью поддерживается этим браузером.", "time_ago": "%{time} назад", // 5 minutes ago "Time of the last block:": "Время последнего блока: ", @@ -2624,6 +2648,7 @@ if(preferredLanguage == "de"){ "busted_avowal": "Ich bin ertappt, habe versucht, hier Schadcode einzugeben!", "btn_ok": "Okay", "Cancel": "Abbrechen", + "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", "сonfirm_group_leaving_body": "Are you sure want to leave %{alias} group?", @@ -2633,6 +2658,7 @@ if(preferredLanguage == "de"){ "Möchtest du stattdessen den [Netzwerkstatus](%{page}) überprüfen?", "confirm_terminate_daemon": "Are you sure you want to exit the daemon?\nThe Twister client will stop working.", "confirm_unfollow_@": "Are you sure you want to unfollow @%{alias}?", + "confirm_uri_shortener_clear_cache": "Are you sure you want to clear browser cache of shortened URIs?", "Change user": "Benutzer wechseln", "Checking...": "Überprüfe...", // checking if username is available "Collapse": "Einklappen", // smaller view of a post @@ -2755,6 +2781,7 @@ if(preferredLanguage == "de"){ + "Note: shortening an URL will produce an 'empty' twist on your behalf containing the full URL.\n" + "This special twist is not displayed by twister clients, but your twist counter will increase.", "shorten_URI_its_public_is_it_ok": "Your link will be public available! Are you OK with that?", + "URI_shortener": "URI Shortener", "The File APIs are not fully supported in this browser.": "Die File-API's werden von diesem Browser nicht vollständig unterstützt.", "time_ago": "vor %{time}", // 5 minutes ago "Time of the last block:": "Zeit des letzten Blocks: ", @@ -2944,6 +2971,7 @@ if(preferredLanguage == "ja"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "キャンセル", + "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", "сonfirm_group_leaving_body": "Are you sure want to leave %{alias} group?", @@ -2953,6 +2981,7 @@ if(preferredLanguage == "ja"){ "[ネットワーク状態ペー](%{page})ジへ移動して確認しますか?", "confirm_terminate_daemon": "Are you sure you want to exit the daemon?\nThe Twister client will stop working.", "confirm_unfollow_@": "Are you sure you want to unfollow @%{alias}?", + "confirm_uri_shortener_clear_cache": "Are you sure you want to clear browser cache of shortened URIs?", "Change user": "ユーザーを変更", "Checking...": "チェック...", // checking if username is available "Collapse": "閉じる", // smaller view of a post @@ -3074,6 +3103,7 @@ if(preferredLanguage == "ja"){ + "Note: shortening an URL will produce an 'empty' twist on your behalf containing the full URL.\n" + "This special twist is not displayed by twister clients, but your twist counter will increase.", "shorten_URI_its_public_is_it_ok": "Your link will be public available! Are you OK with that?", + "URI_shortener": "URI Shortener", "The File APIs are not fully supported in this browser.": "ご使用のブラウザーは完全にファイルAPIに対応していません。", "time_ago": "%{time}前", // 5 minutes ago "Time of the last block:": "最新ブロックの生成日時: ", @@ -3260,6 +3290,7 @@ if(preferredLanguage == "pt-BR"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "Cancelar", + "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", "сonfirm_group_leaving_body": "Are you sure want to leave %{alias} group?", @@ -3269,6 +3300,7 @@ if(preferredLanguage == "pt-BR"){ "Gostaria de verificar o [Estado da Rede](%{page}) ao invés disso?", "confirm_terminate_daemon": "Are you sure you want to exit the daemon?\nThe Twister client will stop working.", "confirm_unfollow_@": "Are you sure you want to unfollow @%{alias}?", + "confirm_uri_shortener_clear_cache": "Are you sure you want to clear browser cache of shortened URIs?", "Change user": "Trocar usuário", "Checking...": "Verificando...", // checking if username is available "Collapse": "Recolher", // smaller view of a post @@ -3391,6 +3423,7 @@ if(preferredLanguage == "pt-BR"){ + "Note: shortening an URL will produce an 'empty' twist on your behalf containing the full URL.\n" + "This special twist is not displayed by twister clients, but your twist counter will increase.", "shorten_URI_its_public_is_it_ok": "Your link will be public available! Are you OK with that?", + "URI_shortener": "URI Shortener", "The File APIs are not fully supported in this browser.": "O gerenciamento de arquivos não é completamente suportado neste navegador.", "time_ago": "%{time} atrás", // 5 minutes ago "Time of the last block:": "Horário do último bloco: ", @@ -3399,6 +3432,7 @@ if(preferredLanguage == "pt-BR"){ "Update": "Atualizar", "Auto updating": "Auto updating", "Updating status...": "Atualizando estado da Cadeia de Blocos...", // status of block chain + "URI_shortener_caption": "URI Shortener", "user_not_yet_accepted": "Outros nós ainda não aceitaram este novo usuário.\n" + "Infelizmente não é possível salvar o perfil\n" + "ou realizar postagens neste estado.\n\n" + @@ -3580,6 +3614,7 @@ if(preferredLanguage == "tr"){ "busted_avowal": "Şüpheli bir şeyler iliştirmeye çalışırken enselendim.", "btn_ok": "Tamam", "Cancel": "İptal", + "clear_cache": "Clear cache", "Confirm": "Onayla", "сonfirm_group_leaving_header": "Gruptan ayrılmayı onayla", "сonfirm_group_leaving_body": "%{alias} grubundan ayrılmak istiyor musun?", @@ -3589,6 +3624,7 @@ if(preferredLanguage == "tr"){ "Bunun yerine [Ağ Durumu sayfasını](%{page}) kontrol etmek ister misiniz?", "confirm_terminate_daemon": "Hizmeti sonlandırmak istiyor musun?\nTwister istemcisi çalışmayacak.", "confirm_unfollow_@": "Are you sure you want to unfollow @%{alias}?", + "confirm_uri_shortener_clear_cache": "Are you sure you want to clear browser cache of shortened URIs?", "Change user": "Kullanıcı değiştir", "Checking...": "Denetleniyor...", // checking if username is available "Collapse": "Kapat", // smaller view of a post @@ -3710,6 +3746,7 @@ if(preferredLanguage == "tr"){ + "Not: URL kısaltma işlemi tam URL'i barındıran 'boş' bir twist oluşturacak.\n" + "Bu özel twist görüntülenmeyecek, fakat gönderi sayınızda hesaba katılacak.", "shorten_URI_its_public_is_it_ok": "Your link will be public available! Are you OK with that?", + "URI_shortener": "URI Shortener", "The File APIs are not fully supported in this browser.": "Dosya API'si tarayıcınızda tam olarak desteklenmiyor.", "time_ago": "%{time} önce", // 5 minutes ago "Time of the last block:": "Son blok saati: ", @@ -3897,6 +3934,7 @@ if(preferredLanguage == "cs"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "Zrušit", + "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", "сonfirm_group_leaving_body": "Are you sure want to leave %{alias} group?", @@ -3906,6 +3944,7 @@ if(preferredLanguage == "cs"){ "Chcete se místo toho podívat na [stav sítě](%{page})?", "confirm_terminate_daemon": "Skutečně chcete ukončit server?\nTwister tím vypnete.", "confirm_unfollow_@": "Are you sure you want to unfollow @%{alias}?", + "confirm_uri_shortener_clear_cache": "Are you sure you want to clear browser cache of shortened URIs?", "Change user": "Změnit uživatele", "Checking...": "Ověřuji...", // checking if username is available "Collapse": "Složit", // smaller view of a post @@ -4028,6 +4067,7 @@ if(preferredLanguage == "cs"){ + "Note: shortening an URL will produce an 'empty' twist on your behalf containing the full URL.\n" + "This special twist is not displayed by twister clients, but your twist counter will increase.", "shorten_URI_its_public_is_it_ok": "Your link will be public available! Are you OK with that?", + "URI_shortener": "URI Shortener", "The File APIs are not fully supported in this browser.": "Upozornění: váš webový prohlížeč nepodporuje File API.", "time_ago": "před %{time}", // 5 minutes ago "Time of the last block:": "Čas posledního bloku: ", diff --git a/theme_calm/css/style.css b/theme_calm/css/style.css index 5980d06..c42aef8 100644 --- a/theme_calm/css/style.css +++ b/theme_calm/css/style.css @@ -2342,6 +2342,42 @@ textarea.splited-post { color: rgba( 0, 0, 0, .6 ); } +/************************************* +********* URI SHORTENER MODAL ******** +**************************************/ + +.uri-shortener-modal .uris-list { + font-size: 12px; + overflow-x: hidden; +} + +.uri-shortener-modal .uris-list li { + padding-left: 2%; + padding-right: 2%; + margin-bottom: 4px; +} + +.uri-shortener-modal .uris-list li:last-child { + margin-bottom: 16px; +} + +.uri-shortener-modal .uris-list li.highlighted, +.uri-shortener-modal .uris-list li:hover { + background-color: #FEFEDF; +} + +.uri-shortener-modal .uris-list .short { + background-color: #F0EFCC; + display: inline-block; + width: 26%; + padding-left: 2px; + padding-right: 2px; +} + +.uri-shortener-modal .uris-list .long { + margin-left: 4px; +} + /************************************* ************ POPUP PROMPT ************ **************************************/ diff --git a/theme_nin/css/style.css b/theme_nin/css/style.css index fbea4da..2c5d1ea 100644 --- a/theme_nin/css/style.css +++ b/theme_nin/css/style.css @@ -3134,6 +3134,57 @@ ol.toptrends-list a:hover { font-style: italic; } +/************************************* +********* URI SHORTENER MODAL ******** +**************************************/ + +.modal-wrapper.uri-shortener-modal { + width: 520px; + height: 720px; + margin: -360px 0 0 -260px; +} + +.uri-shortener-modal .modal-content { + padding: 20px; +} + +.uri-shortener-control.b-buttons { + padding: 4px; +} + +.uri-shortener-modal .uris-list { + font-size: 12px; + overflow-x: hidden; +} + +.uri-shortener-modal .uris-list li { + background-color: #FFF; + padding-left: 2%; + padding-right: 2%; + margin-bottom: 2px; +} + +.uri-shortener-modal .uris-list li:last-child { + margin-bottom: 16px; +} + +.uri-shortener-modal .uris-list li.highlighted, +.uri-shortener-modal .uris-list li:hover { + background-color: #FEFEDF; +} + +.uri-shortener-modal .uris-list .short { + background-color: #EEE; + display: inline-block; + width: 26%; + padding-left: 2px; + padding-right: 2px; +} + +.uri-shortener-modal .uris-list .long { + margin-left: 4px; +} + /******* LOADER ************ */ /* line 978, ../sass/style.sass */ .postboard-loading, .loading-roller { From c1aa85fc9693788a4f50e8fabe3ea4a56e192e38 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Tue, 6 Sep 2016 13:55:22 +0500 Subject: [PATCH 08/54] fix search in cached shortened URIs in newShortURI() --- js/twister_actions.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/js/twister_actions.js b/js/twister_actions.js index 83ec131..9bf55d1 100644 --- a/js/twister_actions.js +++ b/js/twister_actions.js @@ -326,10 +326,12 @@ function newShortURI(uri, cbFunc, cbReq) { return; } - for (var i in twister.URIs) - if (twister.URIs[i] === uri) { + for (var short in twister.URIs) + if (twister.URIs[short] instanceof Array ? + twister.URIs[short][0] === uri : twister.URIs[short] === uri) { if (typeof cbFunc === 'function') - cbFunc(uri, i, cbReq); + cbFunc(uri, short, cbReq); + return; } From 2010f7c1d38652f2f76b4fba6221f766e3d6cc7f Mon Sep 17 00:00:00 2001 From: erqan Date: Tue, 6 Sep 2016 17:49:29 +0300 Subject: [PATCH 09/54] starting to fav... --- css/style.css | 11 ++ home.html | 12 ++- js/interface_common.js | 96 ++++++++++++++++- js/interface_localization.js | 199 ++++++++++++++++++++++++++++++++++- js/twister_actions.js | 61 +++++++++-- js/twister_formatpost.js | 6 ++ 6 files changed, 372 insertions(+), 13 deletions(-) diff --git a/css/style.css b/css/style.css index 283d0dc..4655c31 100644 --- a/css/style.css +++ b/css/style.css @@ -300,6 +300,16 @@ button.follow:hover, button.unfollow:hover, .following-own-modal .following-list opacity: 0.9; } +.userMenu li.userMenu-favs > a { + padding: 0 14px; + opacity: 1; +} + +.userMenu li.userMenu-favs > a:before { + content: '★'; + font-size: 24px; +} + .userMenu li.userMenu-profile > a { background: url(../img/profile.png) no-repeat 5px center; } @@ -1280,6 +1290,7 @@ ol.toptrends-list { .post-favorite:before { content: "★"; + font-size: 18px; } .post-reply:hover, .post-propagate:hover, diff --git a/home.html b/home.html index 89e5136..61b8af6 100644 --- a/home.html +++ b/home.html @@ -76,6 +76,7 @@ +
  2. @@ -343,7 +344,7 @@
    Reply Retransmit - + Favorite
    +
    +
    + +
    +
    @@ -662,6 +671,7 @@ +
    diff --git a/js/interface_common.js b/js/interface_common.js index 90d9c8e..9cf222b 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -510,6 +510,39 @@ function updateQueryModal(req) { requestQuery(req); } +function openFavsModal(event) { + if (event && typeof event.stopPropagation === 'function') { + event.preventDefault(); + event.stopPropagation(); + } + + var userInfo = $(this).closest('[data-screen-name]'); + var peerAlias = ''; + if (userInfo.length) + peerAlias = userInfo.attr('data-screen-name'); + else if (defaultScreenName) + peerAlias = defaultScreenName; + else { + alertPopup({ + //txtTitle: polyglot.t(''), add some title (not 'error', please) or just KISS + txtMessage: polyglot.t('No favs here because you are not logged in.') + }); + return; + } + + window.location.hash = '#favs?user=' + peerAlias; +} + +function openFavsModalHandler(peerAlias) { + var modal = openModal({ + classAdd: 'hashtag-modal', + content: $('#hashtag-modal-template').children().clone(true), + title: polyglot.t('users_favs', {username: peerAlias}) + }); + + setupQueryModalUpdating(modal.content.find('.postboard-posts'), peerAlias, 'fav'); +} + function openMentionsModal(event) { if (event && typeof event.stopPropagation === 'function') { event.preventDefault(); @@ -1131,7 +1164,7 @@ function loadModalFromHash() { // FIXME rework hash scheme from '#following?user=twister' to something like '#/@twister/following' if (hashdata[0] !== '#web+twister') - hashdata = hashstring.match(/(hashtag|profile|mentions|directmessages|followers|following|conversation)\?(?:group|user|hashtag|post)=(.+)/); + hashdata = hashstring.match(/(hashtag|profile|mentions|directmessages|followers|following|conversation|favs)\?(?:group|user|hashtag|post)=(.+)/); if (hashdata && hashdata[1] !== undefined && hashdata[2] !== undefined) { if (hashdata[1] === 'profile') @@ -1158,6 +1191,8 @@ function loadModalFromHash() { splithashdata2 = hashdata[2].split(':'); openConversationModal(splithashdata2[0], splithashdata2[1]); } + else if (hashdata[1] === 'favs') + openFavsModalHandler(hashdata[2]); } else if (hashstring === '#directmessages') openCommonDMsModal(); else if (hashstring === '#followers') @@ -1246,6 +1281,49 @@ function reTwistPopup(event, post, textArea) { replyArea.find('.post-submit').addClass('with-reference'); } +function favPopup(event, post, textArea) { + event.stopPropagation(); + + if (!defaultScreenName) { + alertPopup({ + txtMessage: polyglot.t('You have to log in to favorite messages.') + }); + return; + } + + if (typeof post === 'undefined') + post = $.evalJSON($(event.target).closest('.post-data').attr('data-userpost')); + + var modal = openModal({ + classBase: '.prompt-wrapper', + classAdd: 'fav-this', + title: polyglot.t('fav_this') + }); + + modal.content + .append(postToElem(post, '')) + .append($('#fav-modal-template').children().clone(true)) + ; + /* + //TODO: favs can be also commented + var replyArea = modal.content.find('.post-area .post-area-new'); + if (typeof textArea === 'undefined') { + textArea = replyArea.find('textarea'); + var textAreaPostInline = modal.content.find('.post .post-area-new textarea'); + $.each(['placeholder', 'data-reply-to'], function(i, attribute) { + textArea.attr(attribute, textAreaPostInline.attr(attribute)); + }); + } else { + replyArea.find('textarea').replaceWith(textArea); + if (textArea.val()) { + textArea.focus(); + replyArea.addClass('open'); + } + } + replyArea.find('.post-submit').addClass('with-reference'); + */ +} + // Expande Área do Novo post function replyInitPopup(e, post, textArea) { var modal = openModal({ @@ -2298,6 +2376,17 @@ function retweetSubmit(event) { closePrompt(prompt); } +function favSubmit(event) { + event.preventDefault(); + event.stopPropagation(); + + var prompt = $(event.target).closest('.prompt-wrapper'); + var priv = (event.target.className.indexOf('private') > -1); + + newFavMsg(prompt.find('.post-data'), priv); + closePrompt(prompt); +} + function changeStyle() { var style, profile, menu; var theme = $.Options.theme.val; @@ -2442,6 +2531,7 @@ function initInterfaceCommon() { $('.post-text').on('click', 'a', muteEvent); $('.post-reply').on('click', postReplyClick); $('.post-propagate').on('click', reTwistPopup); + $('.post-favorite').on('click', favPopup); $('.userMenu-config').clickoutside(closeThis.bind($('.config-menu'))); $('.userMenu-config-dropdown').on('click', dropDownMenu); $('#post-template.module.post').on('click', function(event) { @@ -2461,6 +2551,8 @@ function initInterfaceCommon() { ; $('.post-submit').on('click', postSubmit); $('.modal-propagate').on('click', retweetSubmit); + $('.modal-fav-public').on('click', favSubmit); + $('.modal-fav-private').on('click', favSubmit); $('.expanded-content .show-more').on('mouseup', {feeder: '.module.post.original.open .module.post.original .post-data'}, handleClickOpenConversation) .on('click', muteEvent) // to prevent post collapsing @@ -2476,6 +2568,8 @@ function initInterfaceCommon() { //$('.open-following-modal').on('click', openFollowingModal); $('.userMenu-connections a').on('click', openMentionsModal); $('.mentions-from-user').on('click', openMentionsModal); + $('.userMenu-favs a').on('click', openFavsModal); + $('.favs-from-user').on('click', openFavsModal); $('#hashtag-modal-template .postboard-news').on('click', function () { $(this).hide(); diff --git a/js/interface_localization.js b/js/interface_localization.js index a90e3ed..9f48289 100644 --- a/js/interface_localization.js +++ b/js/interface_localization.js @@ -361,6 +361,11 @@ if(preferredLanguage == "en"){ "IP Overhead Upload:": "IP Overhead Upload:", "Payload Download:": "Payload Download:", "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } if(preferredLanguage == "es"){ @@ -681,6 +686,24 @@ if(preferredLanguage == "es"){ "Sound": "Sonido", "Users": "Usuarios", "Direct Message's copy to self": "Direct Message's copy to self", + "Traffic information": "Traffic information", + "DHT Torrents:": "DHT Torrents:", + "Peers:": "Peers:", + "Peer List Size:": "Peer List Size:", + "Active Requests:": "Active Requests:", + "Download:": "Download:", + "Upload:": "Upload:", + "DHT Download:": "DHT Download:", + "DHT Upload:": "DHT Upload:", + "IP Overhead Download:": "IP Overhead Download:", + "IP Overhead Upload:": "IP Overhead Upload:", + "Payload Download:": "Payload Download:", + "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -1001,6 +1024,23 @@ if(preferredLanguage == "uk"){ "Direct Message's copy to self": "Повідомлення скопійовано самому собі", "Traffic information": "Статистика трафіку", "Direct messages with": "Співбесіда з", + "DHT Torrents:": "DHT Torrents:", + "Peers:": "Peers:", + "Peer List Size:": "Peer List Size:", + "Active Requests:": "Active Requests:", + "Download:": "Download:", + "Upload:": "Upload:", + "DHT Download:": "DHT Download:", + "DHT Upload:": "DHT Upload:", + "IP Overhead Download:": "IP Overhead Download:", + "IP Overhead Upload:": "IP Overhead Upload:", + "Payload Download:": "Payload Download:", + "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -1338,6 +1378,11 @@ if(preferredLanguage == "zh-CN"){ "IP Overhead Upload:": "IP层开销上传:", "Payload Download:": "有效载荷下载:", "Payload Upload:": "有效载荷上传:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -1659,6 +1704,24 @@ if(preferredLanguage == "nl"){ "Sound": "Sound", "Users": "Users", "Direct Message's copy to self": "Direct Message's copy to self", + "Traffic information": "Traffic information", + "DHT Torrents:": "DHT Torrents:", + "Peers:": "Peers:", + "Peer List Size:": "Peer List Size:", + "Active Requests:": "Active Requests:", + "Download:": "Download:", + "Upload:": "Upload:", + "DHT Download:": "DHT Download:", + "DHT Upload:": "DHT Upload:", + "IP Overhead Download:": "IP Overhead Download:", + "IP Overhead Upload:": "IP Overhead Upload:", + "Payload Download:": "Payload Download:", + "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -1978,6 +2041,24 @@ if(preferredLanguage == "it"){ "Sound": "Sound", "Users": "Users", "Direct Message's copy to self": "Direct Message's copy to self", + "Traffic information": "Traffic information", + "DHT Torrents:": "DHT Torrents:", + "Peers:": "Peers:", + "Peer List Size:": "Peer List Size:", + "Active Requests:": "Active Requests:", + "Download:": "Download:", + "Upload:": "Upload:", + "DHT Download:": "DHT Download:", + "DHT Upload:": "DHT Upload:", + "IP Overhead Download:": "IP Overhead Download:", + "IP Overhead Upload:": "IP Overhead Upload:", + "Payload Download:": "Payload Download:", + "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -2299,6 +2380,24 @@ if(preferredLanguage == "fr"){ "Sound": "Sound", "Users": "Users", "Direct Message's copy to self": "Direct Message's copy to self", + "Traffic information": "Traffic information", + "DHT Torrents:": "DHT Torrents:", + "Peers:": "Peers:", + "Peer List Size:": "Peer List Size:", + "Active Requests:": "Active Requests:", + "Download:": "Download:", + "Upload:": "Upload:", + "DHT Download:": "DHT Download:", + "DHT Upload:": "DHT Upload:", + "IP Overhead Download:": "IP Overhead Download:", + "IP Overhead Upload:": "IP Overhead Upload:", + "Payload Download:": "Payload Download:", + "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages." + }; } @@ -2626,6 +2725,24 @@ if(preferredLanguage == "ru"){ "New post": "Новый пост", "Search": "Поиск", "Direct Msg": "ЛС", + "Traffic information": "Traffic information", + "DHT Torrents:": "DHT Torrents:", + "Peers:": "Peers:", + "Peer List Size:": "Peer List Size:", + "Active Requests:": "Active Requests:", + "Download:": "Download:", + "Upload:": "Upload:", + "DHT Download:": "DHT Download:", + "DHT Upload:": "DHT Upload:", + "IP Overhead Download:": "IP Overhead Download:", + "IP Overhead Upload:": "IP Overhead Upload:", + "Payload Download:": "Payload Download:", + "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -2728,7 +2845,7 @@ if(preferredLanguage == "de"){ "in postboard": "in der Timeline", "in search result": "in den Suchergebnissen", "in top trends": "in den Top Trends", - "new_posts": "%{smart_count} neuer Post |||| %{smart_count} neue Posts", + "new_posts": "%{smart_count} neuer Post |||| %{smart_count} neue Posts", /* FIXME: duplicate */ "new_mentions": "%{smart_count} neue Erwähnung |||| %{smart_count} neue Erwähnungen", "new_direct_messages": "%{smart_count} neue Direktnachricht |||| %{smart_count} neue Direktnachrichten", "new_group_messages": "%{smart_count} neue Gruppen-Nachricht |||| %{smart_count} neue Gruppen-Nachrichten", @@ -2840,7 +2957,7 @@ if(preferredLanguage == "de"){ "Options": "Einstellungen", "Switch to Promoted posts": "Wechsle zu Promoted Nachrichten", "Switch to Normal posts": "Switch to Normal posts", - "new_posts": "%{smart_count} neue Nachricht |||| %{smart_count} neue Nachrichten", + "new_posts": "%{smart_count} neue Nachricht |||| %{smart_count} neue Nachrichten", /* FIXME: duplicate */ "Use language": "Sprache einstellen", "Ignore": "Ignorieren", "Ignore and clear out": "Ignore and clear out", @@ -2949,6 +3066,24 @@ if(preferredLanguage == "de"){ "Sound": "Sound", "Users": "Users", "Direct Message's copy to self": "Kopie der Direktnachricht an mich selbst", + "Traffic information": "Traffic information", + "DHT Torrents:": "DHT Torrents:", + "Peers:": "Peers:", + "Peer List Size:": "Peer List Size:", + "Active Requests:": "Active Requests:", + "Download:": "Download:", + "Upload:": "Upload:", + "DHT Download:": "DHT Download:", + "DHT Upload:": "DHT Upload:", + "IP Overhead Download:": "IP Overhead Download:", + "IP Overhead Upload:": "IP Overhead Upload:", + "Payload Download:": "Payload Download:", + "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -3267,6 +3402,24 @@ if(preferredLanguage == "ja"){ "Sound": "Sound", "Users": "Users", "Direct Message's copy to self": "Direct Message's copy to self", + "Traffic information": "Traffic information", + "DHT Torrents:": "DHT Torrents:", + "Peers:": "Peers:", + "Peer List Size:": "Peer List Size:", + "Active Requests:": "Active Requests:", + "Download:": "Download:", + "Upload:": "Upload:", + "DHT Download:": "DHT Download:", + "DHT Upload:": "DHT Upload:", + "IP Overhead Download:": "IP Overhead Download:", + "IP Overhead Upload:": "IP Overhead Upload:", + "Payload Download:": "Payload Download:", + "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -3580,7 +3733,6 @@ if(preferredLanguage == "pt-BR"){ "post_rt_time_prep": "at", "undo": "undo", "Daemon exited...": "Daemon exited...", - "Secret Key": "Secret Key", "Copy to clipboard": "Copy to clipboard", "Full name here": "Full name here", "Describe yourself": "Describe yourself", @@ -3592,6 +3744,24 @@ if(preferredLanguage == "pt-BR"){ "Sound": "Sound", "Users": "Users", "Direct Message's copy to self": "Direct Message's copy to self", + "Traffic information": "Traffic information", + "DHT Torrents:": "DHT Torrents:", + "Peers:": "Peers:", + "Peer List Size:": "Peer List Size:", + "Active Requests:": "Active Requests:", + "Download:": "Download:", + "Upload:": "Upload:", + "DHT Download:": "DHT Download:", + "DHT Upload:": "DHT Upload:", + "IP Overhead Download:": "IP Overhead Download:", + "IP Overhead Upload:": "IP Overhead Upload:", + "Payload Download:": "Payload Download:", + "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -3912,6 +4082,24 @@ if(preferredLanguage == "tr"){ "Sound": "Ses", "Users": "Kullanıcılar", "Direct Message's copy to self": "Özel iletinin kopyasını sakla", + "Traffic information": "Trafik bilgileri", + "DHT Torrents:": "DHT Torrentleri:", + "Peers:": "Eşler:", + "Peer List Size:": "Eş listesi uzunluğu:", + "Active Requests:": "Aktif istekler:", + "Download:": "İndirme:", + "Upload:": "Yükleme:", + "DHT Download:": "DHT İndirme:", + "DHT Upload:": "DHT Yükleme:", + "IP Overhead Download:": "IP Başlık İndirme:", + "IP Overhead Upload:": "IP Başlık Yükleme:", + "Payload Download:": "İçerik İndirme:", + "Payload Upload:": "İçerik Yükleme:", + "No favs here because you are not logged in." : "Giriş yapmadan favorileri göremezsin.", + "users_favs": "@%{username} kullanıcısının favorileri", + "Favorites": "Favoriler", + "You have to log in to favorite messages.": "İletileri favorine eklemek için giriş yapmalısın.", + "fav_this": "Sana özel mi?" }; } @@ -4248,6 +4436,11 @@ if(preferredLanguage == "cs"){ "IP Overhead Upload:": "IP Overhead - odesílání:", "Payload Download:": "Data aplikace - stahování:", "Payload Upload:": "Data aplikace - odesílání:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } diff --git a/js/twister_actions.js b/js/twister_actions.js index 9bf55d1..df56d09 100644 --- a/js/twister_actions.js +++ b/js/twister_actions.js @@ -319,6 +319,39 @@ function newRtMsg(postData, msg) { } } +function newFavMsg(postData, priv, msg) { + var userpost = $.evalJSON(postData.attr('data-content_to_rt')); + var sig_userpost = postData.attr('data-content_to_sigrt'); + + if (typeof sig_userpost === 'undefined') { + alert(polyglot.t('error', + {error: 'can\'t sig_userpost is not deifned'} + )); + + return; + } + var rtObj = {sig_userpost: sig_userpost, userpost: userpost}; + + if (typeof lastPostId !== 'undefined') { + if (typeof _sendedPostIDs !== 'undefined') + _sendedPostIDs.push(lastPostId + 1); + + var params = [defaultScreenName, lastPostId + 1, rtObj, priv]; + + if (typeof msg !== 'undefined') + params.push(msg); + + twisterRpc('newfavmsg', params, + function(arg, ret) {incLastPostId();}, null, + function(arg, ret) {var msg = ('message' in ret) ? ret.message : ret; + alert(polyglot.t('ajax_error', {error: msg})); + }, null + ); + } else { + alert(polyglot.t('Internal error: lastPostId unknown (following yourself may fix!)')); + } +} + function newShortURI(uri, cbFunc, cbReq) { if (!uri || !defaultScreenName) return; if (parseInt(twisterVersion) < 93500) { @@ -413,14 +446,22 @@ function clearQueryProcessed(id) { function requestQuery(req) { req.postboard.closest('div').find('.postboard-loading').show(); - dhtget(req.query, req.resource, 'm', - function(req, posts) { - req.posts = posts; - processQuery(req); - }, - req, - req.timeoutArgs - ); + if (req.resource === 'fav'){ + twisterRpc("getfavs", [req.query, 1000], function(req, posts){ + req.posts = posts; + processQuery(req) + }, req); + } + else { + dhtget(req.query, req.resource, 'm', + function (req, posts) { + req.posts = posts; + processQuery(req); + }, + req, + req.timeoutArgs + ); + } } function processQuery(req) { @@ -436,6 +477,10 @@ function processQuery(req) { for (var i = req.posts.length - 1; i >= 0; i--) { var userpost = req.posts[i].userpost; + + if (userpost.fav) + userpost = userpost.fav; + var key = userpost.n + ';' + userpost.time; if (!_queryProcessedMap[req.id][key]) { diff --git a/js/twister_formatpost.js b/js/twister_formatpost.js index 79fd1e5..9e734cc 100644 --- a/js/twister_formatpost.js +++ b/js/twister_formatpost.js @@ -43,6 +43,8 @@ function postToElem(post, kind, promoted) { "dm" : encrypted message (dm) -opt "rt" : original userpost - opt "sig_rt" : sig of rt - opt + "fav" : original userpost - opt + "sif_fav" : sig of fav - opt "reply" : - opt { "n" : reference username @@ -57,6 +59,10 @@ function postToElem(post, kind, promoted) { // Obtain data from userpost var userpost = post.userpost; + //TODO: favorites may have comment also... + if (userpost.fav) + userpost = userpost.fav; + if (post.sig_wort) userpost.sig_wort = post.sig_wort; From a2a7d1c92a4b34f9026d3b695df6f28ff148ff59 Mon Sep 17 00:00:00 2001 From: erqan Date: Tue, 6 Sep 2016 17:54:47 +0300 Subject: [PATCH 10/54] indents... --- js/interface_localization.js | 352 +++++++++++++++++------------------ 1 file changed, 176 insertions(+), 176 deletions(-) diff --git a/js/interface_localization.js b/js/interface_localization.js index 9f48289..b2f0961 100644 --- a/js/interface_localization.js +++ b/js/interface_localization.js @@ -363,9 +363,9 @@ if(preferredLanguage == "en"){ "Payload Upload:": "Payload Upload:", "No favs here because you are not logged in." : "No favs here because you are not logged in.", "users_favs": "Favorites of @%{username}", - "Favorites": "Favorites", - "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } if(preferredLanguage == "es"){ @@ -701,9 +701,9 @@ if(preferredLanguage == "es"){ "Payload Upload:": "Payload Upload:", "No favs here because you are not logged in." : "No favs here because you are not logged in.", "users_favs": "Favorites of @%{username}", - "Favorites": "Favorites", - "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -1024,23 +1024,23 @@ if(preferredLanguage == "uk"){ "Direct Message's copy to self": "Повідомлення скопійовано самому собі", "Traffic information": "Статистика трафіку", "Direct messages with": "Співбесіда з", - "DHT Torrents:": "DHT Torrents:", - "Peers:": "Peers:", - "Peer List Size:": "Peer List Size:", - "Active Requests:": "Active Requests:", - "Download:": "Download:", - "Upload:": "Upload:", - "DHT Download:": "DHT Download:", - "DHT Upload:": "DHT Upload:", - "IP Overhead Download:": "IP Overhead Download:", - "IP Overhead Upload:": "IP Overhead Upload:", - "Payload Download:": "Payload Download:", - "Payload Upload:": "Payload Upload:", - "No favs here because you are not logged in." : "No favs here because you are not logged in.", - "users_favs": "Favorites of @%{username}", - "Favorites": "Favorites", - "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "DHT Torrents:": "DHT Torrents:", + "Peers:": "Peers:", + "Peer List Size:": "Peer List Size:", + "Active Requests:": "Active Requests:", + "Download:": "Download:", + "Upload:": "Upload:", + "DHT Download:": "DHT Download:", + "DHT Upload:": "DHT Upload:", + "IP Overhead Download:": "IP Overhead Download:", + "IP Overhead Upload:": "IP Overhead Upload:", + "Payload Download:": "Payload Download:", + "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -1378,11 +1378,11 @@ if(preferredLanguage == "zh-CN"){ "IP Overhead Upload:": "IP层开销上传:", "Payload Download:": "有效载荷下载:", "Payload Upload:": "有效载荷上传:", - "No favs here because you are not logged in." : "No favs here because you are not logged in.", - "users_favs": "Favorites of @%{username}", - "Favorites": "Favorites", - "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -1704,24 +1704,24 @@ if(preferredLanguage == "nl"){ "Sound": "Sound", "Users": "Users", "Direct Message's copy to self": "Direct Message's copy to self", - "Traffic information": "Traffic information", - "DHT Torrents:": "DHT Torrents:", - "Peers:": "Peers:", - "Peer List Size:": "Peer List Size:", - "Active Requests:": "Active Requests:", - "Download:": "Download:", - "Upload:": "Upload:", - "DHT Download:": "DHT Download:", - "DHT Upload:": "DHT Upload:", - "IP Overhead Download:": "IP Overhead Download:", - "IP Overhead Upload:": "IP Overhead Upload:", - "Payload Download:": "Payload Download:", - "Payload Upload:": "Payload Upload:", - "No favs here because you are not logged in." : "No favs here because you are not logged in.", - "users_favs": "Favorites of @%{username}", - "Favorites": "Favorites", - "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "Traffic information": "Traffic information", + "DHT Torrents:": "DHT Torrents:", + "Peers:": "Peers:", + "Peer List Size:": "Peer List Size:", + "Active Requests:": "Active Requests:", + "Download:": "Download:", + "Upload:": "Upload:", + "DHT Download:": "DHT Download:", + "DHT Upload:": "DHT Upload:", + "IP Overhead Download:": "IP Overhead Download:", + "IP Overhead Upload:": "IP Overhead Upload:", + "Payload Download:": "Payload Download:", + "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -2041,24 +2041,24 @@ if(preferredLanguage == "it"){ "Sound": "Sound", "Users": "Users", "Direct Message's copy to self": "Direct Message's copy to self", - "Traffic information": "Traffic information", - "DHT Torrents:": "DHT Torrents:", - "Peers:": "Peers:", - "Peer List Size:": "Peer List Size:", - "Active Requests:": "Active Requests:", - "Download:": "Download:", - "Upload:": "Upload:", - "DHT Download:": "DHT Download:", - "DHT Upload:": "DHT Upload:", - "IP Overhead Download:": "IP Overhead Download:", - "IP Overhead Upload:": "IP Overhead Upload:", - "Payload Download:": "Payload Download:", - "Payload Upload:": "Payload Upload:", - "No favs here because you are not logged in." : "No favs here because you are not logged in.", - "users_favs": "Favorites of @%{username}", - "Favorites": "Favorites", - "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "Traffic information": "Traffic information", + "DHT Torrents:": "DHT Torrents:", + "Peers:": "Peers:", + "Peer List Size:": "Peer List Size:", + "Active Requests:": "Active Requests:", + "Download:": "Download:", + "Upload:": "Upload:", + "DHT Download:": "DHT Download:", + "DHT Upload:": "DHT Upload:", + "IP Overhead Download:": "IP Overhead Download:", + "IP Overhead Upload:": "IP Overhead Upload:", + "Payload Download:": "Payload Download:", + "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -2380,23 +2380,23 @@ if(preferredLanguage == "fr"){ "Sound": "Sound", "Users": "Users", "Direct Message's copy to self": "Direct Message's copy to self", - "Traffic information": "Traffic information", - "DHT Torrents:": "DHT Torrents:", - "Peers:": "Peers:", - "Peer List Size:": "Peer List Size:", - "Active Requests:": "Active Requests:", - "Download:": "Download:", - "Upload:": "Upload:", - "DHT Download:": "DHT Download:", - "DHT Upload:": "DHT Upload:", - "IP Overhead Download:": "IP Overhead Download:", - "IP Overhead Upload:": "IP Overhead Upload:", - "Payload Download:": "Payload Download:", - "Payload Upload:": "Payload Upload:", - "No favs here because you are not logged in." : "No favs here because you are not logged in.", - "users_favs": "Favorites of @%{username}", - "Favorites": "Favorites", - "You have to log in to favorite messages.": "You have to log in to favorite messages." + "Traffic information": "Traffic information", + "DHT Torrents:": "DHT Torrents:", + "Peers:": "Peers:", + "Peer List Size:": "Peer List Size:", + "Active Requests:": "Active Requests:", + "Download:": "Download:", + "Upload:": "Upload:", + "DHT Download:": "DHT Download:", + "DHT Upload:": "DHT Upload:", + "IP Overhead Download:": "IP Overhead Download:", + "IP Overhead Upload:": "IP Overhead Upload:", + "Payload Download:": "Payload Download:", + "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages." }; } @@ -2725,24 +2725,24 @@ if(preferredLanguage == "ru"){ "New post": "Новый пост", "Search": "Поиск", "Direct Msg": "ЛС", - "Traffic information": "Traffic information", - "DHT Torrents:": "DHT Torrents:", - "Peers:": "Peers:", - "Peer List Size:": "Peer List Size:", - "Active Requests:": "Active Requests:", - "Download:": "Download:", - "Upload:": "Upload:", - "DHT Download:": "DHT Download:", - "DHT Upload:": "DHT Upload:", - "IP Overhead Download:": "IP Overhead Download:", - "IP Overhead Upload:": "IP Overhead Upload:", - "Payload Download:": "Payload Download:", - "Payload Upload:": "Payload Upload:", - "No favs here because you are not logged in." : "No favs here because you are not logged in.", - "users_favs": "Favorites of @%{username}", - "Favorites": "Favorites", - "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "Traffic information": "Traffic information", + "DHT Torrents:": "DHT Torrents:", + "Peers:": "Peers:", + "Peer List Size:": "Peer List Size:", + "Active Requests:": "Active Requests:", + "Download:": "Download:", + "Upload:": "Upload:", + "DHT Download:": "DHT Download:", + "DHT Upload:": "DHT Upload:", + "IP Overhead Download:": "IP Overhead Download:", + "IP Overhead Upload:": "IP Overhead Upload:", + "Payload Download:": "Payload Download:", + "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -3066,24 +3066,24 @@ if(preferredLanguage == "de"){ "Sound": "Sound", "Users": "Users", "Direct Message's copy to self": "Kopie der Direktnachricht an mich selbst", - "Traffic information": "Traffic information", - "DHT Torrents:": "DHT Torrents:", - "Peers:": "Peers:", - "Peer List Size:": "Peer List Size:", - "Active Requests:": "Active Requests:", - "Download:": "Download:", - "Upload:": "Upload:", - "DHT Download:": "DHT Download:", - "DHT Upload:": "DHT Upload:", - "IP Overhead Download:": "IP Overhead Download:", - "IP Overhead Upload:": "IP Overhead Upload:", - "Payload Download:": "Payload Download:", - "Payload Upload:": "Payload Upload:", - "No favs here because you are not logged in." : "No favs here because you are not logged in.", - "users_favs": "Favorites of @%{username}", - "Favorites": "Favorites", - "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "Traffic information": "Traffic information", + "DHT Torrents:": "DHT Torrents:", + "Peers:": "Peers:", + "Peer List Size:": "Peer List Size:", + "Active Requests:": "Active Requests:", + "Download:": "Download:", + "Upload:": "Upload:", + "DHT Download:": "DHT Download:", + "DHT Upload:": "DHT Upload:", + "IP Overhead Download:": "IP Overhead Download:", + "IP Overhead Upload:": "IP Overhead Upload:", + "Payload Download:": "Payload Download:", + "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -3402,24 +3402,24 @@ if(preferredLanguage == "ja"){ "Sound": "Sound", "Users": "Users", "Direct Message's copy to self": "Direct Message's copy to self", - "Traffic information": "Traffic information", - "DHT Torrents:": "DHT Torrents:", - "Peers:": "Peers:", - "Peer List Size:": "Peer List Size:", - "Active Requests:": "Active Requests:", - "Download:": "Download:", - "Upload:": "Upload:", - "DHT Download:": "DHT Download:", - "DHT Upload:": "DHT Upload:", - "IP Overhead Download:": "IP Overhead Download:", - "IP Overhead Upload:": "IP Overhead Upload:", - "Payload Download:": "Payload Download:", - "Payload Upload:": "Payload Upload:", - "No favs here because you are not logged in." : "No favs here because you are not logged in.", - "users_favs": "Favorites of @%{username}", - "Favorites": "Favorites", - "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "Traffic information": "Traffic information", + "DHT Torrents:": "DHT Torrents:", + "Peers:": "Peers:", + "Peer List Size:": "Peer List Size:", + "Active Requests:": "Active Requests:", + "Download:": "Download:", + "Upload:": "Upload:", + "DHT Download:": "DHT Download:", + "DHT Upload:": "DHT Upload:", + "IP Overhead Download:": "IP Overhead Download:", + "IP Overhead Upload:": "IP Overhead Upload:", + "Payload Download:": "Payload Download:", + "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -3744,24 +3744,24 @@ if(preferredLanguage == "pt-BR"){ "Sound": "Sound", "Users": "Users", "Direct Message's copy to self": "Direct Message's copy to self", - "Traffic information": "Traffic information", - "DHT Torrents:": "DHT Torrents:", - "Peers:": "Peers:", - "Peer List Size:": "Peer List Size:", - "Active Requests:": "Active Requests:", - "Download:": "Download:", - "Upload:": "Upload:", - "DHT Download:": "DHT Download:", - "DHT Upload:": "DHT Upload:", - "IP Overhead Download:": "IP Overhead Download:", - "IP Overhead Upload:": "IP Overhead Upload:", - "Payload Download:": "Payload Download:", - "Payload Upload:": "Payload Upload:", - "No favs here because you are not logged in." : "No favs here because you are not logged in.", - "users_favs": "Favorites of @%{username}", - "Favorites": "Favorites", - "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "Traffic information": "Traffic information", + "DHT Torrents:": "DHT Torrents:", + "Peers:": "Peers:", + "Peer List Size:": "Peer List Size:", + "Active Requests:": "Active Requests:", + "Download:": "Download:", + "Upload:": "Upload:", + "DHT Download:": "DHT Download:", + "DHT Upload:": "DHT Upload:", + "IP Overhead Download:": "IP Overhead Download:", + "IP Overhead Upload:": "IP Overhead Upload:", + "Payload Download:": "Payload Download:", + "Payload Upload:": "Payload Upload:", + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } @@ -4082,24 +4082,24 @@ if(preferredLanguage == "tr"){ "Sound": "Ses", "Users": "Kullanıcılar", "Direct Message's copy to self": "Özel iletinin kopyasını sakla", - "Traffic information": "Trafik bilgileri", - "DHT Torrents:": "DHT Torrentleri:", - "Peers:": "Eşler:", - "Peer List Size:": "Eş listesi uzunluğu:", - "Active Requests:": "Aktif istekler:", - "Download:": "İndirme:", - "Upload:": "Yükleme:", - "DHT Download:": "DHT İndirme:", - "DHT Upload:": "DHT Yükleme:", - "IP Overhead Download:": "IP Başlık İndirme:", - "IP Overhead Upload:": "IP Başlık Yükleme:", - "Payload Download:": "İçerik İndirme:", - "Payload Upload:": "İçerik Yükleme:", - "No favs here because you are not logged in." : "Giriş yapmadan favorileri göremezsin.", - "users_favs": "@%{username} kullanıcısının favorileri", - "Favorites": "Favoriler", - "You have to log in to favorite messages.": "İletileri favorine eklemek için giriş yapmalısın.", - "fav_this": "Sana özel mi?" + "Traffic information": "Trafik bilgileri", + "DHT Torrents:": "DHT Torrentleri:", + "Peers:": "Eşler:", + "Peer List Size:": "Eş listesi uzunluğu:", + "Active Requests:": "Aktif istekler:", + "Download:": "İndirme:", + "Upload:": "Yükleme:", + "DHT Download:": "DHT İndirme:", + "DHT Upload:": "DHT Yükleme:", + "IP Overhead Download:": "IP Başlık İndirme:", + "IP Overhead Upload:": "IP Başlık Yükleme:", + "Payload Download:": "İçerik İndirme:", + "Payload Upload:": "İçerik Yükleme:", + "No favs here because you are not logged in." : "Giriş yapmadan favorileri göremezsin.", + "users_favs": "@%{username} kullanıcısının favorileri", + "Favorites": "Favoriler", + "You have to log in to favorite messages.": "İletileri favorine eklemek için giriş yapmalısın.", + "fav_this": "Sana özel mi?" }; } @@ -4436,11 +4436,11 @@ if(preferredLanguage == "cs"){ "IP Overhead Upload:": "IP Overhead - odesílání:", "Payload Download:": "Data aplikace - stahování:", "Payload Upload:": "Data aplikace - odesílání:", - "No favs here because you are not logged in." : "No favs here because you are not logged in.", - "users_favs": "Favorites of @%{username}", - "Favorites": "Favorites", - "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "No favs here because you are not logged in." : "No favs here because you are not logged in.", + "users_favs": "Favorites of @%{username}", + "Favorites": "Favorites", + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "fav_this": "Is it for you only?" }; } From 5cb114b7f22edad1d1b6b16140a7bbe2a9f4113f Mon Sep 17 00:00:00 2001 From: erqan Date: Thu, 8 Sep 2016 15:43:53 +0300 Subject: [PATCH 11/54] fix internal image preview --- js/interface_common.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/interface_common.js b/js/interface_common.js index 0402b78..4ef4418 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -1431,7 +1431,7 @@ function postExpandFunction(e, postLi) { var originalLi = $('
  3. ', {class: 'module post original'}).appendTo(itemOl) .append(originalPost); - setPostImagePreview(postExpandedContent, originalPost.find('a[rel="nofollow"]')); + setPostImagePreview(postExpandedContent, originalPost.find('a[rel^="nofollow"]')); postExpandedContent.slideDown('fast'); From 80d5a5b92f5b4b09bbcef9bb0b34a9fda02e2d66 Mon Sep 17 00:00:00 2001 From: erqan Date: Sat, 10 Sep 2016 18:14:08 +0300 Subject: [PATCH 12/54] adding modal warning field --- css/style.css | 16 ++++++++++++++++ home.html | 4 ++++ js/interface_common.js | 13 +++++++++---- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/css/style.css b/css/style.css index 4655c31..a00f75c 100644 --- a/css/style.css +++ b/css/style.css @@ -1577,6 +1577,22 @@ ol.toptrends-list { font-weight: bold; } +.modal-warn { + display: none; + background: #fffbc3; + font-size: 0.8em; + padding: 10px; + border: 3px solid #fff; +} + +.modal-warn-close { + float:right; + font-size: 1.2em; + color: #e34f42; + cursor: pointer; + margin: -8px; +} + .modal-wrapper .modal-content { background: #fff; overflow-y: auto; diff --git a/home.html b/home.html index 61b8af6..46d05ce 100644 --- a/home.html +++ b/home.html @@ -422,6 +422,10 @@ < + diff --git a/js/interface_common.js b/js/interface_common.js index 9cf222b..15352fe 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -57,6 +57,10 @@ function openModal(modal) { if (modal.title) modal.self.find('.modal-header h3').html(modal.title); + if (modal.warn) + modal.self.find('.modal-warn') + .show() + .find('.warn-text').html(modal.warn); if (modal.content) modal.content = modal.self.find('.modal-content') .append(modal.content); @@ -610,12 +614,11 @@ function openFollowersModal(peerAlias) { var modal = openModal({ classAdd: 'followers-modal', content: twister.tmpl.followersList.clone(true), - title: title + title: title, + warn: txtAlert }); appendFollowersToElem(modal.content.find('ol'), followers); - - alertPopup({txtMessage: txtAlert}); } function appendFollowersToElem(list, followers) { @@ -1537,7 +1540,7 @@ function postExpandFunction(e, postLi) { var originalLi = $('
  4. ', {class: 'module post original'}).appendTo(itemOl) .append(originalPost); - setPostImagePreview(postExpandedContent, originalPost.find('a[rel="nofollow"]')); + setPostImagePreview(postExpandedContent, originalPost.find('a[rel^="nofollow"]')); postExpandedContent.slideDown('fast'); @@ -2517,6 +2520,8 @@ function initInterfaceCommon() { $('.modal-back').on('click', function() {history.back();}); + $('.modal-warn-close').on('click', function() {$(this).closest('.modal-warn').hide()}); + $('.prompt-close').on('click', closePrompt); $('button.follow').on('click', clickFollow); From 173d7e749f3d40a8a6cefc070648e8427694a2eb Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Sun, 11 Sep 2016 17:15:58 +0500 Subject: [PATCH 13/54] make modal inline warning optional for modal; fix modal content height; add CSS for `calm` and `nin` --- css/style.css | 33 +++++++++++++++++---------------- home.html | 11 +++++++---- js/interface_common.js | 36 +++++++++++++++++++++++++++++------- theme_calm/css/style.css | 17 +++++++++++++++++ theme_nin/css/style.css | 18 ++++++++++++++++++ 5 files changed, 88 insertions(+), 27 deletions(-) diff --git a/css/style.css b/css/style.css index a00f75c..854e10f 100644 --- a/css/style.css +++ b/css/style.css @@ -1577,22 +1577,6 @@ ol.toptrends-list { font-weight: bold; } -.modal-warn { - display: none; - background: #fffbc3; - font-size: 0.8em; - padding: 10px; - border: 3px solid #fff; -} - -.modal-warn-close { - float:right; - font-size: 1.2em; - color: #e34f42; - cursor: pointer; - margin: -8px; -} - .modal-wrapper .modal-content { background: #fff; overflow-y: auto; @@ -1662,6 +1646,23 @@ ol.toptrends-list { padding: 10px 15px; } +.inline-warn { + background-color: #FEFEDF; + padding: 10px; +} + +.inline-warn .close { + float: right; + font-size: 1.2em; + color: #e34f42; + cursor: pointer; + margin: -8px 2px 8px 8px; +} + +.inline-warn .text { + font-size: 0.8em; +} + /************************************* ******** DIRECT MESSAGES MODAL ******* **************************************/ diff --git a/home.html b/home.html index 46d05ce..43e8b01 100644 --- a/home.html +++ b/home.html @@ -422,14 +422,17 @@ < - +
    +
    +
    ×
    +
    +
    +
    +
  5. diff --git a/js/interface_common.js b/js/interface_common.js index 5aedcc5..8b1fe9d 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -389,6 +389,7 @@ function checkNetworkStatusAndAskRedirect(cbFunc, cbReq) { } function timeGmtToText(t) { + if (t == 0) return '-'; var d = new Date(0); d.setUTCSeconds(t); return d.toString().replace(/GMT.*/g, ''); @@ -750,6 +751,7 @@ function fillWhoToFollowModal(list, hlist, start) { getFullname(utf, item.find('.twister-user-full')); getBioToElem(utf, item.find('.bio')); getFullname(followingUsers[i], item.find('.followed-by').text(followingUsers[i])); + getStatusTime(utf,item.find('.user-status-time')); item.find('.twister-user-remove').remove(); @@ -2620,6 +2622,8 @@ function initInterfaceCommon() { displayQueryPending($('.hashtag-modal .postboard-posts')); }); + $('.user-status-time').on('mouseup', {feeder: '.user-status-time'}, handleClickOpenConversation); + replaceDashboards(); $(window).resize(replaceDashboards); diff --git a/js/interface_localization.js b/js/interface_localization.js index 6270935..bdae9d0 100644 --- a/js/interface_localization.js +++ b/js/interface_localization.js @@ -366,7 +366,8 @@ if(preferredLanguage == "en"){ "users_favs": "Favorites of @%{username}", "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "fav_this": "Is it for you only?", + "Last activity": "Last activity" }; } if(preferredLanguage == "es"){ @@ -705,7 +706,8 @@ if(preferredLanguage == "es"){ "users_favs": "Favorites of @%{username}", "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "fav_this": "Is it for you only?", + "Last activity": "Last activity" }; } @@ -1043,7 +1045,8 @@ if(preferredLanguage == "uk"){ "users_favs": "Favorites of @%{username}", "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "fav_this": "Is it for you only?", + "Last activity": "Last activity" }; } @@ -1386,7 +1389,8 @@ if(preferredLanguage == "zh-CN"){ "users_favs": "Favorites of @%{username}", "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "fav_this": "Is it for you only?", + "Last activity": "Last activity" }; } @@ -1726,7 +1730,8 @@ if(preferredLanguage == "nl"){ "users_favs": "Favorites of @%{username}", "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "fav_this": "Is it for you only?", + "Last activity": "Last activity" }; } @@ -2064,7 +2069,8 @@ if(preferredLanguage == "it"){ "users_favs": "Favorites of @%{username}", "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "fav_this": "Is it for you only?", + "Last activity": "Last activity" }; } @@ -2403,8 +2409,8 @@ if(preferredLanguage == "fr"){ "No favs here because you are not logged in." : "No favs here because you are not logged in.", "users_favs": "Favorites of @%{username}", "Favorites": "Favorites", - "You have to log in to favorite messages.": "You have to log in to favorite messages." - + "You have to log in to favorite messages.": "You have to log in to favorite messages.", + "Last activity": "Last activity" }; } @@ -2750,7 +2756,8 @@ if(preferredLanguage == "ru"){ "users_favs": "Favorites of @%{username}", "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "fav_this": "Is it for you only?", + "Last activity": "Last activity" }; } @@ -3092,7 +3099,8 @@ if(preferredLanguage == "de"){ "users_favs": "Favorites of @%{username}", "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "fav_this": "Is it for you only?", + "Last activity": "Last activity" }; } @@ -3429,7 +3437,8 @@ if(preferredLanguage == "ja"){ "users_favs": "Favorites of @%{username}", "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "fav_this": "Is it for you only?", + "Last activity": "Last activity" }; } @@ -3772,7 +3781,8 @@ if(preferredLanguage == "pt-BR"){ "users_favs": "Favorites of @%{username}", "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "fav_this": "Is it for you only?", + "Last activity": "Last activity" }; } @@ -4111,7 +4121,8 @@ if(preferredLanguage == "tr"){ "users_favs": "@%{username} kullanıcısının favorileri", "Favorites": "Favoriler", "You have to log in to favorite messages.": "İletileri favorine eklemek için giriş yapmalısın.", - "fav_this": "Sana özel mi?" + "fav_this": "Sana özel mi?", + "Last activity": "Son etkinlik" }; } @@ -4453,7 +4464,8 @@ if(preferredLanguage == "cs"){ "users_favs": "Favorites of @%{username}", "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "fav_this": "Is it for you only?" + "fav_this": "Is it for you only?", + "Last activity": "Last activity" }; } diff --git a/js/twister_following.js b/js/twister_following.js index 3ea7ba9..1d96934 100644 --- a/js/twister_following.js +++ b/js/twister_following.js @@ -515,6 +515,7 @@ function processWhoToFollowSuggestion(suggestion, followedBy) { getAvatar(suggestion, item.find('.twister-user-photo')); getFullname(followedBy, item.find('.followed-by').text(followedBy)); + getStatusTime(suggestion,item.find('.user-status-time')); item.find('.twister-user-remove').on('click', function() { item.remove(); diff --git a/js/twister_io.js b/js/twister_io.js index 5b6a8d8..0a98dc3 100644 --- a/js/twister_io.js +++ b/js/twister_io.js @@ -522,6 +522,25 @@ function getPostsCount(peerAlias, elem) { ); } +function getStatusTime(peerAlias, elem) { + dhtget(peerAlias, 'status', 's', + function(req, v) { + var time = 0; + var k = -1; + if (v && v.userpost) { + time = v.userpost.time; + k = v.userpost.k; + } + elem.text(timeGmtToText(time)); + elem.attr('data-time', time); + if (k > -1) { + elem.attr('data-screen-name', peerAlias); + elem.attr('data-id', k); + } + }, {peerAlias: peerAlias, elem: elem} + ); +} + function getPostMaxAvailability(peerAlias, k, cbFunc, cbReq) { twisterRpc('getpiecemaxseen', [peerAlias, k], function(req, ret) { From c5e8c650f4931332cfd17cde0027b9c4430e8b33 Mon Sep 17 00:00:00 2001 From: erqan Date: Sat, 24 Sep 2016 15:30:09 +0300 Subject: [PATCH 20/54] in following list also --- css/style.css | 8 +++++++- home.html | 6 ++++++ js/interface_common.js | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/css/style.css b/css/style.css index 1392531..db36ed2 100644 --- a/css/style.css +++ b/css/style.css @@ -2346,7 +2346,7 @@ ol.toptrends-list { display: inline-block; text-align: initial; width: 320px; - height: 120px; + height: 130px; margin: 2px; padding: 2px; border: solid 1px rgba(69, 71, 77, .1); @@ -2389,6 +2389,12 @@ ol.toptrends-list { right: 32px; } +.following-own-modal .following-list .last-activity { + position: absolute; + top: 110px; + right: 32px; + margin: 0; +} /************************************* *********** AUTOCOMPLETING *********** **************************************/ diff --git a/home.html b/home.html index 052ed5d..c971185 100644 --- a/home.html +++ b/home.html @@ -780,6 +780,12 @@
    +
    + + Last activity + + +
    diff --git a/js/interface_common.js b/js/interface_common.js index 8b1fe9d..9c68d88 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -711,6 +711,7 @@ function addPeerToFollowingList(list, peerAlias) { .on('mouseup', {route: $.MAL.mentionsUrl(peerAlias)}, routeOnClick); getAvatar(peerAlias, item.find('.mini-profile-photo')); getFullname(peerAlias, item.find('.mini-profile-name')); + getStatusTime(peerAlias, item.find('.user-status-time')); if (peerAlias === defaultScreenName) item.find('.following-config').hide(); From 8662401d0d345ce43d1761e59ab71a17ae268a9c Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Tue, 27 Sep 2016 04:04:35 +0500 Subject: [PATCH 21/54] quibbling to Erkan's latest activity --- css/style.css | 11 ++++++----- home.html | 12 +++++------- js/interface_common.js | 7 ++++--- js/twister_following.js | 2 +- js/twister_io.js | 23 ++++++++++------------- 5 files changed, 26 insertions(+), 29 deletions(-) diff --git a/css/style.css b/css/style.css index db36ed2..b1c131c 100644 --- a/css/style.css +++ b/css/style.css @@ -891,19 +891,19 @@ textarea.splited-post { } .followers, -.last-activity -{ +.latest-activity { font-size: 12px; color: rgba( 0, 0, 0, .6 ); margin-left: 58px; } + .followed-by, -.user-status-time -{ +.latest-activity .time { color: #e34f42; font-size: 13px; cursor: pointer; } + .twister-user-name, .twister-by-user-name { @@ -2389,12 +2389,13 @@ ol.toptrends-list { right: 32px; } -.following-own-modal .following-list .last-activity { +.following-own-modal .following-list .latest-activity { position: absolute; top: 110px; right: 32px; margin: 0; } + /************************************* *********** AUTOCOMPLETING *********** **************************************/ diff --git a/home.html b/home.html index c971185..bdbfd1b 100644 --- a/home.html +++ b/home.html @@ -302,9 +302,9 @@ × -
    +
    Last activity - +
    @@ -780,11 +780,9 @@
    -
    - - Last activity - - +
    + Last activity +
    diff --git a/js/interface_common.js b/js/interface_common.js index 9c68d88..90460ab 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -711,7 +711,7 @@ function addPeerToFollowingList(list, peerAlias) { .on('mouseup', {route: $.MAL.mentionsUrl(peerAlias)}, routeOnClick); getAvatar(peerAlias, item.find('.mini-profile-photo')); getFullname(peerAlias, item.find('.mini-profile-name')); - getStatusTime(peerAlias, item.find('.user-status-time')); + getStatusTime(peerAlias, item.find('.latest-activity .time')); if (peerAlias === defaultScreenName) item.find('.following-config').hide(); @@ -752,7 +752,7 @@ function fillWhoToFollowModal(list, hlist, start) { getFullname(utf, item.find('.twister-user-full')); getBioToElem(utf, item.find('.bio')); getFullname(followingUsers[i], item.find('.followed-by').text(followingUsers[i])); - getStatusTime(utf,item.find('.user-status-time')); + getStatusTime(utf, item.find('.latest-activity .time')); item.find('.twister-user-remove').remove(); @@ -2623,7 +2623,8 @@ function initInterfaceCommon() { displayQueryPending($('.hashtag-modal .postboard-posts')); }); - $('.user-status-time').on('mouseup', {feeder: '.user-status-time'}, handleClickOpenConversation); + getElem('.latest-activity', true).on('mouseup', + {feeder: '.latest-activity'}, handleClickOpenConversation); replaceDashboards(); $(window).resize(replaceDashboards); diff --git a/js/twister_following.js b/js/twister_following.js index 1d96934..c736b05 100644 --- a/js/twister_following.js +++ b/js/twister_following.js @@ -515,7 +515,7 @@ function processWhoToFollowSuggestion(suggestion, followedBy) { getAvatar(suggestion, item.find('.twister-user-photo')); getFullname(followedBy, item.find('.followed-by').text(followedBy)); - getStatusTime(suggestion,item.find('.user-status-time')); + getStatusTime(suggestion, item.find('.latest-activity .time')); item.find('.twister-user-remove').on('click', function() { item.remove(); diff --git a/js/twister_io.js b/js/twister_io.js index 0a98dc3..c9d1ab1 100644 --- a/js/twister_io.js +++ b/js/twister_io.js @@ -524,19 +524,16 @@ function getPostsCount(peerAlias, elem) { function getStatusTime(peerAlias, elem) { dhtget(peerAlias, 'status', 's', - function(req, v) { - var time = 0; - var k = -1; - if (v && v.userpost) { - time = v.userpost.time; - k = v.userpost.k; - } - elem.text(timeGmtToText(time)); - elem.attr('data-time', time); - if (k > -1) { - elem.attr('data-screen-name', peerAlias); - elem.attr('data-id', k); - } + function (req, ret) { + if (!ret || !ret.userpost) + return; + + req.elem.text(timeGmtToText(ret.userpost.time)) + .closest('.latest-activity') + .attr('data-screen-name', req.peerAlias) + .attr('data-id', ret.userpost.k) + .attr('data-time', ret.userpost.time) + ; }, {peerAlias: peerAlias, elem: elem} ); } From c282d9fa6936a451645ae2abdd058f28f3c66ad6 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Tue, 27 Sep 2016 04:05:47 +0500 Subject: [PATCH 22/54] add latest activity CSS for `calm` and `nin` --- theme_calm/css/style.css | 20 +++++++++++++++----- theme_nin/css/style.css | 20 +++++++++++++++++--- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/theme_calm/css/style.css b/theme_calm/css/style.css index 73b38a4..6a9bc02 100644 --- a/theme_calm/css/style.css +++ b/theme_calm/css/style.css @@ -1072,16 +1072,19 @@ textarea.splited-post { opacity: .8; } -.followers -{ +.followers, +.latest-activity { font-size: 12px; color: rgba( 0, 0, 0, .6 ); + margin-left: 58px; } -.followed-by -{ + +.followed-by, +.latest-activity .time { font-size: 13px; cursor: pointer; } + .twister-user-name, .twister-by-user-name { @@ -2767,7 +2770,7 @@ textarea.splited-post { display: inline-block; text-align: initial; width: 320px; - height: 120px; + height: 130px; margin: 2px; padding: 2px; border: solid 1px rgba(69, 71, 77, .1); @@ -2813,6 +2816,13 @@ textarea.splited-post { right: 32px; } +.following-own-modal .following-list .latest-activity { + position: absolute; + top: 110px; + right: 32px; + margin: 0; +} + .gifCheckBox { float: right; vertical-align: middle; diff --git a/theme_nin/css/style.css b/theme_nin/css/style.css index eef5b66..2caf94f 100644 --- a/theme_nin/css/style.css +++ b/theme_nin/css/style.css @@ -2209,7 +2209,8 @@ textarea.splited-post { } /* line 447, ../sass/style.sass */ -.followers { +.followers, +.latest-activity { font-size: 12px; color: #66686B; } @@ -2219,13 +2220,22 @@ textarea.splited-post { } /* line 453, ../sass/style.sass */ -.followed-by { +.followed-by, +.latest-activity { color: #aaa; font-size: 12px; cursor: pointer; display: block; } +.who-to-follow .latest-activity { + margin-bottom: 8px; +} + +.who-to-follow .latest-activity .label { + display: none; +} + /* line 459, ../sass/style.sass */ .twister-user-name, .twister-by-user-name { font-weight: bold; @@ -3356,7 +3366,7 @@ ol.toptrends-list a:hover { .following-own-modal .following-list > li { display: inline-block; width: 320px; - height: 160px; + height: 184px; margin: 2px; padding: 2px; border: solid 1px rgba(69, 71, 77, .1); @@ -3456,6 +3466,10 @@ ol.toptrends-list a:hover { display: block; } +.following-own-modal .following-list .latest-activity { + font-size: 11px; +} + /********** AUTOCOMPLETING *********/ /* line 1087, ../sass/style.sass */ From 32d6d59ee98c7a29b3562e7959dbab4f4d730a0e Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Tue, 27 Sep 2016 04:21:38 +0500 Subject: [PATCH 23/54] add checks to handleClickOpenConversation() --- js/interface_common.js | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/js/interface_common.js b/js/interface_common.js index 90460ab..8abbd24 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -875,14 +875,22 @@ function handleClickOpenProfileModal(event) { } function handleClickOpenConversation(event) { - event.preventDefault(); - event.stopPropagation(); + var elem = $(event.target).closest(event.data.feeder); + if (!elem.length) { + muteEvent(event, true); + return; + } - var elem = $(event.target); - var postData = elem.closest(event.data.feeder); + var post = { + writer: elem.attr('data-screen-name'), + id: elem.attr('data-id') + }; + if (!post.writer || !post.id) { + muteEvent(event, true); + return; + } - event.data.route = '#conversation?post=' + postData.attr('data-screen-name') - + ':post' + postData.attr('data-id'); + event.data.route = '#conversation?post=' + post.writer + ':post' + post.id; routeOnClick(event); } From 214ec3f3c7a9fade979abc135e6e85555d6f2dec Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Thu, 6 Oct 2016 23:33:45 +0500 Subject: [PATCH 24/54] fix DM group joining via key import --- css/style.css | 2 +- home.html | 4 -- js/interface_localization.js | 52 ++++++++++++++++++++++++++ js/twister_directmsg.js | 72 ++++++++++++++++++++++++++++-------- theme_calm/css/style.css | 2 +- theme_nin/css/style.css | 4 +- 6 files changed, 112 insertions(+), 24 deletions(-) diff --git a/css/style.css b/css/style.css index b1c131c..ef791bd 100644 --- a/css/style.css +++ b/css/style.css @@ -1822,7 +1822,7 @@ ol.toptrends-list { .group-messages-join-group.modal-wrapper { height: auto; /*about 360px*/ - margin-top: -240px; + margin-top: -204px; } .group-messages-join-group .modal-content .module { diff --git a/home.html b/home.html index bdbfd1b..2ff27ec 100644 --- a/home.html +++ b/home.html @@ -632,10 +632,6 @@

    Import secret key

    -
    -

    With group alias

    - -
    diff --git a/js/interface_localization.js b/js/interface_localization.js index bdae9d0..ae9e44c 100644 --- a/js/interface_localization.js +++ b/js/interface_localization.js @@ -69,6 +69,10 @@ if(preferredLanguage == "en"){ "Group Messages": "Group Messages", "Group Messages — New Group Creation": "Group Messages — New Group Creation", "Group Messages — Join Group": "Group Messages — Join Group", + "group_key_cant_import": "Can\'t import DM group key", + "group_key_is_invalid_perhaps": "perhaps the key is invalid", + "group_key_was_imported": "Key for DM group %{alias} was imported.\n" + + "Its messages will be fetched soon.", "direct_messages_with": "Direct messages with %{username}", "Disable": "Disable", "display_mentions": "Display mentions", @@ -413,6 +417,10 @@ if(preferredLanguage == "es"){ "Group Messages": "Group Messages", "Group Messages — New Group Creation": "Group Messages — New Group Creation", "Group Messages — Join Group": "Group Messages — Join Group", + "group_key_cant_import": "Can\'t import DM group key", + "group_key_is_invalid_perhaps": "perhaps the key is invalid", + "group_key_was_imported": "Key for DM group %{alias} was imported.\n" + + "Its messages will be fetched soon.", "direct_messages_with": "Mensajes directos con %{username}", "Disable": "Inhabilitar", "display_mentions": "Visualización de menciones", @@ -754,6 +762,10 @@ if(preferredLanguage == "uk"){ "Group Messages": "Group Messages", "Group Messages — New Group Creation": "Group Messages — New Group Creation", "Group Messages — Join Group": "Group Messages — Join Group", + "group_key_cant_import": "Can\'t import DM group key", + "group_key_is_invalid_perhaps": "perhaps the key is invalid", + "group_key_was_imported": "Key for DM group %{alias} was imported.\n" + + "Its messages will be fetched soon.", "direct_messages_with": "Direct messages with %{username}", "Disable": "Вимкнено", "display_mentions": "Показати сповіщення", @@ -1093,6 +1105,10 @@ if(preferredLanguage == "zh-CN"){ "Group Messages": "Group Messages", "Group Messages — New Group Creation": "Group Messages — New Group Creation", "Group Messages — Join Group": "Group Messages — Join Group", + "group_key_cant_import": "Can\'t import DM group key", + "group_key_is_invalid_perhaps": "perhaps the key is invalid", + "group_key_was_imported": "Key for DM group %{alias} was imported.\n" + + "Its messages will be fetched soon.", "direct_messages_with": "Direct messages with %{username}", "Disable": "关闭", "display_mentions": "显示", @@ -1437,6 +1453,10 @@ if(preferredLanguage == "nl"){ "Group Messages": "Group Messages", "Group Messages — New Group Creation": "Group Messages — New Group Creation", "Group Messages — Join Group": "Group Messages — Join Group", + "group_key_cant_import": "Can\'t import DM group key", + "group_key_is_invalid_perhaps": "perhaps the key is invalid", + "group_key_was_imported": "Key for DM group %{alias} was imported.\n" + + "Its messages will be fetched soon.", "direct_messages_with": "Direct messages with %{username}", "Disable": "Uitschakelen", "display_mentions": "Toon vermeldingen", @@ -1778,6 +1798,10 @@ if(preferredLanguage == "it"){ "Group Messages": "Group Messages", "Group Messages — New Group Creation": "Group Messages — New Group Creation", "Group Messages — Join Group": "Group Messages — Join Group", + "group_key_cant_import": "Can\'t import DM group key", + "group_key_is_invalid_perhaps": "perhaps the key is invalid", + "group_key_was_imported": "Key for DM group %{alias} was imported.\n" + + "Its messages will be fetched soon.", "direct_messages_with": "Messaggi Diretti come %{username}", "Disable": "Disabilitato", "display_mentions": "Mostra le menzioni", @@ -2117,6 +2141,10 @@ if(preferredLanguage == "fr"){ "Group Messages": "Group Messages", "Group Messages — New Group Creation": "Group Messages — New Group Creation", "Group Messages — Join Group": "Group Messages — Join Group", + "group_key_cant_import": "Can\'t import DM group key", + "group_key_is_invalid_perhaps": "perhaps the key is invalid", + "group_key_was_imported": "Key for DM group %{alias} was imported.\n" + + "Its messages will be fetched soon.", "direct_messages_with": "Messages privés avec %{username}", "Disable": "Désactiver", "display_mentions": "Afficher les mentions", @@ -2459,6 +2487,10 @@ if(preferredLanguage == "ru"){ "Group Messages": "Групповые сообщения", "Group Messages — New Group Creation": "Групповые сообщения — Создать новую группу", "Group Messages — Join Group": "Групповые сообщения — Присоединиться к группе", + "group_key_cant_import": "невозможно импортировать ключ ЛС группы", + "group_key_is_invalid_perhaps": "возможно, неправильный ключ", + "group_key_was_imported": "Ключ для ЛС группы %{alias} импортирован.\n" + + "Её сообщения будут подгружены в скором времени.", "direct_messages_with": "Личная переписка с %{username}", "Disable": "Отключено", "display_mentions": "Показать упоминания", @@ -2804,6 +2836,10 @@ if(preferredLanguage == "de"){ "Group Messages": "Gruppennachrichten", "Group Messages — New Group Creation": "Gruppennachrichten — Neue Gruppe erstellen", "Group Messages — Join Group": "Gruppennachrichten — Gruppe beitreten", + "group_key_cant_import": "Can\'t import DM group key", + "group_key_is_invalid_perhaps": "perhaps the key is invalid", + "group_key_was_imported": "Key for DM group %{alias} was imported.\n" + + "Its messages will be fetched soon.", "direct_messages_with": "Direktnachrichten mit %{username}", "Disable": "Deaktivieren", "display_mentions": "Zeige Erwähnungen", // Ist das richtig? Ich weiß nicht, in welchem Zusammenhang das benutzt wird. @@ -3147,6 +3183,10 @@ if(preferredLanguage == "ja"){ "Group Messages": "Group Messages", "Group Messages — New Group Creation": "Group Messages — New Group Creation", "Group Messages — Join Group": "Group Messages — Join Group", + "group_key_cant_import": "Can\'t import DM group key", + "group_key_is_invalid_perhaps": "perhaps the key is invalid", + "group_key_was_imported": "Key for DM group %{alias} was imported.\n" + + "Its messages will be fetched soon.", "direct_messages_with": "Direct messages with %{username}", "Disable": "停止", "display_mentions": "メンションを表示する", @@ -3486,6 +3526,10 @@ if(preferredLanguage == "pt-BR"){ "Group Messages": "Group Messages", "Group Messages — New Group Creation": "Group Messages — New Group Creation", "Group Messages — Join Group": "Group Messages — Join Group", + "group_key_cant_import": "Can\'t import DM group key", + "group_key_is_invalid_perhaps": "perhaps the key is invalid", + "group_key_was_imported": "Key for DM group %{alias} was imported.\n" + + "Its messages will be fetched soon.", "direct_messages_with": "Mensagens Diretas com %{username}", "Disable": "Desabilitado", "display_mentions": "Exibir menções", @@ -3829,6 +3873,10 @@ if(preferredLanguage == "tr"){ "Group Messages": "Grup Mesajları", "Group Messages — New Group Creation": "Grup Mesajları — Yeni Grup Oluştur", "Group Messages — Join Group": "Grup Mesajları — Gruba katıl", + "group_key_cant_import": "Can\'t import DM group key", + "group_key_is_invalid_perhaps": "perhaps the key is invalid", + "group_key_was_imported": "Key for DM group %{alias} was imported.\n" + + "Its messages will be fetched soon.", "direct_messages_with": "%{username} ile Direk Mesajlar", "Disable": "Kullanılmaz", "display_mentions": "Bahsedenleri göster", @@ -4169,6 +4217,10 @@ if(preferredLanguage == "cs"){ "Group Messages": "Group Messages", "Group Messages — New Group Creation": "Group Messages — New Group Creation", "Group Messages — Join Group": "Group Messages — Join Group", + "group_key_cant_import": "Can\'t import DM group key", + "group_key_is_invalid_perhaps": "perhaps the key is invalid", + "group_key_was_imported": "Key for DM group %{alias} was imported.\n" + + "Its messages will be fetched soon.", "direct_messages_with": "Direct messages with %{username}", "Disable": "Vypnuto", "display_mentions": "Zobrazit zmínky", diff --git a/js/twister_directmsg.js b/js/twister_directmsg.js index 8df5aa5..0652fc4 100644 --- a/js/twister_directmsg.js +++ b/js/twister_directmsg.js @@ -359,22 +359,13 @@ function openGroupMessagesJoinGroupModal() { closeModal(event); }); - modal.content.find('.secret-key-import, .username-import').on('input', importSecretKeypress); + modal.content.find('.secret-key-import').on('input', + {parentSelector: '.module', enterSelector: '.import-secret-key'}, inputEnterActivator); modal.content.find('.import-secret-key').on('click', function (event) { - var elemModule = $(event.target).closest('.module'); - var groupAlias = elemModule.find('.username-import').val().toLowerCase(); - var secretKey = elemModule.find('.secret-key-import').val(); + groupMsgImportKey($(event.target).closest('.module').find('.secret-key-import').val()); - twisterRpc('importprivkey', [secretKey, groupAlias], - function(req, ret) { - groupMsgInviteToGroup(req.groupAlias, [defaultScreenName]); - closeModal(req.elem); - }, {groupAlias: groupAlias, elem: elemModule}, - function(req, ret) { - alert(polyglot.t('Error in \'importprivkey\'', {rpc: ret.message})); - } - ); + closeModal(event); }); } @@ -392,8 +383,54 @@ function groupMsgCreateGroup(description, peersToInvite) { ); } -function groupMsgInviteToGroup(groupAlias, peersToInvite) { - _groupMsgInviteToGroupQueue.push({groupAlias: groupAlias, peersToInvite: peersToInvite}); +function groupMsgImportKey(key) { + if (parseInt(twisterVersion) < 93800) { + alertPopup({ + //txtTitle: polyglot.t(''), add some title (not 'error', please) or just KISS + txtMessage: polyglot.t('group_key_cant_import') + + ' —\ndaemon is obsolete, version 0.9.38 or higher is required' + }); + return; + } + + twisterRpc('creategroup', ['whatever', key], + function(req, ret) { + if (!ret) { + alertPopup({ + //txtTitle: polyglot.t(''), add some title (not 'error', please) or just KISS + txtMessage: polyglot.t('group_key_cant_import') + ' —\n' + + polyglot.t('group_key_is_invalid_perhaps') + }); + return; + } + + groupMsgInviteToGroup(ret, [defaultScreenName], + function () { + twisterRpc('rescandirectmsgs', [defaultScreenName], + function () {}, undefined, function () {}); + } + ); + alertPopup({ + //txtTitle: polyglot.t(''), add some title (not 'error', please) or just KISS + txtMessage: polyglot.t('group_key_was_imported', {alias: ret}) + }); + }, undefined, + function(req, ret) { + alertPopup({ + //txtTitle: polyglot.t(''), add some title (not 'error', please) or just KISS + txtMessage: polyglot.t('group_key_cant_import') + ' —\n' + ret.message + }); + } + ); +} + +function groupMsgInviteToGroup(groupAlias, peersToInvite, cbFunc, cbReq) { + _groupMsgInviteToGroupQueue.push({ + groupAlias: groupAlias, + peersToInvite: peersToInvite, + cbFunc: cbFunc, + cbReq: cbReq + }); if (_groupMsgInviteToGroupQueue.length === 1) doGroupMsgInviteToGroup(); @@ -408,7 +445,10 @@ function doGroupMsgInviteToGroup() { _groupMsgInviteToGroupQueue.shift(); if (_groupMsgInviteToGroupQueue.length) setTimeout(doGroupMsgInviteToGroup, 200); - }, null, + + if (typeof req.cbFunc === 'function') + req.cbFunc(req.cbReq); + }, {cbFunc: _groupMsgInviteToGroupQueue[0].cbFunc, cbReq: _groupMsgInviteToGroupQueue[0].cbReq}, function(req, ret) { alert(polyglot.t('error', {error: 'can\'t invite ' + req[1] + ' to ' + req[0] + ' group — ' + ret.message})); diff --git a/theme_calm/css/style.css b/theme_calm/css/style.css index 6a9bc02..c377b81 100644 --- a/theme_calm/css/style.css +++ b/theme_calm/css/style.css @@ -2204,7 +2204,7 @@ textarea.splited-post { .group-messages-join-group.modal-wrapper { height: auto; /*about 360px*/ - margin-top: -240px; + margin-top: -204px; } .group-messages-join-group .modal-content .module { diff --git a/theme_nin/css/style.css b/theme_nin/css/style.css index 2caf94f..fb9be7d 100644 --- a/theme_nin/css/style.css +++ b/theme_nin/css/style.css @@ -2974,8 +2974,8 @@ ol.toptrends-list a:hover { .group-messages-join-group.modal-wrapper { width: 580px; - height: auto; /*about 360px*/ - margin: -250px 0 0 -290px; + height: auto; /*about 409px*/ + margin: -204px 0 0 -290px; } .group-messages-join-group .modal-content { From 3c629129d6340e5835b4d162eb34c10bb148e96d Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Thu, 6 Oct 2016 23:44:15 +0500 Subject: [PATCH 25/54] add polyglot 'daemon_is_obsolete' --- js/interface_common.js | 4 ++-- js/interface_localization.js | 13 +++++++++++++ js/twister_actions.js | 12 +++++++----- js/twister_directmsg.js | 4 ++-- js/twister_io.js | 3 ++- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/js/interface_common.js b/js/interface_common.js index 8abbd24..ec2acdd 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -915,8 +915,8 @@ function openRequestShortURIForm(event) { if (parseInt(twisterVersion) < 93500) { alertPopup({ //txtTitle: polyglot.t(''), add some title (not 'error', please) or just KISS - txtMessage: 'You can\'t shorten links because twister daemon is obsolete!\n' - + 'Version 0.9.35 or higher is required. Please keep your twister up to date.' + txtMessage: 'You can\'t shorten links —\n' + + polyglot.t('daemon_is_obsolete', {versionReq: '0.9.35'}) }); return; } diff --git a/js/interface_localization.js b/js/interface_localization.js index ae9e44c..bef7976 100644 --- a/js/interface_localization.js +++ b/js/interface_localization.js @@ -62,6 +62,7 @@ if(preferredLanguage == "en"){ "Configure block generation": "Configure block generation", "Connections:": "Connections: ", // to network "Connection lost.": "Connection lost.", + "daemon_is_obsolete": "twister daemon is obsolete, version %{versionReq} or higher is required", "days": "%{smart_count} day |||| %{smart_count} days", "Detailed information": "Detailed information", "DHT network down.": "DHT network down.", @@ -410,6 +411,7 @@ if(preferredLanguage == "es"){ "Configure block generation": "Configure la generación de bloques", "Connections:": "Conexiones: ", // to network "Connection lost.": "Conexión perdida.", + "daemon_is_obsolete": "twister daemon is obsolete, version %{versionReq} or higher is required", "days": "%{smart_count} día |||| %{smart_count} días", "Detailed information": "Información detallada", "DHT network down.": "Red DHT caida.", @@ -755,6 +757,7 @@ if(preferredLanguage == "uk"){ "Configure block generation": "Налаштувати генерацію блоку", "Connections:": "З’єднання: ", // to network "Connection lost.": "З’єднання втрачено.", + "daemon_is_obsolete": "twister daemon is obsolete, version %{versionReq} or higher is required", "days": "%{smart_count} день |||| %{smart_count} днів", "Detailed information": "Детальна інформація", "DHT network down.": "Мережа DHT недоступна.", @@ -1098,6 +1101,7 @@ if(preferredLanguage == "zh-CN"){ "Configure block generation": "配置区块生成器", "Connections:": "连接数:", // to network "Connection lost.": "连接中断。", + "daemon_is_obsolete": "twister daemon is obsolete, version %{versionReq} or higher is required", "days": "%{smart_count} 天", "Detailed information": "详细信息", "DHT network down.": "DHT网络中断。", @@ -1446,6 +1450,7 @@ if(preferredLanguage == "nl"){ "Configure block generation": "Block productie configureren", "Connections:": "Connecties: ", // to network "Connection lost.": "Verbinding kwijt.", + "daemon_is_obsolete": "twister daemon is obsolete, version %{versionReq} or higher is required", "days": "%{smart_count} dag |||| %{smart_count} dagen", "Detailed information": "Gedetailleerde informatie", "DHT network down.": "DHT netwerk down.", @@ -1791,6 +1796,7 @@ if(preferredLanguage == "it"){ "Configure block generation": "Configura generatore di blocchi", "Connections:": "Connessioni: ", // to network "Connection lost.": "Connessione interrotta.", + "daemon_is_obsolete": "twister daemon is obsolete, version %{versionReq} or higher is required", "days": "%{smart_count} giorno |||| %{smart_count} giorni", "Detailed information": "Informazioni dettagliate", "DHT network down.": "DHT network inaccessibile.", @@ -2134,6 +2140,7 @@ if(preferredLanguage == "fr"){ "Configure block generation": "Configuration de la production de blocs", "Connections:": "Connexions: ", // to network "Connection lost.": "Connexion perdue.", + "daemon_is_obsolete": "twister daemon is obsolete, version %{versionReq} or higher is required", "days": "%{smart_count} jour |||| %{smart_count} jours", "Detailed information": "Informations détaillées", "DHT network down.": "Panne du réseau DHT.", @@ -2480,6 +2487,7 @@ if(preferredLanguage == "ru"){ "Configure block generation": "Настройка майнинга", "Connections:": "Соединений: ", "Connection lost.": "Соединение с сетью было потеряно.", + "daemon_is_obsolete": "твистер демон устарел, необходима версия %{versionReq} или выше", "days": "%{smart_count} день |||| %{smart_count} дней", "Detailed information": "Подробная информация", "DHT network down.": "Недоступна DHT сеть.", @@ -2829,6 +2837,7 @@ if(preferredLanguage == "de"){ "Configure block generation": "Block-Generierung einstellen", "Connections:": "Verbindungen: ", // to network "Connection lost.": "Verbindung verloren.", + "daemon_is_obsolete": "twister daemon is obsolete, version %{versionReq} or higher is required", "days": "%{smart_count} Tag |||| %{smart_count} Tage", "Detailed information": "Detaillierte Informationen", "DHT network down.": "DHT-Netzwerk nicht verfügbar.", @@ -3176,6 +3185,7 @@ if(preferredLanguage == "ja"){ "Configure block generation": "ブロック生成の設定", "Connections:": "接続数: ", // to network "Connection lost.": "切断されました。", + "daemon_is_obsolete": "twister daemon is obsolete, version %{versionReq} or higher is required", "days": "%{smart_count}日 |||| %{smart_count}日", "Detailed information": "詳細", "DHT network down.": "DHTネットワークがダウンしています", @@ -3519,6 +3529,7 @@ if(preferredLanguage == "pt-BR"){ "Configure block generation": "Configurar a geração de blocos", "Connections:": "Conexões: ", // to network "Connection lost.": "Conexão perdida.", + "daemon_is_obsolete": "twister daemon is obsolete, version %{versionReq} or higher is required", "days": "%{smart_count} dia |||| %{smart_count} dias", "Detailed information": "Informações detalhadas", "DHT network down.": "Falha na rede DHT", @@ -3866,6 +3877,7 @@ if(preferredLanguage == "tr"){ "Configure block generation": "Blok üretim ayarları", "Connections:": "Bağlantılar: ", // to network "Connection lost.": "Bağlantı koptu.", + "daemon_is_obsolete": "twister daemon is obsolete, version %{versionReq} or higher is required", "days": "%{smart_count} gün |||| %{smart_count} gün", "Detailed information": "Detaylı bilgi", "DHT network down.": "DHT ağı çalışmıyor.", @@ -4210,6 +4222,7 @@ if(preferredLanguage == "cs"){ "Configure block generation": "Nastavení generace bloků", "Connections:": "Připojení: ", // to network "Connection lost.": "Žádné připojení do sítě.", + "daemon_is_obsolete": "twister daemon is obsolete, version %{versionReq} or higher is required", "days": "%{smart_count} dnem |||| %{smart_count} dny |||| %{smart_count} dny", "Detailed information": "Podrobné informace", "DHT network down.": "Síť DHT je nedostupná.", diff --git a/js/twister_actions.js b/js/twister_actions.js index df56d09..a8ee43c 100644 --- a/js/twister_actions.js +++ b/js/twister_actions.js @@ -271,10 +271,11 @@ function newRtMsg(postData, msg) { if (userpost.rt) { if (parseInt(twisterVersion) <= 93000) { - alert(polyglot.t('error', - {error: 'can\'t handle retwisting of commented retwisted twists with daemon version ' - + twisterDisplayVersion + ' and below of that. Please upgrade it.'} - )); + alertPopup({ + //txtTitle: polyglot.t(''), add some title (not 'error', please) or just KISS + txtMessage: 'Can\'t handle retwisting of commented retwisted twists —\n' + + polyglot.t('daemon_is_obsolete', {versionReq: '0.9.3+'}) + }); return; } else { @@ -355,7 +356,8 @@ function newFavMsg(postData, priv, msg) { function newShortURI(uri, cbFunc, cbReq) { if (!uri || !defaultScreenName) return; if (parseInt(twisterVersion) < 93500) { - console.warn('can\'t shorten URI "' + uri + '": daemon is obsolete, version 0.9.35 or higher is required'); + console.warn('can\'t shorten URI "' + uri + '" — ' + + polyglot.t('daemon_is_obsolete', {versionReq: '0.9.35'})); return; } diff --git a/js/twister_directmsg.js b/js/twister_directmsg.js index 0652fc4..e160b45 100644 --- a/js/twister_directmsg.js +++ b/js/twister_directmsg.js @@ -387,8 +387,8 @@ function groupMsgImportKey(key) { if (parseInt(twisterVersion) < 93800) { alertPopup({ //txtTitle: polyglot.t(''), add some title (not 'error', please) or just KISS - txtMessage: polyglot.t('group_key_cant_import') - + ' —\ndaemon is obsolete, version 0.9.38 or higher is required' + txtMessage: polyglot.t('group_key_cant_import') + ' —\n' + + polyglot.t('daemon_is_obsolete', {versionReq: '0.9.38'}) }); return; } diff --git a/js/twister_io.js b/js/twister_io.js index c9d1ab1..a613690 100644 --- a/js/twister_io.js +++ b/js/twister_io.js @@ -115,7 +115,8 @@ function dhtget(peerAlias, resource, multi, cbFunc, cbReq, timeoutArgs) { function decodeShortURI(locator, cbFunc, cbReq, timeoutArgs) { if (!locator) return; if (parseInt(twisterVersion) < 93500) { - console.warn('can\'t fetch URI "' + req + '": daemon is obsolete, version 0.9.35 or higher is required'); + console.warn('can\'t fetch URI "' + req + '" — ' + + polyglot.t('daemon_is_obsolete', {versionReq: '0.9.35'})); return; } From c154d6109230ed07cfe35fdf85270f66cb743919 Mon Sep 17 00:00:00 2001 From: erqan Date: Sat, 8 Oct 2016 16:48:33 +0300 Subject: [PATCH 26/54] theme syncing for favs --- theme_calm/css/style.css | 10 ++++++++++ theme_nin/css/style.css | 16 ++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/theme_calm/css/style.css b/theme_calm/css/style.css index c377b81..21f5be0 100644 --- a/theme_calm/css/style.css +++ b/theme_calm/css/style.css @@ -344,6 +344,16 @@ button.unfollow:hover { opacity: 0.9; } +.userMenu li.userMenu-favs > a { + padding: 0 14px; + opacity: 1; +} + +.userMenu li.userMenu-favs > a:before { + content: '★'; + font-size: 24px; +} + .userMenu li.userMenu-profile > a { background: url(../img/profile.png) no-repeat 5px center; padding-left: 35px; diff --git a/theme_nin/css/style.css b/theme_nin/css/style.css index fb9be7d..1f5ba6b 100644 --- a/theme_nin/css/style.css +++ b/theme_nin/css/style.css @@ -389,6 +389,15 @@ samp { font-size: 1.5em; } +.userMenu li.userMenu-favs > a { + padding: 0 14px; + opacity: 1; +} + +.userMenu li.userMenu-favs > a:before { + content: '★'; + font-size: 24px; +} /************************************* ************ PROFILE MODAL *********** **************************************/ @@ -961,11 +970,6 @@ samp { color: #727578; } -/* line 195, ../sass/_postboard.sass */ -.post-favorite { - display: none !important; -} - /* line 200, ../sass/_postboard.sass */ .post .show-more { display: inline-block; @@ -1014,7 +1018,7 @@ samp { display: none !important; } /* line 236, ../sass/_postboard.sass */ -.open .related:hover .post-reply, .mini-profile .post-area-new .related:hover .post-reply, #postboard-top .post-area .post-area-new .related:hover .post-reply, .open .related:hover .post-propagate, .mini-profile .post-area-new .related:hover .post-propagate, #postboard-top .post-area .post-area-new .related:hover .post-propagate { +.open .related:hover .post-reply, .mini-profile .post-area-new .related:hover .post-reply, #postboard-top .post-area .post-area-new .related:hover .post-reply, .open .related:hover .post-propagate, .mini-profile .post-area-new .related:hover .post-propagate, #postboard-top .post-area .post-area-new .related:hover .post-propagate, .open .related:hover .post-favorite, .mini-profile .post-area-new .related:hover .post-favorite, #postboard-top .post-area .post-area-new .related:hover .post-favorite { display: inline-block !important; } From 8893d79eede710ea5c5a9396be7f222df8d1287b Mon Sep 17 00:00:00 2001 From: erqan Date: Sat, 19 Nov 2016 14:16:33 +0300 Subject: [PATCH 27/54] new users module --- css/style.css | 29 ++++++++++------ home.html | 19 +++++++++++ js/interface_common.js | 43 ++++++++++++++---------- js/interface_home.js | 28 ++++++++++++++++ js/interface_localization.js | 39 ++++++++++++++-------- js/options.js | 4 +++ js/twister_following.js | 62 +++++++++++++++++++++++++++++----- js/twister_network.js | 65 +++++++++++++++++++++--------------- options.html | 11 ++++++ theme_calm/css/style.css | 29 ++++++++++------ theme_nin/css/style.css | 41 +++++++++++++++-------- 11 files changed, 268 insertions(+), 102 deletions(-) diff --git a/css/style.css b/css/style.css index ef791bd..e04d0e2 100644 --- a/css/style.css +++ b/css/style.css @@ -843,13 +843,13 @@ textarea.splited-post { /*********************************** ********************* WHO TO FOLLOW ***********************************/ -.who-to-follow -{ +.who-to-follow, +.new-users { padding: 10px; margin-bottom: 10px; } -.who-to-follow h3 -{ +.who-to-follow h3, +.new-users h3 { display: inline; } .twister-user @@ -1943,32 +1943,39 @@ ol.toptrends-list { ********* WHO TO FOLLOW MODAL ******** **************************************/ -.who-to-follow-modal ol { +.who-to-follow-modal ol, +.new-users-modal ol { margin: 5px; } -.who-to-follow-modal .open-profile-modal:hover { +.who-to-follow-modal .open-profile-modal:hover, +.new-users-modal .open-profile-modal:hover { text-decoration: none; } -.who-to-follow-modal .open-profile-modal span { +.who-to-follow-modal .open-profile-modal span, +.new-users-modal .open-profile-modal span { vertical-align: middle; } -.who-to-follow-modal .open-profile-modal span:hover { +.who-to-follow-modal .open-profile-modal span:hover, +.new-users-modal .open-profile-modal span:hover { text-decoration: underline; } -.who-to-follow-modal .follow { +.who-to-follow-modal .follow, +.new-users-modal .follow { float: right; margin: -30px 10px 0 10px; } -.who-to-follow-modal .twister-user-info span { +.who-to-follow-modal .twister-user-info span, +.new-users-modal .twister-user-info span { vertical-align: bottom; } -.who-to-follow-modal .bio { +.who-to-follow-modal .bio, +.new-users-modal .bio { font-size: 12px; color: rgba( 0, 0, 0, .6 ); } diff --git a/home.html b/home.html index 2ff27ec..66c96bd 100644 --- a/home.html +++ b/home.html @@ -146,6 +146,8 @@ + + @@ -227,6 +229,23 @@ + +
    +
    +

    New Users

    + . + Refresh + . + View All + +
    +
    +
    +
    +
    +
    diff --git a/js/interface_common.js b/js/interface_common.js index ec2acdd..ff248b9 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -741,22 +741,7 @@ function fillWhoToFollowModal(list, hlist, start) { if (followingUsers.indexOf(utf) < 0 && list.indexOf(utf) < 0) { list.push(utf); - var item = itemTmp.clone(true); - - item.find('.twister-user-info').attr('data-screen-name', utf); - item.find('.twister-user-name').attr('href', $.MAL.userUrl(utf)); - item.find('.twister-by-user-name').attr('href', $.MAL.userUrl(followingUsers[i])); - item.find('.twister-user-tag').text('@' + utf); - - getAvatar(utf, item.find('.twister-user-photo')); - getFullname(utf, item.find('.twister-user-full')); - getBioToElem(utf, item.find('.bio')); - getFullname(followingUsers[i], item.find('.followed-by').text(followingUsers[i])); - getStatusTime(utf, item.find('.latest-activity .time')); - - item.find('.twister-user-remove').remove(); - - hlist.append(item); + processWhoToFollowSuggestion(hlist, utf, followingUsers[i]); } } } @@ -782,12 +767,32 @@ function openWhoToFollowModal() { modal.content.on('scroll', function() { if (modal.content.scrollTop() >= hlist.height() - modal.content.height() - 20) { - if (!fillWhoToFollowModal(tmplist, hlist, tmplist.length)) + if (!fillWhoToFollowModal(tmplist, modal.self, tmplist.length)) modal.content.off('scroll'); } }); - fillWhoToFollowModal(tmplist, hlist, 0); + fillWhoToFollowModal(tmplist, modal.self, 0); +} + +function openNewUsersModal() { + var modal = openModal({ + classAdd: 'new-users-modal', + title: polyglot.t('New Users') + }); + + var hlist = $('') + .appendTo(modal.content); + var count = 10; + + modal.content.on('scroll', function() { + if (modal.content.scrollTop() >= hlist.height() - modal.content.height() - 20) { + !getLastNUsers(5, count, modal.self); + count += 10; + } + }); + + getLastNUsers(10, 0, modal.self); } function openModalUriShortener() @@ -1237,6 +1242,8 @@ function loadModalFromHash() { openWhoToFollowModal(); else if (hashstring === '#/uri-shortener') openModalUriShortener(); + else if (hashstring === '#newusers') + openNewUsersModal(); } function initHashWatching() { diff --git a/js/interface_home.js b/js/interface_home.js index 5b1984f..8d7f0a0 100644 --- a/js/interface_home.js +++ b/js/interface_home.js @@ -100,6 +100,11 @@ var InterfaceFunctions = function() { else killInterfaceModule('who-to-follow'); + if ($.Options.NewUsers.val === 'enable') + initNewUsers(); + else + killInterfaceModule('new-users'); + if ($.Options.TwistdayReminder.val === 'enable') initTwistdayReminder(); else @@ -200,6 +205,29 @@ function refreshWhoToFollow() { } } +function initNewUsers() { + var nus = initInterfaceModule('new-users'); + + if (nus.length) { + var nusRefresh = nus.find('.refresh-users'); + nusRefresh.on('click', refreshNewUsers); + setTimeout(function() {nusRefresh.click();}, 100); + } +} + +function refreshNewUsers() { + var module = $('.module.new-users'); + var list = module.find('.follow-suggestions'); + + if (list.length) { + list.empty().hide(); + module.find('.refresh-users').hide(); + module.find('.loading-roller').show(); + + getLastNUsers(3, 0, module); + } +} + function initTwistdayReminder() { var $module = initInterfaceModule('twistday-reminder'); diff --git a/js/interface_localization.js b/js/interface_localization.js index bef7976..78cf4b3 100644 --- a/js/interface_localization.js +++ b/js/interface_localization.js @@ -372,7 +372,8 @@ if(preferredLanguage == "en"){ "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", - "Last activity": "Last activity" + "Last activity": "Last activity", + "New Users": "New Users" }; } if(preferredLanguage == "es"){ @@ -717,7 +718,8 @@ if(preferredLanguage == "es"){ "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", - "Last activity": "Last activity" + "Last activity": "Last activity", + "New Users": "New Users" }; } @@ -1061,7 +1063,8 @@ if(preferredLanguage == "uk"){ "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", - "Last activity": "Last activity" + "Last activity": "Last activity", + "New Users": "New Users" }; } @@ -1410,7 +1413,8 @@ if(preferredLanguage == "zh-CN"){ "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", - "Last activity": "Last activity" + "Last activity": "Last activity", + "New Users": "New Users" }; } @@ -1756,7 +1760,8 @@ if(preferredLanguage == "nl"){ "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", - "Last activity": "Last activity" + "Last activity": "Last activity", + "New Users": "New Users" }; } @@ -2100,7 +2105,8 @@ if(preferredLanguage == "it"){ "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", - "Last activity": "Last activity" + "Last activity": "Last activity", + "New Users": "New Users" }; } @@ -2445,7 +2451,8 @@ if(preferredLanguage == "fr"){ "users_favs": "Favorites of @%{username}", "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", - "Last activity": "Last activity" + "Last activity": "Last activity", + "New Users": "New Users" }; } @@ -2797,7 +2804,8 @@ if(preferredLanguage == "ru"){ "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", - "Last activity": "Last activity" + "Last activity": "Last activity", + "New Users": "New Users" }; } @@ -3145,7 +3153,8 @@ if(preferredLanguage == "de"){ "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", - "Last activity": "Last activity" + "Last activity": "Last activity", + "New Users": "New Users" }; } @@ -3488,7 +3497,8 @@ if(preferredLanguage == "ja"){ "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", - "Last activity": "Last activity" + "Last activity": "Last activity", + "New Users": "New Users" }; } @@ -3837,7 +3847,8 @@ if(preferredLanguage == "pt-BR"){ "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", - "Last activity": "Last activity" + "Last activity": "Last activity", + "New Users": "New Users" }; } @@ -4182,7 +4193,8 @@ if(preferredLanguage == "tr"){ "Favorites": "Favoriler", "You have to log in to favorite messages.": "İletileri favorine eklemek için giriş yapmalısın.", "fav_this": "Sana özel mi?", - "Last activity": "Son etkinlik" + "Last activity": "Son etkinlik", + "New Users": "Yeni Kullanıcılar" }; } @@ -4530,7 +4542,8 @@ if(preferredLanguage == "cs"){ "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", - "Last activity": "Last activity" + "Last activity": "Last activity", + "New Users": "New Users" }; } diff --git a/js/options.js b/js/options.js index 2acd553..8eb5612 100644 --- a/js/options.js +++ b/js/options.js @@ -41,6 +41,10 @@ function twisterOptions() { name: 'WhoToFollow', valDefault: 'enable' }); + this.add({ + name: 'NewUsers', + valDefault: 'enable' + }); this.add({ name: 'TwistdayReminder', valDefault: 'enable', diff --git a/js/twister_following.js b/js/twister_following.js index c736b05..98de68e 100644 --- a/js/twister_following.js +++ b/js/twister_following.js @@ -15,6 +15,8 @@ var _searchKeypressTimer = undefined; var _lastSearchUsersResults = []; var _lastSearchUsersResultsRemovedFromDHTgetQueue = true; var _lastLoadFromDhtTime = 0; +var _lastProcessedBlock = -1; +var knownNewUsers = []; var twisterFollowingO = undefined; @@ -427,6 +429,36 @@ function followingEmptyOrMyself() { return (!followingUsers.length || (followingUsers.length === 1 && followingUsers[0] === defaultScreenName)) } +function getLastNUsers(n,offset,module) { + + for (var i = offset; i < knownNewUsers.length && i < offset + n; i++) + processWhoToFollowSuggestion(module, knownNewUsers[i]); + + if (knownNewUsers.length >= n + offset) + return; + + if (_lastProcessedBlock == -1) + requestBestBlock(processBlockUsers, {n: n, offset: offset, module: module}); + else + requestNthBlock(_lastProcessedBlock - 1, processBlockUsers, {n: n, offset: offset, module: module}); +} + +function processBlockUsers(block, users){ + _lastProcessedBlock = block.height; + + if (knownNewUsers.length + block.usernames.length < users.n + users.offset) + setTimeout(function(){requestBlock(block.previousblockhash, processBlockUsers, users);}, 100); + + for (var i = 0; i < block.usernames.length; i++) { + if (knownNewUsers.indexOf(block.usernames[i]) == -1) { + processWhoToFollowSuggestion(users.module, block.usernames[i]); + knownNewUsers.push(block.usernames[i]); + if (knownNewUsers.length >= users.n + users.offset) + break; + } + } +} + // randomly choose a user we follow, get "following1" from him and them // choose a suggestion from their list. this function could be way better, but // that's about the simplest we may get to start with. @@ -446,10 +478,11 @@ function getRandomFollowSuggestion() { var suggested = false; var j = Math.floor(Math.random() * twisterFollowingO.followingsFollowings[followingUsers[i]].following.length); + var module = $('.module.who-to-follow'); for( ; j < twisterFollowingO.followingsFollowings[followingUsers[i]].following.length; j++ ) { if( followingUsers.indexOf(twisterFollowingO.followingsFollowings[followingUsers[i]].following[j]) < 0 && _followSuggestions.indexOf(twisterFollowingO.followingsFollowings[followingUsers[i]].following[j]) < 0) { - processWhoToFollowSuggestion(twisterFollowingO.followingsFollowings[followingUsers[i]].following[j], followingUsers[i]); + processWhoToFollowSuggestion(module, twisterFollowingO.followingsFollowings[followingUsers[i]].following[j], followingUsers[i]); _followSuggestions.push(twisterFollowingO.followingsFollowings[followingUsers[i]].following[j]); suggested = true; break; @@ -501,26 +534,37 @@ function getWhoFollows(peerAlias, elem) { ; } -function processWhoToFollowSuggestion(suggestion, followedBy) { +function processWhoToFollowSuggestion(module, suggestion, followedBy) { if (suggestion) { - var module = $('.module.who-to-follow'); var list = module.find('.follow-suggestions'); var item = $('#follow-suggestion-template').clone(true) .removeAttr('id'); item.find('.twister-user-info').attr('data-screen-name', suggestion); item.find('.twister-user-name').attr('href', $.MAL.userUrl(suggestion)); - item.find('.twister-by-user-name').attr('href', $.MAL.userUrl(followedBy)); item.find('.twister-user-tag').text('@' + suggestion); getAvatar(suggestion, item.find('.twister-user-photo')); - getFullname(followedBy, item.find('.followed-by').text(followedBy)); getStatusTime(suggestion, item.find('.latest-activity .time')); - item.find('.twister-user-remove').on('click', function() { - item.remove(); - getRandomFollowSuggestion(); - }); + if (module.hasClass('who-to-follow') || module.hasClass('who-to-follow-modal')) { + item.find('.twister-by-user-name').attr('href', $.MAL.userUrl(followedBy)); + getFullname(followedBy, item.find('.followed-by').text(followedBy)); + item.find('.twister-user-remove').on('click', function () { + item.remove(); + getRandomFollowSuggestion(); + }); + } + else if (module.hasClass('new-users') || module.hasClass('new-users-modal')){ + item.find('.followers').remove(); + item.find('.twister-user-remove').remove(); + } + + if (module.hasClass('modal-wrapper')) { + getFullname(suggestion, item.find('.twister-user-full')); + getBioToElem(suggestion, item.find('.bio')); + item.find('.twister-user-remove').remove(); + } list.append(item).show(); module.find('.refresh-users').show(); diff --git a/js/twister_network.js b/js/twister_network.js index 38694f7..4497937 100644 --- a/js/twister_network.js +++ b/js/twister_network.js @@ -146,46 +146,59 @@ function requestBestBlock(cbFunc, cbArg) { }, {}); } +function requestNthBlock(n, cbFunc, cbArg) { + twisterRpc("getblockhash", [n], + function(args, hash) { + requestBlock(hash, args.cbFunc, args.cbArg); + }, {cbFunc:cbFunc, cbArg:cbArg}, + function(args, ret) { + console.log("getblockhash error"); + }, {}); +} + function requestBlock(hash, cbFunc, cbArg) { twisterRpc("getblock", [hash], function(args, block) { - twisterdLastBlockTime = block.time; - $(".last-block-time").text( timeGmtToText(twisterdLastBlockTime) ); + //twisterdLastBlockTime = block.time; + //$(".last-block-time").text( timeGmtToText(twisterdLastBlockTime) ); if( args.cbFunc ) - args.cbFunc(args.cbArg); + args.cbFunc(block, args.cbArg); }, {cbFunc:cbFunc, cbArg:cbArg}, function(args, ret) { console.log("requestBlock error"); }, {}); } - function networkUpdate(cbFunc, cbArg) { requestNetInfo(function () { - requestBestBlock(function(args) { - var curTime = new Date().getTime() / 1000; - if( twisterdConnections ) { - if( twisterdLastBlockTime > curTime + 3600 ) { - $.MAL.setNetworkStatusMsg(polyglot.t("Last block is ahead of your computer time, check your clock."), false); - twisterdConnectedAndUptodate = false; - } else if( twisterdLastBlockTime > curTime - (2 * 3600) ) { - if( twisterDhtNodes ) { - $.MAL.setNetworkStatusMsg(polyglot.t("Block chain is up-to-date, twister is ready to use!"), true); - twisterdConnectedAndUptodate = true; - } else { - $.MAL.setNetworkStatusMsg(polyglot.t("DHT network down."), false); - twisterdConnectedAndUptodate = true; - } - } else { - var daysOld = (curTime - twisterdLastBlockTime) / (3600*24); - $.MAL.setNetworkStatusMsg(polyglot.t("downloading_block_chain", { days: daysOld.toFixed(2) }), false); - // don't alarm user if blockchain is just a little bit behind - twisterdConnectedAndUptodate = (daysOld < 2); + requestBestBlock(function(block, args) { + + twisterdLastBlockTime = block.time; + $(".last-block-time").text( timeGmtToText(twisterdLastBlockTime) ); + + var curTime = new Date().getTime() / 1000; + if (twisterdConnections) { + if (twisterdLastBlockTime > curTime + 3600) { + $.MAL.setNetworkStatusMsg(polyglot.t("Last block is ahead of your computer time, check your clock."), false); + twisterdConnectedAndUptodate = false; + } else if (twisterdLastBlockTime > curTime - (2 * 3600)) { + if (twisterDhtNodes) { + $.MAL.setNetworkStatusMsg(polyglot.t("Block chain is up-to-date, twister is ready to use!"), true); + twisterdConnectedAndUptodate = true; + } else { + $.MAL.setNetworkStatusMsg(polyglot.t("DHT network down."), false); + twisterdConnectedAndUptodate = true; + } + } else { + var daysOld = (curTime - twisterdLastBlockTime) / (3600 * 24); + $.MAL.setNetworkStatusMsg(polyglot.t("downloading_block_chain", {days: daysOld.toFixed(2)}), false); + // don't alarm user if blockchain is just a little bit behind + twisterdConnectedAndUptodate = (daysOld < 2); + } } - } - if( args.cbFunc ) - args.cbFunc(args.cbArg) + if (args.cbFunc) + args.cbFunc(args.cbArg); }, {cbFunc:cbFunc, cbArg:cbArg} ); }); } diff --git a/options.html b/options.html index 8338e62..ea4645e 100644 --- a/options.html +++ b/options.html @@ -353,6 +353,17 @@
    +
    +

    New Users

    +
    +
    + +
    +
    +

    Twistday Reminder

    diff --git a/theme_calm/css/style.css b/theme_calm/css/style.css index 21f5be0..835dfbb 100644 --- a/theme_calm/css/style.css +++ b/theme_calm/css/style.css @@ -1024,12 +1024,12 @@ textarea.splited-post { /*********************************** ********************* WHO TO FOLLOW ***********************************/ -.who-to-follow -{ +.who-to-follow, +.new-users { padding: 10px; } -.who-to-follow h3 -{ +.who-to-follow h3, +.new-users h3 { display: inline; } .twister-user @@ -2345,19 +2345,23 @@ textarea.splited-post { ********* WHO TO FOLLOW MODAL ******** **************************************/ -.who-to-follow-modal .modal-content { +.who-to-follow-modal .modal-content, +.new-users-modal .modal-content { padding: 15px; } -.who-to-follow-modal ol { +.who-to-follow-modal ol, +.new-users-modal ol { margin: 5px; } -.who-to-follow-modal .open-profile-modal:hover { +.who-to-follow-modal .open-profile-modal:hover, +.new-users-modal .open-profile-modal span:hover { text-decoration: none; } -.who-to-follow-modal .open-profile-modal span { +.who-to-follow-modal .open-profile-modal span, +.new-users-modal .open-profile-modal span { vertical-align: middle; } @@ -2365,16 +2369,19 @@ textarea.splited-post { text-decoration: underline; } -.who-to-follow-modal .follow { +.who-to-follow-modal .follow, +.new-users-modal .follow { float: right; margin: -30px 10px 0 10px; } -.who-to-follow-modal .twister-user-info span { +.who-to-follow-modal .twister-user-info span, +.new-users-modal .twister-user-info span { vertical-align: bottom; } -.who-to-follow-modal .bio { +.who-to-follow-modal .bio, +.new-users-modal .bio { font-size: 12px; color: rgba( 0, 0, 0, .6 ); } diff --git a/theme_nin/css/style.css b/theme_nin/css/style.css index 1f5ba6b..14e9279 100644 --- a/theme_nin/css/style.css +++ b/theme_nin/css/style.css @@ -2159,27 +2159,32 @@ textarea.splited-post { /******** WHO TO FOLLOW ********/ /* line 411, ../sass/style.sass */ -.who-to-follow.module { +.who-to-follow.module, +.new-users.module { width: inherit; margin-bottom: 20px; } /* line 414, ../sass/style.sass */ -.who-to-follow small { +.who-to-follow small, +.new-users small { display: none; } /* line 416, ../sass/style.sass */ -.who-to-follow h3 { +.who-to-follow h3, +.new-users h3 { float: left; } /* line 418, ../sass/style.sass */ -.who-to-follow ol { +.who-to-follow ol, +.new-users ol { clear: both; } -.who-to-follow .twister-user-info { +.who-to-follow .twister-user-info, +.new-users .twister-user-info { margin-top: 8px; } @@ -3130,45 +3135,53 @@ ol.toptrends-list a:hover { /******* WHO TO FOLLOW MODAL****** */ /* line 943, ../sass/style.sass */ -.modal-wrapper.who-to-follow-modal { +.modal-wrapper.who-to-follow-modal, +.modal-wrapper.new-users-modal { width: 520px; height: 580px; margin: -290px 0 0 -260px; } /* line 949, ../sass/style.sass */ -.who-to-follow-modal .modal-content { +.who-to-follow-modal .modal-content, +.new-users-modal .modal-content { padding: 15px; } /* line 955, ../sass/style.sass */ -.who-to-follow-modal ol { +.who-to-follow-modal ol, +.new-users-modal ol { margin: 5px; } /* line 958, ../sass/style.sass */ -.who-to-follow-modal .open-profile-modal:hover { +.who-to-follow-modal .open-profile-modal:hover, +.new-users-modal .open-profile-modal:hover { text-decoration: none; } /* line 960, ../sass/style.sass */ -.who-to-follow-modal .twister-user { - position: relative; +.who-to-follow-modal .twister-user, +.new-users-modal .twister-user { +position: relative; padding: 5px; } /* line 963, ../sass/style.sass */ -.who-to-follow-modal .twister-user-photo { +.who-to-follow-modal .twister-user-photo, +.new-users-modal .twister-user-photo { position: relative; left: 0; float: left; display: block; } /* line 968, ../sass/style.sass */ -.who-to-follow-modal .twister-user-info { +.who-to-follow-modal .twister-user-info, +.new-users-modal .twister-user-info { position: relative; margin-top: 4px; padding-left: 70px; width: auto; } /* line 972, ../sass/style.sass */ -.who-to-follow-modal .bio { +.who-to-follow-modal .bio, +.new-users-modal .bio { color: rgba(0, 0, 0, 0.6); font-style: italic; } From c188e6d1348616def8f053edce487abb5a8a4df4 Mon Sep 17 00:00:00 2001 From: erqan Date: Sat, 19 Nov 2016 14:22:59 +0300 Subject: [PATCH 28/54] removes comment --- js/twister_network.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/js/twister_network.js b/js/twister_network.js index 4497937..cac9384 100644 --- a/js/twister_network.js +++ b/js/twister_network.js @@ -159,9 +159,6 @@ function requestNthBlock(n, cbFunc, cbArg) { function requestBlock(hash, cbFunc, cbArg) { twisterRpc("getblock", [hash], function(args, block) { - //twisterdLastBlockTime = block.time; - //$(".last-block-time").text( timeGmtToText(twisterdLastBlockTime) ); - if( args.cbFunc ) args.cbFunc(block, args.cbArg); }, {cbFunc:cbFunc, cbArg:cbArg}, From 99f8940d38a2c49a054a0d0258f16c649c663d1f Mon Sep 17 00:00:00 2001 From: erqan Date: Sat, 19 Nov 2016 18:31:47 +0300 Subject: [PATCH 29/54] fix some silly mistakes --- js/interface_common.js | 8 ++++---- js/twister_following.js | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/js/interface_common.js b/js/interface_common.js index ff248b9..05f9c6f 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -783,16 +783,16 @@ function openNewUsersModal() { var hlist = $('') .appendTo(modal.content); - var count = 10; + var count = 15; modal.content.on('scroll', function() { if (modal.content.scrollTop() >= hlist.height() - modal.content.height() - 20) { - !getLastNUsers(5, count, modal.self); - count += 10; + if (getLastNUsers(5, count, modal.self)) + count += 5; } }); - getLastNUsers(10, 0, modal.self); + getLastNUsers(15, 0, modal.self); } function openModalUriShortener() diff --git a/js/twister_following.js b/js/twister_following.js index 98de68e..58d48a9 100644 --- a/js/twister_following.js +++ b/js/twister_following.js @@ -17,6 +17,7 @@ var _lastSearchUsersResultsRemovedFromDHTgetQueue = true; var _lastLoadFromDhtTime = 0; var _lastProcessedBlock = -1; var knownNewUsers = []; +var isNewUserThRunning = false; var twisterFollowingO = undefined; @@ -431,23 +432,34 @@ function followingEmptyOrMyself() { function getLastNUsers(n,offset,module) { + if (isNewUserThRunning) + return false; + + isNewUserThRunning = true; for (var i = offset; i < knownNewUsers.length && i < offset + n; i++) processWhoToFollowSuggestion(module, knownNewUsers[i]); if (knownNewUsers.length >= n + offset) - return; + { + isNewUserThRunning = false; + return true; + } if (_lastProcessedBlock == -1) requestBestBlock(processBlockUsers, {n: n, offset: offset, module: module}); else requestNthBlock(_lastProcessedBlock - 1, processBlockUsers, {n: n, offset: offset, module: module}); + + return true; } function processBlockUsers(block, users){ _lastProcessedBlock = block.height; - if (knownNewUsers.length + block.usernames.length < users.n + users.offset) + if (knownNewUsers.length + block.usernames.length < users.n + users.offset && typeof block.previousblockhash !== 'undefined') setTimeout(function(){requestBlock(block.previousblockhash, processBlockUsers, users);}, 100); + else + isNewUserThRunning = false; for (var i = 0; i < block.usernames.length; i++) { if (knownNewUsers.indexOf(block.usernames[i]) == -1) { From 16da1c8e31243b411a767dbeba3f77a653396c24 Mon Sep 17 00:00:00 2001 From: erqan Date: Thu, 24 Nov 2016 15:54:33 +0300 Subject: [PATCH 30/54] fixing & developing --- js/interface_common.js | 17 +++-- js/interface_home.js | 5 +- js/interface_localization.js | 39 ++++++---- js/options.js | 7 ++ js/twister_following.js | 143 ++++++++++++++++++++++++++--------- options.html | 17 ++++- 6 files changed, 168 insertions(+), 60 deletions(-) diff --git a/js/interface_common.js b/js/interface_common.js index 05f9c6f..4f513bc 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -119,6 +119,9 @@ function closeModal(req, switchMode) { else this.remove(); // if it's minimized it will be removed with twister.modal[i].drapper + if (typeof twister.modal[i].onClose === 'function') + twister.modal[i].onClose(twister.modal[i].closeArg); + twister.modal[i].drapper.remove(); twister.modal[i] = undefined; } @@ -731,9 +734,6 @@ function addPeerToFollowingList(list, peerAlias) { } function fillWhoToFollowModal(list, hlist, start) { - var itemTmp = $('#follow-suggestion-template').clone(true) - .removeAttr('id'); - for (var i = 0; i < followingUsers.length && list.length < start + 20; i++) { if (typeof twisterFollowingO.followingsFollowings[followingUsers[i]] !== 'undefined') { for (var j = 0; j < twisterFollowingO.followingsFollowings[followingUsers[i]].following.length && list.length < start + 25; j++) { @@ -746,7 +746,6 @@ function fillWhoToFollowModal(list, hlist, start) { } } } - itemTmp.remove(); if (i >= followingUsers.length - 1) return false; @@ -778,7 +777,10 @@ function openWhoToFollowModal() { function openNewUsersModal() { var modal = openModal({ classAdd: 'new-users-modal', - title: polyglot.t('New Users') + title: polyglot.t('New Users'), + onClose: function() { + NewUserSearch.isNewUserModalOpen = false; + } }); var hlist = $('') @@ -787,12 +789,13 @@ function openNewUsersModal() { modal.content.on('scroll', function() { if (modal.content.scrollTop() >= hlist.height() - modal.content.height() - 20) { - if (getLastNUsers(5, count, modal.self)) + if (newUsers.getLastNUsers(5, count, modal.self)) count += 5; } }); - getLastNUsers(15, 0, modal.self); + NewUserSearch.isNewUserModalOpen = true; + newUsers.getLastNUsers(15, 0, modal.self); } function openModalUriShortener() diff --git a/js/interface_home.js b/js/interface_home.js index 8d7f0a0..03116ec 100644 --- a/js/interface_home.js +++ b/js/interface_home.js @@ -118,7 +118,7 @@ var InterfaceFunctions = function() { if ($.Options.WebTorrent.val === 'enable') initWebTorrent(); } -} +}; function initTopTrends() { var $tt = initInterfaceModule('toptrends'); @@ -208,6 +208,7 @@ function refreshWhoToFollow() { function initNewUsers() { var nus = initInterfaceModule('new-users'); + newUsers = NewUserSearch(); if (nus.length) { var nusRefresh = nus.find('.refresh-users'); nusRefresh.on('click', refreshNewUsers); @@ -224,7 +225,7 @@ function refreshNewUsers() { module.find('.refresh-users').hide(); module.find('.loading-roller').show(); - getLastNUsers(3, 0, module); + newUsers.getLastNUsers(3, 0, module, true); } } diff --git a/js/interface_localization.js b/js/interface_localization.js index 78cf4b3..f3ee644 100644 --- a/js/interface_localization.js +++ b/js/interface_localization.js @@ -373,7 +373,8 @@ if(preferredLanguage == "en"){ "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", "Last activity": "Last activity", - "New Users": "New Users" + "New Users": "New Users", + "Live tracking" : "Live tracking" }; } if(preferredLanguage == "es"){ @@ -719,7 +720,8 @@ if(preferredLanguage == "es"){ "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", "Last activity": "Last activity", - "New Users": "New Users" + "New Users": "New Users", + "Live tracking" : "Live tracking" }; } @@ -1064,7 +1066,8 @@ if(preferredLanguage == "uk"){ "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", "Last activity": "Last activity", - "New Users": "New Users" + "New Users": "New Users", + "Live tracking" : "Live tracking" }; } @@ -1414,7 +1417,8 @@ if(preferredLanguage == "zh-CN"){ "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", "Last activity": "Last activity", - "New Users": "New Users" + "New Users": "New Users", + "Live tracking" : "Live tracking" }; } @@ -1761,7 +1765,8 @@ if(preferredLanguage == "nl"){ "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", "Last activity": "Last activity", - "New Users": "New Users" + "New Users": "New Users", + "Live tracking" : "Live tracking" }; } @@ -2106,7 +2111,8 @@ if(preferredLanguage == "it"){ "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", "Last activity": "Last activity", - "New Users": "New Users" + "New Users": "New Users", + "Live tracking" : "Live tracking" }; } @@ -2452,7 +2458,8 @@ if(preferredLanguage == "fr"){ "Favorites": "Favorites", "You have to log in to favorite messages.": "You have to log in to favorite messages.", "Last activity": "Last activity", - "New Users": "New Users" + "New Users": "New Users", + "Live tracking" : "Live tracking" }; } @@ -2805,7 +2812,8 @@ if(preferredLanguage == "ru"){ "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", "Last activity": "Last activity", - "New Users": "New Users" + "New Users": "New Users", + "Live tracking" : "Live tracking" }; } @@ -3154,7 +3162,8 @@ if(preferredLanguage == "de"){ "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", "Last activity": "Last activity", - "New Users": "New Users" + "New Users": "New Users", + "Live tracking" : "Live tracking" }; } @@ -3498,7 +3507,8 @@ if(preferredLanguage == "ja"){ "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", "Last activity": "Last activity", - "New Users": "New Users" + "New Users": "New Users", + "Live tracking" : "Live tracking" }; } @@ -3848,7 +3858,8 @@ if(preferredLanguage == "pt-BR"){ "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", "Last activity": "Last activity", - "New Users": "New Users" + "New Users": "New Users", + "Live tracking" : "Live tracking" }; } @@ -4194,7 +4205,8 @@ if(preferredLanguage == "tr"){ "You have to log in to favorite messages.": "İletileri favorine eklemek için giriş yapmalısın.", "fav_this": "Sana özel mi?", "Last activity": "Son etkinlik", - "New Users": "Yeni Kullanıcılar" + "New Users": "Yeni Kullanıcılar", + "Live tracking" : "Canlı takip" }; } @@ -4543,7 +4555,8 @@ if(preferredLanguage == "cs"){ "You have to log in to favorite messages.": "You have to log in to favorite messages.", "fav_this": "Is it for you only?", "Last activity": "Last activity", - "New Users": "New Users" + "New Users": "New Users", + "Live tracking" : "Live tracking" }; } diff --git a/js/options.js b/js/options.js index 8eb5612..84f17cb 100644 --- a/js/options.js +++ b/js/options.js @@ -43,6 +43,13 @@ function twisterOptions() { }); this.add({ name: 'NewUsers', + valDefault: 'enable', + tickMethod: function (elem) { + $('#NewUsersCont').css('display', (elem.value === 'enable') ? 'block' : 'none'); + } + }); + this.add({ + name: 'NewUsersLiveTracking', valDefault: 'enable' }); this.add({ diff --git a/js/twister_following.js b/js/twister_following.js index 58d48a9..462d82e 100644 --- a/js/twister_following.js +++ b/js/twister_following.js @@ -15,11 +15,9 @@ var _searchKeypressTimer = undefined; var _lastSearchUsersResults = []; var _lastSearchUsersResultsRemovedFromDHTgetQueue = true; var _lastLoadFromDhtTime = 0; -var _lastProcessedBlock = -1; -var knownNewUsers = []; -var isNewUserThRunning = false; var twisterFollowingO = undefined; +var newUsers = undefined; var TwisterFollowing = function (user) { if (!(this instanceof TwisterFollowing)) @@ -430,46 +428,116 @@ function followingEmptyOrMyself() { return (!followingUsers.length || (followingUsers.length === 1 && followingUsers[0] === defaultScreenName)) } -function getLastNUsers(n,offset,module) { +/* NEW USER SEARCH */ +var NewUserSearch = function(){ + if (!(this instanceof NewUserSearch)) + return new NewUserSearch(); - if (isNewUserThRunning) - return false; + this.init(); +}; + +NewUserSearch.knownNewUsers = []; +NewUserSearch.isNewUserThRunning = false; +NewUserSearch.isNewUserModalOpen = false; +NewUserSearch.startProcessedBlock = -1; +NewUserSearch.lastProcessedBlock = -1; +NewUserSearch.processBlockUsersProxy = function(block, args){ + if (args.obj instanceof NewUserSearch) + args.obj.processBlockUsers(block, args); +}; +NewUserSearch.live = function(module) { + newUsers.getNewUsers(module); +}; +NewUserSearch.processBestBlockUsersProxy = function(block, args){ + if (block.height > NewUserSearch.startProcessedBlock) { + if (args.obj instanceof NewUserSearch) + args.obj.processBlockUsers(block, {obj: args.obj, args: {n: 0, offset: 0, module: args.args.module, prepend: true, live: true}}); + } +}; + +NewUserSearch.prototype = { + storage: undefined, + isForced: false, + + init: function() { + this.storage = $.initNamespaceStorage(defaultScreenName).sessionStorage; + if (this.storage.isSet("knownNewUsers")) + NewUserSearch.knownNewUsers = this.storage.get("knownNewUsers"); + if (this.storage.isSet("lastProcessedBlock")) + NewUserSearch.lastProcessedBlock = this.storage.get("lastProcessedBlock"); + if (this.storage.isSet("startProcessedBlock")) + NewUserSearch.startProcessedBlock = this.storage.get("startProcessedBlock"); + + if ($.Options.NewUsersLiveTracking.val === 'enable') + setInterval(function(){NewUserSearch.live($('.module.new-users'));}, 10000); + }, + + save: function(){ + this.storage.set("knownNewUsers", NewUserSearch.knownNewUsers); + this.storage.set("lastProcessedBlock", NewUserSearch.lastProcessedBlock); + this.storage.set("startProcessedBlock", NewUserSearch.startProcessedBlock); + }, + + getNewUsers: function(module) { + requestBestBlock(NewUserSearch.processBestBlockUsersProxy, {obj: this, args: {module: module}}); + }, + + getLastNUsers: function (n, offset, module, forced) { + for (var i = offset; i < NewUserSearch.knownNewUsers.length && i < offset + n; i++) + processWhoToFollowSuggestion(module, NewUserSearch.knownNewUsers[i]); + + if (NewUserSearch.knownNewUsers.length >= n + offset) { + NewUserSearch.isNewUserThRunning = false; + return true; + } - isNewUserThRunning = true; - for (var i = offset; i < knownNewUsers.length && i < offset + n; i++) - processWhoToFollowSuggestion(module, knownNewUsers[i]); + if (NewUserSearch.isNewUserThRunning) + return false; + + NewUserSearch.isNewUserThRunning = true; + this.isForced = forced; + + if (NewUserSearch.lastProcessedBlock == -1) + requestBestBlock(NewUserSearch.processBlockUsersProxy, {obj: this, args: {n: n, offset: offset, module: module}}); + else + requestNthBlock(NewUserSearch.lastProcessedBlock - 1, NewUserSearch.processBlockUsersProxy, {obj: this, args: {n: n, offset: offset, module: module}}); - if (knownNewUsers.length >= n + offset) - { - isNewUserThRunning = false; return true; - } + }, - if (_lastProcessedBlock == -1) - requestBestBlock(processBlockUsers, {n: n, offset: offset, module: module}); - else - requestNthBlock(_lastProcessedBlock - 1, processBlockUsers, {n: n, offset: offset, module: module}); + processBlockUsers: function (block, args) { + if (NewUserSearch.startProcessedBlock === -1) + NewUserSearch.startProcessedBlock = block.height; + if (NewUserSearch.lastProcessedBlock === -1 || block.height < NewUserSearch.lastProcessedBlock) + NewUserSearch.lastProcessedBlock = block.height; - return true; -} + if ((this.isForced || NewUserSearch.isNewUserModalOpen) && + NewUserSearch.knownNewUsers.length + block.usernames.length < args.args.n + args.args.offset && + typeof block.previousblockhash !== 'undefined') { -function processBlockUsers(block, users){ - _lastProcessedBlock = block.height; + setTimeout(function () { + requestBlock(block.previousblockhash, NewUserSearch.processBlockUsersProxy, {obj: args.obj, args: args.args}); + }, 100); - if (knownNewUsers.length + block.usernames.length < users.n + users.offset && typeof block.previousblockhash !== 'undefined') - setTimeout(function(){requestBlock(block.previousblockhash, processBlockUsers, users);}, 100); - else - isNewUserThRunning = false; + } else { + NewUserSearch.isNewUserThRunning = false; + this.isForced = false; + } - for (var i = 0; i < block.usernames.length; i++) { - if (knownNewUsers.indexOf(block.usernames[i]) == -1) { - processWhoToFollowSuggestion(users.module, block.usernames[i]); - knownNewUsers.push(block.usernames[i]); - if (knownNewUsers.length >= users.n + users.offset) - break; + for (var i = 0; i < block.usernames.length; i++) { + if (NewUserSearch.knownNewUsers.indexOf(block.usernames[i]) == -1) { + processWhoToFollowSuggestion(args.args.module, block.usernames[i], undefined, args.args.prepend); + if (args.args.prepend) + NewUserSearch.knownNewUsers.unshift(block.usernames[i]); + else + NewUserSearch.knownNewUsers.push(block.usernames[i]); + if (!args.args.live && NewUserSearch.knownNewUsers.length >= args.args.n + args.args.offset) + break; + } } + this.save(); } -} +}; // randomly choose a user we follow, get "following1" from him and them // choose a suggestion from their list. this function could be way better, but @@ -546,7 +614,7 @@ function getWhoFollows(peerAlias, elem) { ; } -function processWhoToFollowSuggestion(module, suggestion, followedBy) { +function processWhoToFollowSuggestion(module, suggestion, followedBy, prepend) { if (suggestion) { var list = module.find('.follow-suggestions'); var item = $('#follow-suggestion-template').clone(true) @@ -578,7 +646,14 @@ function processWhoToFollowSuggestion(module, suggestion, followedBy) { item.find('.twister-user-remove').remove(); } - list.append(item).show(); + if (prepend) + list.prepend(item).show(); + else + list.append(item).show(); + + while (module.hasClass('new-users') && list.children().length > 3) + list.children().last().remove(); + module.find('.refresh-users').show(); module.find('.loading-roller').hide(); } else diff --git a/options.html b/options.html index ea4645e..a915fbc 100644 --- a/options.html +++ b/options.html @@ -357,10 +357,19 @@

    New Users

    - +

    + +

    +
    +

    Live tracking

    + +
    From 4637c68df7a582f4db4883e03fe159d740fb24da Mon Sep 17 00:00:00 2001 From: erqan Date: Thu, 24 Nov 2016 16:00:41 +0300 Subject: [PATCH 31/54] shaping --- js/twister_network.js | 44 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/js/twister_network.js b/js/twister_network.js index cac9384..bbfb2df 100644 --- a/js/twister_network.js +++ b/js/twister_network.js @@ -171,31 +171,31 @@ function networkUpdate(cbFunc, cbArg) { requestNetInfo(function () { requestBestBlock(function(block, args) { - twisterdLastBlockTime = block.time; - $(".last-block-time").text( timeGmtToText(twisterdLastBlockTime) ); - - var curTime = new Date().getTime() / 1000; - if (twisterdConnections) { - if (twisterdLastBlockTime > curTime + 3600) { - $.MAL.setNetworkStatusMsg(polyglot.t("Last block is ahead of your computer time, check your clock."), false); - twisterdConnectedAndUptodate = false; - } else if (twisterdLastBlockTime > curTime - (2 * 3600)) { - if (twisterDhtNodes) { - $.MAL.setNetworkStatusMsg(polyglot.t("Block chain is up-to-date, twister is ready to use!"), true); - twisterdConnectedAndUptodate = true; - } else { - $.MAL.setNetworkStatusMsg(polyglot.t("DHT network down."), false); - twisterdConnectedAndUptodate = true; - } + twisterdLastBlockTime = block.time; + $(".last-block-time").text(timeGmtToText(twisterdLastBlockTime)); + + var curTime = new Date().getTime() / 1000; + if (twisterdConnections) { + if (twisterdLastBlockTime > curTime + 3600) { + $.MAL.setNetworkStatusMsg(polyglot.t("Last block is ahead of your computer time, check your clock."), false); + twisterdConnectedAndUptodate = false; + } else if (twisterdLastBlockTime > curTime - (2 * 3600)) { + if (twisterDhtNodes) { + $.MAL.setNetworkStatusMsg(polyglot.t("Block chain is up-to-date, twister is ready to use!"), true); + twisterdConnectedAndUptodate = true; } else { - var daysOld = (curTime - twisterdLastBlockTime) / (3600 * 24); - $.MAL.setNetworkStatusMsg(polyglot.t("downloading_block_chain", {days: daysOld.toFixed(2)}), false); - // don't alarm user if blockchain is just a little bit behind - twisterdConnectedAndUptodate = (daysOld < 2); + $.MAL.setNetworkStatusMsg(polyglot.t("DHT network down."), false); + twisterdConnectedAndUptodate = true; } + } else { + var daysOld = (curTime - twisterdLastBlockTime) / (3600 * 24); + $.MAL.setNetworkStatusMsg(polyglot.t("downloading_block_chain", {days: daysOld.toFixed(2)}), false); + // don't alarm user if blockchain is just a little bit behind + twisterdConnectedAndUptodate = (daysOld < 2); } - if (args.cbFunc) - args.cbFunc(args.cbArg); + } + if (args.cbFunc) + args.cbFunc(args.cbArg); }, {cbFunc:cbFunc, cbArg:cbArg} ); }); } From 46d62647430dae9fbb54bab1336d7b81ba845a53 Mon Sep 17 00:00:00 2001 From: erqan Date: Thu, 24 Nov 2016 18:10:26 +0300 Subject: [PATCH 32/54] decreasing delay between block and being sure all users in block is got --- js/twister_following.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/js/twister_following.js b/js/twister_following.js index 462d82e..ec1848e 100644 --- a/js/twister_following.js +++ b/js/twister_following.js @@ -517,7 +517,7 @@ NewUserSearch.prototype = { setTimeout(function () { requestBlock(block.previousblockhash, NewUserSearch.processBlockUsersProxy, {obj: args.obj, args: args.args}); - }, 100); + }, 10); } else { NewUserSearch.isNewUserThRunning = false; @@ -527,14 +527,15 @@ NewUserSearch.prototype = { for (var i = 0; i < block.usernames.length; i++) { if (NewUserSearch.knownNewUsers.indexOf(block.usernames[i]) == -1) { processWhoToFollowSuggestion(args.args.module, block.usernames[i], undefined, args.args.prepend); - if (args.args.prepend) - NewUserSearch.knownNewUsers.unshift(block.usernames[i]); - else - NewUserSearch.knownNewUsers.push(block.usernames[i]); if (!args.args.live && NewUserSearch.knownNewUsers.length >= args.args.n + args.args.offset) break; } } + if (args.args.prepend) + NewUserSearch.knownNewUsers.unshift(block.usernames); + else + NewUserSearch.knownNewUsers.push(block.usernames); + this.save(); } }; From a303cce84787c47743acbda91894f1251e4d5f44 Mon Sep 17 00:00:00 2001 From: erqan Date: Thu, 24 Nov 2016 19:02:44 +0300 Subject: [PATCH 33/54] fixing silliness (2) --- js/twister_following.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/js/twister_following.js b/js/twister_following.js index ec1848e..f0a700a 100644 --- a/js/twister_following.js +++ b/js/twister_following.js @@ -524,17 +524,26 @@ NewUserSearch.prototype = { this.isForced = false; } - for (var i = 0; i < block.usernames.length; i++) { + var i = 0; + for (; i < block.usernames.length; i++) { if (NewUserSearch.knownNewUsers.indexOf(block.usernames[i]) == -1) { processWhoToFollowSuggestion(args.args.module, block.usernames[i], undefined, args.args.prepend); + if (args.args.prepend) + NewUserSearch.knownNewUsers.unshift(block.usernames[i]); + else + NewUserSearch.knownNewUsers.push(block.usernames[i]); if (!args.args.live && NewUserSearch.knownNewUsers.length >= args.args.n + args.args.offset) break; } } - if (args.args.prepend) - NewUserSearch.knownNewUsers.unshift(block.usernames); - else - NewUserSearch.knownNewUsers.push(block.usernames); + for (; i < block.usernames.length; i++) { + if (NewUserSearch.knownNewUsers.indexOf(block.usernames[i]) == -1) { + if (args.args.prepend) + NewUserSearch.knownNewUsers.unshift(block.usernames[i]); + else + NewUserSearch.knownNewUsers.push(block.usernames[i]); + } + } this.save(); } From 1718b901bd24c7cdd6a0f108545c4c88ca0ff382 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Fri, 25 Nov 2016 01:17:48 +0500 Subject: [PATCH 34/54] fix confirmPopup() on login.html --- login.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/login.html b/login.html index eebcccb..0941020 100644 --- a/login.html +++ b/login.html @@ -14,6 +14,7 @@ + @@ -106,6 +107,13 @@
    + + + + +
    From 4349e33097820c1cd2d80ea2e033720d0b3c4b2c Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Fri, 25 Nov 2016 02:46:41 +0500 Subject: [PATCH 35/54] tune processWhoToFollowSuggestion() --- home.html | 13 +++---- js/interface_common.js | 1 + js/twister_following.js | 80 ++++++++++++++++++++--------------------- 3 files changed, 46 insertions(+), 48 deletions(-) diff --git a/home.html b/home.html index 66c96bd..8deaac4 100644 --- a/home.html +++ b/home.html @@ -220,9 +220,7 @@ Refresh . View All - +
    @@ -237,9 +235,7 @@ Refresh . View All - +
    @@ -301,8 +297,8 @@
    - -
  6. +
    +
  7. +
      diff --git a/js/interface_common.js b/js/interface_common.js index 4f513bc..f4ee860 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -2812,6 +2812,7 @@ $(document).ready(function () { twister.tmpl.followersPeer = extractTemplate('#template-followers-peer'); twister.tmpl.followingList = extractTemplate('#template-following-list'); twister.tmpl.followingPeer = extractTemplate('#template-following-peer'); + twister.tmpl.whoTofollowPeer = extractTemplate('#template-whotofollow-peer'); twister.tmpl.commonDMsListItem = extractTemplate('#template-direct-messages-list-item') .on('mouseup', function (event) { event.data = {route: diff --git a/js/twister_following.js b/js/twister_following.js index f0a700a..848234e 100644 --- a/js/twister_following.js +++ b/js/twister_following.js @@ -624,50 +624,50 @@ function getWhoFollows(peerAlias, elem) { ; } -function processWhoToFollowSuggestion(module, suggestion, followedBy, prepend) { - if (suggestion) { - var list = module.find('.follow-suggestions'); - var item = $('#follow-suggestion-template').clone(true) - .removeAttr('id'); - - item.find('.twister-user-info').attr('data-screen-name', suggestion); - item.find('.twister-user-name').attr('href', $.MAL.userUrl(suggestion)); - item.find('.twister-user-tag').text('@' + suggestion); - - getAvatar(suggestion, item.find('.twister-user-photo')); - getStatusTime(suggestion, item.find('.latest-activity .time')); - - if (module.hasClass('who-to-follow') || module.hasClass('who-to-follow-modal')) { - item.find('.twister-by-user-name').attr('href', $.MAL.userUrl(followedBy)); - getFullname(followedBy, item.find('.followed-by').text(followedBy)); - item.find('.twister-user-remove').on('click', function () { - item.remove(); - getRandomFollowSuggestion(); - }); - } - else if (module.hasClass('new-users') || module.hasClass('new-users-modal')){ - item.find('.followers').remove(); - item.find('.twister-user-remove').remove(); - } +function processWhoToFollowSuggestion(module, peerAlias, followedBy, prepend) { + if (!peerAlias) { + console.warn('nothing to proceed: no twisters to follow was suggested'); + return; + } - if (module.hasClass('modal-wrapper')) { - getFullname(suggestion, item.find('.twister-user-full')); - getBioToElem(suggestion, item.find('.bio')); - item.find('.twister-user-remove').remove(); - } + var list = module.find('.follow-suggestions'); + var item = twister.tmpl.whoTofollowPeer.clone(true); - if (prepend) - list.prepend(item).show(); - else - list.append(item).show(); + item.find('.twister-user-info').attr('data-screen-name', peerAlias); + item.find('.twister-user-name').attr('href', $.MAL.userUrl(peerAlias)); + item.find('.twister-user-tag').text('@' + peerAlias); - while (module.hasClass('new-users') && list.children().length > 3) - list.children().last().remove(); + getAvatar(peerAlias, item.find('.twister-user-photo')); + getStatusTime(peerAlias, item.find('.latest-activity .time')); - module.find('.refresh-users').show(); - module.find('.loading-roller').hide(); - } else - console.warn('nothing to proceed: no twisters to follow was suggested'); + if (module.hasClass('who-to-follow') || module.hasClass('who-to-follow-modal')) { + item.find('.twister-by-user-name').attr('href', $.MAL.userUrl(followedBy)); + getFullname(followedBy, item.find('.followed-by').text(followedBy)); + item.find('.twister-user-remove').on('click', {item: item}, function (event) { + event.data.item.remove(); + getRandomFollowSuggestion(); + }); + } else if (module.hasClass('new-users') || module.hasClass('new-users-modal')) { + item.find('.followers').remove(); + item.find('.twister-user-remove').remove(); + } + + if (module.hasClass('modal-wrapper')) { + getFullname(peerAlias, item.find('.twister-user-full')); + getBioToElem(peerAlias, item.find('.bio')); + item.find('.twister-user-remove').remove(); + } + + if (prepend) + list.prepend(item).show(); + else + list.append(item).show(); + + while (module.hasClass('new-users') && list.children().length > 3) + list.children().last().remove(); + + module.find('.refresh-users').show(); + module.find('.loading-roller').hide(); } function closeSearchDialog(event) { From 43a1e8b3c8dcdeba4e7c55d9c4387470d7897bd3 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Fri, 25 Nov 2016 02:52:57 +0500 Subject: [PATCH 36/54] rename modal.onClose() arg for similarity with modal.onResume() --- js/interface_common.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/interface_common.js b/js/interface_common.js index f4ee860..9332fcf 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -120,7 +120,7 @@ function closeModal(req, switchMode) { this.remove(); // if it's minimized it will be removed with twister.modal[i].drapper if (typeof twister.modal[i].onClose === 'function') - twister.modal[i].onClose(twister.modal[i].closeArg); + twister.modal[i].onClose(twister.modal[i].onCloseReq); twister.modal[i].drapper.remove(); twister.modal[i] = undefined; From 3415df6d6019e602dd4cb6b20ae43ceb1034182f Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Fri, 25 Nov 2016 03:10:22 +0500 Subject: [PATCH 37/54] tune alertion about suspucious URIs in twists --- js/twister_formatpost.js | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/js/twister_formatpost.js b/js/twister_formatpost.js index 9e734cc..0599df5 100644 --- a/js/twister_formatpost.js +++ b/js/twister_formatpost.js @@ -626,21 +626,25 @@ function htmlFormatMsg(msg, opt) { break; } if (i < k) { - var x = getSubStrEnd(msg.str, i, ':', false, '') + 1; // following check is NOT for real protection (we have blocking CSP rule instead), it's just to aware people - if (msg.str[i] === '#' || (x > i && x < k && (msg.str.slice(x - 6, x).toLowerCase() === 'script' // other things would be added when W3C and all the people invent it - || msg.str.slice(x - 4, x).toLowerCase() === 'data'))) { + if (isUriSuspicious(msg.str.slice(i, k + 1))) { msg = msgAddHtmlEntity(msg, j - 1, getSubStrEnd(msg.str, k + 1, ')', true, '') + 2, '…
      ' + polyglot.t('busted_oh') + ' ' - + polyglot.t('busted_avowal') + ':
      ' + + polyglot.t('busted_avowal') + ':
      [' + + linkName + .replace(/&(?!lt;|gt;)/g, '&') + .replace(/"/g, '"') + .replace(/'/g, ''') + + '](' + msg.str.slice(i, k + 1) .replace(/&(?!lt;|gt;)/g, '&') .replace(/"/g, '"') .replace(/'/g, ''') - + '
      ' + + ')


      ' ); } else { - if ((x = getSubStrEnd(msg.str, i + 1, whiteSpacesUrl, false, '')) < k) // use only first word as href target, others drop silently + var x = getSubStrEnd(msg.str, i + 1, whiteSpacesUrl, false, ''); + if (x < k) // use only first word as href target, others drop silently k = x; linkName = applyHtml( // we're handling markup inside [] of []() markout(markout(markout(markout( @@ -793,6 +797,27 @@ function htmlFormatMsg(msg, opt) { return {html: msg, mentions: mentions}; } +function isUriSuspicious(req) { + var colonPos = req.search(/:|%3A/gi); + if (colonPos === 0) + return true; + + var hashPos = req.search(/#|%23/g); + + if (colonPos === -1) + if (hashPos > -1) + return req = req.slice(hashPos + 1), + (req.search(/^(?:hashtag|profile|conversation|mentions|favs|directmessages|groupmessages|newusers|followers|following|whotofollow|groupmessages\+newgroup|groupmessages\+joingroup\/uri\-shortener)\b/) > -1) ? false : true; + else + return false; //(req.search(/^\s*@[A-Za-z0-9]+\/\d/g) === 0) ? false : true; + + if (hashPos > -1 && hashPos < colonPos) + return true; + + return req = req.slice(req.search(/\S/g), colonPos), + req.search(/[^A-Za-z0-9\+\.\-]/) > -1 || req.search(/(?:script|data)$/i) > -1; +} + function proxyURL(url) { var proxyOpt = $.Options.useProxy.val; if (proxyOpt !== 'disable' && !$.Options.useProxyForImgOnly.val From 90f5ee1bde07321be02cec0e5b252b2884003827 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Fri, 25 Nov 2016 03:12:07 +0500 Subject: [PATCH 38/54] add alertion about suspucious stuff in fetched URIs --- js/interface_common.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/js/interface_common.js b/js/interface_common.js index 9332fcf..d425118 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -1004,12 +1004,28 @@ function fetchShortenedURI(req, attemptCount) { function applyShortenedURI(short, uriAndMimetype) { var long = (uriAndMimetype instanceof Array) ? uriAndMimetype[0] : uriAndMimetype; var mimetype = (uriAndMimetype instanceof Array) ? uriAndMimetype[1] : undefined; - var elems = getElem('.link-shortened[href="' + short + '"]') + var elems = getElem('.link-shortened[href="' + short + '"]'); + + if (isUriSuspicious(long)) { + elems.replaceWith( + '…
      ' + polyglot.t('busted_oh') + ' ' + + polyglot.t('busted_avowal') + ':
      ' + + long + .replace(/&(?!lt;|gt;)/g, '&') + .replace(/"/g, '"') + .replace(/'/g, ''') + + '

      ' + ); + return; + } + + elems .attr('href', long) .removeClass('link-shortened') .off('click mouseup') .on('click mouseup', muteEvent) ; + var cropped = (/*$.Options.cropLongURIs &&*/ long.length > 23) ? long.slice(0, 23) + '…' : undefined; for (var i = 0; i < elems.length; i++) { if (elems[i].text === short) // there may be some other text, possibly formatted, so we check it From a2619a3bffecc62e172990b7be361099c1fd659d Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Sun, 27 Nov 2016 03:39:20 +0500 Subject: [PATCH 39/54] markout: improve `` escaping --- js/twister_formatpost.js | 85 +++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 50 deletions(-) diff --git a/js/twister_formatpost.js b/js/twister_formatpost.js index 0599df5..7ba30f3 100644 --- a/js/twister_formatpost.js +++ b/js/twister_formatpost.js @@ -496,56 +496,31 @@ function htmlFormatMsg(msg, opt) { } // changing the string - if (chr === '`' && markoutOpt === 'apply') { // if markoutOpt === 'clear' then ` does not escape anythyng so it needs to be handled like other tags - for (i = 0; i < p.length; i++) { - if (p[i].a > -1) { - if (p[i].t === -1 || (p[i].t === 0 && p[i].a > i)) { - if (p[i].k > 1) - t = Array(p[i].k).join(chr); - else - t = ''; - j = p[i].a; - t = t + msg.str.slice(p[i].i + p[i].k, p[j].i); - if (p[j].k > 1) - t = t + Array(p[i].k).join(chr); - t = '<' + tag + '>' + t + ''; - msg.htmlEntities.push(t.replace(/&(?!lt;|gt;)/g, '&')); - htmlEntityEncoded = '>' + (msg.htmlEntities.length - 1).toString() + '<'; - msg.str = msg.str.slice(0, p[i].i) + htmlEntityEncoded + msg.str.slice(p[j].i + p[j].k); - l = htmlEntityEncoded.length - p[j].i - p[j].k + p[i].i; - i = j; - for (j += 1; j < p.length; j++) - p[j].i += l; - } - } - } - } else { - if (markoutOpt === 'apply') { - t = ''; - tag = '<' + tag + '>'; - } else { // markoutOpt === 'clear' so we're clearing markup - t = ''; - tag = ''; - } - for (i = 0; i < p.length; i++) { - if (p[i].a > -1) { - if (p[i].t === -1 || (p[i].t === 0 && p[i].a > i)) { - if (p[i].k > 1) - msg.htmlEntities.push(tag + Array(p[i].k).join(chr)); - else - msg.htmlEntities.push(tag); - } else if (p[i].t === 1 || (p[i].t === 0 && p[i].a < i)) { - if (p[i].k > 1) - msg.htmlEntities.push(Array(p[i].k).join(chr) + t); - else - msg.htmlEntities.push(t); - } - htmlEntityEncoded = '>' + (msg.htmlEntities.length - 1).toString() + '<'; - msg.str = msg.str.slice(0, p[i].i) + htmlEntityEncoded + msg.str.slice(p[i].i + p[i].k); - l = htmlEntityEncoded.length - p[i].k; - for (j = i + 1; j < p.length; j++) - p[j].i += l; + if (markoutOpt === 'apply') { + t = ''; + tag = '<' + tag + '>'; + } else { // markoutOpt === 'clear' so we're clearing markup + t = ''; + tag = ''; + } + for (i = 0; i < p.length; i++) { + if (p[i].a > -1) { + if (p[i].t === -1 || (p[i].t === 0 && p[i].a > i)) { + if (p[i].k > 1) + msg.htmlEntities.push(tag + Array(p[i].k).join(chr)); + else + msg.htmlEntities.push(tag); + } else if (p[i].t === 1 || (p[i].t === 0 && p[i].a < i)) { + if (p[i].k > 1) + msg.htmlEntities.push(Array(p[i].k).join(chr) + t); + else + msg.htmlEntities.push(t); } + htmlEntityEncoded = '>' + (msg.htmlEntities.length - 1).toString() + '<'; + msg.str = msg.str.slice(0, p[i].i) + htmlEntityEncoded + msg.str.slice(p[i].i + p[i].k); + l = htmlEntityEncoded.length - p[i].k; + for (j = i + 1; j < p.length; j++) + p[j].i += l; } } @@ -610,7 +585,17 @@ function htmlFormatMsg(msg, opt) { msg = {str: escapeHtmlEntities(msg), htmlEntities: []}; - msg = markout(msg, markoutOpt, '`', 'samp'); // tag is kind of monospace, here sequence of chars inside it will be escaped from markup + // markout is not applied for chars inside of ``; to escape ` use backslash + if (markoutOpt === 'apply') + msg.str = msg.str.replace(/`(?:[^`\\]|\\.)*`/g, function (s) { + msg.htmlEntities.push('' + s.slice(1, -1).replace(/\\`/g, '`') + .replace(/&(?!lt;|gt;)/g, '&') + ''); + return '>' + (msg.htmlEntities.length - 1).toString() + '<'; + }); + else if (markoutOpt === 'clear') + msg.str = msg.str.replace(/`((?:[^`\\]|\\.)*)`/g, function (s) { + return s.slice(1, -1).replace(/\\`/g, '`'); + }); // handling links for (i = 0; i < msg.str.length - 7; i++) { From 8d37b7cf4f2e5c9aa7ad020114fa8adac7b4a845 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Sat, 21 Jan 2017 18:09:24 +0500 Subject: [PATCH 40/54] fix of "long twists in citations are shown not in full" --- js/twister_formatpost.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/twister_formatpost.js b/js/twister_formatpost.js index 7ba30f3..acc3c97 100644 --- a/js/twister_formatpost.js +++ b/js/twister_formatpost.js @@ -244,7 +244,7 @@ function setPostReference(elem, rt, sig_rt) { .attr('data-screen-name', rt.n) .attr('data-id', rt.k) .attr('data-userpost', $.toJSON({userpost: rt, sig_userpost: sig_rt})) - .find('.post-text').each(function (i, elem) {fillElemWithTxt($(elem), rt.msg);}) + .find('.post-text').each(function (i, elem) {fillElemWithTxt($(elem), rt.msg + (rt.msg2 || ''));}) ; setPostCommon(elem, rt.n, rt.time); } From 8399674f3a4d79268bc62f90261515636752e8f8 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Mon, 23 Jan 2017 03:32:34 +0500 Subject: [PATCH 41/54] add the button for manual checking for client (twister-html itself) updates --- home.html | 1 + js/interface_common.js | 12 ++- js/interface_localization.js | 117 +++++++++++++++++++++++++ js/mobile_abstract.js | 163 +++++++++++++++++++++++++++++++++++ network.html | 2 +- 5 files changed, 293 insertions(+), 2 deletions(-) diff --git a/home.html b/home.html index 8deaac4..9d7f887 100644 --- a/home.html +++ b/home.html @@ -53,6 +53,7 @@
      Options Network config Setup account + Check for client's updates Following users Change user diff --git a/js/interface_common.js b/js/interface_common.js index d425118..4589307 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -16,7 +16,10 @@ var twister = { tmpl: { // templates pointers are stored here root: $('
      ') // templates should be detached from DOM and attached here; use extractTemplate() }, - modal: {} + modal: {}, + var: { + updatesCheckClient: {} + } }; var window_scrollY = 0; var _watchHashChangeRelaxDontDoIt = window.location.hash === '' ? true : false; @@ -2701,6 +2704,13 @@ function initInterfaceCommon() { $('.uri-shortener').on('mouseup', {route: '#/uri-shortener'}, routeOnClick); + $('.updates-check-client').text(polyglot.t('updates_check_client')) + .on('mouseup', function (event) { + muteEvent(event); + checkUpdatesClient(true); + } + ); + $('.post-area-new textarea') .on('focus', function (event) { diff --git a/js/interface_localization.js b/js/interface_localization.js index f3ee644..5608c75 100644 --- a/js/interface_localization.js +++ b/js/interface_localization.js @@ -45,6 +45,7 @@ if(preferredLanguage == "en"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "Cancel", + 'cant_get_requested_resourse': 'Can\'t get resourse at %{link}\n status: %{status}.', "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", @@ -191,6 +192,14 @@ if(preferredLanguage == "en"){ "Unfollow": "Unfollow", "Update": "Update", "Auto updating": "Automatic updating", + 'updates_are_available': 'Updates are available', + 'updates_not_available': 'No updates are available', + 'updates_check_client': 'Check for client\'s updates', + 'updates_repo_overview': 'Currently we are on the branch %{branch} of %{repo} at the commit\n %{commit} of %{date}\n' + + 'but HEAD of its source is already at the commit\n %{commitUpstream} of %{dateUpstream}.', + 'updates_checkout_diff': 'Checkout [the diff on GitHub](%{link}) to learn what is changed.', + 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', + 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Updating status...", // status of block chain "user_not_yet_accepted": "Other peers have not yet accepted this new user.\n" + "Unfortunately it is not possible to save profile\n" + @@ -396,6 +405,7 @@ if(preferredLanguage == "es"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "Cancelar", + 'cant_get_requested_resourse': 'Can\'t get resourse at %{link}\n status: %{status}.', "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", @@ -542,6 +552,14 @@ if(preferredLanguage == "es"){ "Unfollow": "Dejar de seguir", "Update": "Actualizar", "Auto updating": "Auto updating", + 'updates_are_available': 'Updates are available', + 'updates_not_available': 'No updates are available', + 'updates_check_client': 'Check for client\'s updates', + 'updates_repo_overview': 'Currently we are on the branch %{branch} of %{repo} at the commit\n %{commit} of %{date}\n' + + 'but HEAD of its source is already at the commit\n %{commitUpstream} of %{dateUpstream}.', + 'updates_checkout_diff': 'Checkout [the diff on GitHub](%{link}) to learn what is changed.', + 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', + 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Actualización del estado ...", // status of block chain "user_not_yet_accepted": "Otros pares no han aceptado este nuevo usuario.\n" + "Por desgracia, no es posible guardar el perfil\n" + @@ -744,6 +762,7 @@ if(preferredLanguage == "uk"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "Відміна", + 'cant_get_requested_resourse': 'Can\'t get resourse at %{link}\n status: %{status}.', "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", @@ -891,6 +910,14 @@ if(preferredLanguage == "uk"){ "Unfollow": "Відписатись", "Update": "Оновити", "Auto updating": "Автоматичне оновлення", + 'updates_are_available': 'Updates are available', + 'updates_not_available': 'No updates are available', + 'updates_check_client': 'Check for client\'s updates', + 'updates_repo_overview': 'Currently we are on the branch %{branch} of %{repo} at the commit\n %{commit} of %{date}\n' + + 'but HEAD of its source is already at the commit\n %{commitUpstream} of %{dateUpstream}.', + 'updates_checkout_diff': 'Checkout [the diff on GitHub](%{link}) to learn what is changed.', + 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', + 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Оновлення статусу...", // status of block chain "user_not_yet_accepted": "Триває підтвердження нового користувача.\n" + "У цей час не можна редагувати профіль та надсилати повідомлення.\n\n" + @@ -1090,6 +1117,7 @@ if(preferredLanguage == "zh-CN"){ "busted_avowal": "系统检测到此用户试图在这里注入恶意代码", "btn_ok": "Okay", "Cancel": "取消", + 'cant_get_requested_resourse': 'Can\'t get resourse at %{link}\n status: %{status}.', "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", @@ -1236,6 +1264,14 @@ if(preferredLanguage == "zh-CN"){ "Unfollow": "取消关注", "Update": "更新", "Auto updating": "自动更新", + 'updates_are_available': 'Updates are available', + 'updates_not_available': 'No updates are available', + 'updates_check_client': 'Check for client\'s updates', + 'updates_repo_overview': 'Currently we are on the branch %{branch} of %{repo} at the commit\n %{commit} of %{date}\n' + + 'but HEAD of its source is already at the commit\n %{commitUpstream} of %{dateUpstream}.', + 'updates_checkout_diff': 'Checkout [the diff on GitHub](%{link}) to learn what is changed.', + 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', + 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "状态更新中...", // status of block chain "user_not_yet_accepted": "其他节点还没有接受这个新用户。\n" + "很抱歉,现在你还不能保存你的个人简介\n" + @@ -1441,6 +1477,7 @@ if(preferredLanguage == "nl"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "Annuleren", + 'cant_get_requested_resourse': 'Can\'t get resourse at %{link}\n status: %{status}.', "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", @@ -1587,6 +1624,14 @@ if(preferredLanguage == "nl"){ "Unfollow": "Ontvolgen", "Update": "Update", "Auto updating": "Auto updating", + 'updates_are_available': 'Updates are available', + 'updates_not_available': 'No updates are available', + 'updates_check_client': 'Check for client\'s updates', + 'updates_repo_overview': 'Currently we are on the branch %{branch} of %{repo} at the commit\n %{commit} of %{date}\n' + + 'but HEAD of its source is already at the commit\n %{commitUpstream} of %{dateUpstream}.', + 'updates_checkout_diff': 'Checkout [the diff on GitHub](%{link}) to learn what is changed.', + 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', + 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Status aan het updaten...", // status of block chain "user_not_yet_accepted": "Other peers have not yet accepted this new user.\n" + "Unfortunately it is not possible to save profile\n" + @@ -1789,6 +1834,7 @@ if(preferredLanguage == "it"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "Cancella", + 'cant_get_requested_resourse': 'Can\'t get resourse at %{link}\n status: %{status}.', "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", @@ -1935,6 +1981,14 @@ if(preferredLanguage == "it"){ "Unfollow": "Smetti di seguire", "Update": "Aggiorna", "Auto updating": "Auto updating", + 'updates_are_available': 'Updates are available', + 'updates_not_available': 'No updates are available', + 'updates_check_client': 'Check for client\'s updates', + 'updates_repo_overview': 'Currently we are on the branch %{branch} of %{repo} at the commit\n %{commit} of %{date}\n' + + 'but HEAD of its source is already at the commit\n %{commitUpstream} of %{dateUpstream}.', + 'updates_checkout_diff': 'Checkout [the diff on GitHub](%{link}) to learn what is changed.', + 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', + 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Aggiornamento in corso...", // status of block chain "user_not_yet_accepted": "Gli altri nodi non hanno ancora accettato il nuovo utente.\n" + "Al momento non puoi salvare il profilo o spedire messaggi.\n" + @@ -2135,6 +2189,7 @@ if(preferredLanguage == "fr"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "Annuler", + 'cant_get_requested_resourse': 'Can\'t get resourse at %{link}\n status: %{status}.', "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", @@ -2281,6 +2336,14 @@ if(preferredLanguage == "fr"){ "Unfollow": "Se désabonner", "Update": "Mettre à jour", "Auto updating": "Mise à jour automatique", + 'updates_are_available': 'Updates are available', + 'updates_not_available': 'No updates are available', + 'updates_check_client': 'Check for client\'s updates', + 'updates_repo_overview': 'Currently we are on the branch %{branch} of %{repo} at the commit\n %{commit} of %{date}\n' + + 'but HEAD of its source is already at the commit\n %{commitUpstream} of %{dateUpstream}.', + 'updates_checkout_diff': 'Checkout [the diff on GitHub](%{link}) to learn what is changed.', + 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', + 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Mise à jour du statut...", // status of block chain "user_not_yet_accepted": "Les autres pairs n'ont pas encore accepté ce nouvel utilisateur.\n" + "Malheureusement, il n'est pas possible d'enregistrer le profil\n" + @@ -2484,6 +2547,7 @@ if(preferredLanguage == "ru"){ "busted_avowal": "я пойман на попытке вставить этот подозрительный код здесь", "btn_ok": "Лады́", "Cancel": "Отмена", + 'cant_get_requested_resourse': 'Невозможно получить %{link}\n статус: %{status}.', "clear_cache": "Очистить кэш", "Confirm": "Несомненно", "сonfirm_group_leaving_header": "Подтверждение ухода из группы", @@ -2630,6 +2694,14 @@ if(preferredLanguage == "ru"){ "Unfollow": "Отписаться", "Update": "Обновить", "Auto updating": "Автоматическое обновление", + 'updates_are_available': 'Доступны обновления', + 'updates_not_available': 'Обновления не доступны', + 'updates_check_client': 'Проверить обновления клиента', + 'updates_repo_overview': 'Мы сейчас на ветке %{branch} в %{repo} на коммите\n %{commit} от %{date},\n' + + 'а вот HEAD её источника уже на коммите\n %{commitUpstream} от %{dateUpstream}.', + 'updates_checkout_diff': 'Смотри [сравнение на GitHub](%{link}), чтобы узнать каковы изменения.', + 'updates_checkout_diff_nfmt': 'Смотри сравнение на GitHub, чтобы узнать каковы изменения:\n %{link}', + 'updates_upstream_isnt_changed': 'Соответствующая ветка в исходном репозитории выглядит неизменённой.', "Updating status...": "Обновление информации...", // status of block chain "user_not_yet_accepted": "Другие участники сети еще не получили информацию о новом пользователе.\n" + "К сожалению, сейчас вы не можете редактировать ваш профиль\n" + @@ -2836,6 +2908,7 @@ if(preferredLanguage == "de"){ "busted_avowal": "Ich bin ertappt, habe versucht, hier Schadcode einzugeben!", "btn_ok": "Okay", "Cancel": "Abbrechen", + 'cant_get_requested_resourse': 'Can\'t get resourse at %{link}\n status: %{status}.', "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", @@ -2983,6 +3056,14 @@ if(preferredLanguage == "de"){ "Unfollow": "Nicht mehr folgen", "Update": "Aktualisieren", "Auto updating": "Automatische Aktualisierung", + 'updates_are_available': 'Updates are available', + 'updates_not_available': 'No updates are available', + 'updates_check_client': 'Check for client\'s updates', + 'updates_repo_overview': 'Currently we are on the branch %{branch} of %{repo} at the commit\n %{commit} of %{date}\n' + + 'but HEAD of its source is already at the commit\n %{commitUpstream} of %{dateUpstream}.', + 'updates_checkout_diff': 'Checkout [the diff on GitHub](%{link}) to learn what is changed.', + 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', + 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Status wird aktualisiert...", // status of block chain "user_not_yet_accepted": "Andere Peers haben diesen Benutzter noch nicht akzeptiert.\n" + "Leider ist es nicht möglich, das Profil zu speichern\n" + @@ -3186,6 +3267,7 @@ if(preferredLanguage == "ja"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "キャンセル", + 'cant_get_requested_resourse': 'Can\'t get resourse at %{link}\n status: %{status}.', "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", @@ -3332,6 +3414,14 @@ if(preferredLanguage == "ja"){ "Unfollow": "解除", "Update": "アップデート", "Auto updating": "Auto updating", + 'updates_are_available': 'Updates are available', + 'updates_not_available': 'No updates are available', + 'updates_check_client': 'Check for client\'s updates', + 'updates_repo_overview': 'Currently we are on the branch %{branch} of %{repo} at the commit\n %{commit} of %{date}\n' + + 'but HEAD of its source is already at the commit\n %{commitUpstream} of %{dateUpstream}.', + 'updates_checkout_diff': 'Checkout [the diff on GitHub](%{link}) to learn what is changed.', + 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', + 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "ブロックチェーンを更新中…", // status of block chain "user_not_yet_accepted": "この新ユーザーが他のピアーにまだ認証されていない。\n" + "なので、プロファイルの保存やメッセージの投稿は現在不可能です。\n" + @@ -3532,6 +3622,7 @@ if(preferredLanguage == "pt-BR"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "Cancelar", + 'cant_get_requested_resourse': 'Can\'t get resourse at %{link}\n status: %{status}.', "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", @@ -3679,6 +3770,14 @@ if(preferredLanguage == "pt-BR"){ "Unfollow": "Deixar de seguir", "Update": "Atualizar", "Auto updating": "Auto updating", + 'updates_are_available': 'Updates are available', + 'updates_not_available': 'No updates are available', + 'updates_check_client': 'Check for client\'s updates', + 'updates_repo_overview': 'Currently we are on the branch %{branch} of %{repo} at the commit\n %{commit} of %{date}\n' + + 'but HEAD of its source is already at the commit\n %{commitUpstream} of %{dateUpstream}.', + 'updates_checkout_diff': 'Checkout [the diff on GitHub](%{link}) to learn what is changed.', + 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', + 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Atualizando estado da Cadeia de Blocos...", // status of block chain "URI_shortener_caption": "URI Shortener", "user_not_yet_accepted": "Outros nós ainda não aceitaram este novo usuário.\n" + @@ -3882,6 +3981,7 @@ if(preferredLanguage == "tr"){ "busted_avowal": "Şüpheli bir şeyler iliştirmeye çalışırken enselendim.", "btn_ok": "Tamam", "Cancel": "İptal", + 'cant_get_requested_resourse': 'Can\'t get resourse at %{link}\n status: %{status}.', "clear_cache": "Geçmişi temizle", "Confirm": "Onayla", "сonfirm_group_leaving_header": "Gruptan ayrılmayı onayla", @@ -4028,6 +4128,14 @@ if(preferredLanguage == "tr"){ "Unfollow": "Takibi bırak", "Update": "Güncelle", "Auto updating": "Otomatik güncelleme", + 'updates_are_available': 'Updates are available', + 'updates_not_available': 'No updates are available', + 'updates_check_client': 'Check for client\'s updates', + 'updates_repo_overview': 'Currently we are on the branch %{branch} of %{repo} at the commit\n %{commit} of %{date}\n' + + 'but HEAD of its source is already at the commit\n %{commitUpstream} of %{dateUpstream}.', + 'updates_checkout_diff': 'Checkout [the diff on GitHub](%{link}) to learn what is changed.', + 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', + 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Durum güncelleniyor...", // status of block chain "user_not_yet_accepted": "Diğer eşler bu yeni kullanıcıyı henüz kabul etmediler.\n" + "Malesef profili kaydetmek ya da bu durumda\n" + @@ -4229,6 +4337,7 @@ if(preferredLanguage == "cs"){ "busted_avowal": "I\'m busted trying inject this suspicious stuff here", "btn_ok": "Okay", "Cancel": "Zrušit", + 'cant_get_requested_resourse': 'Can\'t get resourse at %{link}\n status: %{status}.', "clear_cache": "Clear cache", "Confirm": "Confirm", "сonfirm_group_leaving_header": "Confirm group leaving", @@ -4376,6 +4485,14 @@ if(preferredLanguage == "cs"){ "Unfollow": "Přestat sledovat", "Update": "Aktualizovat", "Auto updating": "Automatická aktualizace", + 'updates_are_available': 'Updates are available', + 'updates_not_available': 'No updates are available', + 'updates_check_client': 'Check for client\'s updates', + 'updates_repo_overview': 'Currently we are on the branch %{branch} of %{repo} at the commit\n %{commit} of %{date}\n' + + 'but HEAD of its source is already at the commit\n %{commitUpstream} of %{dateUpstream}.', + 'updates_checkout_diff': 'Checkout [the diff on GitHub](%{link}) to learn what is changed.', + 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', + 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Aktualizuji stav...", // status of block chain "user_not_yet_accepted": "Ostatní uzly ještě nepřijaly tohoto nového uživatele.\n" + "Proto zatím není možné uložit profil nebo vkládat příspěvky.\n" + diff --git a/js/mobile_abstract.js b/js/mobile_abstract.js index a2406ea..ae5456c 100644 --- a/js/mobile_abstract.js +++ b/js/mobile_abstract.js @@ -592,3 +592,166 @@ function filterLang(string) { } } +function checkUpdatesClient(alertIfNoUpdates) { + function handleGetFail(jqXHR) { + twister.var.updatesCheckClient.isOngoing = false; + + console.warn(polyglot.t('cant_get_requested_resourse', {link: this.url, status: jqXHR.status + ', \'' + jqXHR.statusText + '\''})); + + if (alertIfNoUpdates) { + if ($.hasOwnProperty('mobile')) + alert(polyglot.t('updates_not_available') + '.\n\n' + + polyglot.t('cant_get_requested_resourse', {link: this.url, status: jqXHR.status + ', \'' + jqXHR.statusText + '\''}) + ); + else + alertPopup({ + txtTitle: polyglot.t('updates_not_available'), + txtMessage: polyglot.t('cant_get_requested_resourse', {link: this.url, status: jqXHR.status + ', ~' + jqXHR.statusText + '~'}) + }); + } + } + + if (twister.var.updatesCheckClient.isOngoing) + return; + + twister.var.updatesCheckClient.isOngoing = true; + + $.get('.git/HEAD', function (ret) { + if (ret.slice(0, 16) !== 'ref: refs/heads/') { + twister.var.updatesCheckClient.isOngoing = false; + if (alertIfNoUpdates) + alert(polyglot.t('updates_not_available') + '.\n\nCan\'t parse local HEAD: unknown syntax, FUBAR!'); + + return; + } + + var branch = ret.slice(16).trim(); + + $.get('.git/refs/heads/' + branch, function (ret) { + var commit = ret.trim(); + if (!commit) { + twister.var.updatesCheckClient.isOngoing = false; + if (alertIfNoUpdates) + alert(polyglot.t('updates_not_available') + '.\n\nCan\'t parse local HEAD: \'' + '.git/refs/heads/' + branch + '\' is empty, FUBAR!'); + + return; + } + + var repo = 'twister-html'; // TODO source repo selection in options + var repoOwner = 'miguelfreitas'; + + // TODO notification if local branch was changed ('r u wanna reload the page?') + /*if (!twister.var.updatesCheckClient.formerBranch || !twister.var.updatesCheckClient.formerCommit) { + twister.var.updatesCheckClient.formerBranch = branch; + twister.var.updatesCheckClient.formerCommit = commit; + }*/ + + console.log('currently we are on the branch \'' + branch + '\' of ' + repo + ' at the commit ' + commit); + + $.get('https://api.github.com/repos/' + repoOwner + '/' + repo + '/branches', function (ret) { + for (var i = 0; i < ret.length; i++) { + if (ret[i].name === branch) { + if (ret[i].commit.sha === commit) { + twister.var.updatesCheckClient.isOngoing = false; + + console.log(polyglot.t('updates_upstream_isnt_changed')); + + if (alertIfNoUpdates) { + if ($.hasOwnProperty('mobile')) + alert(polyglot.t('updates_not_available') + '.\n\n' + + polyglot.t('updates_upstream_isnt_changed') + ); + else + alertPopup({ + txtTitle: polyglot.t('updates_not_available'), + txtMessage: polyglot.t('updates_upstream_isnt_changed') + }); + } + } else { + console.log('source branch has a different HEAD: ' + ret[i].commit.sha); + + var commitUpstream = ret[i].commit.sha; + + $.get('https://api.github.com/repos/' + repoOwner + '/' + repo + '/git/commits/' + commit, function (ret) { + if (ret.sha !== commit) { // the response is wrong if so, should be 404 instead + twister.var.updatesCheckClient.isOngoing = false; + console.log('upstream tree doesn\'t have our most recent commit,\nlooks like we are in the process of development locally.'); + if (alertIfNoUpdates) + alert(polyglot.t('updates_not_available') + '.\n\nUpstream tree doesn\'t have our most recent commit,\nlooks like we are in the process of development locally.'); + + return; + } + + commit = ret; + + $.get('https://api.github.com/repos/' + repoOwner + '/' + repo + '/git/commits/' + commitUpstream, function (ret) { + twister.var.updatesCheckClient.isOngoing = false; + + if (ret.sha !== commitUpstream) { // the response is wrong if so, should be 404 instead + console.warn('upstream tree doesn\'t have the commit which is named most recent in the list of branches, FUBAR!'); + if (alertIfNoUpdates) + alert(polyglot.t('updates_not_available') + '.\n\nUpstream tree doesn\'t have the commit which is named most recent in the list of branches, FUBAR!'); + + return; + } + + commitUpstream = ret; + var linkGitHubDiff = 'https://github.com/' + repoOwner + '/' + repo + '/compare/' + commit.sha + '...' + repoOwner + ':' + branch; + + console.log(polyglot.t('updates_checkout_diff_nfmt', {link: linkGitHubDiff})); + + if ($.hasOwnProperty('mobile')) + alert(polyglot.t('updates_are_available') + '.\n\n' + + polyglot.t('updates_repo_overview', { + branch: '\'' + branch + '\'', + repo: repo, + commit: commit.sha, + date: new Date(commit.author.date).toString().replace(/ GMT.*/g, ''), + commitUpstream: commitUpstream.sha, + dateUpstream: new Date(commitUpstream.author.date).toString().replace(/ GMT.*/g, '') + }) + '\n\n' + + polyglot.t('updates_checkout_diff_nfmt', {link: linkGitHubDiff}) + ); + else + alertPopup({ + txtTitle: polyglot.t('updates_are_available'), + txtMessage: polyglot.t('updates_repo_overview', { + branch: '~' + branch + '~', + repo: repo, + commit: '*' + commit.sha + '*', + date: new Date(commit.author.date).toString().replace(/ GMT.*/g, ''), + commitUpstream: '*' + commitUpstream.sha + '*', + dateUpstream: new Date(commitUpstream.author.date).toString().replace(/ GMT.*/g, '') + }) + '\n\n' + + polyglot.t('updates_checkout_diff', {link: linkGitHubDiff}) + }); + }).fail(function (jqXHR) { + if (jqXHR.status === 404) { + twister.var.updatesCheckClient.isOngoing = false; + console.warn('upstream tree doesn\'t have the commit which is named most recent in the list of branches, FUBAR!'); + if (alertIfNoUpdates) + alert(polyglot.t('updates_not_available') + '.\n\nUpstream tree doesn\'t have the commit which is named most recent in the list of branches, FUBAR!'); + } else + handleGetFail(jqXHR); + }); + }).fail(function (jqXHR) { + if (jqXHR.status === 404) { + twister.var.updatesCheckClient.isOngoing = false; + console.log('upstream tree doesn\'t have our most recent commit,\nlooks like we are in the process of development locally.'); + if (alertIfNoUpdates) + alert(polyglot.t('updates_not_available') + '.\n\nUpstream tree doesn\'t have our most recent commit,\nlooks like we are in the process of development locally.'); + } else + handleGetFail(jqXHR); + }); + } + return; + } + } + twister.var.updatesCheckClient.isOngoing = false; + console.log('upstream tree doesn\'t have our branch,\nlooks like we are in the process of development locally.'); + if (alertIfNoUpdates) + alert(polyglot.t('updates_not_available') + '.\n\nUpstream tree doesn\'t have our branch,\nlooks like we are in the process of development locally.'); + }).fail(handleGetFail); + }).fail(handleGetFail); + }).fail(handleGetFail); +} diff --git a/network.html b/network.html index dfe79f2..d76b91b 100644 --- a/network.html +++ b/network.html @@ -45,7 +45,7 @@
      Options Setup account - Network config + Check for client's updates Change user From 1ae8e6be3e07d151596c6a87f82fe39ab674853d Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Mon, 23 Jan 2017 04:23:44 +0500 Subject: [PATCH 42/54] fix follow buttons on new-users and who-to-follow (sic!) lists --- js/interface_common.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/interface_common.js b/js/interface_common.js index 4589307..fce95c0 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -2603,7 +2603,7 @@ function initInterfaceCommon() { $('.prompt-close').on('click', closePrompt); - $('button.follow').on('click', clickFollow); + getElem('button.follow', true).on('click', clickFollow); $('.following-config-method-buttons .public-following').on('click', function(event) { setFollowingMethod(event); From b1646914cb9fcff7a26c21e8e28427675ef1253d Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Thu, 2 Feb 2017 14:17:10 +0500 Subject: [PATCH 43/54] convert login.html to #/login modal --- css/style.css | 176 +++++++++-------------- home.html | 49 ++++++- js/interface_common.js | 129 ++++++++++++++--- js/interface_home.js | 3 +- js/interface_localization.js | 122 +++++++++++++++- js/interface_login.js | 37 ----- js/mobile_abstract.js | 40 +++++- js/tmobile.js | 20 +-- js/twister_network.js | 7 +- js/twister_user.js | 263 ++++++++++++++--------------------- login.html | 150 -------------------- network.html | 2 +- options.html | 1 - profile-edit.html | 2 +- theme_calm/css/style.css | 185 +++++++++--------------- theme_nin/css/style.css | 167 +++++++++------------- theme_nin/sass/_login.sass | 55 -------- theme_nin/sass/style.sass | 76 +++++++++- tmobile.html | 96 +++++++------ 19 files changed, 746 insertions(+), 834 deletions(-) delete mode 100644 js/interface_login.js delete mode 100644 login.html delete mode 100644 theme_nin/sass/_login.sass diff --git a/css/style.css b/css/style.css index e04d0e2..c758d00 100644 --- a/css/style.css +++ b/css/style.css @@ -1408,8 +1408,7 @@ ol.toptrends-list { border: solid 1px rgba( 69, 71, 77, .05 ); padding: 10px; } -.singleBlock h2, .header-bold -{ +.singleBlock h2 { font-weight: bold; line-height: 40px; color: rgba( 255, 255, 255, 1 ); @@ -1480,76 +1479,6 @@ ol.toptrends-list { margin-right: 20px; } -/************************************* -************* LOGIN PAGE ************* -**************************************/ - -.login .header-bold { - display: block; - width: 720px; - margin: 0px auto 12px auto; -} - -.login .module { - display: block; - width: 720px; - padding: 32px 40px; - margin: 8px auto; - background: #fff; -} - -.login .module p { - margin-bottom: 5px; -} - -.login .module input { - padding: 5px 10px; - background: #f3f3f3; - border: solid 1px #dcdcdc; - transition: box-shadow 0.3s, border 0.3s; - font-size: 14px; -} - -.login .module input:focus, .login .module select:focus { - background: #fff; - transition: background-color 100ms linear; - border: solid 1px rgba( 227, 79, 66, .5 ); - box-shadow: 0 0 10px rgba(0, 0, 0, .3 ); -} - -.login .module select { - height: 30px; - padding: 3px 30px 3px 10px; - margin: 0; - border: 1px solid #ccc; - font-size: 14px; -} - -.login .module span.availability { - margin-left: 10px; - color: #45474d; -} - -.with-nickname, .import-secret-key, .create-user { - margin-top: 10px; -} - -.login .module:nth-child(2) div , -.login .module:nth-child(3) div:nth-child(2), -.login .secret-key-import, -.login .username-import { - margin-top: 20px; - margin-bottom: 20px; - margin-left: 16px; -} - -.login .create-user, -.login .import-secret-key { - display: block; - margin-left: auto; - margin-right: 16px; -} - /************************************* ************* POPUP MODAL ************ **************************************/ @@ -1580,12 +1509,12 @@ ol.toptrends-list { font-weight: bold; } -.modal-wrapper .modal-content { +.modal-content { background: #fff; overflow-y: auto; } -.modal-wrapper .modal-blackout { +.modal-blackout { background: rgba(0,0,0, .6); z-index: -1; position: fixed; @@ -1673,6 +1602,60 @@ ol.toptrends-list { margin-top: 4px; } +/************************************* +******* LOGIN TO ACCOUNT MODAL ******* +**************************************/ + +.login-modal.modal-wrapper { + height: auto; /*about 580px*/ + margin-top: -290px; +} + +.login-modal .module { + margin: 4px; +} + +.login-modal .module > div { + width: 100%; + margin: 4px 0; + padding: 4px 12px; +} + +.login-modal .module > div:last-child { + text-align: right; + margin: 8px 0; +} + +.login-modal .module input { + border: solid 1px rgba(0, 0, 0, .3); + border-radius: 3px; + width: 320px; + margin: 12px 16px; + padding: 2px 4px; +} + +.login-modal .module select { + border: solid 1px rgba(0, 0, 0, .3); + border-radius: 3px; + width: 310px; + margin: 12px 16px; + padding: 2px 4px; +} + +.login-modal .module input:focus, .login-modal .module select:focus { + border: solid 1px rgba(227, 79, 66, .5); +} + +.login-modal .module .secret-key { + width: 500px; +} + +.login-modal .module .availability { + color: #45474D; + display: inline-block; + margin-left: 16px; +} + /************************************* ******** DIRECT MESSAGES MODAL ******* **************************************/ @@ -1867,38 +1850,6 @@ ol.toptrends-list { margin: 8px 8px 0; } -/************************************* -*********** NEW USER MODAL *********** -**************************************/ - -.new-user.modal-wrapper { - width: 720px; - height: 580px; - margin: -290px 0 0 -360px; -} - -.new-user .modal-content { - padding: 25px; -} - -.new-user .modal-close { - display: none; -} - -.new-user .text { - margin: 0 0 15px 0; -} - -.new-user .emphasis { - font-size: 18px; - text-align: center; -} - -.new-user .secret-key { - color: rgba(.5,0,0, 1.0); - font-weight: bold; -} - /************************************* ************ HASHTAG MODAL *********** **************************************/ @@ -2033,7 +1984,7 @@ ol.toptrends-list { } .prompt-wrapper .modal-buttons { - margin: 4px 16px; + padding: 4px 16px 16px; text-align: right; } @@ -2053,12 +2004,19 @@ ol.toptrends-list { .confirm-popup .message { text-align: center; - margin: 12px; + padding: 12px; } .confirm-popup .modal-buttons { text-align: center; - padding: 4px; +} + +/************************************* +********* NEW ACCOUNT POPUP ********** +**************************************/ + +.new-account-briefing.prompt-wrapper { + margin-top: -164px; } /************************************* diff --git a/home.html b/home.html index 9d7f887..1100eaf 100644 --- a/home.html +++ b/home.html @@ -53,9 +53,9 @@ Options Network config Setup account + Change user Check for client's updates Following users - Change user Direct Messages Group Messages @@ -458,11 +458,12 @@
      - - + + +
      @@ -473,6 +474,42 @@
      +
      +
      +
      +

      Existing local users

      + +
      +
      + +
      +
      + + +
      +
      diff --git a/js/interface_common.js b/js/interface_common.js index fce95c0..c5f61c4 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -18,6 +18,7 @@ var twister = { }, modal: {}, var: { + localAccounts: [], updatesCheckClient: {} } }; @@ -58,6 +59,9 @@ function openModal(modal) { modal.self = $('#templates ' + modal.classBase).clone(true) .addClass(modal.classAdd); + if (modal.removeBlackout) + modal.self.find('.modal-blackout').remove(); + if (modal.title) modal.self.find('.modal-header h3').html(modal.title); if (modal.content) @@ -305,8 +309,9 @@ function confirmPopup(req) { var modal = openModal({ classBase: '.prompt-wrapper', - classAdd: 'confirm-popup', + classAdd: req.classAdd ? 'confirm-popup ' + req.classAdd : 'confirm-popup', content: $('#confirm-popup-template').children().clone(true), + removeBlackout: !req.addBlackout, title: req.txtTitle }); @@ -361,6 +366,8 @@ function confirmPopup(req) { btn.on('click', {cbFunc: req.cbClose, cbReq: req.cbCloseReq}, closePrompt); } } + + return modal; } function alertPopup(req) { @@ -377,7 +384,7 @@ function alertPopup(req) { req.removeCancel = true; } - confirmPopup(req); + return confirmPopup(req); } function checkNetworkStatusAndAskRedirect(cbFunc, cbReq) { @@ -419,6 +426,94 @@ function timeSincePost(t) { return polyglot.t('time_ago', {time: expression}); } +function openModalLogin() { + var modal = openModal({ + classAdd: 'login-modal', + content: twister.tmpl.loginMC.clone(true), + title: polyglot.t('twister login') + }); +} + +function handleClickAccountLoginLogin(event) { + loginToAccount($(event.target).closest('.module').find('select.local-usernames').val()); +} + +function handleInputAccountCreateSetReq(event) { + var container = $(event.target).closest('.module'); + + container.find('.availability').text(''); + $.MAL.enableButton(container.find('.check')); + $.MAL.disableButton(container.find('.create')); +} + +function handleClickAccountCreateCheckReq(event) { + var container = $(event.target).closest('.module'); + var peerAliasElem = container.find('.alias'); + var peerAlias = peerAliasElem.val().toLowerCase(); + var availField = container.find('.availability'); + + peerAliasElem.val(peerAlias); + $.MAL.disableButton(container.find('.check')); + + if (!peerAlias.length) + return; + if (peerAlias.length > 16) { + availField.text(polyglot.t('Must be 16 characters or less.')); + return; + } + + // check for non-alphabetic characters and space + if (peerAlias.search(/[^a-z0-9_]/) !== -1) { + availField.text(polyglot.t('Only alphanumeric and underscore allowed.')); + return; + } + + availField.text(polyglot.t('Checking...')); + + dumpPubkey(peerAlias, + function(req, ret) { + if (ret) { + req.container.find('.availability').text(polyglot.t('Not available')); + } else { + req.container.find('.availability').text(polyglot.t('Available')); + $.MAL.enableButton(req.container.find('.create')); + } + }, {container: container} + ); +} + +function handleClickAccountCreateCreate(event) { + var container = $(event.target).closest('.module'); + var peerAlias = container.find('.alias').val().toLowerCase(); + + if (twister.var.localAccounts.indexOf(peerAlias) < 0) { + createAccount(peerAlias); + } else { + // user exists in wallet but transaction not sent + dumpPrivkey(peerAlias, + function (req, ret) { + $.MAL.processCreateAccount(req.peerAlias, ret); + }, {peerAlias: peerAlias} + ); + } +} + +function handleInputAccountImportSetReq(event) { + var container = $(event.target).closest('.module'); + + if (container.find('.secret-key').val().length === 52 + && container.find('.alias').val().toLowerCase().length) + $.MAL.enableButton(container.find('.import')); + else + $.MAL.disableButton(container.find('.import')); +} + +function handleClickAccountImportImport(event) { + var container = $(event.target).closest('.module'); + + importAccount(container.find('.alias').val().toLowerCase(), container.find('.secret-key').val()) +} + function openGroupProfileModalWithNameHandler(groupAlias) { var modal = openModal({ classAdd: 'profile-modal', @@ -1260,6 +1355,8 @@ function loadModalFromHash() { openGroupMessagesNewGroupModal(); else if (hashstring === '#groupmessages+joingroup') openGroupMessagesJoinGroupModal(); + else if (hashstring === '#/login') + openModalLogin(); else if (hashstring === '#whotofollow') openWhoToFollowModal(); else if (hashstring === '#/uri-shortener') @@ -2593,7 +2690,7 @@ function initInterfaceCommon() { }) ; - $('.modal-close, .modal-blackout').not('.prompt-close').on('click', closeModal); + getElem('.modal-wrapper .modal-close, .modal-wrapper .modal-blackout').on('click', closeModal); $('.minimize-modal').on('click', function (event) { minimizeModal($(event.target).closest('.modal-wrapper')); @@ -2765,18 +2862,6 @@ function inputEnterActivator(event) { .attr('disabled', elemEvent.val().trim() === ''); } -function importSecretKeypress(event) { // FIXME rename - var elemModule = $(event.target).closest('.module'); - var elemEnter = elemModule.find('.import-secret-key'); - var secretKey = elemModule.find('.secret-key-import').val(); - var peerAlias = elemModule.find('.username-import').val().toLowerCase(); - - if (secretKey.length === 52 && peerAlias.length) - $.MAL.enableButton(elemEnter); - else - $.MAL.disableButton(elemEnter); -} - function pasteToTextarea(ta, p) { if (!ta || typeof ta.val !== 'function') return; @@ -2834,6 +2919,16 @@ $(document).ready(function () { if ($.localStorage.isSet('twistaURIs')) twister.URIs = $.localStorage.get('twistaURIs'); twister.html.blanka.appendTo('body').hide(); + twister.tmpl.loginMC = extractTemplate('#template-login-modal'); + twister.tmpl.loginMC.find('.login').on('click', handleClickAccountLoginLogin); + var module = twister.tmpl.loginMC.closest('.create-account'); + module.find('.alias').on('input', handleInputAccountCreateSetReq); + module.find('.check').on('click', handleClickAccountCreateCheckReq); + module.find('.create').on('click', handleClickAccountCreateCreate); + module = twister.tmpl.loginMC.closest('.import-account'); + module.find('.secret-key').on('input', handleInputAccountImportSetReq); + module.find('.alias').on('input', handleInputAccountImportSetReq); + module.find('.import').on('click', handleClickAccountImportImport); twister.tmpl.followersList = extractTemplate('#template-followers-list'); twister.tmpl.followersPeer = extractTemplate('#template-followers-peer'); twister.tmpl.followingList = extractTemplate('#template-following-list'); @@ -2892,9 +2987,7 @@ $(document).ready(function () { var path = window.location.pathname; var page = path.split("/").pop(); - if (page.indexOf("login.html") === 0) { - initInterfaceLogin(); - } else if (page.indexOf("network.html") === 0) { + if (page.indexOf('network.html') === 0) { initInterfaceNetwork(); } else if (page.indexOf('options.html') === 0) { initInterfaceCommon(); diff --git a/js/interface_home.js b/js/interface_home.js index 03116ec..4e31144 100644 --- a/js/interface_home.js +++ b/js/interface_home.js @@ -49,8 +49,7 @@ var InterfaceFunctions = function() { //$("span.screen-name").text('@' + user); var $miniProfile = $(".mini-profile"); if (!defaultScreenName) { - $(".userMenu-profile > a").text(polyglot.t("Login")); - $(".userMenu-profile > a").attr("href","login.html"); + $('.userMenu-profile > a').attr('href', '#/login').text(polyglot.t('Login')); $(".post-area-new > textarea").attr("placeholder",polyglot.t("You have to log in to post messages.")); $(".post-area-new > textarea").attr("disabled","true"); $miniProfile.find(".mini-profile-name").text("guest"); diff --git a/js/interface_localization.js b/js/interface_localization.js index 5608c75..06f36e8 100644 --- a/js/interface_localization.js +++ b/js/interface_localization.js @@ -201,6 +201,15 @@ if(preferredLanguage == "en"){ 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Updating status...", // status of block chain + 'new_account_briefing': 'A new account was created and it is being propagated to the network. ' + + 'Please do not close this window, this might take a few minutes.\n\n' + + 'Your secret key is: *%{secretKey}*\n\n' + + 'It is highly recommended that you take this time to save your secret key. ' + + 'Print it, do a screenshot, use the camera in your phone or write it down to a piece of paper.\n\n' + + 'The secret key will be needed to use this account from different computers. ' + + 'If you ever lose your secret key your account will be locked forever ' + + '(note: ~this is alpha software and it may crash, causing loss of data~).\n\n' + + 'Just wait. The OK button will be shown faster you can say ~decentralization~.', "user_not_yet_accepted": "Other peers have not yet accepted this new user.\n" + "Unfortunately it is not possible to save profile\n" + "or send any posts in this state.\n\n" + @@ -561,6 +570,15 @@ if(preferredLanguage == "es"){ 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Actualización del estado ...", // status of block chain + 'new_account_briefing': 'A new account was created and it is being propagated to the network. ' + + 'Please do not close this window, this might take a few minutes.\n\n' + + 'Your secret key is: *%{secretKey}*\n\n' + + 'It is highly recommended that you take this time to save your secret key. ' + + 'Print it, do a screenshot, use the camera in your phone or write it down to a piece of paper.\n\n' + + 'The secret key will be needed to use this account from different computers. ' + + 'If you ever lose your secret key your account will be locked forever ' + + '(note: ~this is alpha software and it may crash, causing loss of data~).\n\n' + + 'Just wait. The OK button will be shown faster you can say ~decentralization~.', "user_not_yet_accepted": "Otros pares no han aceptado este nuevo usuario.\n" + "Por desgracia, no es posible guardar el perfil\n" + "o enviar ningún mensaje en este estado.\n\n" + @@ -919,6 +937,15 @@ if(preferredLanguage == "uk"){ 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Оновлення статусу...", // status of block chain + 'new_account_briefing': 'A new account was created and it is being propagated to the network. ' + + 'Please do not close this window, this might take a few minutes.\n\n' + + 'Your secret key is: *%{secretKey}*\n\n' + + 'It is highly recommended that you take this time to save your secret key. ' + + 'Print it, do a screenshot, use the camera in your phone or write it down to a piece of paper.\n\n' + + 'The secret key will be needed to use this account from different computers. ' + + 'If you ever lose your secret key your account will be locked forever ' + + '(note: ~this is alpha software and it may crash, causing loss of data~).\n\n' + + 'Just wait. The OK button will be shown faster you can say ~decentralization~.', "user_not_yet_accepted": "Триває підтвердження нового користувача.\n" + "У цей час не можна редагувати профіль та надсилати повідомлення.\n\n" + "Будь ласка, зачекайте декілька хвилин.\n" + @@ -1273,6 +1300,15 @@ if(preferredLanguage == "zh-CN"){ 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "状态更新中...", // status of block chain + 'new_account_briefing': 'A new account was created and it is being propagated to the network. ' + + 'Please do not close this window, this might take a few minutes.\n\n' + + 'Your secret key is: *%{secretKey}*\n\n' + + 'It is highly recommended that you take this time to save your secret key. ' + + 'Print it, do a screenshot, use the camera in your phone or write it down to a piece of paper.\n\n' + + 'The secret key will be needed to use this account from different computers. ' + + 'If you ever lose your secret key your account will be locked forever ' + + '(note: ~this is alpha software and it may crash, causing loss of data~).\n\n' + + 'Just wait. The OK button will be shown faster you can say ~decentralization~.', "user_not_yet_accepted": "其他节点还没有接受这个新用户。\n" + "很抱歉,现在你还不能保存你的个人简介\n" + "或发送新的推文。\n\n" + @@ -1633,6 +1669,15 @@ if(preferredLanguage == "nl"){ 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Status aan het updaten...", // status of block chain + 'new_account_briefing': 'A new account was created and it is being propagated to the network. ' + + 'Please do not close this window, this might take a few minutes.\n\n' + + 'Your secret key is: *%{secretKey}*\n\n' + + 'It is highly recommended that you take this time to save your secret key. ' + + 'Print it, do a screenshot, use the camera in your phone or write it down to a piece of paper.\n\n' + + 'The secret key will be needed to use this account from different computers. ' + + 'If you ever lose your secret key your account will be locked forever ' + + '(note: ~this is alpha software and it may crash, causing loss of data~).\n\n' + + 'Just wait. The OK button will be shown faster you can say ~decentralization~.', "user_not_yet_accepted": "Other peers have not yet accepted this new user.\n" + "Unfortunately it is not possible to save profile\n" + "or send any posts in this state.\n\n" + @@ -1990,6 +2035,15 @@ if(preferredLanguage == "it"){ 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Aggiornamento in corso...", // status of block chain + 'new_account_briefing': 'A new account was created and it is being propagated to the network. ' + + 'Please do not close this window, this might take a few minutes.\n\n' + + 'Your secret key is: *%{secretKey}*\n\n' + + 'It is highly recommended that you take this time to save your secret key. ' + + 'Print it, do a screenshot, use the camera in your phone or write it down to a piece of paper.\n\n' + + 'The secret key will be needed to use this account from different computers. ' + + 'If you ever lose your secret key your account will be locked forever ' + + '(note: ~this is alpha software and it may crash, causing loss of data~).\n\n' + + 'Just wait. The OK button will be shown faster you can say ~decentralization~.', "user_not_yet_accepted": "Gli altri nodi non hanno ancora accettato il nuovo utente.\n" + "Al momento non puoi salvare il profilo o spedire messaggi.\n" + "Attendi qualche minuto prima di continuare.\n\n" + @@ -2345,6 +2399,15 @@ if(preferredLanguage == "fr"){ 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Mise à jour du statut...", // status of block chain + 'new_account_briefing': 'A new account was created and it is being propagated to the network. ' + + 'Please do not close this window, this might take a few minutes.\n\n' + + 'Your secret key is: *%{secretKey}*\n\n' + + 'It is highly recommended that you take this time to save your secret key. ' + + 'Print it, do a screenshot, use the camera in your phone or write it down to a piece of paper.\n\n' + + 'The secret key will be needed to use this account from different computers. ' + + 'If you ever lose your secret key your account will be locked forever ' + + '(note: ~this is alpha software and it may crash, causing loss of data~).\n\n' + + 'Just wait. The OK button will be shown faster you can say ~decentralization~.', "user_not_yet_accepted": "Les autres pairs n'ont pas encore accepté ce nouvel utilisateur.\n" + "Malheureusement, il n'est pas possible d'enregistrer le profil\n" + "ou envoyer des billets pour le moment.\n\n" + @@ -2703,6 +2766,15 @@ if(preferredLanguage == "ru"){ 'updates_checkout_diff_nfmt': 'Смотри сравнение на GitHub, чтобы узнать каковы изменения:\n %{link}', 'updates_upstream_isnt_changed': 'Соответствующая ветка в исходном репозитории выглядит неизменённой.', "Updating status...": "Обновление информации...", // status of block chain + 'new_account_briefing': 'Новая учётная запись создана и сейчас распространяется по сети. ' + + 'Пожалуйста, не закрывай это окно: это может занять несколько минут.\n\n' + + 'Твой секретный ключ: *%{secretKey}*\n\n' + + 'Настоятельно рекомендуется провести время ожидания, сохраняя этот ключ. ' + + 'Распечатай его, сделай скриншот, сфотографируй телефоном или перепиши на бумагу.\n\n' + + 'Секретный ключ будет необходим для использования на разных устройствах. ' + + 'В случае его утери учётная запись окажется недосягаемой навсегда ' + + '(заметь: ~это альфа-версия и возможны сбои, приводящие к утере данных~).\n\n' + + 'Подожди. Кнопка OK станет доступна быстрее, чем ты произнесёшь ~децентрализация~.', "user_not_yet_accepted": "Другие участники сети еще не получили информацию о новом пользователе.\n" + "К сожалению, сейчас вы не можете редактировать ваш профиль\n" + "или отправлять сообщение.\n\n" + @@ -3065,6 +3137,15 @@ if(preferredLanguage == "de"){ 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Status wird aktualisiert...", // status of block chain + 'new_account_briefing': 'A new account was created and it is being propagated to the network. ' + + 'Please do not close this window, this might take a few minutes.\n\n' + + 'Your secret key is: *%{secretKey}*\n\n' + + 'It is highly recommended that you take this time to save your secret key. ' + + 'Print it, do a screenshot, use the camera in your phone or write it down to a piece of paper.\n\n' + + 'The secret key will be needed to use this account from different computers. ' + + 'If you ever lose your secret key your account will be locked forever ' + + '(note: ~this is alpha software and it may crash, causing loss of data~).\n\n' + + 'Just wait. The OK button will be shown faster you can say ~decentralization~.', "user_not_yet_accepted": "Andere Peers haben diesen Benutzter noch nicht akzeptiert.\n" + "Leider ist es nicht möglich, das Profil zu speichern\n" + "oder Nachrichten zu senden.\n\n" + @@ -3423,6 +3504,15 @@ if(preferredLanguage == "ja"){ 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "ブロックチェーンを更新中…", // status of block chain + 'new_account_briefing': 'A new account was created and it is being propagated to the network. ' + + 'Please do not close this window, this might take a few minutes.\n\n' + + 'Your secret key is: *%{secretKey}*\n\n' + + 'It is highly recommended that you take this time to save your secret key. ' + + 'Print it, do a screenshot, use the camera in your phone or write it down to a piece of paper.\n\n' + + 'The secret key will be needed to use this account from different computers. ' + + 'If you ever lose your secret key your account will be locked forever ' + + '(note: ~this is alpha software and it may crash, causing loss of data~).\n\n' + + 'Just wait. The OK button will be shown faster you can say ~decentralization~.', "user_not_yet_accepted": "この新ユーザーが他のピアーにまだ認証されていない。\n" + "なので、プロファイルの保存やメッセージの投稿は現在不可能です。\n" + "しばらくしてから続行してください。\n\n" + @@ -3780,6 +3870,15 @@ if(preferredLanguage == "pt-BR"){ 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Atualizando estado da Cadeia de Blocos...", // status of block chain "URI_shortener_caption": "URI Shortener", + 'new_account_briefing': 'A new account was created and it is being propagated to the network. ' + + 'Please do not close this window, this might take a few minutes.\n\n' + + 'Your secret key is: *%{secretKey}*\n\n' + + 'It is highly recommended that you take this time to save your secret key. ' + + 'Print it, do a screenshot, use the camera in your phone or write it down to a piece of paper.\n\n' + + 'The secret key will be needed to use this account from different computers. ' + + 'If you ever lose your secret key your account will be locked forever ' + + '(note: ~this is alpha software and it may crash, causing loss of data~).\n\n' + + 'Just wait. The OK button will be shown faster you can say ~decentralization~.', "user_not_yet_accepted": "Outros nós ainda não aceitaram este novo usuário.\n" + "Infelizmente não é possível salvar o perfil\n" + "ou realizar postagens neste estado.\n\n" + @@ -4137,6 +4236,15 @@ if(preferredLanguage == "tr"){ 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Durum güncelleniyor...", // status of block chain + 'new_account_briefing': 'A new account was created and it is being propagated to the network. ' + + 'Please do not close this window, this might take a few minutes.\n\n' + + 'Your secret key is: *%{secretKey}*\n\n' + + 'It is highly recommended that you take this time to save your secret key. ' + + 'Print it, do a screenshot, use the camera in your phone or write it down to a piece of paper.\n\n' + + 'The secret key will be needed to use this account from different computers. ' + + 'If you ever lose your secret key your account will be locked forever ' + + '(note: ~this is alpha software and it may crash, causing loss of data~).\n\n' + + 'Just wait. The OK button will be shown faster you can say ~decentralization~.', "user_not_yet_accepted": "Diğer eşler bu yeni kullanıcıyı henüz kabul etmediler.\n" + "Malesef profili kaydetmek ya da bu durumda\n" + "ileti gönedermek mümkün değil.\n\n" + @@ -4494,6 +4602,15 @@ if(preferredLanguage == "cs"){ 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Aktualizuji stav...", // status of block chain + 'new_account_briefing': 'A new account was created and it is being propagated to the network. ' + + 'Please do not close this window, this might take a few minutes.\n\n' + + 'Your secret key is: *%{secretKey}*\n\n' + + 'It is highly recommended that you take this time to save your secret key. ' + + 'Print it, do a screenshot, use the camera in your phone or write it down to a piece of paper.\n\n' + + 'The secret key will be needed to use this account from different computers. ' + + 'If you ever lose your secret key your account will be locked forever ' + + '(note: ~this is alpha software and it may crash, causing loss of data~).\n\n' + + 'Just wait. The OK button will be shown faster you can say ~decentralization~.', "user_not_yet_accepted": "Ostatní uzly ještě nepřijaly tohoto nového uživatele.\n" + "Proto zatím není možné uložit profil nebo vkládat příspěvky.\n" + "Počkejte prosím pár minut.\n\n" + @@ -4717,12 +4834,7 @@ var fixedLabels = [ ".network label", ".network input", - // login page - ".login ul li span", ".module span", - ".login span", - ".login-local-username", - ".login input", // mobile version // diff --git a/js/interface_login.js b/js/interface_login.js deleted file mode 100644 index a39e97e..0000000 --- a/js/interface_login.js +++ /dev/null @@ -1,37 +0,0 @@ -// interface_login.js -// 2013 Miguel Freitas - -function processCreateUser(username, secretKey) { - defaultScreenName = username; - if (defaultScreenName) - saveScreenName(); - - openModal({ - classAdd: 'new-user', - content: $('#new-user-modal-template').children().clone(true), - title: polyglot.t('propagating_nickname', {username: username}) - }) - .content.find('.secret-key').text(secretKey); - - sendNewUserTransaction(username, processSendnewusertransaction); -} - -function processSendnewusertransaction() { - $( ".login-created-user").show(); -} - -function loginCreatedUser() { - $.MAL.goProfileEdit(); -} - -function initInterfaceLogin() { - initUser(); - initInterfaceCommon(); - checkNetworkStatusAndAskRedirect(); - - interfaceCommonLoginHandlers(); - $( ".create-user").bind( "click", function() { createUserClick( processCreateUser ); } ); - $( ".login-created-user").bind( "click", loginCreatedUser ); -} - - diff --git a/js/mobile_abstract.js b/js/mobile_abstract.js index ae5456c..769d851 100644 --- a/js/mobile_abstract.js +++ b/js/mobile_abstract.js @@ -321,12 +321,12 @@ var MAL = function() } this.goLogin = function() { - if( $.hasOwnProperty("mobile") ) { - $.mobile.navigate( "#login" ); + if ($.hasOwnProperty('mobile')) { + $.mobile.navigate('#login'); } else { - window.location.href = "login.html"; + window.location.hash = '#/login'; } - } + }; this.goNetwork = function() { if( $.hasOwnProperty("mobile") ) { @@ -418,6 +418,38 @@ var MAL = function() } } + this.processCreateAccount = function (peerAlias, secretKey) { + defaultScreenName = peerAlias; + if (defaultScreenName) { + saveScreenName(); + } + + if ($.hasOwnProperty('mobile')) { + $('.secret-key').text(secretKey); + sendNewUserTransaction(peerAlias); + $.mobile.navigate('#new-user-modal'); + } else { + var modal = confirmPopup({ + classAdd: 'new-account-briefing', + txtTitle: polyglot.t('propagating_nickname', {username: peerAlias}), + txtMessage: polyglot.t('new_account_briefing', {secretKey: secretKey}), + txtConfirm: polyglot.t('Login'), + cbConfirm: $.MAL.goProfileEdit, + addBlackout: true, + removeCancel: true, + removeClose: true + }); + + modal.content.find('.confirm').attr('disabled', true); + + sendNewUserTransaction(peerAlias, + function (accountCreatedModal) { + accountCreatedModal.content.find('.confirm').attr('disabled', false); + }, modal + ); + } + }; + this.changedUser = function() { if( $.hasOwnProperty("mobile") ) { timelineChangedUser(); diff --git a/js/tmobile.js b/js/tmobile.js index 517b9d6..602dc7c 100644 --- a/js/tmobile.js +++ b/js/tmobile.js @@ -8,7 +8,6 @@ var handlersInstalled = false; function initializeTwister( redirectNetwork, redirectLogin, cbFunc, cbArg ) { if( !handlersInstalled ) { interfaceNetworkHandlers(); - interfaceCommonLoginHandlers(); installUserSearchHandler(); installProfileEditHandlers(); // install scrollbottom handler to load more posts as needed @@ -253,11 +252,12 @@ var router=new $.mobile.Router( }); }, login: function(type,match,ui) { + if (!$('#login .content').children().length) + $('#login .content').append(twister.tmpl.loginMC.clone(true)).trigger('create'); $.mobile.showPageLoadingMsg(); initializeTwister( true, false, function() { $.mobile.hidePageLoadingMsg(); - $("select.local-usernames.login-user").selectmenu("refresh", true); - installCreateUserClick(); + $("select.local-usernames").selectmenu("refresh", true); }); }, network: function(type,match,ui) { @@ -421,19 +421,6 @@ function installRetransmitConfirmClick() { }); } -function installCreateUserClick() { - $( ".create-user").unbind('click').click( function(e) { - createUserClick( function(username, secretKey) { - defaultScreenName = username; - if(defaultScreenName) { - saveScreenName(); - } - $(".secret-key").text(secretKey); - sendNewUserTransaction( username, function() {} ); - $.mobile.navigate( "#new-user-modal" ); } ); - }); -} - function installUserSearchHandler() { $('.userMenu-search-field') .off('click input') @@ -600,4 +587,3 @@ $(document).bind('mobileinit', function () { $.mobile.defaultDialogTransition = 'none'; $.mobile.defaultPageTransition = 'none'; }); - diff --git a/js/twister_network.js b/js/twister_network.js index bbfb2df..7f47a58 100644 --- a/js/twister_network.js +++ b/js/twister_network.js @@ -328,12 +328,9 @@ function initInterfaceNetwork() { initMentionsCount(); initDMsCount(); }); + } else { + $('.userMenu-profile > a').attr('href', '#/login').text(polyglot.t('Login')); } - else - { - $(".userMenu-profile > a").text(polyglot.t("Login")); - $(".userMenu-profile > a").attr("href","login.html"); - } }); networkUpdate(); setInterval("networkUpdate()", 2000); diff --git a/js/twister_user.js b/js/twister_user.js index 77a419a..4d28c1c 100644 --- a/js/twister_user.js +++ b/js/twister_user.js @@ -6,47 +6,48 @@ // Load/save profile (profile-edit.html) var defaultScreenName = undefined; -var localUsernames = []; var lastPostId = undefined; // basic user functions // ------------------------------- -function initUser(cbFunc, cbArg) { - loadWalletlUsers( function() { - var $localUsersList = $("select.local-usernames"); - if( $localUsersList.length ) { - for( var i = 0; i < localUsernames.length; i++ ) { - var $existingOption = $localUsersList.find("option[value='" + localUsernames[i] + "']"); - if( !$existingOption.length ) { - var $userOption = $("
      @@ -275,6 +274,7 @@ ×
      +
      diff --git a/options.html b/options.html index a915fbc..7035574 100644 --- a/options.html +++ b/options.html @@ -38,7 +38,6 @@ Options Network config Setup account - Change user
      diff --git a/profile-edit.html b/profile-edit.html index 5afdaf4..dcbe2e6 100644 --- a/profile-edit.html +++ b/profile-edit.html @@ -50,7 +50,6 @@ Options Setup account Network config - Change user @@ -95,6 +94,7 @@ × +
      diff --git a/theme_calm/css/style.css b/theme_calm/css/style.css index 835dfbb..6d538c5 100644 --- a/theme_calm/css/style.css +++ b/theme_calm/css/style.css @@ -1784,8 +1784,7 @@ textarea.splited-post { padding: 10px; border-radius: 6px; } -.singleBlock h2, .header-bold -{ +.singleBlock h2 { font-weight: bold; line-height: 40px; color: rgba( 255, 255, 255, 1 ); @@ -1856,83 +1855,6 @@ textarea.splited-post { margin-right: 20px; } -/************************************* -************* LOGIN PAGE ************* -**************************************/ - -.login .header-bold { - display: block; - width: 500px; - margin: 0px auto 12px auto; -} - -.login .module { - padding: 20px; - width: 500px; - margin: 10px auto; - border: 3px solid #c7cdda; - border-radius: 6px; -} -.login .module p { - font: 14px "Open Sans", sans-serif; - margin-bottom: 5px; - -} -.login .module input { - padding: 5px 10px; - font: 13px/24px "Open sans"; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - background: #f3f3f3; -} -.login .module input:focus { - background: #fff; - transition: background-color 100ms linear; -} -.login .module select { - height: 30px; - font: 13px/24px "Open sans"; - text-align: center; - padding: 3px 30px 3px 10px; - margin: 0; - background: #fff url(../img/form-arrow-down-black.png) no-repeat right center; - border: 1px solid #ccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -/* hide default apperance select element and arrow in firefox */ - -webkit-appearance:none; - -moz-appearance:none; - appearance:none; - text-indent: 0.01px; - text-overflow: ''; -/* end */ -} - -.login .module span.availability { - margin-left: 10px; - font: italic 16px "Open sans"; - color: #45474d; -} -.with-nickname, .import-secret-key, .create-user { - margin-top: 10px; -} - -.login .module input:focus::-webkit-input-placeholder { - color: #fff; -} -.login .module input:focus:-moz-placeholder { - color: #fff; -} -.login .module input:focus::-moz-placeholder { - color: #fff; -} -.login .module input::-ms-input-placeholder { - color: #fff; -} - /************************************* ************* POPUP MODAL ************ **************************************/ @@ -1963,12 +1885,12 @@ textarea.splited-post { font-weight: bold; } -.modal-wrapper .modal-content { +.modal-content { background: #fff; overflow-y: auto; } -.modal-wrapper .modal-blackout { +.modal-blackout { background: rgba(0,0,0, .6); z-index: -1; position: fixed; @@ -2056,6 +1978,62 @@ textarea.splited-post { margin-top: 4px; } +/************************************* +******* LOGIN TO ACCOUNT MODAL ******* +**************************************/ + +.login-modal.modal-wrapper { + height: auto; /*about 580px*/ + margin-top: -290px; +} + +.login-modal .module { + margin: 4px; +} + +.login-modal .module > div { + width: 100%; + margin: 4px 0; + padding: 4px 12px; +} + +.login-modal .module > div:last-child { + text-align: right; + margin: 8px 0; +} + +.login-modal .module input { + border: solid 1px rgba(0, 0, 0, .3); + border-radius: 4px; + width: 320px; + margin: 12px 16px; + padding: 2px 4px; +} + +.login-modal .module select { + border: solid 1px rgba(0, 0, 0, .3); + border-radius: 4px; + width: 310px; + margin: 12px 16px; + padding: 2px 4px; +} + +.login-modal .module input:focus, .login-modal .module select:focus { + border: solid 1px rgba(118, 145, 206, .8); + box-shadow: 0 0 10px rgba(0, 0, 0, .3); +} + +.login-modal .module .secret-key { + width: 500px; +} + +.login-modal .module .availability { + font: italic 13px "Open sans"; + color: #45474D; + display: inline-block; + margin-left: 16px; +} + /************************************* ******** DIRECT MESSAGES MODAL ******* **************************************/ @@ -2260,38 +2238,6 @@ textarea.splited-post { margin: 8px 8px 0; } -/************************************* -*********** NEW USER MODAL *********** -**************************************/ - -.new-user.modal-wrapper { - width: 720px; - height: 580px; - margin: -290px 0 0 -360px; -} - -.new-user .modal-content { - padding: 25px; -} - -.new-user .modal-close { - display: none; -} - -.new-user .text { - margin: 0 0 15px 0; -} - -.new-user .emphasis { - font-size: 18px; - text-align: center; -} - -.new-user .secret-key { - color: rgba(.5,0,0, 1.0); - font-weight: bold; -} - /************************************* ************ HASHTAG MODAL *********** **************************************/ @@ -2439,7 +2385,7 @@ textarea.splited-post { } .prompt-wrapper .modal-buttons { - margin: 4px 16px; + margin: 4px 16px 16px; text-align: right; } @@ -2459,12 +2405,19 @@ textarea.splited-post { .confirm-popup .message { text-align: center; - margin: 12px; + padding: 12px; } .confirm-popup .modal-buttons { text-align: center; - padding: 4px; +} + +/************************************* +********* NEW ACCOUNT POPUP ********** +**************************************/ + +.new-account-briefing.prompt-wrapper { + margin-top: -164px; } /************************************* diff --git a/theme_nin/css/style.css b/theme_nin/css/style.css index 14e9279..dd551e0 100644 --- a/theme_nin/css/style.css +++ b/theme_nin/css/style.css @@ -1312,75 +1312,6 @@ h3 .isFollowing:after { display: none; } -/************************************* -************* LOGIN PAGE ************* -**************************************/ - -.login .header-bold { - display: block; - width: 720px; - margin: 0px auto 12px auto; -} - -.login .module { - display: block; - width: 720px; - padding: 32px 40px; - margin: 8px auto; - background: #fff; -} - -.login .module p { - margin-bottom: 5px; -} - -.login .module input { - padding: 5px 10px; - background: #f3f3f3; - border: solid 1px #dcdcdc; - transition: box-shadow 0.3s, border 0.3s; - font-size: 14px; -} - -.login .module input:focus, .login .module select:focus { - background: #fff; - transition: background-color 100ms linear; - border-bottom: solid 2px #B4C669; -} - -.login .module select { - height: 30px; - padding: 3px 30px 3px 10px; - margin: 0; - border: 1px solid #ccc; - font-size: 14px; -} - -.login .module span.availability { - margin-left: 10px; - color: #45474d; -} - -.with-nickname, .import-secret-key, .create-user { - margin-top: 10px; -} - -.login .module:nth-child(2) div , -.login .module:nth-child(3) div:nth-child(2), -.login .secret-key-import, -.login .username-import { - margin-top: 20px; - margin-bottom: 20px; - margin-left: 16px; -} - -.login .create-user, -.login .import-secret-key { - display: block; - margin-left: auto; - margin-right: 16px; -} - /************** BUTTONS *********** */ /* line 65, ../sass/_commons.sass */ button, .mini-profile-actions span, a.button { @@ -2638,6 +2569,15 @@ ol.toptrends-list a:hover { margin: 8px 12px 20px; } +/************************************* +********* NEW ACCOUNT POPUP ********** +**************************************/ + +.new-account-briefing.prompt-wrapper { + top: 50%; + margin-top: -164px; +} + /****** FOLLOWING-CONFIG PROMPT ******/ .following-config-modal.prompt-wrapper { @@ -2697,6 +2637,62 @@ ol.toptrends-list a:hover { padding-bottom: 6px; } +/************************************* +******* LOGIN TO ACCOUNT MODAL ******* +**************************************/ + +.login-modal.modal-wrapper { + width: 580px; + height: auto; /*about 532px*/ + margin: -270px 0 0 -290px; +} + +.login-modal .modal-content { + padding: 0; +} + +.login-modal .module { + margin: 4px; +} + +.login-modal .module > div { + margin: 4px 0; + padding: 4px 12px; +} + +.login-modal .module > div:last-child { + text-align: right; + margin: 8px 0; +} + +.login-modal .module input { + border: 1px solid rgba(0, 0, 0, .1); + width: 320px; + margin: 12px 16px; + padding: 2px 4px; +} + +.login-modal .module select { + border: 1px solid rgba(0, 0, 0, .1); + width: 310px; + margin: 12px 16px; + padding: 2px 4px; +} + +.login-modal .module input:focus, .login-modal .module select:focus { + border-bottom: solid 1px #B4C669; +} + +.login-modal .module .secret-key { + width: 500px; +} + +.login-modal .module .availability { + color: #45474D; + display: inline-block; + margin-left: 16px; +} + /****** DIRECT MESSAGES MODAL********* */ /* line 736, ../sass/style.sass */ .modal-wrapper.directMessages { @@ -3032,39 +3028,6 @@ ol.toptrends-list a:hover { margin: 8px 8px 0; } -/********* NEW USER MODAL************* */ - -.new-user.modal-wrapper { - width: 720px; - height: 580px; - margin: -290px 0 0 -360px; -} - -.new-user .modal-content { - padding: 25px; -} - -/* line 870, ../sass/style.sass */ -.new-user .modal-close { - display: none; -} -/* line 872, ../sass/style.sass */ -.new-user .text { - margin: 0 0 15px 0; -} -/* line 874, ../sass/style.sass */ -.new-user .emphasis { - text-align: center; -} -/* line 877, ../sass/style.sass */ -.new-user .secret-key { - display: block; - margin-top: 8px; - color: black; - font-weight: bold; - font-size: 110%; -} - /******** HASHTAG MODAL********** */ /* line 884, ../sass/style.sass */ .modal-wrapper.hashtag-modal { diff --git a/theme_nin/sass/_login.sass b/theme_nin/sass/_login.sass deleted file mode 100644 index 350832c..0000000 --- a/theme_nin/sass/_login.sass +++ /dev/null @@ -1,55 +0,0 @@ -.login .header-bold - display: block - width: 720px - margin: 0px auto 12px auto - -.login .module - display: block - width: 720px - padding: 32px 40px - margin: 8px auto - background: white - -.login .module p - margin-bottom: 5px - -.login .module input - padding: 5px 10px - background: #f3f3f3 - border: solid 1px #dcdcdc - transition: box-shadow 0.3s, border 0.3s - font-size: 14px - -.login .module input:focus, -.login .module select:focus - background: white - transition: background-color 100ms linear - border-bottom: solid 2px $color-green - -.login .module select - height: 30px - padding: 3px 30px 3px 10px - margin: 0 - border: 1px solid #ccc - font-size: 14px - -.login .module span.availability - margin-left: 10px - color: #45474d - -.with-nickname, .import-secret-key, .create-user - margin-top: 10px - -.login .module:nth-child(2) div, -.login .module:nth-child(3) div:nth-child(2), -.login .secret-key-import, -.login .username-import - margin-top: 20px - margin-bottom: 20px - margin-left: 16px - -.login .create-user, -.login .import-secret-key - display: block - margin-left: auto - margin-right: 16px diff --git a/theme_nin/sass/style.sass b/theme_nin/sass/style.sass index 1c951c7..0eda3a2 100755 --- a/theme_nin/sass/style.sass +++ b/theme_nin/sass/style.sass @@ -8,7 +8,6 @@ @import _profile @import _postboard @import _following -@import _login @import _network @import _commons @import _tabs @@ -784,6 +783,43 @@ ol.toptrends-list float: left margin: 4px + +.inline-warn + background-color: #FEFEDF + padding: 10px + .close + float: right + font-size: 1.2em + color: #E34F42 + cursor: pointer + margin: -8px 2px 8px 8px + .text + font-size: 0.8em + text-align: center + .options + font-size: 0.8em + text-align: right + margin-top: 4px + +/************************************* +*********** CONFIRM POPUP ************ +**************************************/ + +.confirm-popup + &.prompt-wrapper + top: 30% + .message + margin: 8px 12px 20px + +/************************************* +********* NEW ACCOUNT POPUP ********** +**************************************/ + +.new-account-briefing + &.prompt-wrapper + top: 50% + margin-top: -164px + /************ FOLLOWING-CONFIG MODAL **********/ .prompt-wrapper.following-config-modal @@ -822,6 +858,44 @@ ol.toptrends-list .post-area padding-bottom: 6px +/************************************* +******* LOGIN TO ACCOUNT MODAL ******* +**************************************/ + +.login-modal + &.modal-wrapper + width: 580px + height: auto /*about 532px*/ + margin: -270px 0 0 -290px + .modal-content + padding: 0 + .module + margin: 4px + > div + margin: 4px 0 + padding: 4px 12px + > div:last-child + text-align: right + margin: 8px 0 + input + border: 1px solid rgba(0, 0, 0, .1) + width: 320px + margin: 12px 16px + padding: 2px 4px + select + border: 1px solid rgba(0, 0, 0, .1) + width: 310px + margin: 12px 16px + padding: 2px 4px + input:focus, select:focus + border-bottom: solid 1px #B4C669 + .secret-key + width: 500px + .availability + color: #45474D + display: inline-block + margin-left: 16px + /****** DIRECT MESSAGES MODAL**********/ .modal-wrapper.directMessages diff --git a/tmobile.html b/tmobile.html index e9a7699..41328d3 100644 --- a/tmobile.html +++ b/tmobile.html @@ -171,55 +171,7 @@

      twister login

      -
      - - -
      +
      + +
      +
      + Existing local users +
      +
      + +
      +
      + +
      +
      +
      + +
      + Or... + + + +
      + Or... + + +
      From 61d37b0431026bfb7bba885e18e61b963db6d81f Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Thu, 2 Feb 2017 20:15:30 +0500 Subject: [PATCH 44/54] fix URI shortener caption localization --- home.html | 2 +- js/interface_common.js | 4 ++-- js/interface_localization.js | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/home.html b/home.html index 1100eaf..d83a2fe 100644 --- a/home.html +++ b/home.html @@ -49,7 +49,7 @@ Fulano da Silva View - URI shortener + URI_shortener Options Network config Setup account diff --git a/js/interface_common.js b/js/interface_common.js index c5f61c4..25d2296 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -1038,7 +1038,7 @@ function openRequestShortURIForm(event) { function showURIPair(uriLong, uriShort) { // FIXME req if (uriShort) alertPopup({ - txtTitle: 'URI shortener', + txtTitle: polyglot.t('URI_shortener'), txtMessage: uriLong + ' — `' + uriShort + '`' }); else @@ -1047,7 +1047,7 @@ function showURIPair(uriLong, uriShort) { // FIXME req function showURIShortenerErrorRPC(ret) { alertPopup({ - txtTitle: 'URI shortener', + txtTitle: polyglot.t('URI_shortener'), txtMessage: 'something went wrong. RPC error message:\n' + (ret && ret.message ? ret.message : ret) }); } diff --git a/js/interface_localization.js b/js/interface_localization.js index 06f36e8..abf858c 100644 --- a/js/interface_localization.js +++ b/js/interface_localization.js @@ -3869,7 +3869,6 @@ if(preferredLanguage == "pt-BR"){ 'updates_checkout_diff_nfmt': 'Checkout the diff on GitHub to learn what is changed:\n %{link}', 'updates_upstream_isnt_changed': 'A corresponding branch of the source repository seems to have not changed.', "Updating status...": "Atualizando estado da Cadeia de Blocos...", // status of block chain - "URI_shortener_caption": "URI Shortener", 'new_account_briefing': 'A new account was created and it is being propagated to the network. ' + 'Please do not close this window, this might take a few minutes.\n\n' + 'Your secret key is: *%{secretKey}*\n\n' From cf814dfd188c95c869bfd89046d1335bea5456e9 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Wed, 29 Mar 2017 20:21:33 +0500 Subject: [PATCH 45/54] add hiding of twists' counters in DMs on mark-all-as-read event --- js/twister_directmsg.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/js/twister_directmsg.js b/js/twister_directmsg.js index e160b45..c21877d 100644 --- a/js/twister_directmsg.js +++ b/js/twister_directmsg.js @@ -179,13 +179,14 @@ function openCommonDMsModal() { modal.self.find('.mark-all-as-read') .css('display', 'inline') .attr('title', polyglot.t('Mark all as read')) - .on('click', function() { + .on('click', function (event) { for (var user in _newDMsPerUser) { if (user[0] !== '*') _newDMsPerUser[user] = 0; } saveDMsToStorage(); $.MAL.updateNewDMsUI(getNewDMsCount()); + $(event.target).closest('.directMessages').find('.direct-messages-list .messages-qtd').hide(); }) ; } @@ -236,13 +237,14 @@ function openGroupMessagesModal(groupAlias) { modal.self.find('.mark-all-as-read') .css('display', 'inline') .attr('title', polyglot.t('Mark all as read')) - .on('click', function() { + .on('click', function (event) { for (var user in _newDMsPerUser) { if (user[0] === '*') _newDMsPerUser[user] = 0; } saveDMsToStorage(); $.MAL.updateNewGroupDMsUI(getNewGroupDMsCount()); + $(event.target).closest('.groupMessages').find('.direct-messages-list .messages-qtd').hide(); }) ; } else { From e406822f17cde24887e779450b8ca8995d5b7f57 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Fri, 16 Jun 2017 21:10:31 +0500 Subject: [PATCH 46/54] add reset of new DMs counter on click on the show-new-twists button inside mentions' modal --- js/interface_common.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/js/interface_common.js b/js/interface_common.js index 25d2296..c15f353 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -2752,9 +2752,13 @@ function initInterfaceCommon() { $('.userMenu-favs a').on('click', openFavsModal); $('.favs-from-user').on('click', openFavsModal); - $('#hashtag-modal-template .postboard-news').on('click', function () { - $(this).hide(); - displayQueryPending($('.hashtag-modal .postboard-posts')); + $('#hashtag-modal-template .postboard-news').on('click', function (event) { + var elem = $(event.target).hide().closest('.postboard').find('.postboard-posts'); + + displayQueryPending(elem); + + if (elem.attr('data-request-id') === defaultScreenName + '@mention') + resetMentionsCount(); }); getElem('.latest-activity', true).on('mouseup', From ff8b99f9397ad24a6e1c9f8aa898940b2cf11534 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Fri, 16 Jun 2017 22:46:47 +0500 Subject: [PATCH 47/54] fix storing of ID of updateQueryModal() interval calls --- js/interface_common.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/interface_common.js b/js/interface_common.js index c15f353..329ebe9 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -611,12 +611,12 @@ function setupQueryModalUpdating(postboard, query, resource) { // then we may possibly collect more posts on our second try by waiting more. req.timeoutArgs = [10000, 2000, 3]; - postboard.attr('data-request-interval', setInterval(updateQueryModal, 5000, req)); // FIXME + req.interval = setInterval(updateQueryModal, 5000, req); } function updateQueryModal(req) { if (!isModalWithElemExists(req.postboard)) { - clearInterval(req.postboard.attr('data-request-interval')); + clearInterval(req.interval); clearQueryProcessed(req.id); return; } From f28d4f41533508d54b98004da8f451e8ca0ed8b8 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Sat, 17 Jun 2017 23:59:30 +0500 Subject: [PATCH 48/54] add session caching of results of mentions' and hashtags' searchings --- js/interface_common.js | 66 +++++---------- js/tmobile.js | 31 +++---- js/twister_actions.js | 186 ++++++++++++++++++++++++----------------- js/twister_newmsgs.js | 36 +++++--- 4 files changed, 164 insertions(+), 155 deletions(-) diff --git a/js/interface_common.js b/js/interface_common.js index 329ebe9..36179dd 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -17,6 +17,7 @@ var twister = { root: $('
      ') // templates should be detached from DOM and attached here; use extractTemplate() }, modal: {}, + res: {}, // reses for various reqs are cached here var: { localAccounts: [], updatesCheckClient: {} @@ -591,37 +592,20 @@ function openHashtagModalFromSearchHandler(hashtag) { title: '#' + hashtag }); - setupQueryModalUpdating(modal.content.find('.postboard-posts'), hashtag, 'hashtag'); + var req = queryStart(modal.content.find('.postboard-posts'), hashtag, 'hashtag'); + modal.content.find('.postboard-news').on('click', {req: req}, handleClickDisplayPendingTwists); } -function setupQueryModalUpdating(postboard, query, resource) { - var req = { - postboard: postboard, - query: query, - resource: resource, - id: query + '@' + resource - }; - - postboard.attr('data-request-id', req.id); +function handleClickDisplayPendingTwists(event) { + if (!event || !event.data || !event.data.req) + return; - requestQuery(req); + $(event.target).hide(); - // use extended timeout parameters on modal refresh (requires twister_core >= 0.9.14). - // our first query above should be faster (with default timeoutArgs of twisterd), - // then we may possibly collect more posts on our second try by waiting more. - req.timeoutArgs = [10000, 2000, 3]; + queryPendingDraw(event.data.req); - req.interval = setInterval(updateQueryModal, 5000, req); -} - -function updateQueryModal(req) { - if (!isModalWithElemExists(req.postboard)) { - clearInterval(req.interval); - clearQueryProcessed(req.id); - return; - } - - requestQuery(req); + if (typeof event.data.cbFunc === 'function') + event.data.cbFunc(event.data.cbReq); } function openFavsModal(event) { @@ -654,7 +638,8 @@ function openFavsModalHandler(peerAlias) { title: polyglot.t('users_favs', {username: peerAlias}) }); - setupQueryModalUpdating(modal.content.find('.postboard-posts'), peerAlias, 'fav'); + var req = queryStart(modal.content.find('.postboard-posts'), peerAlias, 'fav'); + modal.content.find('.postboard-news').on('click', {req: req}, handleClickDisplayPendingTwists); } function openMentionsModal(event) { @@ -686,18 +671,16 @@ function openMentionsModalHandler(peerAlias) { title: polyglot.t('users_mentions', {username: peerAlias}) }); - setupQueryModalUpdating(modal.content.find('.postboard-posts'), peerAlias, 'mention'); + var req = queryStart(modal.content.find('.postboard-posts'), peerAlias, 'mention'); + modal.content.find('.postboard-news') + .on('click', + {req: req, cbFunc: (peerAlias === defaultScreenName) ? resetMentionsCount : ''}, + handleClickDisplayPendingTwists + ) + ; - if (peerAlias === defaultScreenName) { - // obtain already cached mention posts from twister_newmsgs.js - processQuery({ - postboard: modal.content.find('.postboard-posts'), - query: defaultScreenName, - resource: 'mention', - posts: getMentionsData() - }); + if (peerAlias === defaultScreenName) resetMentionsCount(); - } } function openFollowersModal(peerAlias) { @@ -2752,15 +2735,6 @@ function initInterfaceCommon() { $('.userMenu-favs a').on('click', openFavsModal); $('.favs-from-user').on('click', openFavsModal); - $('#hashtag-modal-template .postboard-news').on('click', function (event) { - var elem = $(event.target).hide().closest('.postboard').find('.postboard-posts'); - - displayQueryPending(elem); - - if (elem.attr('data-request-id') === defaultScreenName + '@mention') - resetMentionsCount(); - }); - getElem('.latest-activity', true).on('mouseup', {feeder: '.latest-activity'}, handleClickOpenConversation); diff --git a/js/tmobile.js b/js/tmobile.js index 602dc7c..6248d27 100644 --- a/js/tmobile.js +++ b/js/tmobile.js @@ -528,27 +528,22 @@ function encode_utf8(s) { return s; } -var tmobileQueryReq = {}; // FIXME need to rework all that searching +var tmobileQueryReq; -function setupHashtagOrMention(postboard, tag, res) { +function setupHashtagOrMention(board, query, resource) { $.MAL.setPostTemplate( $("#post-template-home") ); $.mobile.showPageLoadingMsg(); + board.empty(); - var reqId = tag + '@' + res; + var req = queryStart(board, query, resource); - clearQueryProcessed(reqId); + twister.res[req].boardAutoAppend = true; + twister.res[req].skidoo = function (req) { + var curPage = $.mobile.activePage.attr('id'); + return (curPage !== 'mentions' && curPage !== 'hashtag') || req !== tmobileQueryReq; + }; - tmobileQueryReq.postboard = postboard.text('').attr('data-request-id', reqId); - tmobileQueryReq.query = tag; - tmobileQueryReq.resource = res; - - if (tag === defaultScreenName && res === 'mention') { - // obtain already cached mention posts from twister_newmsgs.js - tmobileQueryReq.posts = getMentionsData(); - processQuery(tmobileQueryReq); - } - - requestQuery(tmobileQueryReq); + tmobileQueryReq = req; } // every 2 seconds do something page specific. @@ -570,12 +565,6 @@ function tmobileTick() { } }, {} ); } - - else if (curPage === 'mentions' || curPage === 'hashtag') { - autoUpdateQuery = true; - requestQuery(tmobileQueryReq); - } - if (curPage === 'dmchat') requestDmConversation($('#dmchat .direct-messages-thread'), dmChatUser); } diff --git a/js/twister_actions.js b/js/twister_actions.js index a8ee43c..0431b64 100644 --- a/js/twister_actions.js +++ b/js/twister_actions.js @@ -12,9 +12,6 @@ var postsPerRefresh = 10; var maxExpandPost = 8; var maxExpandPostTop = 4; -var _queryProcessedMap = {}; -var _queryPendingPosts = {}; -var autoUpdateQuery = false; // ---------------- @@ -439,55 +436,120 @@ function updateProfilePosts(postsView, username, useGetposts) { }); } -function clearQueryProcessed(id) { - if (!id) return; +function queryStart(board, query, resource) { + var req = query + '@' + resource; + + if (typeof twister.res[req] !== 'object') + twister.res[req] = { + board: board, + query: query, + resource: resource, + twists: { + cached: {}, + pending: [] + } + }; + else { + twister.res[req].board = board; + for (var i in twister.res[req].twists.cached) + if (twister.res[req].twists.pending.indexOf(i) === -1) + twister.res[req].twists.pending.push(i); + + queryPendingDraw(req) + } + + queryRequest(req); + + // use extended timeout parameters on modal refresh (requires twister_core >= 0.9.14). + // our first query above should be faster (with default timeoutArgs of twisterd), + // then we may possibly collect more posts on our second try by waiting more. + twister.res[req].timeoutArgs = [10000, 2000, 3]; + + twister.res[req].interval = setInterval(queryTick, 5000, req); - _queryProcessedMap[id] = {}; - _queryPendingPosts[id] = []; + return req; } -function requestQuery(req) { - req.postboard.closest('div').find('.postboard-loading').show(); - if (req.resource === 'fav'){ - twisterRpc("getfavs", [req.query, 1000], function(req, posts){ - req.posts = posts; - processQuery(req) - }, req); - } - else { - dhtget(req.query, req.resource, 'm', - function (req, posts) { - req.posts = posts; - processQuery(req); - }, - req, - req.timeoutArgs - ); +function queryTick(req) { + if (typeof twister.res[req].skidoo === 'function' ? twister.res[req].skidoo(req) + : !isModalWithElemExists(twister.res[req].board)) { + clearInterval(twister.res[req].interval); + queryClear(req); + return; } + + queryRequest(req); } -function processQuery(req) { - if (!isModalWithElemExists(req.postboard) || !req.posts || !req.posts.length) +function queryClear(req) { + if (!req || !twister.res[req] || !twister.res[req].twists) return; - if (!req.id) - req.id = req.query + '@' + req.resource; - if (typeof _queryProcessedMap[req.id] !== 'object') - _queryProcessedMap[req.id] = {}; - if (typeof _queryPendingPosts[req.id] !== 'object') - _queryPendingPosts[req.id] = []; + twister.res[req].twists.pending = []; +} - for (var i = req.posts.length - 1; i >= 0; i--) { - var userpost = req.posts[i].userpost; +function queryRequest(req) { + twister.res[req].board.closest('div').find('.postboard-loading').show(); - if (userpost.fav) - userpost = userpost.fav; + if (twister.res[req].resource === 'fav') + twisterRpc('getfavs', [twister.res[req].query, 1000], + queryProcess, req); + else + dhtget(twister.res[req].query, twister.res[req].resource, 'm', + queryProcess, req, twister.res[req].timeoutArgs); +} + +function queryProcess(req, twists) { + queryPendingPush(req, twists); + + if (typeof twister.res[req].skidoo === 'function' ? twister.res[req].skidoo(req) + : !isModalWithElemExists(twister.res[req].board)) + return; + + if (twister.res[req].twists.pending.length) { + if (twister.res[req].board.children().length && !$.mobile + && $.Options.showDesktopNotifPostsModal.val === 'enable' + && (twister.res[req].resource !== 'mention' || twister.res[req].query !== defaultScreenName)) + $.MAL.showDesktopNotification({ + body: polyglot.t('You got') + ' ' + polyglot.t('new_posts', twister.res[req].twists.pending.length) + ' ' + + polyglot.t('in search result') + '.', + tag: 'twister_notification_new_posts_modal', + timeout: $.Options.showDesktopNotifPostsModalTimer.val, + funcClick: (function() { + focusModalWithElement(twister.res[this.req].board, + function (req) { + twister.res[req].board.closest('.postboard') + .find('.postboard-news').click(); + }, + this.req + ); + }).bind({req: req}) + }); - var key = userpost.n + ';' + userpost.time; + if (!twister.res[req].board.children().length || twister.res[req].boardAutoAppend) + queryPendingDraw(req); + else { + twister.res[req].board.closest('div').find('.postboard-news') // FIXME we'd replace 'div' with '.postboard' but need to dig through tmobile first + .text(polyglot.t('new_posts', twister.res[req].twists.pending.length)) + .fadeIn('slow') + ; + twister.res[req].board.closest('div').find('.postboard-loading').hide(); + } + } +} + +function queryPendingPush(req, twists) { + if (!req || !twister.res[req] || !twists || !twists.length) + return; + + for (var i = twists.length - 1; i >= 0; i--) { + var userpost = twists[i].userpost; + var j = userpost.n + '/' + userpost.time; - if (!_queryProcessedMap[req.id][key]) { - _queryProcessedMap[req.id][key] = true; + if (userpost.fav) + userpost = userpost.fav; + if (typeof twister.res[req].twists.cached[j] === 'undefined') { if ((typeof userpost.msg !== 'string' || userpost.msg === '') && (typeof userpost.rt !== 'object' || typeof userpost.rt.msg !== 'string' || userpost.rt.msg === '')) @@ -500,53 +562,27 @@ function processQuery(req) { langFilterData = filterLang(userpost.rt.msg); if ($.Options.filterLangSimulate.val) { - req.posts[i].langFilter = langFilterData; + twists[i].langFilter = langFilterData; } else { if (!langFilterData.pass) continue; } } - _queryPendingPosts[req.id].push(req.posts[i]); - } - } - - if (_queryPendingPosts[req.id].length) { - if (!$.hasOwnProperty('mobile') && $.Options.showDesktopNotifPostsModal.val === 'enable' - && (req.resource !== 'mention' || req.query !== defaultScreenName)) { - $.MAL.showDesktopNotification({ - body: polyglot.t('You got') + ' ' + polyglot.t('new_posts', _queryPendingPosts[req.id].length) + ' ' - + polyglot.t('in search result') + '.', - tag: 'twister_notification_new_posts_modal', - timeout: $.Options.showDesktopNotifPostsModalTimer.val, - funcClick: (function() { - focusModalWithElement(this.postboard, - function (req) { - req.postboard.closest('.postboard').find('.postboard-news').hide(); - displayQueryPending(req.postboard); - }, {postboard: this.postboard} - ); - }).bind({postboard: req.postboard}) - }); - } - - if (!req.postboard.children().length || autoUpdateQuery) { - displayQueryPending(req.postboard); - } else { - req.postboard.closest('div').find('.postboard-news') // FIXME we'd replace 'div' with '.postboard' but need to dig through tmobile first - .text(polyglot.t('new_posts', _queryPendingPosts[req.id].length)) - .fadeIn('slow') - ; - req.postboard.closest('div').find('.postboard-loading').hide(); + twister.res[req].twists.cached[j] = twists[i]; + twister.res[req].twists.pending.push(j); } } } -function displayQueryPending(postboard) { - var reqId = postboard.attr('data-request-id'); +function queryPendingDraw(req) { + var twists = []; + for (var i = 0; i < twister.res[req].twists.pending.length; i++) + twists.push(twister.res[req].twists.cached[twister.res[req].twists.pending[i]]); + + attachPostsToStream(twister.res[req].board, twists, false); - attachPostsToStream(postboard, _queryPendingPosts[reqId], false); - _queryPendingPosts[reqId] = []; + queryClear(req); $.MAL.postboardLoaded(); } diff --git a/js/twister_newmsgs.js b/js/twister_newmsgs.js index 535c3ed..3691a47 100644 --- a/js/twister_newmsgs.js +++ b/js/twister_newmsgs.js @@ -30,10 +30,12 @@ function processMention(user, mentionTime, data) { _lastMentionTime = Math.max(mentionTime, _lastMentionTime); data.isNew = true; - var reqId = defaultScreenName + '@mention'; - if (typeof _queryPendingPosts[reqId] !== 'object') - _queryPendingPosts[reqId] = []; - _queryPendingPosts[reqId].push(data); + var req = defaultScreenName + '@mention'; + var j = data.userpost.n + '/' + data.userpost.time; + if (typeof twister.res[req].twists.cached[j] === 'undefined') { + twister.res[req].twists.cached[j] = data; + twister.res[req].twists.pending.push(j); + } } _knownMentions[key] = {mentionTime: mentionTime, data: data}; purgeOldMentions(); @@ -114,15 +116,13 @@ function requestMentionsCount() { tag: 'twister_notification_new_mentions', timeout: $.Options.showDesktopNotifMentionsTimer.val, funcClick: function () { - var postboardSelector = - '.postboard-posts[data-request-id="' + defaultScreenName + '@mention"]'; - if (!focusModalWithElement(postboardSelector, + var req = defaultScreenName + '@mention'; + if (!focusModalWithElement(twister.res[req].board, function (req) { - var postboard = $(req.postboardSelector); - postboard.closest('.postboard').find('.postboard-news').hide(); - displayQueryPending(postboard); - resetMentionsCount(); - }, {postboardSelector: postboardSelector} + twister.res[req].board.closest('.postboard') + .find('.postboard-news').click(); + }, + req )) $.MAL.showMentions(defaultScreenName); } @@ -175,8 +175,18 @@ function resetMentionsCount() { } function initMentionsCount() { - // polling mentions is a temporary solution + var req = defaultScreenName + '@mention'; + twister.res[req] = { + query: defaultScreenName, + resource: 'mention', + twists: { + cached: {}, + pending: [] + } + }; loadMentionsFromStorage(); + queryPendingPush(req, getMentionsData()); + $.MAL.updateNewMentionsUI(_newMentions); requestMentionsCount(); setInterval(requestMentionsCount, 10000); From dc8cfc20ef10ff3008b4abfdb30d31e7fcbec0cd Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Sat, 1 Jul 2017 05:44:36 +0500 Subject: [PATCH 49/54] tune mentions processing --- js/twister_actions.js | 3 + js/twister_newmsgs.js | 283 +++++++++++++++++++++++------------------- 2 files changed, 160 insertions(+), 126 deletions(-) diff --git a/js/twister_actions.js b/js/twister_actions.js index 0431b64..37b9692 100644 --- a/js/twister_actions.js +++ b/js/twister_actions.js @@ -458,6 +458,9 @@ function queryStart(board, query, resource) { queryPendingDraw(req) } + if (req === defaultScreenName + '@mention') + return req; + queryRequest(req); // use extended timeout parameters on modal refresh (requires twister_core >= 0.9.14). diff --git a/js/twister_newmsgs.js b/js/twister_newmsgs.js index 3691a47..ec70cec 100644 --- a/js/twister_newmsgs.js +++ b/js/twister_newmsgs.js @@ -6,130 +6,91 @@ // --- mentions --- -var _knownMentions = {} -var _lastMentionTime = 0; -var _newMentions = 0; -var _lastLocalMentionId = -1; -var PURGE_OLD_MENTIONS_TIMEOUT = 3600 * 24 * 30; // one month -var _newMentionsUpdated = false; var _newDMsUpdated = false; var groupChatAliases = [] -// process a mention received to check if it is really new -function processMention(user, mentionTime, data) { - var key = user + ';' + mentionTime; - var curTime = new Date().getTime() / 1000; - if (mentionTime > curTime + 7200) // 3600 * 2 - console.warn('ignoring mention from the future'); - else { - if (!_knownMentions[key]) { - // mention must be somewhat recent compared to last known one to be considered new - if (mentionTime + 259200 > _lastMentionTime) { // 3600 * 24 * 3 - _newMentions++; - _newMentionsUpdated = true; - _lastMentionTime = Math.max(mentionTime, _lastMentionTime); - data.isNew = true; - - var req = defaultScreenName + '@mention'; - var j = data.userpost.n + '/' + data.userpost.time; - if (typeof twister.res[req].twists.cached[j] === 'undefined') { - twister.res[req].twists.cached[j] = data; - twister.res[req].twists.pending.push(j); - } +function saveMentionsToStorage() { + var twists = [], length = 0; + for (var j in twister.mentions.twists.cached) { + for (var i = 0; i < length; i++) + if (twister.mentions.twists.cached[j].userpost.time > twists[i].userpost.time) { + twists.splice(i, 0, twister.mentions.twists.cached[j]); + break; } - _knownMentions[key] = {mentionTime: mentionTime, data: data}; - purgeOldMentions(); - saveMentionsToStorage(); - } + + if (length === twists.length) + twists.push(twister.mentions.twists.cached[j]); + + length++; } + + $.initNamespaceStorage(defaultScreenName).localStorage + .set('mentions', { + twists: twists.slice(0, 100), // TODO add an option to specify number of mentions to cache + lastTime: twister.mentions.lastTime, + lastTorrentId: twister.mentions.lastTorrentId + }) + ; } -function purgeOldMentions() { - for (var key in _knownMentions) { - if (_knownMentions[key]) { - if (!_knownMentions[key].mentionTime || !_knownMentions[key].data || - _knownMentions[key].mentionTime + PURGE_OLD_MENTIONS_TIMEOUT < _lastMentionTime) { - delete _knownMentions[key]; +function loadMentionsFromStorage() { + var storage = $.initNamespaceStorage(defaultScreenName).localStorage; + + if (storage.isSet('mentions')) { + var mentions = storage.get('mentions'); + if (typeof mentions === 'object') { + for (var i = 0; i < mentions.twists.length; i++) { + var j = mentions.twists[i].userpost.n + '/' + mentions.twists[i].userpost.time; + if (typeof twister.mentions.twists.cached[j] === 'undefined') { + twister.mentions.twists.cached[j] = mentions.twists[i]; + if (twister.mentions.twists.cached[j].isNew) + twister.mentions.lengthNew++; + } } + twister.mentions.lastTime = mentions.lastTime; + twister.mentions.lastTorrentId = mentions.lastTorrentId; } } -} -function saveMentionsToStorage() { - var ns = $.initNamespaceStorage(defaultScreenName); - ns.localStorage.set('knownMentions', _knownMentions); - ns.localStorage.set('lastMentionTime', _lastMentionTime); - ns.localStorage.set('newMentions', _newMentions); - ns.localStorage.set('lastLocalMentionId', _lastLocalMentionId); -} + // WARN all following storage keys are deprecated + if (storage.isSet('knownMentions')) { + var mentions = storage.get('knownMentions'); + if (typeof mentions === 'object') + for (var i in mentions) { + var j = mentions[i].data.userpost.n + '/' + mentions[i].mentionTime; + if (typeof twister.mentions.twists.cached[j] === 'undefined') { + twister.mentions.twists.cached[j] = mentions[i].data; + if (twister.mentions.twists.cached[j].isNew) + twister.mentions.lengthNew++; + } + } -function loadMentionsFromStorage() { - var ns = $.initNamespaceStorage(defaultScreenName); - if (ns.localStorage.isSet('knownMentions')) - _knownMentions = ns.localStorage.get('knownMentions'); - if (ns.localStorage.isSet('lastMentionTime')) - _lastMentionTime = ns.localStorage.get('lastMentionTime'); - if (ns.localStorage.isSet('newMentions')) - _newMentions = ns.localStorage.get('newMentions'); - if (ns.localStorage.isSet('lastLocalMentionId')) - _lastLocalMentionId = ns.localStorage.get('lastLocalMentionId'); + storage.remove('knownMentions'); + } + if (storage.isSet('lastMentionTime')) { + twister.mentions.lastTime = storage.get('lastMentionTime'); + storage.remove('lastMentionTime'); + } + if (storage.isSet('lastLocalMentionId')) { + twister.mentions.lastTorrentId = storage.get('lastLocalMentionId'); + storage.remove('lastLocalMentionId'); + } + if (storage.isSet('newMentions')) + storage.remove('newMentions'); } function requestMentionsCount() { // first: getmentions from torrents we follow - twisterRpc('getmentions', [defaultScreenName, 100, {since_id: _lastLocalMentionId}], - function(args, data) { - if (data) { - for (var i = 0; i < data.length; i++) { - _lastLocalMentionId = Math.max(_lastLocalMentionId, data[i].id); - var userpost = data[i].userpost; - processMention(userpost.n, userpost.time, data[i]); - } - $.MAL.updateNewMentionsUI(_newMentions); - } - }, null, + twisterRpc('getmentions', [defaultScreenName, 100, {since_id: twister.mentions.lastTorrentId}], + processNewMentions, undefined, function(req, ret) {console.warn('getmentions API requires twister-core > 0.9.27');}, null ); // second: get mentions from dht (not-following) dhtget(defaultScreenName, 'mention', 'm', - function(args, data) { - if (data) { - for (var i = 0; i < data.length; i++) { - var userpost = data[i].userpost; - processMention(userpost.n, userpost.time, data[i]); - } - $.MAL.updateNewMentionsUI(_newMentions); - } - }, {}, - [10000, 2000, 3] // use extended timeout parameters (requires twister_core >= 0.9.14) + processNewMentions, undefined, + twister.res[defaultScreenName + '@mention'].timeoutArgs ); - if (_newMentionsUpdated) { - _newMentionsUpdated = false; - - if (_newMentions) { - $.MAL.soundNotifyMentions(); - - if (!$.hasOwnProperty('mobile') && $.Options.showDesktopNotifMentions.val === 'enable') - $.MAL.showDesktopNotification({ - body: polyglot.t('You got') + ' ' + polyglot.t('new_mentions', _newMentions) + '.', - tag: 'twister_notification_new_mentions', - timeout: $.Options.showDesktopNotifMentionsTimer.val, - funcClick: function () { - var req = defaultScreenName + '@mention'; - if (!focusModalWithElement(twister.res[req].board, - function (req) { - twister.res[req].board.closest('.postboard') - .find('.postboard-news').click(); - }, - req - )) - $.MAL.showMentions(defaultScreenName); - } - }); - } - } - // was moved here from requestDMsCount() because that is not ticking right // we would place it with other notifications into separate notification center if (_newDMsUpdated) { @@ -164,14 +125,92 @@ function requestMentionsCount() { } } -function resetMentionsCount() { - _newMentions = 0; - for (var key in _knownMentions) { - if (_knownMentions[key] && _knownMentions[key].data) - delete _knownMentions[key].data.isNew +function processNewMentions(req, res) { + if (!res || !res.length) + return; + + var lengthNew = 0; + var lengthPending = twister.mentions.twists.pending.length; + var timeCurrent = new Date().getTime() / 1000 + 7200; // 60 * 60 * 2 + var timeLastMention = twister.mentions.lastTime; + + for (var i = 0; i < res.length; i++) { + if (res[i].userpost.time > timeCurrent) { + console.warn('ignoring mention from the future:'); + console.log(res[i]); + continue; + } + + if (res[i].id) { + twister.mentions.lastTorrentId = Math.max(twister.mentions.lastTorrentId, res[i].id); + delete res[i].id; + } + + var j = res[i].userpost.n + '/' + res[i].userpost.time; + if (typeof twister.mentions.twists.cached[j] === 'undefined') { + twister.mentions.twists.cached[j] = res[i]; + twister.mentions.twists.pending.push(j); + + // mention must be somewhat recent compared to last known one to be considered new + if (res[i].userpost.time + 259200 > timeLastMention) { // 3600 * 24 * 3 + lengthNew++; + twister.mentions.lastTime = Math.max(res[i].userpost.time, twister.mentions.lastTime); + twister.mentions.twists.cached[j].isNew = true; + } + } + } + + if (lengthNew) { + twister.mentions.lengthNew += lengthNew; + $.MAL.updateNewMentionsUI(twister.mentions.lengthNew); + $.MAL.soundNotifyMentions(); + if (!$.mobile && $.Options.showDesktopNotifMentions.val === 'enable') + $.MAL.showDesktopNotification({ + body: polyglot.t('You got') + ' ' + polyglot.t('new_mentions', twister.mentions.lengthNew) + '.', + tag: 'twister_notification_new_mentions', + timeout: $.Options.showDesktopNotifMentionsTimer.val, + funcClick: function () { + var req = defaultScreenName + '@mention'; + if (!twister.res[req].board || !focusModalWithElement(twister.res[req].board, + function (req) { + twister.res[req].board.closest('.postboard') + .find('.postboard-news').click(); + }, + req + )) + $.MAL.showMentions(defaultScreenName); + } + }); + } + + if (twister.mentions.twists.pending.length > lengthPending) { + saveMentionsToStorage(); + + var req = defaultScreenName + '@mention'; + if (!twister.res[req].board || !isModalWithElemExists(twister.res[req].board)) + return; + + if (!twister.res[req].board.children().length || twister.res[req].boardAutoAppend) + queryPendingDraw(req); + else { + twister.res[req].board.closest('div').find('.postboard-news') // FIXME we'd replace 'div' with '.postboard' but need to dig through tmobile first + .text(polyglot.t('new_posts', twister.mentions.twists.pending.length)) + .fadeIn('slow') + ; + twister.res[req].board.closest('div').find('.postboard-loading').hide(); + } } +} + +function resetMentionsCount() { + twister.mentions.lengthNew = 0; + + for (var j in twister.mentions.twists.cached) + if (twister.mentions.twists.cached[j].isNew) + delete twister.mentions.twists.cached[j].isNew; + saveMentionsToStorage(); - $.MAL.updateNewMentionsUI(_newMentions); + $.MAL.updateNewMentionsUI(twister.mentions.lengthNew); } function initMentionsCount() { @@ -179,27 +218,21 @@ function initMentionsCount() { twister.res[req] = { query: defaultScreenName, resource: 'mention', + timeoutArgs: [10000, 2000, 3], twists: { cached: {}, - pending: [] - } + pending: [], + }, + lastTime: 0, + lastTorrentId: -1, + lengthNew: 0 }; + twister.mentions = twister.res[req]; loadMentionsFromStorage(); - queryPendingPush(req, getMentionsData()); - $.MAL.updateNewMentionsUI(_newMentions); + $.MAL.updateNewMentionsUI(twister.mentions.lengthNew); requestMentionsCount(); - setInterval(requestMentionsCount, 10000); -} - -function getMentionsData() { - mentions = [] - for (var key in _knownMentions) { - if (_knownMentions[key] && _knownMentions[key].data) { - mentions.push(_knownMentions[key].data); - } - } - return mentions; + twister.mentions.interval = setInterval(requestMentionsCount, 10000); } // --- direct messages --- @@ -307,7 +340,5 @@ function initDMsCount() { } function newmsgsChangedUser() { - _knownMentions = {} - _lastMentionTime = 0; - _newMentions = 0; + clearInterval(twister.mentions.interval); } From 01283059dbe8e164d618f5610aa46b3759062746 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Sat, 1 Jul 2017 05:50:46 +0500 Subject: [PATCH 50/54] complement comment info --- js/twister_newmsgs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/twister_newmsgs.js b/js/twister_newmsgs.js index ec70cec..979703f 100644 --- a/js/twister_newmsgs.js +++ b/js/twister_newmsgs.js @@ -52,7 +52,7 @@ function loadMentionsFromStorage() { } } - // WARN all following storage keys are deprecated + // WARN all following storage keys are deprecated (see commit dc8cfc20ef10ff3008b4abfdb30d31e7fcbec0cd) if (storage.isSet('knownMentions')) { var mentions = storage.get('knownMentions'); if (typeof mentions === 'object') From e3c66c956866e39fad58c18cfc861434a085dfd5 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Sun, 2 Jul 2017 00:05:25 +0500 Subject: [PATCH 51/54] tune new DMs notification --- js/twister_newmsgs.js | 70 +++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 39 deletions(-) diff --git a/js/twister_newmsgs.js b/js/twister_newmsgs.js index 979703f..dc82ee7 100644 --- a/js/twister_newmsgs.js +++ b/js/twister_newmsgs.js @@ -6,7 +6,6 @@ // --- mentions --- -var _newDMsUpdated = false; var groupChatAliases = [] function saveMentionsToStorage() { @@ -90,39 +89,6 @@ function requestMentionsCount() { processNewMentions, undefined, twister.res[defaultScreenName + '@mention'].timeoutArgs ); - - // was moved here from requestDMsCount() because that is not ticking right - // we would place it with other notifications into separate notification center - if (_newDMsUpdated) { - _newDMsUpdated = false; - - var newDMs = getNewDMsCount(); - if (newDMs) { - $.MAL.soundNotifyDM(); - - if (!$.hasOwnProperty('mobile') && $.Options.showDesktopNotifDMs.val === 'enable') { - $.MAL.showDesktopNotification({ - body: polyglot.t('You got') + ' ' + polyglot.t('new_direct_messages', newDMs) + '.', - tag: 'twister_notification_new_DMs', - timeout: $.Options.showDesktopNotifDMsTimer.val, - funcClick: function () {$.MAL.showDMchat();} - }); - } - } - var newDMs = getNewGroupDMsCount(); - if (newDMs) { - $.MAL.soundNotifyDM(); - - if (!$.hasOwnProperty('mobile') && $.Options.showDesktopNotifDMs.val === 'enable') { - $.MAL.showDesktopNotification({ - body: polyglot.t('You got') + ' ' + polyglot.t('new_group_messages', newDMs) + '.', - tag: 'twister_notification_new_DMs', - timeout: $.Options.showDesktopNotifDMsTimer.val, - funcClick: function () {$.MAL.showDMchat({group: true});} - }); - } - } - } } function processNewMentions(req, res) { @@ -263,25 +229,51 @@ function requestDMsCount() { twisterRpc('getdirectmsgs', [defaultScreenName, 1, followList], function(req, dmUsers) { + var newDMsUpdated; + for (var u in dmUsers) { if (dmUsers[u]) { var dmData = dmUsers[u][0]; if (u in _lastDMIdPerUser && u in _newDMsPerUser) { if (dmData.id !== _lastDMIdPerUser[u]) { _newDMsPerUser[u] += dmData.id - _lastDMIdPerUser[u]; - _newDMsUpdated = true; + newDMsUpdated = true; } } else { _newDMsPerUser[u] = dmData.id + 1; - _newDMsUpdated = true; + newDMsUpdated = true; } _lastDMIdPerUser[u] = dmData.id; } } - if (_newDMsUpdated) { + if (newDMsUpdated) { saveDMsToStorage(); - $.MAL.updateNewDMsUI(getNewDMsCount()); - $.MAL.updateNewGroupDMsUI(getNewGroupDMsCount()); + var newDMs = getNewDMsCount(); + if (newDMs) { + $.MAL.updateNewDMsUI(newDMs); + $.MAL.soundNotifyDM(); + if (!$.mobile && $.Options.showDesktopNotifDMs.val === 'enable') { + $.MAL.showDesktopNotification({ + body: polyglot.t('You got') + ' ' + polyglot.t('new_direct_messages', newDMs) + '.', + tag: 'twister_notification_new_DMs', + timeout: $.Options.showDesktopNotifDMsTimer.val, + funcClick: function () {$.MAL.showDMchat();} + }); + } + } + var newDMs = getNewGroupDMsCount(); + if (newDMs) { + $.MAL.updateNewGroupDMsUI(newDMs); + $.MAL.soundNotifyDM(); + if (!$.mobile && $.Options.showDesktopNotifDMs.val === 'enable') { + $.MAL.showDesktopNotification({ + body: polyglot.t('You got') + ' ' + polyglot.t('new_group_messages', newDMs) + '.', + tag: 'twister_notification_new_DMs', + timeout: $.Options.showDesktopNotifDMsTimer.val, + funcClick: function () {$.MAL.showDMchat({group: true});} + }); + } + } } }, null, function(req, ret) {console.warn('ajax error:' + ret);}, null From 727a4a7fd11339fcd3f205778afceac8cbeb5fe9 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Sun, 2 Jul 2017 03:40:58 +0500 Subject: [PATCH 52/54] tune twists' requests processing --- js/tmobile.js | 14 +++--- js/twister_actions.js | 99 +++++++++++++++++++++++++++++++------------ js/twister_newmsgs.js | 95 +++++++++-------------------------------- 3 files changed, 98 insertions(+), 110 deletions(-) diff --git a/js/tmobile.js b/js/tmobile.js index 6248d27..bf69bbe 100644 --- a/js/tmobile.js +++ b/js/tmobile.js @@ -535,13 +535,13 @@ function setupHashtagOrMention(board, query, resource) { $.mobile.showPageLoadingMsg(); board.empty(); - var req = queryStart(board, query, resource); - - twister.res[req].boardAutoAppend = true; - twister.res[req].skidoo = function (req) { - var curPage = $.mobile.activePage.attr('id'); - return (curPage !== 'mentions' && curPage !== 'hashtag') || req !== tmobileQueryReq; - }; + var req = queryStart(board, query, resource, undefined, undefined, { + boardAutoAppend: true, + skidoo: function (req) { + var curPage = $.mobile.activePage.attr('id'); + return (curPage !== 'mentions' && curPage !== 'hashtag') || req !== tmobileQueryReq; + } + }); tmobileQueryReq = req; } diff --git a/js/twister_actions.js b/js/twister_actions.js index 37b9692..bec3efe 100644 --- a/js/twister_actions.js +++ b/js/twister_actions.js @@ -436,10 +436,10 @@ function updateProfilePosts(postsView, username, useGetposts) { }); } -function queryStart(board, query, resource) { +function queryStart(board, query, resource, timeoutArgs, intervalTimeout, extra) { var req = query + '@' + resource; - if (typeof twister.res[req] !== 'object') + if (typeof twister.res[req] !== 'object') { twister.res[req] = { board: board, query: query, @@ -449,16 +449,18 @@ function queryStart(board, query, resource) { pending: [] } }; - else { + for (i in extra) + twister.res[req][i] = extra[i]; + } else { twister.res[req].board = board; for (var i in twister.res[req].twists.cached) if (twister.res[req].twists.pending.indexOf(i) === -1) twister.res[req].twists.pending.push(i); - queryPendingDraw(req) + queryPendingDraw(req); } - if (req === defaultScreenName + '@mention') + if (twister.res[req].interval) return req; queryRequest(req); @@ -466,9 +468,9 @@ function queryStart(board, query, resource) { // use extended timeout parameters on modal refresh (requires twister_core >= 0.9.14). // our first query above should be faster (with default timeoutArgs of twisterd), // then we may possibly collect more posts on our second try by waiting more. - twister.res[req].timeoutArgs = [10000, 2000, 3]; + twister.res[req].timeoutArgs = timeoutArgs ? timeoutArgs : [10000, 2000, 3]; - twister.res[req].interval = setInterval(queryTick, 5000, req); + twister.res[req].interval = setInterval(queryTick, intervalTimeout ? intervalTimeout : 5000, req); return req; } @@ -477,24 +479,30 @@ function queryTick(req) { if (typeof twister.res[req].skidoo === 'function' ? twister.res[req].skidoo(req) : !isModalWithElemExists(twister.res[req].board)) { clearInterval(twister.res[req].interval); - queryClear(req); + twister.res[req].interval = 0; + queryPendingClear(req); return; } queryRequest(req); } -function queryClear(req) { - if (!req || !twister.res[req] || !twister.res[req].twists) - return; - +function queryPendingClear(req) { twister.res[req].twists.pending = []; } function queryRequest(req) { - twister.res[req].board.closest('div').find('.postboard-loading').show(); + if (twister.res[req].board && isModalWithElemExists(twister.res[req].board)) + twister.res[req].board.closest('div').find('.postboard-loading').show(); - if (twister.res[req].resource === 'fav') + if (twister.res[req].resource === 'mention' && twister.res[req].query === defaultScreenName) { + twisterRpc('getmentions', [twister.res[req].query, 100, {since_id: twister.res[req].lastTorrentId}], + queryProcess, req, + function () {console.warn('getmentions API requires twister-core > 0.9.27');} + ); + dhtget(twister.res[req].query, twister.res[req].resource, 'm', + queryProcess, req, twister.res[req].timeoutArgs); + } else if (twister.res[req].resource === 'fav') twisterRpc('getfavs', [twister.res[req].query, 1000], queryProcess, req); else @@ -503,16 +511,44 @@ function queryRequest(req) { } function queryProcess(req, twists) { - queryPendingPush(req, twists); + if (!req || !twister.res[req] || !twists || !twists.length) + return; - if (typeof twister.res[req].skidoo === 'function' ? twister.res[req].skidoo(req) - : !isModalWithElemExists(twister.res[req].board)) + var lengthNew = 0; + var lengthPending = twister.res[req].twists.pending.length; + + if (twister.res[req].resource === 'mention' && twister.res[req].query === defaultScreenName) + lengthNew = queryPendingPushMentions(req, twists); + else + lengthNew = queryPendingPush(req, twists); + + if (typeof twister.res[req].skidoo === 'function' && twister.res[req].skidoo(req)) return; - if (twister.res[req].twists.pending.length) { - if (twister.res[req].board.children().length && !$.mobile - && $.Options.showDesktopNotifPostsModal.val === 'enable' - && (twister.res[req].resource !== 'mention' || twister.res[req].query !== defaultScreenName)) + if (lengthNew) + if (twister.res[req].resource === 'mention' && twister.res[req].query === defaultScreenName) { + $.MAL.updateNewMentionsUI(twister.res[req].lengthNew); + $.MAL.soundNotifyMentions(); + if (!$.mobile && $.Options.showDesktopNotifMentions.val === 'enable') + $.MAL.showDesktopNotification({ + body: polyglot.t('You got') + ' ' + polyglot.t('new_mentions', twister.res[req].lengthNew) + '.', + tag: 'twister_notification_new_mentions', + timeout: $.Options.showDesktopNotifMentionsTimer.val, + funcClick: (function () { + if (!twister.res[this.req].board || !focusModalWithElement(twister.res[this.req].board, + function (req) { + twister.res[req].board.closest('.postboard') + .find('.postboard-news').click(); + }, + this.req + )) + $.MAL.showMentions(defaultScreenName); + }).bind({req: req}) + }); + } else if (!$.mobile && $.Options.showDesktopNotifPostsModal.val === 'enable' + && (twister.res[req].resource !== 'mention' || twister.res[req].query !== defaultScreenName) + && twister.res[req].board && isModalWithElemExists(twister.res[req].board) + && twister.res[req].board.children().length) $.MAL.showDesktopNotification({ body: polyglot.t('You got') + ' ' + polyglot.t('new_posts', twister.res[req].twists.pending.length) + ' ' + polyglot.t('in search result') + '.', @@ -529,6 +565,10 @@ function queryProcess(req, twists) { }).bind({req: req}) }); + if (twister.res[req].twists.pending.length > lengthPending) { // there is some twists may be which are not considered new so lengthNew equals zero (mentions thing) + if (!twister.res[req].board || (!$.mobile && !isModalWithElemExists(twister.res[req].board))) + return; + if (!twister.res[req].board.children().length || twister.res[req].boardAutoAppend) queryPendingDraw(req); else { @@ -542,23 +582,23 @@ function queryProcess(req, twists) { } function queryPendingPush(req, twists) { - if (!req || !twister.res[req] || !twists || !twists.length) - return; + var lengthNew = 0; + var needForFilter = $.Options.filterLang.val !== 'disable' && $.Options.filterLangForSearching.val; for (var i = twists.length - 1; i >= 0; i--) { var userpost = twists[i].userpost; var j = userpost.n + '/' + userpost.time; - if (userpost.fav) - userpost = userpost.fav; - if (typeof twister.res[req].twists.cached[j] === 'undefined') { + if (userpost.fav) + userpost = userpost.fav; + if ((typeof userpost.msg !== 'string' || userpost.msg === '') && (typeof userpost.rt !== 'object' || typeof userpost.rt.msg !== 'string' || userpost.rt.msg === '')) continue; - if ($.Options.filterLang.val !== 'disable' && $.Options.filterLangForSearching.val) { + if (needForFilter) { if (typeof userpost.msg === 'string' && userpost.msg !== '') langFilterData = filterLang(userpost.msg); else @@ -572,10 +612,13 @@ function queryPendingPush(req, twists) { } } + lengthNew++; twister.res[req].twists.cached[j] = twists[i]; twister.res[req].twists.pending.push(j); } } + + return lengthNew; } function queryPendingDraw(req) { @@ -585,7 +628,7 @@ function queryPendingDraw(req) { attachPostsToStream(twister.res[req].board, twists, false); - queryClear(req); + queryPendingClear(req); $.MAL.postboardLoaded(); } diff --git a/js/twister_newmsgs.js b/js/twister_newmsgs.js index dc82ee7..92b3b1a 100644 --- a/js/twister_newmsgs.js +++ b/js/twister_newmsgs.js @@ -78,27 +78,11 @@ function loadMentionsFromStorage() { storage.remove('newMentions'); } -function requestMentionsCount() { - // first: getmentions from torrents we follow - twisterRpc('getmentions', [defaultScreenName, 100, {since_id: twister.mentions.lastTorrentId}], - processNewMentions, undefined, - function(req, ret) {console.warn('getmentions API requires twister-core > 0.9.27');}, null - ); - // second: get mentions from dht (not-following) - dhtget(defaultScreenName, 'mention', 'm', - processNewMentions, undefined, - twister.res[defaultScreenName + '@mention'].timeoutArgs - ); -} - -function processNewMentions(req, res) { - if (!res || !res.length) - return; - +function queryPendingPushMentions(req, res) { var lengthNew = 0; - var lengthPending = twister.mentions.twists.pending.length; + var lengthPending = twister.res[req].twists.pending.length; var timeCurrent = new Date().getTime() / 1000 + 7200; // 60 * 60 * 2 - var timeLastMention = twister.mentions.lastTime; + var timeLastMention = twister.res[req].lastTime; for (var i = 0; i < res.length; i++) { if (res[i].userpost.time > timeCurrent) { @@ -108,64 +92,31 @@ function processNewMentions(req, res) { } if (res[i].id) { - twister.mentions.lastTorrentId = Math.max(twister.mentions.lastTorrentId, res[i].id); + twister.res[req].lastTorrentId = Math.max(twister.res[req].lastTorrentId, res[i].id); delete res[i].id; } var j = res[i].userpost.n + '/' + res[i].userpost.time; - if (typeof twister.mentions.twists.cached[j] === 'undefined') { - twister.mentions.twists.cached[j] = res[i]; - twister.mentions.twists.pending.push(j); + if (typeof twister.res[req].twists.cached[j] === 'undefined') { + twister.res[req].twists.cached[j] = res[i]; + twister.res[req].twists.pending.push(j); // mention must be somewhat recent compared to last known one to be considered new if (res[i].userpost.time + 259200 > timeLastMention) { // 3600 * 24 * 3 lengthNew++; - twister.mentions.lastTime = Math.max(res[i].userpost.time, twister.mentions.lastTime); - twister.mentions.twists.cached[j].isNew = true; + twister.res[req].lastTime = Math.max(res[i].userpost.time, twister.res[req].lastTime); + twister.res[req].twists.cached[j].isNew = true; } } } - if (lengthNew) { - twister.mentions.lengthNew += lengthNew; - $.MAL.updateNewMentionsUI(twister.mentions.lengthNew); - $.MAL.soundNotifyMentions(); - if (!$.mobile && $.Options.showDesktopNotifMentions.val === 'enable') - $.MAL.showDesktopNotification({ - body: polyglot.t('You got') + ' ' + polyglot.t('new_mentions', twister.mentions.lengthNew) + '.', - tag: 'twister_notification_new_mentions', - timeout: $.Options.showDesktopNotifMentionsTimer.val, - funcClick: function () { - var req = defaultScreenName + '@mention'; - if (!twister.res[req].board || !focusModalWithElement(twister.res[req].board, - function (req) { - twister.res[req].board.closest('.postboard') - .find('.postboard-news').click(); - }, - req - )) - $.MAL.showMentions(defaultScreenName); - } - }); - } + if (lengthNew) + twister.res[req].lengthNew += lengthNew; - if (twister.mentions.twists.pending.length > lengthPending) { + if (twister.res[req].twists.pending.length > lengthPending) saveMentionsToStorage(); - var req = defaultScreenName + '@mention'; - if (!twister.res[req].board || !isModalWithElemExists(twister.res[req].board)) - return; - - if (!twister.res[req].board.children().length || twister.res[req].boardAutoAppend) - queryPendingDraw(req); - else { - twister.res[req].board.closest('div').find('.postboard-news') // FIXME we'd replace 'div' with '.postboard' but need to dig through tmobile first - .text(polyglot.t('new_posts', twister.mentions.twists.pending.length)) - .fadeIn('slow') - ; - twister.res[req].board.closest('div').find('.postboard-loading').hide(); - } - } + return lengthNew; } function resetMentionsCount() { @@ -180,25 +131,17 @@ function resetMentionsCount() { } function initMentionsCount() { - var req = defaultScreenName + '@mention'; - twister.res[req] = { - query: defaultScreenName, - resource: 'mention', - timeoutArgs: [10000, 2000, 3], - twists: { - cached: {}, - pending: [], - }, + var req = queryStart('', defaultScreenName, 'mention', [10000, 2000, 3], 10000, { lastTime: 0, lastTorrentId: -1, - lengthNew: 0 - }; + lengthNew: 0, + skidoo: function () {return false;} + }); twister.mentions = twister.res[req]; + loadMentionsFromStorage(); $.MAL.updateNewMentionsUI(twister.mentions.lengthNew); - requestMentionsCount(); - twister.mentions.interval = setInterval(requestMentionsCount, 10000); } // --- direct messages --- @@ -252,6 +195,7 @@ function requestDMsCount() { if (newDMs) { $.MAL.updateNewDMsUI(newDMs); $.MAL.soundNotifyDM(); + if (!$.mobile && $.Options.showDesktopNotifDMs.val === 'enable') { $.MAL.showDesktopNotification({ body: polyglot.t('You got') + ' ' + polyglot.t('new_direct_messages', newDMs) + '.', @@ -265,6 +209,7 @@ function requestDMsCount() { if (newDMs) { $.MAL.updateNewGroupDMsUI(newDMs); $.MAL.soundNotifyDM(); + if (!$.mobile && $.Options.showDesktopNotifDMs.val === 'enable') { $.MAL.showDesktopNotification({ body: polyglot.t('You got') + ' ' + polyglot.t('new_group_messages', newDMs) + '.', From 059616e0ac8d833fccc6ed0552c34cb1bc7fdc82 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Mon, 3 Jul 2017 04:23:53 +0500 Subject: [PATCH 53/54] relocate mentions preloading from local storage --- js/twister_actions.js | 9 +++++++-- js/twister_newmsgs.js | 7 ++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/js/twister_actions.js b/js/twister_actions.js index bec3efe..3626440 100644 --- a/js/twister_actions.js +++ b/js/twister_actions.js @@ -449,8 +449,13 @@ function queryStart(board, query, resource, timeoutArgs, intervalTimeout, extra) pending: [] } }; - for (i in extra) - twister.res[req][i] = extra[i]; + if (extra) { + for (i in extra) + twister.res[req][i] = extra[i]; + + if (typeof extra.ready === 'function') + extra.ready(req, extra.readyReq); + } } else { twister.res[req].board = board; for (var i in twister.res[req].twists.cached) diff --git a/js/twister_newmsgs.js b/js/twister_newmsgs.js index 92b3b1a..0577af6 100644 --- a/js/twister_newmsgs.js +++ b/js/twister_newmsgs.js @@ -135,11 +135,12 @@ function initMentionsCount() { lastTime: 0, lastTorrentId: -1, lengthNew: 0, + ready: function (req) { + twister.mentions = twister.res[req]; + loadMentionsFromStorage(); + }, skidoo: function () {return false;} }); - twister.mentions = twister.res[req]; - - loadMentionsFromStorage(); $.MAL.updateNewMentionsUI(twister.mentions.lengthNew); } From 9e17f2da10d3926cab92440f68e56aa23622f4d1 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Mon, 3 Jul 2017 22:36:30 +0500 Subject: [PATCH 54/54] add mentions' retrievement on scroll to the bottom of the mentions modal --- js/interface_common.js | 4 +++- js/twister_newmsgs.js | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/js/interface_common.js b/js/interface_common.js index 36179dd..664bcf3 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -679,8 +679,10 @@ function openMentionsModalHandler(peerAlias) { ) ; - if (peerAlias === defaultScreenName) + if (peerAlias === defaultScreenName) { + modal.content.on('scroll', handleMentionsModalScroll); resetMentionsCount(); + } } function openFollowersModal(peerAlias) { diff --git a/js/twister_newmsgs.js b/js/twister_newmsgs.js index 0577af6..7a2c9c8 100644 --- a/js/twister_newmsgs.js +++ b/js/twister_newmsgs.js @@ -44,6 +44,8 @@ function loadMentionsFromStorage() { twister.mentions.twists.cached[j] = mentions.twists[i]; if (twister.mentions.twists.cached[j].isNew) twister.mentions.lengthNew++; + + twister.mentions.lengthFromTorrent++; } } twister.mentions.lastTime = mentions.lastTime; @@ -61,6 +63,8 @@ function loadMentionsFromStorage() { twister.mentions.twists.cached[j] = mentions[i].data; if (twister.mentions.twists.cached[j].isNew) twister.mentions.lengthNew++; + + twister.mentions.lengthFromTorrent++; } } @@ -94,6 +98,7 @@ function queryPendingPushMentions(req, res) { if (res[i].id) { twister.res[req].lastTorrentId = Math.max(twister.res[req].lastTorrentId, res[i].id); delete res[i].id; + twister.res[req].lengthFromTorrent++; } var j = res[i].userpost.n + '/' + res[i].userpost.time; @@ -137,6 +142,7 @@ function initMentionsCount() { lengthNew: 0, ready: function (req) { twister.mentions = twister.res[req]; + twister.mentions.lengthFromTorrent = 0; loadMentionsFromStorage(); }, skidoo: function () {return false;} @@ -145,6 +151,27 @@ function initMentionsCount() { $.MAL.updateNewMentionsUI(twister.mentions.lengthNew); } +function handleMentionsModalScroll(event) { + if (!event || twister.mentions.scrollQueryActive) + return; + + var elem = $(event.target); + if (elem.scrollTop() >= elem[0].scrollHeight - elem.height() - 50) { + twister.mentions.scrollQueryActive = true; + + twisterRpc('getmentions', [twister.mentions.query, 10, + {max_id: twister.mentions.lastTorrentId - twister.mentions.lengthFromTorrent}], + function (req, res) { + twister.mentions.scrollQueryActive = false; + twister.res[req].boardAutoAppend = true; // FIXME all pending twists will be appended + queryProcess(req, res); + twister.res[req].boardAutoAppend = false; + }, twister.mentions.query + '@' + twister.mentions.resource, + function () {console.warn('getmentions API requires twister-core > 0.9.27');} + ); + } +} + // --- direct messages --- var _lastDMIdPerUser = {};