diff --git a/css/style.css b/css/style.css index 4167ecd..dc3a83a 100644 --- a/css/style.css +++ b/css/style.css @@ -123,7 +123,7 @@ button:disabled:hover, button.disabled:hover { color: rgba(255, 255, 255, .8); } -button.follow, button.unfollow, .following-list button.private { +button.follow, button.unfollow, .following-own-modal .following-list button.private { color: rgba( 0, 0, 0, .4 ); background: none; border: solid 1px rgba( 0, 0, 0, .2 ); @@ -131,19 +131,19 @@ button.follow, button.unfollow, .following-list button.private { font-size: 12px; } -.following-list .public-following { +.following-own-modal .following-list .public-following { padding: 4px 16px; font-size: 12px; } -.following-list .public-following:hover { +.following-own-modal .following-list .public-following:hover { color: rgba( 0, 0, 0, .4 ); background: none; border: solid 1px rgba( 0, 0, 0, .2 ); padding: 3px 15px; } -button.follow:hover, button.unfollow:hover, .following-list button.private:hover { +button.follow:hover, button.unfollow:hover, .following-own-modal .following-list button.private:hover { color: #fff; background: #45474d; } @@ -545,10 +545,7 @@ button.follow:hover, button.unfollow:hover, .following-list button.private:hover position: relative; z-index: 2; } -.following-list .mini-profile-name -{ - padding: 5px 5px 5px 5px; -} + .profile-data { @@ -584,58 +581,51 @@ button.follow:hover, button.unfollow:hover, .following-list button.private:hover display: block; font-size: 16px; } -.mini-profile-actions -{ - position: relative; - width: auto; - display: inline-block; + +.mini-profile-actions { + position: absolute; + top: 0; + right: 8px; } -.mini-profile-actions span -{ + +.mini-profile-actions span { color: #e34f42; cursor: pointer; font-size: 12px; display: inline-block; - transition: all .2s linear; + position: relative; + z-index: 10; } -.mini-profile-actions ul -{ + +.mini-profile-actions ul { height: 0; overflow: hidden; position: absolute; + z-index: 20; + right: 0; transition: height .2s linear; background: #fff; - z-index: 3; -} -.mini-profile-actions:hover span -{ -} -.mini-profile-actions:hover span:after -{ } -.mini-profile-actions:hover ul -{ - height: 118px; - box-shadow: 0 2px 5px #65686f; + +.mini-profile-actions:hover ul { + /*height: ;*/ + border: solid 1px rgba(69, 71, 77, .1); + border-right: solid 4px rgba(227, 79, 66, .82); + box-shadow: 8px 10px 10px 0px rgba(0, 0, 0, .2); } -.mini-profile-actions ul li -{ + +.mini-profile-actions ul > li { white-space: nowrap; - color: rgba( 0, 0, 0, .7 ); - font-size: 13px; + color: rgba(0, 0, 0, .7); + font-size: 12px; cursor: pointer; - padding: 5px; - margin: 2px; + padding: 4px 16px 4px 8px; } -.mini-profile-actions ul li + li -{ - margin: 0 2px; -} -.mini-profile-actions:hover ul li:hover -{ - background: rgba( 0, 0, 0, .7 ); - color: #fff; + +.mini-profile-actions ul > li:hover { + background-color: #FEFEDF; } + .mini-profile-info a:hover { text-decoration: none; @@ -2199,68 +2189,55 @@ ol.toptrends-list { *********** FOLLOWING PAGE *********** **************************************/ -.following .header-bold { - display: block; - width: 100%; - margin: 0px auto 12px auto; -} - -.following-list -{ - overflow-y: auto; +.following-own-modal.modal-wrapper { + width: 662px; + margin-left: -331px; } -.following ol.following-list > li{ - width: 425px; - height: 160px; - margin: 5px; - padding: 8px; +.following-own-modal .following-list > li { + width: 320px; + height: 120px; + margin: 2px; + padding: 2px; float: left; - border: solid 1px rgba( 69, 71, 77, .1 ); + border: solid 1px rgba(69, 71, 77, .1); background: #fff; } -.w1200 .following ol.following-list > li{ - width: 385px; +.following-own-modal .following-list > li:hover { + border: solid 1px rgba(227, 79, 66, .5); } -.following ol.following-list > li:hover{ - border: solid 1px rgba( 227, 79, 66, .5 ); +.following-own-modal .following-list .mini-profile-name { + padding: 4px; } -.following-list .mini-screen-name { +.following-own-modal .following-list .mini-screen-name { position: absolute; top: 32px; } -.following-list .following-config -{ +.following-own-modal .following-list .following-config { width: 100%; position: absolute; - top: 64px; + top: 62px; text-align: center; } -.following-list .following-config button -{ +.following-own-modal .following-list .following-config button { display: inline-block; } -.following-list .mini-profile-actions -{ - position: absolute; - top: 0; - right: 8px; - z-index: 10; +.following-own-modal .following-list .mini-profile-actions:hover ul { + height: 50px; } -.following-list .swarm-status -{ +.following-own-modal .following-list .swarm-status { font: 12px "Open Sans", sans-serif; display: block; position: absolute; - top: 120px; - right: 8px; + top: 94px; + right: 32px; } /************************************* diff --git a/following.html b/following.html deleted file mode 100644 index cecf27a..0000000 --- a/following.html +++ /dev/null @@ -1,638 +0,0 @@ - - - - - Following - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
-
-
user-photo
- - View -
- -
- -
- - -
-

Following

- - - -
    - -
- - -
- -
- - - - - - - - - - - diff --git a/home.html b/home.html index 8d0ecd8..24f4253 100644 --- a/home.html +++ b/home.html @@ -52,7 +52,7 @@ Options Network config Setup account - Following users + Following users Change user Direct Messages @@ -117,7 +117,7 @@ @@ -357,7 +357,7 @@ -
+
user-photo
-
+
twisted again by @@ -684,6 +684,44 @@
+
+
    +
    +
    +
    +
+
+ +
+
  • +
    + + user-photo + Fulano da Silva + @ + +
    +
    + Actions ▼ +
      +
    • Send direct message
    • + +
    • Display mentions
    • + +
    +
    +
    + + +
    +
    +
    + +
    +
    +
  • +
    +
    @@ -708,19 +746,15 @@
    -
    - -
    -

    Which way do you want to follow @:

    +
    + Which way do you want to follow @
    -
    -
    diff --git a/js/interface_common.js b/js/interface_common.js index df55ed6..4eda637 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -5,9 +5,30 @@ // Profile, mentions and hashtag modal // Post actions: submit, count characters +var twister = { + html: { + detached: $('
    '), // here elements go to detach themself + blanka: $('') // to open stuff in new tab, see routeOnClick() + }, + tmpl: {}, // templates should be detached and stored here + modal: {} +}; var window_scrollY = 0; var _watchHashChangeRelaxDontDoIt = window.location.hash === '' ? true : false; -var _minimizedModals = {}; + +// FIXME so looks like it's wrapper over $; it's here to select and manipulate detached elements too +// and actually I'm talking about 'so called \'detached\'' elements which appended to twister.html.detached +// we may just append twister.html.detached to document instead and remove this weird shit (or I need to +// improve my google skills to find native jQuery way to dig through all detached elemets with one query) +function getElem(req) { + var elem = $(req); + var h = twister.html.detached.find(req); + + for (var i = 0; i < h.length; i++) + elem[elem.length++] = h[i]; + + return elem; +} function openModal(modal) { if (!modal.classBase) { @@ -17,7 +38,8 @@ function openModal(modal) { $('body').css('overflow', 'hidden'); } - $(modal.classBase + ':not(#templates *)').remove(); + if (modal.classBase !== '.prompt-wrapper') + closeModal($(modal.classBase + ':not(#templates *)'), true); modal.self = $('#templates ' + modal.classBase).clone(true) .addClass(modal.classAdd); @@ -30,9 +52,14 @@ function openModal(modal) { else modal.content = modal.self.find('.modal-content'); - modal.self.prependTo('body').fadeIn('fast'); + modal.self.appendTo('body').fadeIn('fast'); // FIXME maybe it's better to append it to some container inside body if (modal.classBase === '.modal-wrapper') { + twister.modal[window.location.hash] = modal; + modal.self.attr('data-modal-id', window.location.hash); + + modal.drapper = $('
    ').appendTo(twister.html.detached); // here modal goes instead detaching + modal.content.outerHeight(modal.self.height() - modal.self.find('.modal-header').outerHeight()); var windowHeight = $(window).height(); @@ -46,49 +73,95 @@ function openModal(modal) { return modal; } -function closeModal() { - closeModalHandler('.modal-wrapper'); +function closeModal(req, switchMode) { + if (typeof req === 'undefined') + var elem = $('.modal-wrapper:not(#templates *)'); // select active modal(s) + else if (req.jquery) + var elem = req; + else if (req.target) + var elem = getElem(req.target); // getElem() to search in minimized too + else if (typeof req === 'string' || req.outerHTML) + var elem = getElem(req); + + if (!elem || !elem.length) + return; + + // we close all modals which are containing element(s) + elem.closest('.modal-wrapper:not(.closed)').addClass('closed') + .fadeOut(switchMode ? 10 : 'fast', function () { + var i = this.getAttribute('data-modal-id'); + + if (twister.modal[i].minimized) + twister.modal[i].btnResume.fadeOut('fast', function () {this.remove();}); + else + this.remove(); // if it's minimized it will be removed with twister.modal[i].drapper - if (window.location.hash !== '') { - _watchHashChangeRelaxDontDoIt = true; - window.location.hash = '#'; + twister.modal[i].drapper.remove(); + twister.modal[i] = undefined; + } + ); + + if (!switchMode) { + if (window.location.hash !== '') { + _watchHashChangeRelaxDontDoIt = true; + window.location.hash = '#'; + } + window.scroll(window.pageXOffset, window_scrollY); + $('body').css({ + 'overflow': 'auto', + 'margin-right': '0' + }); } - window.scroll(window.pageXOffset, window_scrollY); - $('body').css({ - 'overflow': 'auto', - 'margin-right': '0' - }); } -function closePrompt() { - closeModalHandler('.prompt-wrapper'); -} +function closePrompt(req) { + if (typeof req === 'undefined') + var elem = $('.prompt-wrapper:not(#templates *)'); + else if (req.jquery) + var elem = req; + else if (req.target) + var elem = $(req.target); + else if (typeof req === 'string' || req.outerHTML) + var elem = $(req); + + if (!elem || !elem.length) + return; -function closeModalHandler(classBase) { - var modalWindows = $(classBase+':not(#templates *)'); + if (typeof req.stopPropagation === 'function') { + req.preventDefault(); + req.stopPropagation(); + req = req.data; + } - modalWindows.fadeOut('fast', function() {modalWindows.remove();}); + // we close all prompts which are containing element(s) + elem.closest('.prompt-wrapper:not(.closed)').addClass('closed') + .fadeOut('fast', function() {this.remove();}); + + if (req && typeof req.cbFunc === 'function') // FIXME maybe bind to ^ prompt fadeout function + req.cbFunc(req.cbReq); } function minimizeModal(modal, switchMode) { + function minimize(modal, scroll) { - modal.detach(); + var i = modal.attr('data-modal-id'); - btnResume = $('
  • ' + modal.find('.modal-header h3').text() + '
  • ') + modal.appendTo(twister.modal[i].drapper); + + twister.modal[i].minimized = true; + twister.modal[i].scroll = scroll; + twister.modal[i].btnResume = $('
  • ' + modal.find('.modal-header h3').text() + '
  • ') .on('click', {hashString: window.location.hash}, resumeModal) + .on('mouseup', {route: window.location.hash, blankOnly: true}, routeOnClick) .appendTo($('#modals-minimized')) ; - - _minimizedModals[window.location.hash] = { - self: modal, - scroll: scroll, - btnResume: btnResume - }; } + if (modal.is('.closed')) return; + var scroll; // MUST be setted before modal.detach(), modal.fadeOut() and so on if (modal.is('.directMessages') || modal.is('.group-messages-new-group') - || modal.is('.group-messages-join-group')) { + || modal.is('.group-messages-join-group') || modal.is('.following-own-modal')) { scroll = { targetSelector: '.modal-content', top: modal.find('.modal-content').scrollTop() @@ -123,10 +196,9 @@ function minimizeModal(modal, switchMode) { } function resumeModal(event) { - var elemEvent = $(event.target); - elemEvent.fadeOut('fast', function () {elemEvent.remove();}); + $(event.target).fadeOut('fast', function () {this.remove();}); - var modalActive = $('.modal-wrapper:not(#templates *)'); + var modalActive = $('.modal-wrapper:not(#templates *)').not('.closed'); if (modalActive.length) minimizeModal(modalActive, true); else { @@ -134,9 +206,10 @@ function resumeModal(event) { $('body').css('overflow', 'hidden'); } - var modal = _minimizedModals[event.data.hashString]; - if (modal) { - _minimizedModals[event.data.hashString] = undefined; + var modal = twister.modal[event.data.hashString]; + if (modal.self.not('.closed') && modal.minimized) { + modal.minimized = false; + modal.btnResume = undefined; if (window.location.hash !== event.data.hashString) { _watchHashChangeRelaxDontDoIt = true; window.location.hash = event.data.hashString; @@ -146,35 +219,39 @@ function resumeModal(event) { if (modal.scroll) modal.self.find($(modal.scroll.targetSelector).scrollTop(modal.scroll.top)); - if (modal.resume && typeof modal.resume.cbFunc === 'function') - modal.resume.cbFunc(modal.resume.cbArg); + if (typeof modal.onResume === 'function') + modal.onResume(modal.onResumeReq); }); } } -function focusModalWithElement(elem, cbFunc, cbArg) { +function focusModalWithElement(elem, cbFunc, cbReq) { if (elem.jquery ? elem.is('html *') : $(elem).is('html *')) { if (typeof cbFunc === 'function') - cbFunc(cbArg); + cbFunc(cbReq); return true; } - var hash = getHashOfMinimizedModalWithElem(elem); - if (hash) { - _minimizedModals[hash].resume = {cbFunc: cbFunc, cbArg: cbArg}; - _minimizedModals[hash].btnResume.click(); + var i = getHashOfMinimizedModalWithElem(elem); + if (i) { + if (typeof i === 'object') i = i[0]; // several modals, but only one may be active currently + twister.modal[i].onResume = cbFunc; + twister.modal[i].onResumeReq = cbReq; + twister.modal[i].btnResume.click(); return true; } return false; } -function getHashOfMinimizedModalWithElem(elem) { - for (var i in _minimizedModals) - if (_minimizedModals[i] && _minimizedModals[i].self.find(elem).length) - return i; +function getHashOfMinimizedModalWithElem(req) { + var hashes = []; + + for (var i in twister.modal) + if (twister.modal[i] && twister.modal[i].minimized && twister.modal[i].drapper.find(req).length) + hashes[hashes.length++] = i; - return ''; + return hashes.length > 1 ? hashes : hashes[0]; } function isModalWithElemExists(elem) { @@ -184,90 +261,97 @@ function isModalWithElemExists(elem) { return getHashOfMinimizedModalWithElem(elem) ? true : false; } -function confirmPopup(event, req) { - if (event && event.stopPropagation) { - event.stopPropagation(); +function confirmPopup(req) { + if (!req) return; - if (!req && event.data) - req = event.data; + if (typeof req.stopPropagation === 'function') { + req.preventDefault(); + req.stopPropagation(); + if (req.data) + req = req.data; + else + return; } var modal = openModal({ classBase: '.prompt-wrapper', classAdd: 'confirm-popup', content: $('#confirm-popup-template').children().clone(true), - title: req.titleTxt + title: req.txtTitle }); - if (req.messageTxt) - modal.content.find('.message').html(htmlFormatMsg(req.messageTxt, {markout: 'apply'}).html); + if (req.txtMessage) + modal.content.find('.message').html(htmlFormatMsg(req.txtMessage, {markout: 'apply'}).html); var btn = modal.content.find('.confirm'); if (req.removeConfirm) btn.remove(); else { - if (req.confirmTxt) - btn.text(req.confirmTxt); + if (req.txtConfirm) + btn.text(req.txtConfirm); else btn.text(polyglot.t('Confirm')); - if (req.confirmFunc) { - btn.on('click', function () { - closePrompt(); - req.confirmFunc(req.confirmFuncArgs); - }); - } else + + if (req.cbConfirm) + btn.on('click', {cbFunc: req.cbConfirm, cbReq: req.cbConfirmReq}, closePrompt); + else btn.on('click', closePrompt); } var btn = modal.content.find('.cancel'); if (req.removeCancel) btn.remove(); else { - if (req.cancelTxt) - btn.text(req.cancelTxt); + if (req.txtCancel) + btn.text(req.txtCancel); else btn.text(polyglot.t('Cancel')); - if (req.cancelFunc) { - btn.on('click', function () { - closePrompt(); - req.cancelFunc(req.cancelFuncArgs); - }); - } else + + if (req.cbCancel) + btn.on('click', {cbFunc: req.cbCancel, cbReq: req.cbCancelReq}, closePrompt); + else btn.on('click', closePrompt); } var btn = modal.self.find('.prompt-close'); if (req.removeClose) btn.remove(); else { - if (req.closeFunc) { - if (typeof req.closeFunc === 'string') { - if (req.closeFunc === 'confirmFunc') { - req.closeFunc = req.confirmFunc; - req.closeFuncArgs = req.confirmFuncArgs; - } else if (req.closeFunc === 'cancelFunc') { - req.closeFunc = req.cancelFunc; - req.closeFuncArgs = req.cancelFuncArgs; + if (req.cbClose) { + if (typeof req.cbClose === 'string') + if (req.cbClose === 'cbConfirm') { + req.cbClose = req.cbConfirm; + req.cbCloseReq = req.cbConfirmReq; + } else if (req.cbClose === 'cbCancel') { + req.cbClose = req.cbCancel; + req.cbCloseReq = req.cbCancelReq; } - } - btn.on('click', function () { - closePrompt(); - req.closeFunc(req.closeFuncArgs); - }); + + btn.on('click', {cbFunc: req.cbClose, cbReq: req.cbCloseReq}, closePrompt); } } } -function checkNetworkStatusAndAskRedirect(cbFunc, cbArg) { - networkUpdate(function(args) { +function alertPopup(req) { + if (!req) return; + + if (!req.txtConfirm) + req.txtConfirm = polyglot.t('btn_ok'); + req.removeCancel = true; + + confirmPopup(req); +} + +function checkNetworkStatusAndAskRedirect(cbFunc, cbReq) { + networkUpdate(function(req) { if (!twisterdConnectedAndUptodate) { - confirmPopup(null, { - messageTxt: polyglot.t('confirm_switch_to_network', {page: '/network.html'}), - confirmFunc: $.MAL.goNetwork + confirmPopup({ + txtMessage: polyglot.t('confirm_switch_to_network', {page: '/network.html'}), + cbConfirm: $.MAL.goNetwork }); } else { - if (args.cbFunc) - args.cbFunc(args.cbArg); + if (req.cbFunc) + req.cbFunc(req.cbReq); } - }, {cbFunc:cbFunc,cbArg:cbArg}); + }, {cbFunc: cbFunc, cbReq: cbReq}); } function timeGmtToText(t) { @@ -335,10 +419,10 @@ function openGroupProfileModalWithNameHandler(groupAlias) { elemFitNextIntoParentHeight(modal.content.find('.profile-card')); } -function openUserProfileModalWithNameHandler(username) { +function openUserProfileModalWithNameHandler(peerAlias) { var content = $('#profile-modal-template').children().clone(true); - updateProfileData(content, username); + updateProfileData(content, peerAlias); // FIXME following ctc could be part of updateProfileData() when mobile will be ready for this content.find('.tox-ctc').attr('title', polyglot.t('Copy to clipboard')); content.find('.bitmessage-ctc').attr('title', polyglot.t('Copy to clipboard')); @@ -346,17 +430,14 @@ function openUserProfileModalWithNameHandler(username) { var modal = openModal({ classAdd: 'profile-modal', content: content, - title: polyglot.t('users_profile', {username: username}) + title: polyglot.t('users_profile', {username: peerAlias}) }); - // setup follow button in profile modal window - var button = modal.content.find('.profile-card-buttons .follow'); - if (button) { - if (followingUsers.indexOf(username) !== -1) - toggleFollowButton(username, true, function() {setTimeout(loadModalFromHash, 500);}); - else - button.on('click', userClickFollow); - } + toggleFollowButton({ + button: modal.content.find('.profile-card-buttons .follow'), + peerAlias: peerAlias, + toggleUnfollow: followingUsers.indexOf(peerAlias) !== -1 ? true : false + }); elemFitNextIntoParentHeight(modal.content.find('.profile-card')); @@ -405,35 +486,38 @@ function updateQueryModal(req) { requestQuery(req); } -function openMentionsModal(e) { - if (e && e.stopPropagation) { - e.stopPropagation(); - e.preventDefault(); +function openMentionsModal(event) { + if (event && typeof event.stopPropagation === 'function') { + event.preventDefault(); + event.stopPropagation(); } var userInfo = $(this).closest('[data-screen-name]'); if (userInfo.length) - var username = userInfo.attr('data-screen-name'); + var peerAlias = userInfo.attr('data-screen-name'); else if (defaultScreenName) - var username = defaultScreenName; + var peerAlias = defaultScreenName; else { - alert(polyglot.t('No one can mention you because you are not logged in.')); + alertPopup({ + //txtTitle: polyglot.t(''), add some title (not 'error', please) or just KISS + txtMessage: polyglot.t('No one can mention you because you are not logged in.') + }); return; } - window.location.hash = '#mentions?user=' + username; + window.location.hash = '#mentions?user=' + peerAlias; } -function openMentionsModalHandler(username) { +function openMentionsModalHandler(peerAlias) { var modal = openModal({ classAdd: 'hashtag-modal', content: $('#hashtag-modal-template').children().clone(true), - title: polyglot.t('users_mentions', {username: username}) + title: polyglot.t('users_mentions', {username: peerAlias}) }); - setupQueryModalUpdating(modal.content.find('.postboard-posts'), username, 'mention'); + setupQueryModalUpdating(modal.content.find('.postboard-posts'), peerAlias, 'mention'); - if (username === defaultScreenName) { + if (peerAlias === defaultScreenName) { // obtain already cached mention posts from twister_newmsgs.js processQuery({ postboard: modal.content.find('.postboard-posts'), @@ -445,17 +529,73 @@ function openMentionsModalHandler(username) { } } -function openFollowingModal(username) { - var content = $('#following-modal-template').children().clone(true); +function openFollowingModal(peerAlias) { + if (!peerAlias || peerAlias === defaultScreenName) { + if (!defaultScreenName) { + alertPopup({ + //txtTitle: polyglot.t(''), add some title (not 'error', please) or just KISS + txtMessage: polyglot.t('You are not following anyone because you are not logged in.') + }); + history.back(); + return; + } - content.find('.following-screen-name b').text(username); - loadFollowingIntoList(username, content.closest('ol')); + var modal = openModal({ + classAdd: 'following-own-modal', + content: twister.tmpl.followingList.clone(true), + title: polyglot.t('Following') + }); + showFollowingUsers(modal.content.find('.following-list')); + requestSwarmProgress(); + } else { + var modal = openModal({ + classAdd: 'following-modal', + content: $('#following-modal-template').children().clone(true), + title: polyglot.t('followed_by', {username: peerAlias}) + }); + modal.content.find('.following-screen-name b').text(peerAlias); + loadFollowingIntoList(peerAlias, modal.content.find('ol')); + } +} - openModal({ - classAdd: 'following-modal', - content: content, - title: polyglot.t('followed_by', {username: username}) +function showFollowingUsers(followingList) { + if (followingEmptyOrMyself()) + $.MAL.warnFollowingNotAny(closeModal, followingList); + else + for (var i = 0; i < followingUsers.length; i++) + addToFollowingList(followingList, followingUsers[i]); + + $.MAL.followingListLoaded(followingList); +} + +function addToFollowingList(followingList, peerAlias) { + var item = twister.tmpl.followingUser.clone(true).attr('data-peer-alias', peerAlias); + + item.find('.mini-profile-info').attr('data-screen-name', peerAlias) + item.find('.following-screen-name').text(peerAlias); + item.find('a.open-profile-modal').attr('href', $.MAL.userUrl(peerAlias)); + item.find('.direct-messages-with-user').text(polyglot.t('send_DM')) + .on('mouseup', {route: $.MAL.dmchatUrl(peerAlias)}, routeOnClick); + item.find('.mentions-from-user').text(polyglot.t('display_mentions')) + .on('mouseup', {route: $.MAL.mentionsUrl(peerAlias)}, routeOnClick); + getAvatar(peerAlias, item.find('.mini-profile-photo')); + getFullname(peerAlias, item.find('.mini-profile-name')); + + if (peerAlias === defaultScreenName) + item.find('following-config').hide(); + + toggleFollowButton({ + button: item.find('.follow'), + peerAlias: peerAlias, + toggleUnfollow: true }); + var elem = item.find('.public-following').on('click', followingListPublicCheckbox); + if (isPublicFollowing(peerAlias)) + elem.text(polyglot.t('Public')); + else + elem.text(polyglot.t('Private')).addClass('private'); + + item.prependTo(followingList); } function fillWhoToFollowModal(list, hlist, start) { @@ -517,10 +657,10 @@ function openWhoToFollowModal() { fillWhoToFollowModal(tmplist, hlist, 0); } -function newConversationModal(username, resource) { +function newConversationModal(peerAlias, resource) { var content = $('#hashtag-modal-template').children().clone(true); - requestPost(content.find('.postboard-posts'), username, resource, + requestPost(content.find('.postboard-posts'), peerAlias, resource, function(args) { var postboard = args.content.find('.postboard-posts'); var postLi = postboard.children().first() @@ -532,27 +672,42 @@ function newConversationModal(username, resource) { return content; } -function openConversationClick(e) { - e.stopPropagation(); - e.preventDefault(); +function openConversationClick(event) { + event.preventDefault(); + event.stopPropagation(); - var postData = $(this).closest(e.data.feeder); + var elem = $(event.target); + var postData = elem.closest(event.data.feeder); - window.location.hash = '#conversation?post=' + postData.attr('data-screen-name') + - ':post' + postData.attr('data-id'); + event.data.route = '#conversation?post=' + postData.attr('data-screen-name') + + ':post' + postData.attr('data-id'); + routeOnClick(event); } -function openConversationModal(username, resource) { +function openConversationModal(peerAlias, resource) { openModal({ classAdd: 'conversation-modal', - content: newConversationModal(username, resource), - title: polyglot.t('conversation_title', {username: username}) + content: newConversationModal(peerAlias, resource), + title: polyglot.t('conversation_title', {username: peerAlias}) }); } -function watchHashChange(e) { - if (e != null) { - var prevurlsplit = e.oldURL.split('#'); +function routeOnClick(event) { + if (!event || !event.data || !event.data.route) + return; + + event.stopPropagation(); + event.preventDefault(); + + if (event.button === 0 && !event.data.blankOnly) // left mouse button + window.location = event.data.route; + else if (event.button === 1) // middle mouse button + twister.html.blanka.attr('href', event.data.route)[0].click(); +} + +function watchHashChange(event) { + if (typeof event !== 'undefined') { + var prevurlsplit = event.oldURL.split('#'); var prevhashstring = prevurlsplit[1]; // FIXME need to move back button handling to special function and call it in openModal() and resumeModal() @@ -575,17 +730,18 @@ function watchHashChange(e) { } function loadModalFromHash() { - if (_minimizedModals[window.location.hash]) { + var i = window.location.hash; + if (twister.modal[i] && twister.modal[i].minimized) { // need to remove active modal before btnResume.click() or it will be minimized in resumeModal() // e.g. for case when you click on profile link in some modal having this profile's modal minimized already $('.modal-wrapper:not(#templates *)').remove(); - _minimizedModals[window.location.hash].btnResume.click(); + twister.modal[i].btnResume.click(); return; } var hashstring = decodeURIComponent(window.location.hash); if (hashstring === '') { - closeModal(); + closeModal(); // close active modal(s) return; } var hashdata = hashstring.split(':'); @@ -618,6 +774,8 @@ function loadModalFromHash() { } } else if (hashstring === '#directmessages') directMessagesPopup(); + else if (hashstring === '#following') + openFollowingModal(); else if (hashstring === '#groupmessages') openGroupMessagesModal(); else if (hashstring === '#groupmessages+newgroup') @@ -649,7 +807,10 @@ function reTwistPopup(event, post, textArea) { event.stopPropagation(); if (!defaultScreenName) { - alert(polyglot.t('You have to log in to retransmit messages.')); + alertPopup({ + //txtTitle: polyglot.t(''), add some title (not 'error', please) or just KISS + txtMessage: polyglot.t('You have to log in to retransmit messages.') + }); return; } @@ -669,8 +830,13 @@ function reTwistPopup(event, post, textArea) { modal.content.find('.switch-mode') .text(polyglot.t('Switch to Reply')) - .on('click', (function(event) {replyInitPopup(event, post, - $(event.target).closest('form').find('textarea').detach());}).bind(post)) + .on('click', {post: post}, + function(event) { + var textArea = $(event.target).closest('form').find('textarea').detach(); + closePrompt(event.target); + replyInitPopup(event, event.data.post, textArea); + } + ) ; var replyArea = modal.content.find('.post-area .post-area-new'); @@ -707,8 +873,13 @@ function replyInitPopup(e, post, textArea) { modal.content.find('.switch-mode') .text(polyglot.t('Switch to Retransmit')) - .on('click', (function(event) {reTwistPopup(event, post, - $(event.target).closest('form').find('textarea').detach())}).bind(post)) + .on('click', {post: post}, + function(event) { + var textArea = $(event.target).closest('form').find('textarea').detach(); + closePrompt(event.target); + reTwistPopup(event, event.data.post, textArea); + } + ) ; var replyArea = modal.content.find('.post-area .post-area-new').addClass('open'); @@ -734,48 +905,144 @@ function closeThis() { $(this).slideUp('fast'); } -function toggleFollowButton(username, toggleUnfollow, bindFunc) { - if (!username) +function toggleFollowButton(req) { + if (!req || !req.peerAlias) return; - if (toggleUnfollow) { - $('[data-screen-name="'+username+'"]').find('.follow') + if (req.toggleUnfollow) { + if (!req.button || !req.button.jquery) + req.button = getElem('[data-screen-name="' + req.peerAlias + '"]').find('.follow'); + req.button + .text(polyglot.t('Unfollow')) .removeClass('follow') .addClass('unfollow') .off('click') - .on('click', - (function(e) { - e.stopPropagation(); - - unfollow(this.username.toString(), - (function() { - toggleFollowButton(this.username); - if (this.bindFunc) - this.bindFunc; - }).bind({username: this.username, bindFunc: this.bindFunc}) - ); - }).bind({username: username, bindFunc: bindFunc}) - ) - .text(polyglot.t('Unfollow')) - .trigger('eventToggleUnfollow') + .on('click', {peerAlias: req.peerAlias}, clickUnfollow) ; } else { - $('[data-screen-name="'+username+'"]').find('.unfollow') + if (!req.button || !req.button.jquery) + req.button = getElem('[data-screen-name="' + req.peerAlias + '"]').find('.unfollow'); + req.button + .text(polyglot.t('Follow')) .removeClass('unfollow') .addClass('follow') .off('click') - .on('click', - (function(e) { - userClickFollow(e); - if (this.bindFunc) - this.bindFunc; - }).bind({bindFunc: bindFunc}) - ) - .text(polyglot.t('Follow')) - .trigger('eventToggleFollow'); + .on('click', {peerAlias: req.peerAlias}, clickFollow) + ; } } +function clickFollow(event) { + event.preventDefault(); + event.stopPropagation(); + + if (!defaultScreenName) { + alertPopup({ + //txtTitle: polyglot.t(''), add some title (not 'error', please) or just KISS + txtMessage: polyglot.t('You have to log in to follow users.') + }); + return; + } + + var peerAlias = (event.data && event.data.peerAlias) ? event.data.peerAlias + : $(event.target).closest('[data-screen-name]').attr('data-screen-name'); + var content = $('#following-config-modal-template').children().clone(true); + + content.closest('.following-config-modal-content').attr('data-screen-name', peerAlias); + content.find('.following-config-method-message') + .html(htmlFormatMsg(polyglot.t('select_way_to_follow_@', {alias: peerAlias}), {markout: 'apply'}).html); + content.find('.following-screen-name b').text(peerAlias); + + openModal({ + classBase: '.prompt-wrapper', // FIXME it will be modal with advanced following set up in future + classAdd: 'following-config-modal', + content: content, + title: polyglot.t('Following config') + }); +} + +function clickUnfollow(event) { + event.preventDefault(); + event.stopPropagation(); + + var peerAlias = (event.data && event.data.peerAlias) ? event.data.peerAlias + : $(event.target).closest('[data-screen-name]').attr('data-screen-name'); + + confirmPopup({ + txtMessage: polyglot.t('confirm_unfollow_@', {alias: peerAlias}), + cbConfirm: function (peerAlias) { + unfollow(peerAlias, + function(req) { + $('.mini-profile .following-count').text(followingUsers.length - 1); + $('.wrapper .postboard .post').each(function() { + var elem = $(this); + if ((elem.find('[data-screen-name="' + req.peerAlias + '"]').length + && !elem.find(".post-rt-by .open-profile-modal").text()) + || elem.find(".post-rt-by .open-profile-modal").text() === '@' + req.peerAlias) + elem.remove(); + }); // FIXME also need to check list of pending posts to remove from there + toggleFollowButton({peerAlias: req.peerAlias}); + var followingList = getElem('.following-own-modal .following-list'); + if (followingList.length) + followingList.find('li[data-peer-alias="' + req.peerAlias + '"]').remove(); + }, {peerAlias: peerAlias} + ); + }, + cbConfirmReq: peerAlias + }); +} + +function setFollowingMethod(event) { + event.preventDefault(); + event.stopPropagation(); + + var button = $(event.target); + var peerAlias = button.closest('.following-config-modal-content').attr('data-screen-name'); + + follow(peerAlias, button.hasClass('private') ? false : true, + function(req) { + $('.mini-profile .following-count').text(followingUsers.length - 1); + setTimeout(requestTimelineUpdate, 1000, 'latest', postsPerRefresh, [req.peerAlias], promotedPostsOnly); + toggleFollowButton({peerAlias: req.peerAlias, toggleUnfollow: req.toggleUnfollow}); + var followingList = getElem('.following-own-modal .following-list'); + if (followingList.length) + addToFollowingList(followingList, req.peerAlias); + }, {peerAlias: peerAlias, toggleUnfollow: true} + ); +} + +function followingListPublicCheckbox(event) { + event.preventDefault(); + event.stopPropagation(); + + var tickSelection = function (req) { + if (req.isPublic === req.wasPublic) return; + + var elem = $('.mini-profile-info[data-screen-name="' + req.peerAlias + '"] .public-following'); + elem.toggleClass('private'); + if (!req.isPublic) + elem.text(polyglot.t('Private')); + else + elem.text(polyglot.t('Public')); + + //console.log('set following method of @' + peerAlias + ' for ' + isPublic); + follow(req.peerAlias, req.isPublic); + }; + var elem = $(event.target); + var peerAlias = elem.closest('.mini-profile-info').attr('data-screen-name'); + var wasPublic = !elem.hasClass('private'); + + confirmPopup({ + txtMessage: polyglot.t('select_way_to_follow_@', {alias: peerAlias}), + txtConfirm: polyglot.t('Public'), + cbConfirm: tickSelection, + cbConfirmReq: {isPublic: true, wasPublic: wasPublic, peerAlias: peerAlias}, + txtCancel: polyglot.t('Private'), + cbCancel: tickSelection, + cbCancelReq: {isPublic: false, wasPublic: wasPublic, peerAlias: peerAlias} + }); +} + function postExpandFunction(e, postLi) { if (!postLi.hasClass('original')) return; @@ -825,23 +1092,26 @@ function postExpandFunction(e, postLi) { e.stopPropagation(); } -function postReplyClick(e) { +function postReplyClick(event) { if (!defaultScreenName) { - e.stopPropagation(); - alert(polyglot.t('You have to log in to post replies.')); + event.stopPropagation(); + alertPopup({ + //txtTitle: polyglot.t(''), add some title (not 'error', please) or just KISS + txtMessage: polyglot.t('You have to log in to post replies.') + }); return; } var post = $(this).closest('.post'); if (!post.hasClass('original')) - replyInitPopup(e, $.evalJSON(post.find('.post-data').attr('data-userpost'))); + replyInitPopup(event, $.evalJSON(post.find('.post-data').attr('data-userpost'))); else { if (!post.closest('.post.open').length) - postExpandFunction(e, post); - composeNewPost(e, post.find('.post-area-new')); + postExpandFunction(event, post); + composeNewPost(event, post.find('.post-area-new')); } - e.stopPropagation(); + event.stopPropagation(); } // Expande Área do Novo post @@ -1588,7 +1858,7 @@ function postSubmit(e, oldLastPostId) { } if (btnPostSubmit.closest('.prompt-wrapper').length) - closePrompt(); + closePrompt(btnPostSubmit); else { textArea.val('').attr('placeholder', polyglot.t('Your message was sent!')); btnPostSubmit.closest('form').find('.post-area-remaining').text('140'); @@ -1601,13 +1871,14 @@ function postSubmit(e, oldLastPostId) { } } -function retweetSubmit(e) { - e.stopPropagation(); - e.preventDefault(); +function retweetSubmit(event) { + event.preventDefault(); + event.stopPropagation(); - newRtMsg($(this).closest('.prompt-wrapper').find('.post-data')); + var prompt = $(event.target).closest('.prompt-wrapper'); - closePrompt(); + newRtMsg(prompt.find('.post-data')); + closePrompt(prompt); } function changeStyle() { @@ -1680,13 +1951,7 @@ function replaceDashboards() { } function initInterfaceCommon() { - $('.modal-close, .modal-blackout').not('.prompt-close').on('click', function() { - if ($('.modal-content').attr('style') != undefined) - $('.modal-content').removeAttr('style'); - $('.modal-back').css('display', 'none'); - $('.mark-all-as-read').css('display', 'none'); - closeModal(); - }); + $('.modal-close, .modal-blackout').not('.prompt-close').on('click', closeModal); $('.minimize-modal').on('click', function (event) { minimizeModal($(event.target).closest('.modal-wrapper')); @@ -1696,13 +1961,12 @@ function initInterfaceCommon() { $('.prompt-close').on('click', closePrompt); - /* - $('.modal-back').on('click', function() { - if ($('.modal-content .direct-messages-list')[0]) return; - directMessagesPopup(); - $('.modal-content').removeAttr('style'); + $('button.follow').on('click', clickFollow); + + $('.following-config-method-buttons .public-following').on('click', function(event) { + setFollowingMethod(event); + closePrompt(event); }); - */ $('.post-text').on('click', 'a', function(e) {e.stopPropagation();}); $('.post-reply').on('click', postReplyClick); @@ -1726,7 +1990,7 @@ function initInterfaceCommon() { ; $('.post-submit').on('click', postSubmit); $('.modal-propagate').on('click', retweetSubmit); - $('.expanded-content .show-more').on('click', + $('.expanded-content .show-more').on('mouseup', {feeder: '.module.post.original.open .module.post.original .post-data'}, openConversationClick); if ($.Options.unicodeConversion.val === 'disable') @@ -1792,6 +2056,10 @@ function initInterfaceCommon() { } } +function extractTemplate(selector) { + return $(selector).appendTo(twister.html.detached).children(); +} + function promptCopyAttrData(event) { window.prompt(polyglot.t('copy_to_clipboard'), $(event.target).attr('data')); } @@ -1855,14 +2123,17 @@ function setTextcompleteDropdownListPos(position) { return this; } -$(document).ready(function() -{ +$(document).ready(function () { + twister.html.blanka.appendTo('body').hide(); + twister.tmpl.followingList = extractTemplate('#template-following-list'); + twister.tmpl.followingUser = extractTemplate('#template-following-user'); + twister.tmpl.postRtReference = extractTemplate('#template-post-rt-reference') + .on('mouseup', {feeder: '.post-rt-reference'}, openConversationClick); + twister.tmpl.postRtBy = extractTemplate('#template-post-rt-by'); + var path = window.location.pathname; var page = path.split("/").pop(); - if (page.indexOf("following.html") === 0) { - initInterfaceFollowing(); - initHashWatching(); - } else if (page.indexOf("login.html") === 0) { + if (page.indexOf("login.html") === 0) { initInterfaceLogin(); } else if (page.indexOf("network.html") === 0) { initInterfaceNetwork(); diff --git a/js/interface_home.js b/js/interface_home.js index 6510b87..c7b4e1b 100644 --- a/js/interface_home.js +++ b/js/interface_home.js @@ -100,22 +100,6 @@ var InterfaceFunctions = function() { args.cbFunc(args.cbArg); }, {cbFunc:cbFunc, cbArg:cbArg}); - $(window) - .on('eventFollow', function(e, user) { - $('.mini-profile .following-count').text(followingUsers.length - 1); - setTimeout(requestTimelineUpdate, 1000, 'latest', postsPerRefresh, [user], promotedPostsOnly); - }) - .on('eventUnfollow', function(e, user) { - $('.mini-profile .following-count').text(followingUsers.length - 1); - $('.wrapper .postboard .post').each( function() { - var elem = $(this); - if ((elem.find('[data-screen-name="' + user + '"]').length - && !elem.find(".post-rt-by .open-profile-modal").text()) - || elem.find(".post-rt-by .open-profile-modal").text() === '@' + user) - elem.remove(); - }); - }); - if ($.Options.WhoToFollow.val === 'enable') initWhoToFollow(); else diff --git a/js/interface_localization.js b/js/interface_localization.js index 47ede16..a76107b 100644 --- a/js/interface_localization.js +++ b/js/interface_localization.js @@ -53,6 +53,7 @@ if(preferredLanguage == "en"){ "If you stay in this page your actions may not work.\n" + "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}?", "Change user": "Change user", "Checking...": "Checking...", // checking if username is available "Collapse": "Collapse", // smaller view of a post @@ -68,7 +69,7 @@ if(preferredLanguage == "en"){ "Group Messages — Join Group": "Group Messages — Join Group", "direct_messages_with": "Direct messages with %{username}", "Disable": "Disable", - "Display mentions to @": "Display mentions to @", + "display_mentions": "Display mentions", "Display retransmissions": "Display retransmissions", "DNS to obtain list of peers:": "DNS to obtain list of peers:", "downloading_block_chain": "Downloading block chain, please wait before continuing (block chain is %{days} days old).", @@ -84,7 +85,7 @@ if(preferredLanguage == "en"){ "File APIs not supported in this browser.": "File APIs not supported in this browser.", "Follow": "Follow", "Following config": "Following config", - "Which way do you want to follow": "Which way do you want to follow", + "select_way_to_follow_@": "Which way do you want to follow @%{alias}", "Followed by": "Followed by", "followed_by": "Followed by %{username}", "Followers": "Followers", @@ -126,6 +127,7 @@ if(preferredLanguage == "en"){ "new_group_messages": "%{smart_count} new group message |||| %{smart_count} new group messages", "nobody": "nobody", // used to promote a post without attaching the user "Not available": "Not available", // username is not available + "warn_following_not_any": "Not following any twisters!\nSearch and follow someone.", "notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.", "notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for %{this_domain} in settings of your browser.", "notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.", @@ -159,7 +161,7 @@ if(preferredLanguage == "en"){ "seconds": "%{smart_count} second |||| %{smart_count} seconds", "send": "send", "Send post with username": "Send post with username ", - "Sent Direct Message": "Sent Direct Message", + "send_DM": "Send direct message", "Sent Post to @": "Sent Post to @", "Setup account": "Setup account", "The File APIs are not fully supported in this browser.": "The File APIs are not fully supported in this browser.", @@ -374,6 +376,7 @@ if(preferredLanguage == "es"){ "Si te quedas en esta página tus acciones pueden no funcionar.\n" + "¿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}?", "Change user": "Cambiar de usuario", "Checking...": "Comprobando ...", // checking if username is available "Collapse": "Colapsar", // smaller view of a post @@ -389,7 +392,7 @@ if(preferredLanguage == "es"){ "Group Messages — Join Group": "Group Messages — Join Group", "direct_messages_with": "Mensajes directos con %{username}", "Disable": "Inhabilitar", - "Display mentions to @": "Visualización de menciones a @", + "display_mentions": "Visualización de menciones", "Display retransmissions": "Visualización de retransmisiones", "DNS to obtain list of peers:": "DNS para obtener la lista de los pares:", "downloading_block_chain": "Descarga de la cadena de bloques, por favor espere antes de continuar (la cadena de bloques esta %{days} días).", @@ -405,7 +408,7 @@ if(preferredLanguage == "es"){ "File APIs not supported in this browser.": "Los archivos API no compatibles con este navegador", "Follow": "Seguir", "Following config": "Following config", - "Which way do you want to follow": "Which way do you want to follow", + "select_way_to_follow_@": "Which way do you want to follow @%{alias}", "Followed by": "Seguido por", "followed_by": "Seguido por %{username}", "Followers": "Seguidores", @@ -447,6 +450,7 @@ if(preferredLanguage == "es"){ "new_group_messages": "%{smart_count} new group message |||| %{smart_count} new group messages", "nobody": "Nadie", // used to promote a post without attaching the user "Not available": "No disponible", // username is not available + "warn_following_not_any": "Not following any twisters!\nSearch and follow someone.", "notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.", "notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for %{this_domain} in settings of your browser.", "notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.", @@ -480,7 +484,7 @@ if(preferredLanguage == "es"){ "seconds": "%{smart_count} segundo |||| %{smart_count} segundos", "send": "send", "Send post with username": "Enviar post con nombre de usuario ", - "Sent Direct Message": "Mensaje directo", + "send_DM": "Mensaje directo", "Sent Post to @": "El Post enviado a @", "Setup account": "Configuración de la cuenta", "The File APIs are not fully supported in this browser.": "Las API de archivos no son totalmente compatibles con este navegador.", @@ -679,6 +683,7 @@ if(preferredLanguage == "uk"){ "Якщо ви залишитесь на цій сторінці ваші дії можуть не спрацювати.\n" + "Чи бажаєте ви перевірити [сторінку зі статусом мережі](%{page})?", "confirm_terminate_daemon": "Ви впевнені, що бажаєте завершити роботу?\nКлієнт Twister буде зупинено допоки ви не запустите його знову.", + "confirm_unfollow_@": "Are you sure you want to unfollow @%{alias}?", "Change user": "Змінити користувача", "Checking...": "Перевірка...", // checking if username is available "Collapse": "Згорнути", // smaller view of a post @@ -694,7 +699,7 @@ if(preferredLanguage == "uk"){ "Group Messages — Join Group": "Group Messages — Join Group", "direct_messages_with": "Direct messages with %{username}", "Disable": "Вимкнено", - "Display mentions to @": "Показати сповіщення @", + "display_mentions": "Показати сповіщення", "Display retransmissions": "Показати пересилання", "DNS to obtain list of peers:": "DNS для отримання пірів:", "dns address": "адреса DNS", @@ -711,7 +716,7 @@ if(preferredLanguage == "uk"){ "File APIs not supported in this browser.": "File APIs не підтримуєтся цим браузером.", "Follow": "Читати", "Following config": "Налаштування читання", - "Which way do you want to follow": "У який спосіб ви бажаєте читати", + "select_way_to_follow_@": "У який спосіб ви бажаєте читати @%{alias}", "Followed by": "читає", "followed_by": "%{username} читає", "Followers": "Читачі", @@ -753,6 +758,7 @@ if(preferredLanguage == "uk"){ "new_group_messages": "%{smart_count} new group message |||| %{smart_count} new group messages", "nobody": "анонім", // used to promote a post without attaching the user "Not available": "Не доступне", // username is not available + "warn_following_not_any": "Not following any twisters!\nSearch and follow someone.", "notify_desktop_error": "Twister не може створити сповіщення: невідома помилка.", "notify_desktop_perm_denied": "Twister не може створити сповіщення на робочому столі: доступ обмежено.\n\nЯкщо ви бажаєте отримувати сповіщення, дозвольте їх виконання в налаштуваннях браузера для %{this_domain}.", "notify_desktop_test": "Є дещо новеньке у стрічці.", @@ -786,7 +792,7 @@ if(preferredLanguage == "uk"){ "seconds": "%{smart_count} секунда |||| %{smart_count} секунд", "send": "відіслати", "Send post with username": "Надіслати повідомлення від", - "Sent Direct Message": "Надіслати особисте повідомлення", + "send_DM": "Надіслати особисте повідомлення", "Sent Post to @": "Надіслати твіст @", "Setup account": "Обліковий запис", "The File APIs are not fully supported in this browser.": "File APIs не повністю підтримується браузером.", @@ -983,6 +989,7 @@ if(preferredLanguage == "zh-CN"){ "如果你留在此页面你的操作将不会生效。\n" + "你要跳转到[网络状态页](%{page})吗?", "confirm_terminate_daemon": "你确定要退出后台进程?\nTwister 客户端将停止工作。", + "confirm_unfollow_@": "Are you sure you want to unfollow @%{alias}?", "Change user": "切换用户", "Checking...": "检查中...", // checking if username is available "Collapse": "折叠", // smaller view of a post @@ -998,7 +1005,7 @@ if(preferredLanguage == "zh-CN"){ "Group Messages — Join Group": "Group Messages — Join Group", "direct_messages_with": "Direct messages with %{username}", "Disable": "关闭", - "Display mentions to @": "显示@", + "display_mentions": "显示", "Display retransmissions": "显示转发", "DNS to obtain list of peers:": "用DNS获取节点列表:", "downloading_block_chain": "区块链下载中,请等待下载完成(区块链仍落后 %{days} 天)。", @@ -1014,7 +1021,7 @@ if(preferredLanguage == "zh-CN"){ "File APIs not supported in this browser.": "这个浏览器不支持 File API。", "Follow": "关注", "Following config": "关注配置", - "Which way do you want to follow": "你想以哪种方式关注", + "select_way_to_follow_@": "你想以哪种方式关注 @%{alias}", "Followed by": "关注者", "followed_by": "被 %{username} 关注", "Followers": "粉丝", @@ -1056,6 +1063,7 @@ if(preferredLanguage == "zh-CN"){ "new_group_messages": "%{smart_count} new group message |||| %{smart_count} new group messages", "nobody": "无名", // used to promote a post without attaching the user "Not available": "用户名不可用", // username is not available + "warn_following_not_any": "Not following any twisters!\nSearch and follow someone.", "notify_desktop_error": "Twister 无法发出桌面提醒:发生未知错误。", "notify_desktop_perm_denied": "Twister 无法发出桌面提醒:权限被拒绝。\n\n如果你想收到提醒,请在你的浏览器设置中允许 %{this_domain} 发出提醒。", "notify_desktop_test": "我们都在用 Twister。\n欢迎你的加入。", @@ -1089,7 +1097,7 @@ if(preferredLanguage == "zh-CN"){ "seconds": "%{smart_count} 秒", "send": "发送", "Send post with username": "发送推文的用户名", - "Sent Direct Message": "发送私信", + "send_DM": "发送私信", "Sent Post to @": "发送推文 @", "Setup account": "设置账号", "The File APIs are not fully supported in this browser.": "这个浏览器不能完全支持 File API。", @@ -1304,6 +1312,7 @@ if(preferredLanguage == "nl"){ "If you stay in this page your actions may not work.\n" + "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}?", "Change user": "Gebruiker wijzigen", "Checking...": "Controleren...", // checking if username is available "Collapse": "Uitklappen", // smaller view of a post @@ -1319,7 +1328,7 @@ if(preferredLanguage == "nl"){ "Group Messages — Join Group": "Group Messages — Join Group", "direct_messages_with": "Direct messages with %{username}", "Disable": "Uitschakelen", - "Display mentions to @": "Toon vermeldingen voor @", + "display_mentions": "Toon vermeldingen", "Display retransmissions": "Toon retransmissions", "DNS to obtain list of peers:": "DNS om peers lijst op te halen:", "downloading_block_chain": "Bezig met downloaden block chain, wacht a.u.b. voordat je doorgaat (block chain is %{days} dagen oud).", @@ -1335,7 +1344,7 @@ if(preferredLanguage == "nl"){ "File APIs not supported in this browser.": "File APIs worden nie ondersteund in deze browser.", "Follow": "Volgen", "Following config": "Following config", - "Which way do you want to follow": "Which way do you want to follow", + "select_way_to_follow_@": "Which way do you want to follow @%{alias}", "Followed by": "Gevolgd door", "followed_by": "Gevolgd door %{username}", "Followers": "Volgers", @@ -1377,6 +1386,7 @@ if(preferredLanguage == "nl"){ "new_group_messages": "%{smart_count} new group message |||| %{smart_count} new group messages", "nobody": "nobody", // used to promote a post without attaching the user "Not available": "Niet beschikbaar", // username is not available + "warn_following_not_any": "Not following any twisters!\nSearch and follow someone.", "notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.", "notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for %{this_domain} in settings of your browser.", "notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.", @@ -1410,7 +1420,7 @@ if(preferredLanguage == "nl"){ "seconds": "%{smart_count} seconde |||| %{smart_count} seconden", "send": "Verstuur", "Send post with username": "Verstuur bericht met gebruikersnaam ", - "Sent Direct Message": "Verstuur privébericht", + "send_DM": "Verstuur privébericht", "Sent Post to @": "Verstuur bericht naar @", "Setup account": "Account instellingen", "The File APIs are not fully supported in this browser.": "The File APIs are not fully supported in this browser.", @@ -1609,6 +1619,7 @@ if(preferredLanguage == "it"){ "Se rimani su questa pagina, Twister potrebbe non funzionare.\n" + "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}?", "Change user": "Cambia utente", "Checking...": "Controllo in corso...", // checking if username is available "Collapse": "Chiudi", // smaller view of a post @@ -1624,7 +1635,7 @@ if(preferredLanguage == "it"){ "Group Messages — Join Group": "Group Messages — Join Group", "direct_messages_with": "Messaggi Diretti come %{username}", "Disable": "Disabilitato", - "Display mentions to @": "Mostra le menzioni di @", + "display_mentions": "Mostra le menzioni", "Display retransmissions": "Mostra Ripubblicazioni", "DNS to obtain list of peers:": "DNS per la lista dei nodi:", "downloading_block_chain": "Scaricamento della catena di blocchi in corso, attendere prego (la catena risale a %{days} giorni fa).", @@ -1640,7 +1651,7 @@ if(preferredLanguage == "it"){ "File APIs not supported in this browser.": "File APIs non supportati in questo browser.", "Follow": "Segui", "Following config": "Following config", - "Which way do you want to follow": "Which way do you want to follow", + "select_way_to_follow_@": "Which way do you want to follow @%{alias}", "Followed by": "Seguito da", "followed_by": "Seguiti da %{username}", "Followers": "Lettori", @@ -1682,6 +1693,7 @@ if(preferredLanguage == "it"){ "new_group_messages": "%{smart_count} new group message |||| %{smart_count} new group messages", "nobody": "nessuno", // used to promote a post without attaching the user "Not available": "Non disponibile", // username is not available + "warn_following_not_any": "Not following any twisters!\nSearch and follow someone.", "notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.", "notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for %{this_domain} in settings of your browser.", "notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.", @@ -1715,7 +1727,7 @@ if(preferredLanguage == "it"){ "seconds": "%{smart_count} secondo |||| %{smart_count} secondi", "send": "Invia", "Send post with username": "Pubblica come utente ", - "Sent Direct Message": "Messaggi Diretti inviati", + "send_DM": "Messaggi Diretti inviati", "Sent Post to @": "Messaggi inviati a @", "Setup account": "Configurazione Utente", "The File APIs are not fully supported in this browser.": "Le API File non sono interamente supportate da questo browser.", @@ -1912,6 +1924,7 @@ if(preferredLanguage == "fr"){ "Si vous restez dans cette page vos actions peuvent ne pas être prises en compte.\n" + "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}?", "Change user": "Changer d'utilisateur", "Checking...": "Vérification...", // checking if username is available "Collapse": "Fermer", // smaller view of a post @@ -1927,7 +1940,7 @@ if(preferredLanguage == "fr"){ "Group Messages — Join Group": "Group Messages — Join Group", "direct_messages_with": "Messages privés avec %{username}", "Disable": "Désactiver", - "Display mentions to @": "Afficher les mentions pour @", + "display_mentions": "Afficher les mentions", "Display retransmissions": "Afficher les retransmissions", "DNS to obtain list of peers:": "DNS où obtenir une liste des pairs:", "downloading_block_chain": "Téléchargement de la chaîne de blocs, veuillez patienter avant de continuer (la chaîne de blocs a %{days} jours de retard).", @@ -1943,7 +1956,7 @@ if(preferredLanguage == "fr"){ "File APIs not supported in this browser.": "L'API de fichiers n'est pas pris en charge dans votre navigateur.", "Follow": "Suivre", "Following config": "Following config", - "Which way do you want to follow": "Which way do you want to follow", + "select_way_to_follow_@": "Which way do you want to follow @%{alias}", "Followed by": "Suivi par", "followed_by": "Suivi par %{username}", "Followers": "Abonnés", @@ -1985,6 +1998,7 @@ if(preferredLanguage == "fr"){ "new_group_messages": "%{smart_count} new group message |||| %{smart_count} new group messages", "nobody": "nobody", // used to promote a post without attaching the user "Not available": "Non disponible", // username is not available + "warn_following_not_any": "Not following any twisters!\nSearch and follow someone.", "notify_desktop_error": "Impossible d'afficher les notifications: une erreur inconnue est survenue.", "notify_desktop_perm_denied": "Impossible d'afficher les notifications: autorisation refusée.\n\nSi tu souhaites afficher les notifications, autorise le %{this_domain} dans les paramêtres de ton navigateur.", "notify_desktop_test": "All the twisters gonna twist.\nBienvenue à toi!", @@ -2018,7 +2032,7 @@ if(preferredLanguage == "fr"){ "seconds": "%{smart_count} seconde |||| %{smart_count} secondes", "send": "envoyer", "Send post with username": "Envoyer le billet avec le pseudo", - "Sent Direct Message": "Message privé envoyé", + "send_DM": "Message privé envoyé", "Sent Post to @": "Envoyer un billet à @", "Setup account": "Configuration du compte", "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.", @@ -2219,6 +2233,7 @@ if(preferredLanguage == "ru"){ "Если вы останетесь на этой странице ваши действия могут быть не выполнены.\n" + "Не хотите перейти на [страницу настройки сети](%{page})?", "confirm_terminate_daemon": "Вы уверены, что хотите выключить демон?\nTwister клиент перестанет работать.", + "confirm_unfollow_@": "Действительно отписаться от @%{alias}?", "Change user": "Сменить пользователя", "Checking...": "Проверка...", "Collapse": "Свернуть", @@ -2234,7 +2249,7 @@ if(preferredLanguage == "ru"){ "Group Messages — Join Group": "Групповые сообщения — Присоединиться к группе", "direct_messages_with": "Личная переписка с %{username}", "Disable": "Отключено", - "Display mentions to @": "Показать ответы для @", + "display_mentions": "Показать упоминания", "Display retransmissions": "Показать репосты", "DNS to obtain list of peers:": "DNS адрес для получения пиров:", "downloading_block_chain": "Загрузка цепочки блоков, пожалуйста подождите, (Цепочка блоков устарела на %{days} дней).", @@ -2250,11 +2265,11 @@ if(preferredLanguage == "ru"){ "File APIs not supported in this browser.": "Ваш браузер не поддерживает File APIs.", "Follow": "Подписаться", "Following config": "Настройка подписки", - "Which way do you want to follow": "Выберите тип подписки на", + "select_way_to_follow_@": "Выбери же тип подписки на @%{alias}", "Followed by": "Подписчик у", "followed_by": "%{username} подписан", - "Followers": "Читателей", - "Following": "Читаемых", + "Followers": "Читатели", + "Following": "Читаемые", "Following users": "Подписанные пользователи", "Force connection to peer:": "Принудительно подключиться к пиру:", "General information": "Основное", @@ -2292,6 +2307,7 @@ if(preferredLanguage == "ru"){ "new_group_messages": "%{smart_count} новое сообщение в группе |||| %{smart_count} новых групповых сообщений", "nobody": "Анонимно", // used to promote a post without attaching the user "Not available": "Недоступно", + "warn_following_not_any": "Пока что таки нет читаемых!\nПоди ж найди кого-нибудь да и подпишись.", "notify_desktop_error": "Твистер не может выполнить уведомление: произошла неизвестная ошибка.", "notify_desktop_perm_denied": "Твистер не может выполнить уведомление: разрешение не получено.\n\nЧтобы получать уведомления, разрешите их для %{this_domain} в настройках вашего браузера.", "notify_desktop_test": "Одна лягушка сказала:\n'если не буду квакать — лопну'.\nВы нужны нам, берегите себя.", @@ -2325,7 +2341,7 @@ if(preferredLanguage == "ru"){ "seconds": "%{smart_count} секунда |||| %{smart_count} секунд", "send": "отправить", "Send post with username": "Отправить сообщение от имени", - "Sent Direct Message": "Отправить личное сообщение", + "send_DM": "Отправить личное сообщение", "Sent Post to @": "Отправить сообщение для @", "Setup account": "Настроить аккаунт", "The File APIs are not fully supported in this browser.": "File APIs не полностью поддерживается этим браузером.", @@ -2528,6 +2544,7 @@ if(preferredLanguage == "de"){ "Wenn du auf dieser Seite bleibst können deine Handlungen nicht funktionieren.\n" + "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}?", "Change user": "Benutzer wechseln", "Checking...": "Überprüfe...", // checking if username is available "Collapse": "Einklappen", // smaller view of a post @@ -2543,7 +2560,7 @@ if(preferredLanguage == "de"){ "Group Messages — Join Group": "Gruppennachrichten — Gruppe beitreten", "direct_messages_with": "Direktnachrichten mit %{username}", "Disable": "Deaktivieren", - "Display mentions to @": "Zeige Erwähnungen von @", //Ist das richtig? Ich weiß nicht, in welchem Zusammenhang das benutzt wird. + "display_mentions": "Zeige Erwähnungen", // Ist das richtig? Ich weiß nicht, in welchem Zusammenhang das benutzt wird. "Display retransmissions": "Weiterleitungen anzeigen", "DNS to obtain list of peers:": "DNS um Peer-Liste abzurufen:", "dns address": "DNS-Adresse", @@ -2560,7 +2577,7 @@ if(preferredLanguage == "de"){ "File APIs not supported in this browser.": "File APIs werden von diesem Browser nicht unterstützt.", "Follow": "Folgen", "Following config": "Following config", - "Which way do you want to follow": "Which way do you want to follow", + "select_way_to_follow_@": "Which way do you want to follow @%{alias}", "Followed by": "Gefolgt von", "followed_by": "Gefolgt von %{username}", "Followers": "Followers", @@ -2602,6 +2619,7 @@ if(preferredLanguage == "de"){ "new_group_messages": "%{smart_count} neue Gruppen-Nachricht |||| %{smart_count} neue Gruppen-Nachrichten", "nobody": "nobody", // used to promote a post without attaching the user "Not available": "Nicht verfügbar", // username is not available + "warn_following_not_any": "Not following any twisters!\nSearch and follow someone.", "notify_desktop_error": "Twister kann keine Desktop-Meldungen anzeigen: ein unbekannter Fehler trat auf.", "notify_desktop_perm_denied": "Twister kann keine Desktop-Meldungen anzeigen: Keine Berechtigung.\n\nWenn Du Meldungen angezeigt haben möchtest, erlaube sie für %{this_domain} in den Einstellungen Deines Browsers.", "notify_desktop_test": "All die Twisterer werden twisten..\nDu bist nun auch willkommen!", @@ -2635,7 +2653,7 @@ if(preferredLanguage == "de"){ "seconds": "%{smart_count} Sekunde |||| %{smart_count} Sekunden", "send": "senden", "Send post with username": "Sende Post mit Benutzernamen ", - "Sent Direct Message": "Direktnachricht senden", + "send_DM": "Direktnachricht senden", "Sent Post to @": "Sende Post an @", "Setup account": "Accounteinstellungen", "The File APIs are not fully supported in this browser.": "Die File-API's werden von diesem Browser nicht vollständig unterstützt.", @@ -2835,6 +2853,7 @@ if(preferredLanguage == "ja"){ "このページを使用しつづければ、あなたの変更が適用されないおそれがあります。\n" + "[ネットワーク状態ペー](%{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}?", "Change user": "ユーザーを変更", "Checking...": "チェック...", // checking if username is available "Collapse": "閉じる", // smaller view of a post @@ -2850,7 +2869,7 @@ if(preferredLanguage == "ja"){ "Group Messages — Join Group": "Group Messages — Join Group", "direct_messages_with": "Direct messages with %{username}", "Disable": "停止", - "Display mentions to @": "メンションを表示する", + "display_mentions": "メンションを表示する", "Display retransmissions": "リトランスミットを表示する", "DNS to obtain list of peers:": "ピア取得用のDNS:", "downloading_block_chain": "ブロックチェインをダウンロードしています。しばらくお待ちください。(ブロックチェーンは%{days}日送れています)", @@ -2866,7 +2885,7 @@ if(preferredLanguage == "ja"){ "File APIs not supported in this browser.": "利用しているブラウザはファイルAPIをサポートしていません。", "Follow": "フォロー", "Following config": "Following config", - "Which way do you want to follow": "Which way do you want to follow", + "select_way_to_follow_@": "Which way do you want to follow @%{alias}", "Followed by": "フォローされている", "followed_by": "%{username}にフォローされている", "Followers": "フォロワー", @@ -2908,6 +2927,7 @@ if(preferredLanguage == "ja"){ "new_group_messages": "%{smart_count} new group message |||| %{smart_count} new group messages", "nobody": "ナナシ", // used to promote a post without attaching the user "Not available": "使用中", // username is not available + "warn_following_not_any": "Not following any twisters!\nSearch and follow someone.", "notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.", "notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for %{this_domain} in settings of your browser.", "notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.", @@ -2941,7 +2961,7 @@ if(preferredLanguage == "ja"){ "seconds": "%{smart_count} 秒 |||| %{smart_count} 秒", "send": "送信", "Send post with username": "プロモートメッセージの送信元", - "Sent Direct Message": "ダイレクトメッセージを送る", + "send_DM": "ダイレクトメッセージを送る", "Sent Post to @": "メンションを投稿する", "Setup account": "アカウント設定", "The File APIs are not fully supported in this browser.": "ご使用のブラウザーは完全にファイルAPIに対応していません。", @@ -3138,6 +3158,7 @@ if(preferredLanguage == "pt-BR"){ "Se permanecer nesta página suas ações podem não ter efeito.\n" + "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}?", "Change user": "Trocar usuário", "Checking...": "Verificando...", // checking if username is available "Collapse": "Recolher", // smaller view of a post @@ -3153,7 +3174,7 @@ if(preferredLanguage == "pt-BR"){ "Group Messages — Join Group": "Group Messages — Join Group", "direct_messages_with": "Mensagens Diretas com %{username}", "Disable": "Desabilitado", - "Display mentions to @": "Exibir menções a @", + "display_mentions": "Exibir menções", "Display retransmissions": "Exibir retransmissões", "DNS to obtain list of peers:": "DNS para obter a lista de nós:", "downloading_block_chain": "Baixando a Cadeia de Blocos, por favor aguarde (A Cadeia de Blocos está %{days} dias desatualizada).", @@ -3169,7 +3190,7 @@ if(preferredLanguage == "pt-BR"){ "File APIs not supported in this browser.": "O gerenciamento de arquivos não é suportado neste navegador.", "Follow": "Seguir", "Following config": "Following config", - "Which way do you want to follow": "Which way do you want to follow", + "select_way_to_follow_@": "Which way do you want to follow @%{alias}", "Followed by": "Seguido por", "followed_by": "Seguido por %{username}", "Followers": "Seguidores", @@ -3211,6 +3232,7 @@ if(preferredLanguage == "pt-BR"){ "new_group_messages": "%{smart_count} new group message |||| %{smart_count} new group messages", "nobody": "nobody", // used to promote a post without attaching the user "Not available": "Indisponível", // username is not available + "warn_following_not_any": "Not following any twisters!\nSearch and follow someone.", "notify_desktop_error": "Twister cannot perform desktop notification: unknown error occured.", "notify_desktop_perm_denied": "Twister cannot perform desktop notification: permission denied.\n\nIf you want to get notifications, allow them for %{this_domain} in settings of your browser.", "notify_desktop_test": "All the twisters gonna twist.\nNow you are welcome too.", @@ -3245,7 +3267,7 @@ if(preferredLanguage == "pt-BR"){ "seconds": "%{smart_count} segundo |||| %{smart_count} segundos", "send": "enviar", "Send post with username": "Promover esta mensagem como usuário", - "Sent Direct Message": "Mensagens Diretas trocadas", + "send_DM": "Mensagens Diretas trocadas", "Sent Post to @": "Postagens enviadas para @", "Setup account": "Configurar conta", "The File APIs are not fully supported in this browser.": "O gerenciamento de arquivos não é completamente suportado neste navegador.", @@ -3445,6 +3467,7 @@ if(preferredLanguage == "tr"){ "Eğer bu sayfada kalırsanız eylemlerinizi işlemeyebilir.\n" + "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}?", "Change user": "Kullanıcı değiştir", "Checking...": "Denetleniyor...", // checking if username is available "Collapse": "Kapat", // smaller view of a post @@ -3460,7 +3483,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 to @": "@ adının geçtiği gönderiler", + "display_mentions": "@ adının geçtiği gönderiler", // FIXME "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).", @@ -3476,7 +3499,7 @@ if(preferredLanguage == "tr"){ "File APIs not supported in this browser.": "Tarayıcınızda dosya API'si desteklenmiyor.", "Follow": "Takip et", "Following config": "Takip ayarları", - "Which way do you want to follow": "Nasıl takip etmek istiyorsun", + "select_way_to_follow_@": "Nasıl takip etmek istiyorsun @%{alias}", "Followed by": "Takip edenler", "followed_by": "%{username} tarafından takip edilenler", "Followers": "Takipçiler", @@ -3518,6 +3541,7 @@ 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.", "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!", @@ -3551,7 +3575,7 @@ if(preferredLanguage == "tr"){ "seconds": "%{smart_count} saniye |||| %{smart_count} saniye", "send": "gönder", "Send post with username": "İletiyi kullanıcı adıyla gönder ", - "Sent Direct Message": "Direk Mesaj Gönder", + "send_DM": "Direk Mesaj Gönder", "Sent Post to @": "@ Kullanıcıya Gönder", "Setup account": "Hesap ayarları", "The File APIs are not fully supported in this browser.": "Dosya API'si tarayıcınızda tam olarak desteklenmiyor.", @@ -3749,6 +3773,7 @@ if(preferredLanguage == "cs"){ "Pokud zůstanete na této stránce, vaše akce možná nebudou fungovat.\n" + "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}?", "Change user": "Změnit uživatele", "Checking...": "Ověřuji...", // checking if username is available "Collapse": "Složit", // smaller view of a post @@ -3764,7 +3789,7 @@ if(preferredLanguage == "cs"){ "Group Messages — Join Group": "Group Messages — Join Group", "direct_messages_with": "Direct messages with %{username}", "Disable": "Vypnuto", - "Display mentions to @": "Zobrazit zmínky o @", + "display_mentions": "Zobrazit zmínky", "Display retransmissions": "Zobrazit přeposlané", "DNS to obtain list of peers:": "DNS pro načtení seznamu uzlů:", "downloading_block_chain": "Stahuji blockchain, prosím počkejte (blockchain je %{days} dnů starý).", @@ -3780,7 +3805,7 @@ if(preferredLanguage == "cs"){ "File APIs not supported in this browser.": "Upozornění: váš webový prohlížeč nepodporuje File API.", "Follow": "Sledovat", "Following config": "Nastavení sledování", - "Which way do you want to follow": "Zvolte způsob sledování", + "select_way_to_follow_@": "Zvolte způsob sledování @%{alias}", "Followed by": "tohoto uživatele sleduje", "followed_by": "Uživatelé, které sleduje %{username}", "Followers": "Sledující", @@ -3822,6 +3847,7 @@ if(preferredLanguage == "cs"){ "new_group_messages": "%{smart_count} new group message |||| %{smart_count} new group messages", "nobody": "nikdo", // used to promote a post without attaching the user "Not available": "Tuto přezdívku již někdo používá", // username is not available + "warn_following_not_any": "Not following any twisters!\nSearch and follow someone.", "notify_desktop_error": "Twisteru se nepodařilo zobrazit upozornění na ploše: došlo k neznámé chybě.", "notify_desktop_perm_denied": "Twisteru se nepodařilo zobrazit upozornění na ploše: přístup byl odepřen.\n\nPokud chcete používat upozornění na ploše, povolte je pro %{this_domain} v nastavení vašeho prohlížeče.", "notify_desktop_test": "Twister to umí pořádně roztočit.\nKaždý je tu vítán.", @@ -3856,7 +3882,7 @@ if(preferredLanguage == "cs"){ "seconds": "%{smart_count} vteřinou |||| %{smart_count} vteřinami |||| %{smart_count} vteřinami", "send": "odeslat", "Send post with username": "Příspěvek vložit pod přezdívkou ", - "Sent Direct Message": "Poslat přímou zprávu", + "send_DM": "Poslat přímou zprávu", "Sent Post to @": "Poslat veřejný příspěvek pro @", "Setup account": "Upravit profil", "The File APIs are not fully supported in this browser.": "Upozornění: váš webový prohlížeč nepodporuje File API.", diff --git a/js/mobile_abstract.js b/js/mobile_abstract.js index 4099741..5e75d10 100644 --- a/js/mobile_abstract.js +++ b/js/mobile_abstract.js @@ -63,15 +63,26 @@ var MAL = function() } } + this.warnFollowingNotAny = function(cbFunc, cbReq) { + if ($.hasOwnProperty('mobile')) + alert(polyglot.t('warn_following_not_any')); + else + alertPopup({ + //txtTitle: polyglot.t(''), add some title (not 'error', please) or KISS + txtMessage: polyglot.t('warn_following_not_any'), + cbConfirm: cbFunc, + cbConfirmReq: cbReq, + cbClose: 'cbConfirm' + }); + }; - this.followingListLoaded = function() { - if( $.hasOwnProperty("mobile") ) { + this.followingListLoaded = function(followingList) { + if ($.hasOwnProperty('mobile')) { $.mobile.hidePageLoadingMsg(); - $(".following-list").listview('refresh'); - } else { - $(".postboard-loading").hide(); - } - } + followingList.listview('refresh'); + } else + followingList.find('.loading-roller').hide(); + }; this.searchUserListLoaded = function() { if( $.hasOwnProperty("mobile") ) { diff --git a/js/tmobile.js b/js/tmobile.js index 1fb1b45..c296a5c 100644 --- a/js/tmobile.js +++ b/js/tmobile.js @@ -161,7 +161,10 @@ var router=new $.mobile.Router( } $.mobile.showPageLoadingMsg(); $("#following a.ui-btn").removeClass("ui-btn-active"); - showFollowingUsers(); + var followingList = twister.tmpl.followingList.clone(true).appendTo($("#following .content")) + .closest('.following-list').listview(); + showFollowingUsers(followingList); + followingList.find('[data-role="button"]').button(); }); }, post: function(type,match,ui) { diff --git a/js/twister_directmsg.js b/js/twister_directmsg.js index 97431e3..16aaf47 100644 --- a/js/twister_directmsg.js +++ b/js/twister_directmsg.js @@ -324,7 +324,7 @@ function openGroupMessagesNewGroupModal() { groupMsgCreateGroup(elemForm.find('.description').val(), peersToInvite); - closeModal(); + closeModal(event); }); } @@ -375,7 +375,7 @@ function openGroupMessagesJoinGroupModal() { for (var i = 0; i < groups.length; i++) groupMsgInviteToGroup(groups[i].getAttribute('data-screen-name'), [defaultScreenName]); - closeModal(); + closeModal(event); }); modal.content.find('.secret-key-import, .username-import').on('input', importSecretKeypress); @@ -388,8 +388,8 @@ function openGroupMessagesJoinGroupModal() { twisterRpc('importprivkey', [secretKey, groupAlias], function(req, ret) { groupMsgInviteToGroup(req.groupAlias, [defaultScreenName]); - closeModal(); - }, {groupAlias: groupAlias}, + closeModal(req.elem); + }, {groupAlias: groupAlias, elem: elemModule}, function(req, ret) { alert(polyglot.t('Error in \'importprivkey\'', {rpc: ret.message})); } @@ -544,16 +544,16 @@ function initInterfaceDirectMsg() { }); $('.group-messages-control .leave').on('click', function (event) { - var elemEvent = $(event.target); - var groupAlias = elemEvent.closest('[data-screen-name]').attr('data-screen-name'); - confirmPopup(event, { - titleTxt: polyglot.t('сonfirm_group_leaving_header'), - messageTxt: polyglot.t('сonfirm_group_leaving_body', {alias: groupAlias}), - confirmFunc: function (groupAlias) { + var groupAlias = $(event.target).closest('[data-screen-name]').attr('data-screen-name'); + event.data = { + txtTitle: polyglot.t('сonfirm_group_leaving_header'), + txtMessage: polyglot.t('сonfirm_group_leaving_body', {alias: groupAlias}), + cbConfirm: function (groupAlias) { groupMsgLeaveGroup(groupAlias, function () {history.back();}); }, - confirmFuncArgs: groupAlias - }); + cbConfirmReq: groupAlias + }; + confirmPopup(event); }); $('.group-messages-control .new').on('click', function () { diff --git a/js/twister_following.js b/js/twister_following.js index a9747c0..744d974 100644 --- a/js/twister_following.js +++ b/js/twister_following.js @@ -373,7 +373,6 @@ function follow(user, publicFollow, cbFunc, cbArg) { if( followingUsers.indexOf(user) < 0 ) { followingUsers.push(user); twisterFollowingO.update(user); - $(window).trigger("eventFollow", user) } if( publicFollow == undefined || publicFollow ) _isFollowPublic[user] = true; @@ -389,8 +388,6 @@ function unfollow(user, cbFunc, cbArg) { if (i >= 0) { followingUsers.splice(i, 1); twisterFollowingO.update(user); - // FIXME also need to check list of pending posts to remove from there - $(window).trigger('eventUnfollow', user); } delete _isFollowPublic[user]; saveFollowing(); @@ -512,46 +509,6 @@ function getWhoFollows(username, item) { } } -// adds following users to the interface (following.html) -function showFollowingUsers(){ - var $notFollowing = $(".not-following-any"); - if( followingEmptyOrMyself() ) { - $notFollowing.show(); - } else { - $notFollowing.hide(); - } - - var $followingList = $(".following-list"); - var $template = $("#following-user-template").detach(); - - $followingList.empty(); - $followingList.append($template); - - for( var i = 0; i < followingUsers.length; i++ ) { - var resItem = $template.clone(true); - resItem.removeAttr('id'); - resItem.show(); - resItem.find(".mini-profile-info").attr("data-screen-name", followingUsers[i]); - resItem.find(".following-screen-name").text(followingUsers[i]); - resItem.find("a.open-profile-modal").attr("href",$.MAL.userUrl(followingUsers[i])); - resItem.find("a.direct-messages-with-user").attr("href", $.MAL.dmchatUrl(followingUsers[i])); - if (isPublicFollowing(followingUsers[i])) { - resItem.find(".public-following").text(polyglot.t("Public")); - } else { - resItem.find(".public-following").text(polyglot.t("Private")).addClass( "private" ); - } - getAvatar(followingUsers[i],resItem.find(".mini-profile-photo")); - getFullname(followingUsers[i],resItem.find(".mini-profile-name")); - if( followingUsers[i] == defaultScreenName ) { - resItem.find("button").hide(); - } - - resItem.prependTo($followingList); - toggleFollowButton(followingUsers[i], true) - } - $.MAL.followingListLoaded(); -} - function processWhoToFollowSuggestion(suggestion, followedBy) { if (suggestion) { var module = $('.module.who-to-follow'); @@ -664,37 +621,16 @@ function processDropdownUserResults(event, results) { getFullname(results[i], item.find('.mini-profile-name')); item.appendTo(container); - if (followingUsers.indexOf(results[i]) !== -1) - toggleFollowButton(results[i], true); + toggleFollowButton({ + button: item.find('.follow'), + peerAlias: results[i], + toggleUnfollow: followingUsers.indexOf(results[i]) !== -1 ? true : false + }); } $.MAL.searchUserListLoaded(); } -function userClickFollow(e) { - e.stopPropagation(); - e.preventDefault(); - - if (!defaultScreenName) { - alert(polyglot.t('You have to log in to follow users.')); - return; - } - - var username = $(e.target).closest('[data-screen-name]').attr('data-screen-name'); - var content = $('#following-config-modal-template').children().clone(true); - - content.closest('.following-config-modal-content').attr('data-screen-name', username); - content.find('.following-config-method-message').text(polyglot.t('Which way do you want to follow')); - content.find('.following-screen-name b').text(username); - - openModal({ - classBase: '.prompt-wrapper', - classAdd: 'following-config-modal', - content: content, - title: polyglot.t('Following config') - }); -} - function initUserSearch() { var elem = $('.userMenu-search-field') .on('click input', @@ -703,16 +639,6 @@ function initUserSearch() { .on('keyup', userSearchEnter) ; $('.userMenu-search').clickoutside(closeSearchDialog.bind(elem)); - - // following stuff should be moved to special function - $('button.follow').on('click', userClickFollow); - $('.following-config-method-buttons .public-following') - .on('click', function(e) { - setFollowingMethod(e); - closePrompt(); - window.setTimeout(loadModalFromHash, 500); // delay reload so dhtput may do it's job - }) - ; } function userSearchEnter(event) { @@ -723,37 +649,6 @@ function userSearchEnter(event) { } } -function followingListPublicCheckbox(e) { - e.stopPropagation(); - - var $this = $(this); - var username = $this.closest(".mini-profile-info").attr("data-screen-name"); - var publicFollow = false; - $this.toggleClass( "private" ); - if( $this.hasClass( "private" ) ) { - $this.text( polyglot.t("Private") ); - } else { - $this.text( polyglot.t("Public") ); - publicFollow = true; - } - - //console.log("set following method of @" +username +" for "+publicFollow); - follow(username, publicFollow); -} - -function setFollowingMethod(event) { - var button = $(event.target); - var username = button.closest('.following-config-modal-content').attr('data-screen-name'); - - follow(username, - (button.hasClass('private')) ? false : true, // is folowing public - toggleFollowButton, username, true // last two are args for toggleFollowButton() - ); - - event.stopPropagation(); -} - - function requestSwarmProgress() { twisterRpc("getlasthave", [defaultScreenName], function(args, ret) {processSwarmProgressPartial(ret);}, null, @@ -794,83 +689,3 @@ function followingChangedUser() { _followSuggestions = []; _lastLoadFromDhtTime = 0; } - -function initInterfaceFollowing() { - initInterfaceCommon(); - initUserSearch(); - initInterfaceDirectMsg(); - - $(".mini-profile-info .public-following").bind( "click", followingListPublicCheckbox ); - - $(".mentions-from-user").bind( "click", openMentionsModal ); - - initUser( function() { - if( !defaultScreenName ) { - alert(polyglot.t("username_undefined")); - $.MAL.goLogin(); - return; - } - checkNetworkStatusAndAskRedirect(); - - $(".postboard-loading").fadeIn(); - loadFollowing( function(args) { - twisterFollowingO = TwisterFollowing(defaultScreenName); - - showFollowingUsers(); - requestSwarmProgress(); - }); - initMentionsCount(); - initDMsCount(); - }); - - $(window) - .on('eventFollow', function(e, user) { - $('.mini-profile .following-count').text(followingUsers.length - 1); - showFollowingUsers(); - }) - .on('eventUnfollow', function(e, user) { - $('.mini-profile .following-count').text(followingUsers.length - 1); - showFollowingUsers(); - }); -} - - -var InterfaceFunctions = function () { - this.init = function () { - initUser(initFollowing_); - }; - - function initFollowing_(cbFunc, cbArg) { - var $miniProfile = $(".left .mini-profile"); - if(!defaultScreenName) - { - - } - else - { - $miniProfile.find("a.mini-profile-name").attr("href",$.MAL.userUrl(defaultScreenName)); - $miniProfile.find("a.open-profile-modal").attr("href",$.MAL.userUrl(defaultScreenName)); - $miniProfile.find(".mini-profile-name").text(defaultScreenName); - getFullname( defaultScreenName, $miniProfile.find(".mini-profile-name") ); - getAvatar( defaultScreenName, $miniProfile.find(".mini-profile-photo").find("img") ); - getPostsCount( defaultScreenName, $miniProfile.find(".posts-count") ); - getFollowers( defaultScreenName, $miniProfile.find(".followers-count") ); - - loadFollowing( function(args) { - $(".left .following-count").text(followingUsers.length-1); - initMentionsCount(); - initDMsCount(); - }, {cbFunc:cbFunc, cbArg:cbArg}); - - } - - } -}; - -//*********************************************** -//******************* INIT ************** -//*********************************************** -if (!/\/home.html$/i.test(document.location)) { // FIXME we're doing it wrong, interfaceFunctions declaration should be inside interface common - var interfaceFunctions = new InterfaceFunctions; - $(document).ready(interfaceFunctions.init); -} diff --git a/js/twister_formatpost.js b/js/twister_formatpost.js index a103b96..556a520 100644 --- a/js/twister_formatpost.js +++ b/js/twister_formatpost.js @@ -3,18 +3,13 @@ // // Format JSON posts and DMs to HTML. -var _templatePostRtReference; -var _templatePostRtBy; var _htmlFormatMsgLinkTemplateExternal; var _htmlFormatMsgLinkTemplateUser; var _htmlFormatMsgLinkTemplateHashtag; $(document).ready(function() { - // we're setting it here for perfomance improvement purpose // to not search and prepare it for for every post every time - _templatePostRtReference = $('#post-rt-reference-template').children().clone(true); - _templatePostRtReference.find('.post-text') - .on('click', {feeder: '.post-rt-reference'}, openConversationClick); - _templatePostRtBy = $('#post-rt-by-template').children().clone(true); + // we're setting it here for perfomance improvement purpose + // to not search and prepare it for for every post every time _htmlFormatMsgLinkTemplateExternal = $('#external-page-link-template') if (_htmlFormatMsgLinkTemplateExternal.length) { _htmlFormatMsgLinkTemplateExternal = _htmlFormatMsgLinkTemplateExternal[0].cloneNode(); @@ -156,7 +151,7 @@ function postToElem(post, kind, promoted) { if (userpost.msg) { setPostReference(postContext, rt, userpost.sig_rt); } else { - postContext.append(_templatePostRtBy.clone(true)).addClass('post-rt-by') + postContext.append(twister.tmpl.postRtBy.clone(true)).addClass('post-rt-by') .find('.post-rt-sign .prep').text(polyglot.t('post_rt_sign_prep')) .siblings('.open-profile-modal') .attr('href', $.MAL.userUrl(retweeted_by)).text('@' + retweeted_by) @@ -232,7 +227,7 @@ function setPostCommon(elem, username, time) { } function setPostReference(elem, rt, sig_rt) { - elem.append(_templatePostRtReference.clone(true)) + elem.append(twister.tmpl.postRtReference.clone(true)) .find('.post-rt-reference') .attr('data-screen-name', rt.n) .attr('data-id', rt.k) diff --git a/js/twister_network.js b/js/twister_network.js index 9380588..3389458 100644 --- a/js/twister_network.js +++ b/js/twister_network.js @@ -304,7 +304,7 @@ function interfaceNetworkHandlers() { function (e) {e.stopPropagation(); $(this).addClass('open'); usePostSpliting = false;}); $('.post-submit.update-spam-msg').off('click').on('click', setSpamMsg); $('.terminate-daemon').on('click', - {messageTxt: polyglot.t('confirm_terminate_daemon'), confirmFunc: exitDaemon}, confirmPopup); + {txtMessage: polyglot.t('confirm_terminate_daemon'), cbConfirm: exitDaemon}, confirmPopup); } diff --git a/js/twister_user.js b/js/twister_user.js index c154de9..c0b5b73 100644 --- a/js/twister_user.js +++ b/js/twister_user.js @@ -273,20 +273,18 @@ function saveProfile(e) { function completeProfileSaving(req, isAvatarDataSaved) { if (req.isProfileDataSaved && isAvatarDataSaved) { clearAvatarAndProfileCache(defaultScreenName); - var titleTxt = ''; - var messageTxt = polyglot.t('profile_saved'); + var txtTitle = ''; + var txtMessage = polyglot.t('profile_saved'); } else { - var titleTxt = polyglot.t('error', {error: ''}); - var messageTxt = polyglot.t('profile_not_saved'); + var txtTitle = polyglot.t('error', {error: ''}); + var txtMessage = polyglot.t('profile_not_saved'); } - confirmPopup(null, { - titleTxt: titleTxt, - messageTxt: messageTxt, - confirmTxt: polyglot.t('btn_ok'), - confirmFunc: $.MAL.enableButton, - confirmFuncArgs: $('.submit-changes'), - closeFunc: 'confirmFunc', - removeCancel: true + alertPopup({ + txtTitle: txtTitle, + txtMessage: messageTxt, + cbConfirm: $.MAL.enableButton, + cbConfirmReq: $('.submit-changes'), + cbClose: 'cbConfirm' }); } diff --git a/network.html b/network.html index b17a461..0873a4e 100644 --- a/network.html +++ b/network.html @@ -44,7 +44,6 @@
    Options Setup account - Following users Network config Change user
    diff --git a/options.html b/options.html index 2126038..596c46f 100644 --- a/options.html +++ b/options.html @@ -38,7 +38,6 @@ Options Network config Setup account - Following users Change user
    diff --git a/profile-edit.html b/profile-edit.html index 4a6d976..3f87b1f 100644 --- a/profile-edit.html +++ b/profile-edit.html @@ -47,7 +47,6 @@
    Options Setup account - Following users Network config Change user
    diff --git a/theme_calm/css/style.css b/theme_calm/css/style.css index 9b3f66a..b7ec014 100644 --- a/theme_calm/css/style.css +++ b/theme_calm/css/style.css @@ -134,7 +134,7 @@ button:disabled:hover, button.disabled:hover { color: rgba(255, 255, 255, .8); } -button.follow, button.unfollow, .following-list button.private { +button.follow, button.unfollow, .following-own-modal .following-list button.private { color: rgba( 0, 0, 0, .4 ); background: none; border: solid 1px rgba( 0, 0, 0, .2 ); @@ -142,19 +142,19 @@ button.follow, button.unfollow, .following-list button.private { font-size: 12px; } -.following-list .public-following { +.following-own-modal .following-list .public-following { padding: 4px 16px; font-size: 12px; } -.following-list .public-following:hover { +.following-own-modal .following-list .public-following:hover { color: rgba( 0, 0, 0, .4 ); background: none; border: solid 1px rgba( 0, 0, 0, .2 ); padding: 3px 15px; } -.following-list button.private:hover { +.following-own-modal .following-list button.private:hover { color: #fff; background: #45474d; } @@ -668,10 +668,7 @@ input.userMenu-search-field:focus::-ms-input-placeholder { position: relative; z-index: 2; } -.following-list .mini-profile-name -{ - padding: 5px 5px 5px 5px; -} + .profile-data { border-left: none; @@ -704,59 +701,55 @@ input.userMenu-search-field:focus::-ms-input-placeholder { display: block; font-size: 16px; } -.mini-profile-actions -{ - position: relative; - width: auto; - display: inline-block; + +.mini-profile-actions { + position: absolute; + top: 0; + right: 8px; } -.mini-profile-actions span -{ - color: #e18881; + +.mini-profile-actions span { + color: rgba(0, 0, 0, .5); cursor: pointer; - font-size: 14px; + font-size: 12px; display: inline-block; - width: 85px; - transition: all .2s linear; + position: relative; + z-index: 10; } -.mini-profile-actions ul -{ + +.mini-profile-actions span:hover { + color: #768fce; +} + +.mini-profile-actions ul { height: 0; overflow: hidden; position: absolute; + z-index: 20; + right: 0; transition: height .2s linear; background: #fff; - z-index: 3; -} -.mini-profile-actions:hover span -{ } -.mini-profile-actions:hover span:after -{ -} -.mini-profile-actions:hover ul -{ - height: 90px; - box-shadow: 0 2px 5px #65686f; + +.mini-profile-actions:hover ul { + /*height: ;*/ + border: solid 1px rgba(69, 71, 77, .1); + border-right: solid 4px #B2D67B; + box-shadow: 8px 10px 10px 0px rgba(0, 0, 0, .2); } -.mini-profile-actions ul li -{ + +.mini-profile-actions ul li { white-space: nowrap; - color: rgba( 0, 0, 0, .7 ); - font-size: 13px; + color: rgba(0, 0, 0, .7); + font-size: 12px; cursor: pointer; - padding: 5px; - margin: 2px; -} -.mini-profile-actions ul li + li -{ - margin: 0 2px; + padding: 4px 16px 4px 8px; } -.mini-profile-actions:hover ul li:hover -{ - background: rgba( 0, 0, 0, .7 ); - color: #fff; + +.mini-profile-actions ul li:hover { + background: #FCFDFF; } + .mini-profile-info a:hover { text-decoration: none; @@ -2634,63 +2627,65 @@ textarea.splited-post { *********** FOLLOWING PAGE *********** **************************************/ -.following .header-bold { - display: block; - width: 100%; - margin: 0px auto 12px auto; +.following-own-modal.modal-wrapper { + width: 662px; + margin-left: -331px; } -.following ol.following-list > li{ - display: inline-block; - width: 280px; +.following-own-modal .following-list > li { + width: 320px; height: 120px; - margin: 5px; + margin: 2px; + padding: 2px; float: left; - border: 3px dashed #e0e6f5; + border: solid 1px rgba(69, 71, 77, .1); background: #fff; border-radius: 10px; } -.following ol.following-list li .swarm-status { - font: 11px "Open Sans", sans-serif; - color: #343434; - display: block; - position: absolute; - top: 94px; - right: 8px; + +.following-own-modal .following-list .mini-profile-name { + padding: 4px; } -.following ol.following-list li span.mini-profile-name:hover { + +.following-own-modal .following-list .mini-profile-name:hover { color: #5e8da4; } -.following ol.following-list li span.mini-screen-name { + +.following-own-modal .following-list .mini-screen-name { color: #5e8da4; position: absolute; top: 32px; } -.following ol.following-list li span.mini-screen-name:hover { + +.following-own-modal .following-list .mini-screen-name:hover { color: #76b2ce; } -.following ol.following-list .mini-profile-info .mini-profile-actions { + +.following-own-modal .following-list .following-config { + width: 100%; position: absolute; - top: 8px; - right: 2px; - z-index: 10; + top: 62px; + text-align: center; } -.following ol.following-list .mini-profile-info button { - margin-top: 5px; + +.following-own-modal .following-list .mini-profile-actions:hover ul { + height: 50px; +} + +.following-own-modal .following-list .swarm-status { + font: 11px "Open Sans", sans-serif; + color: #343434; + display: block; + position: absolute; + top: 94px; + right: 32px; } + .gifCheckBox { float: right; vertical-align: middle; } -.following-list .following-config -{ - width: 100%; - position: absolute; - top: 60px; - text-align: center; -} - /************************************* *********** AUTOCOMPLETING *********** **************************************/ diff --git a/theme_nin/css/style.css b/theme_nin/css/style.css index 3aa92ab..33ad59d 100644 --- a/theme_nin/css/style.css +++ b/theme_nin/css/style.css @@ -1136,309 +1136,6 @@ samp { height: 100%; } -/* line 1, ../sass/_following.sass */ -.following { - width: 100% !important; -} - -/* line 4, ../sass/_following.sass */ -.following-list li { - text-align: center; - float: left; - width: 30%; - padding: 13px; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - float: left; - margin: 0 2% 2% 0; -} - -/* line 15, ../sass/_following.sass */ -.following .mini-profile { - margin-bottom: 10px; -} - -/* line 18, ../sass/_following.sass */ -.following .mini-profile-info { - position: relative; -} - -/* line 21, ../sass/_following.sass */ -.following .mini-profile-photo { - margin: 0 auto 10px auto; - display: block; - width: 64px; - height: 64px; - overflow: hidden; - background: #E2E1DE; -} - -/* line 29, ../sass/_following.sass */ -.following .mini-profile-view { - display: inline; - color: rgba(0, 0, 0, 0.5); - font-size: 12px; - position: absolute; - top: 32px; - left: 65px; - z-index: 1; -} - -/* line 38, ../sass/_following.sass */ -.following .mini-profile-name { - font-weight: 900; - font-size: 1em; - line-height: 1em; - padding: 0; - text-decoration: none; - display: block; - color: inherit; - display: inline; -} - -/* line 47, ../sass/_following.sass */ -.following .mini-screen-name { - color: inherit; - display: block; - margin-bottom: 10px; -} - -/* line 52, ../sass/_following.sass */ -.following button, .following .mini-profile-actions span, .mini-profile-actions .following span { - display: inline-block; - margin: 5px 0; -} -/* line 55, ../sass/_following.sass */ -.following button.unfollow, .following .mini-profile-actions span.unfollow, .mini-profile-actions .following span.unfollow { - background-color: #aaa; -} -/* line 57, ../sass/_following.sass */ -.following button.public-following, .following .mini-profile-actions span.public-following, .mini-profile-actions .following span.public-following { - background-color: #B4C669; -} - -/* line 62, ../sass/_following.sass */ -.mini-profile-actions { - position: absolute; - width: auto; - top: 0; - right: -16px; - display: inline-block; -} -/* line 69, ../sass/_following.sass */ -.mini-profile-actions span { - cursor: pointer !important; - border-top-right-radius: 0 !important; - border-bottom-right-radius: 0 !important; -} -/* line 76, ../sass/_following.sass */ -.mini-profile-actions span:before { - margin: 0; - padding: 0; - line-height: 1em; - font-size: 10px; -} -/* line 81, ../sass/_following.sass */ -.mini-profile-actions ul { - height: 0; - overflow: hidden; - position: absolute; - top: 2em; - right: -2em; - transition: height 0.4s linear; - transition: padding-top 0.1s linear; - background: #66686B; - z-index: 3; -} -/* line 96, ../sass/_following.sass */ -.mini-profile-actions:hover ul { - padding: 8px; - height: 112px; -} -/* line 101, ../sass/_following.sass */ -.mini-profile-actions ul li { - text-align: left; - margin: 0; - background: #66686B; - white-space: nowrap; - color: #aaa; - font-size: 12px; - line-height: 12px; - cursor: pointer; - display: block; - float: none; - width: auto; - padding: 8px; -} -/* line 117, ../sass/_following.sass */ -.mini-profile-actions:hover ul li:hover { - color: #B4C669; -} - -/* line 123, ../sass/_following.sass */ -.following .who-follow { - height: auto; - background-color: rgba(69, 71, 77, 0.1); - overflow: hidden; - font-size: 12px; -} - -/* line 129, ../sass/_following.sass */ -.following .show-more-followers { - color: #f11; - font-weight: bold; - cursor: pointer; - float: right; -} - -/* line 135, ../sass/_following.sass */ -.following .mini-follower-link { - display: inline-block; - margin-right: 10px; -} -/* line 138, ../sass/_following.sass */ -.following .mini-follower-link:before { - content: " ‧"; -} - -/* line 141, ../sass/_following.sass */ -.following a.open-profile-modal { - display: inline; - text-align: center; - color: #66686B; -} -/* line 145, ../sass/_following.sass */ -.following a.open-profile-modal:hover { - color: #aaa; -} - -/* line 151, ../sass/_following.sass */ -.following .post-area-new { - padding-bottom: 4px; -} -/* line 153, ../sass/_following.sass */ -.following .post-area-new textarea { - resize: none; - width: 445px; - display: block; - transition: all 0.3s linear; - -webkit-transition: height 0.3s linear; - -moz-transition: height 0.3s linear; - -o-transition: height 0.3s linear; - -ms-transition: height 0.3s linear; - height: 28px; - border-radius: 3px; - border: solid 1px rgba(0, 0, 0, 0.3); - margin-left: 55px; - margin-bottom: 10px; - padding: 4px; - font-size: 13px; -} - -/* line 170, ../sass/_following.sass */ -.following .mini-profile .post-area-new { - padding: 9px; -} -/* line 172, ../sass/_following.sass */ -.following .mini-profile .post-area-new textarea { - margin-left: 0; - width: 100%; -} - -/* line 176, ../sass/_following.sass */ -.following .post-area-new.open textarea, .following .mini-profile .post-area-new textarea, .mini-profile .following .post-area-new textarea, .following #postboard-top .post-area .post-area-new textarea, #postboard-top .post-area .following .post-area-new textarea { - height: 80px; - border: solid 1px rgba(227, 79, 66, 0.5); - box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); -} - -/* line 181, ../sass/_following.sass */ -.following textarea.splited-post { - box-shadow: none !important; - height: 28px; -} - -/* line 185, ../sass/_following.sass */ -.following .splited-post-counter { - color: rgba(0, 0, 0, 0.3); - font-weight: bold; -} -/* line 188, ../sass/_following.sass */ -.following .splited-post-counter:before { - content: "…"; -} - -/* line 191, ../sass/_following.sass */ -.following .post-area-extras { - overflow: hidden; - height: 0; - text-align: right; -} - -/* line 196, ../sass/_following.sass */ -.following .post-submit { - background: #45474d; - color: rgba(255, 255, 255, 0.8); - border: none; - padding: 5px 10px; - cursor: pointer; - display: inline-block; - margin-top: 4px; -} - -/* line 205, ../sass/_following.sass */ -.following .post-area-new.open > .post-area-extras, .following .mini-profile .post-area-new > .post-area-extras, .mini-profile .following .post-area-new > .post-area-extras, .following #postboard-top .post-area .post-area-new > .post-area-extras, #postboard-top .post-area .following .post-area-new > .post-area-extras { - height: 35px; - transition: all 0.6s linear; -} - -/* line 209, ../sass/_following.sass */ -.following .post-area-remaining { - font-size: 13px; -} -/* line 211, ../sass/_following.sass */ -.following .post-area-remaining.warn { - color: #ff0000; -} - -/* line 214, ../sass/_following.sass */ -.following .post .show-more { - font-size: 13px; - font-weight: bold; - margin-left: 60px; - color: rgba(0, 0, 0, 0.5); -} -/* line 219, ../sass/_following.sass */ -.following .post .show-more:before { - content: "💭"; -} - -/* line 222, ../sass/_following.sass */ -.swarm-status { - display: none !important; -} - -/* line 232, ../sass/_following.sass */ -.mini-following-info { - width: 45px; - height: 45px; - text-align: center; - background: white; - margin: 1%; - float: left; -} -/* line 241, ../sass/_following.sass */ -.mini-following-info .mini-screen-name, .mini-following-info .mini-following-name { - display: none; -} -/* line 243, ../sass/_following.sass */ -.mini-following-info .mini-profile-photo { - height: 45px; - width: 45px; - border-radius: 0; -} - /********** LOGIN AND NETWORK PAGES ****** */ /* line 4, ../sass/_network.sass */ .network.singleBlock ul { @@ -2817,6 +2514,18 @@ ol.toptrends-list a:hover { margin: 4px; } +/************************************* +*********** CONFIRM POPUP ************ +**************************************/ + +.confirm-popup.prompt-wrapper { + top: 30%; +} + +.confirm-popup .message { + margin: 8px 12px 20px; +} + /****** FOLLOWING-CONFIG PROMPT ******/ .following-config-modal.prompt-wrapper { @@ -3468,6 +3177,122 @@ ol.toptrends-list a:hover { font-style: normal; } +/************************************* +*********** FOLLOWING PAGE *********** +**************************************/ + +.modal-wrapper.following-own-modal { + width: 674px; + height: 600px; + margin: -300px 0 0 -337px; +} + +.following-own-modal .modal-content { + padding: 0; +} + +.following-own-modal .following-list > li { + width: 320px; + height: 160px; + margin: 2px; + padding: 2px; + float: left; + border: solid 1px rgba(69, 71, 77, .1); + background: #FFF; + text-align: center; +} + +.following-own-modal .following-list > li > div { + position: relative; +} + +.following-own-modal .following-list > li:hover { + border-bottom: solid 1px #B4C669; +} + +.following-own-modal .following-list .mini-profile-photo { + width: 64px; + height: 64px; + margin-top: 12px; + margin-bottom: 2px; +} + +.following-own-modal .following-list .mini-profile-name { + padding: 4px; +} + +.following-own-modal .following-list .mini-screen-name { + display: none; +} + +.following-own-modal .following-list .following-config { + width: 100%; + text-align: center; + margin: 4px; +} + +.following-own-modal .following-list .following-config button { + display: inline-block; +} + +.following-own-modal .following-list .mini-profile-actions { + display: none; + position: absolute; + top: 0; + right: 8px; +} + +.following-own-modal .following-list > li:hover .mini-profile-actions { + display: block; +} + +.following-own-modal .following-list .mini-profile-actions span { + cursor: pointer; + display: inline-block; + position: relative; + z-index: 10; + background: #B4C669; +} + +.following-own-modal .following-list .mini-profile-actions span:hover { + background: #AAA; +} + +.following-own-modal .following-list .mini-profile-actions ul { + height: 0; + overflow: hidden; + position: absolute; + z-index: 20; + right: 0; + padding: 0; + background: #FFF; + transition: height .2s linear; +} + +.following-own-modal .following-list .mini-profile-actions:hover ul { + height: 56px; + box-shadow: 8px 10px 10px 0px rgba(0, 0, 0, .2); +} + +.following-own-modal .following-list .mini-profile-actions ul > li { + text-align: left; + white-space: nowrap; + color: rgba(0, 0, 0, .7); + font-size: 12px; + margin: 0; + padding: 4px 16px 4px 8px; + border-bottom: solid 1px rgba(0, 0, 0, 0); + background: #FFF; +} + +.following-own-modal .following-list .mini-profile-actions ul > li:hover { + border-bottom: solid 1px #B4C669; +} + +.following-own-modal .following-list .swarm-status { + font-size: 11px; + display: block; +} /********** AUTOCOMPLETING *********/ diff --git a/theme_nin/js/theme_option.js b/theme_nin/js/theme_option.js index 6105585..56f686f 100644 --- a/theme_nin/js/theme_option.js +++ b/theme_nin/js/theme_option.js @@ -7,8 +7,8 @@ $(function(){ $('img[src$="img/tornado_avatar.png"]').attr("src","theme_nin/img/tornado_avatar.png"); $('.mini-profile-actions span').html(''); - $.globalEval(postToElem.toString().replace(/postContext.append\(_templatePostRtBy/, - 'postContext.prependTo(postContext.parent()).append(_templatePostRtBy')); + $.globalEval(postToElem.toString().replace(/postContext.append\(twister\.tmpl\.postRtBy/, + 'postContext.prependTo(postContext.parent()).append(twister.tmpl.postRtBy')); $( '.userMenu-home.current a' ).on( 'click', function() { diff --git a/theme_nin/sass/_following.sass b/theme_nin/sass/_following.sass deleted file mode 100755 index 3f27a82..0000000 --- a/theme_nin/sass/_following.sass +++ /dev/null @@ -1,239 +0,0 @@ -.following - width: 100%!important - -.following-list li - text-align: center - @extend .clear-fix - float: left - width: 30% - padding: 13px - +box-sizing(border-box) - float: left - margin: 0 2% 2% 0 - - -.following .mini-profile - margin-bottom: 10px - -.following .mini-profile-info - position: relative - -.following .mini-profile-photo - margin: 0 auto 10px auto - display: block - width: 64px - height: 64px - overflow: hidden - background: $main-background-color - -.following .mini-profile-view - display: inline - color: rgba(0, 0, 0, 0.5) - font-size: 12px - position: absolute - top: 32px - left: 65px - z-index: 1 - -.following .mini-profile-name - font-weight: 900 - font-size: 1em - line-height: 1em - padding: 0 - text-decoration: none - display: block - color: inherit - display: inline -.following .mini-screen-name - color: inherit - display: block - margin-bottom: 10px - -.following button - display: inline-block - margin: 5px 0 - &.unfollow - background-color: $main-color-light - &.public-following - background-color: $main-color-color - - - -.mini-profile-actions - position: absolute - width: auto - top: 0 - right: -16px - display: inline-block - - span - cursor: pointer!important - @extend button - border-top-right-radius: 0!important - border-bottom-right-radius: 0!important - @extend .extend-icon - @extend .icon-plus - &:before - margin: 0 - padding: 0 - line-height: 1em - font-size: 10px - ul - $action-padding-height: 8px - height: 0 - overflow: hidden - position: absolute - top: 2em - right: -2em - transition: height .4s linear - transition: padding-top .1s linear - background: $main-color-dark - z-index: 3 - - - - &:hover - ul - $action-li-height : 12px - $action-padding-height: 8px - padding: $action-padding-height - height: $action-li-height*4 + $action-padding-height*2*4 - ul li - text-align: left - margin: 0 - background: $main-color-dark - $action-li-height : 12px - $action-padding-height: 8px - white-space: nowrap - color: $main-color-light - font-size: $action-li-height - line-height: $action-li-height - cursor: pointer - display: block - float: none - width: auto - padding: $action-padding-height - - &:hover ul li:hover - color: $main-color-color - - - - -.following .who-follow - height: auto - background-color: rgba(69, 71, 77, 0.1) - overflow: hidden - font-size: 12px - -.following .show-more-followers - color: #f11 - font-weight: bold - cursor: pointer - float: right - -.following .mini-follower-link - display: inline-block - margin-right: 10px - &:before - content: " \2027" - -.following a.open-profile-modal - display: inline - text-align: center - color: $dark-grey - &:hover - color: $main-color-light - - - - -.following .post-area-new - padding-bottom: 4px - textarea - resize: none - width: 445px - display: block - transition: all .3s linear - -webkit-transition: height 0.3s linear - -moz-transition: height 0.3s linear - -o-transition: height 0.3s linear - -ms-transition: height 0.3s linear - height: 28px - border-radius: 3px - border: solid 1px rgba(0, 0, 0, 0.3) - margin-left: 55px - margin-bottom: 10px - padding: 4px - font-size: 13px - -.following .mini-profile .post-area-new - padding: 9px - textarea - margin-left: 0 - width: 100% - -.following .post-area-new.open textarea - height: 80px - border: solid 1px rgba(227, 79, 66, 0.5) - box-shadow: 0 0 10px rgba(0, 0, 0, 0.3) - -.following textarea.splited-post - box-shadow: none!important - height: 28px - -.following .splited-post-counter - color: rgba(0, 0, 0, 0.3) - font-weight: bold - &:before - content: '\2026' - -.following .post-area-extras - overflow: hidden - height: 0 - text-align: right - -.following .post-submit - background: #45474d - color: rgba(255, 255, 255, 0.8) - border: none - padding: 5px 10px - cursor: pointer - display: inline-block - margin-top: 4px - -.following .post-area-new.open > .post-area-extras - height: 35px - transition: all .6s linear - -.following .post-area-remaining - font-size: 13px - &.warn - color: #ff0000 - -.following .post .show-more - font-size: 13px - font-weight: bold - margin-left: 60px - color: rgba(0, 0, 0, 0.5) - &:before - content: '💭' - -.swarm-status - display: none!important - -.mini-following-info - width: 45px - height: 45px - text-align: center - background: $bloc-background-color - margin: 1% - float: left - &:after - @extend .clear-fix - .mini-screen-name, .mini-following-name - display: none - .mini-profile-photo - height: 45px - width: 45px - border-radius: 0 diff --git a/tmobile.html b/tmobile.html index d3c7f65..6c82856 100644 --- a/tmobile.html +++ b/tmobile.html @@ -467,37 +467,7 @@

    Following

    -
    - - - -
    +
    -
    +
    user-photo
    -
    +
    twisted again by
    @@ -865,6 +835,32 @@

    +
    +
      +
      + +