From 98bbdbc560b07525df7a7d4875dc8fc8d0d84f5e Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Sat, 24 Oct 2015 01:20:41 +0500 Subject: [PATCH 1/3] add ability to change DM's group description --- css/profile.css | 20 ++++++++++++++++++++ css/style.css | 25 +++++++++++++++++++++++++ following.html | 6 +++++- home.html | 6 +++++- js/interface_common.js | 38 +++++++++++++++++++++++++++++++++++++- js/twister_directmsg.js | 11 +++++++++++ theme_calm/css/profile.css | 21 +++++++++++++++++++++ theme_calm/css/style.css | 30 ++++++++++++++++++++++++++++++ theme_nin/css/style.css | 21 +++++++++++++++++++++ 9 files changed, 175 insertions(+), 3 deletions(-) diff --git a/css/profile.css b/css/profile.css index 74c1bff..667b614 100644 --- a/css/profile.css +++ b/css/profile.css @@ -293,6 +293,26 @@ h2.profile-screen-name { display: block; } +.profile-card .profile-bio .group-description { + color: #fff; + background: rgba(0, 0, 0, 0); + border: none; + text-align: center; + padding: 4px; + vertical-align: middle; +} + +.profile-card .profile-bio .group-description:focus, +.profile-card .profile-bio .group-description:hover { + color: #fff; + background: rgba(0, 0, 0, .5); +} + +.profile-card .profile-bio .save, .profile-card .profile-bio .cancel { + display: none; + margin-left: 2px; +} + .group-messages-control .invite-form, .group-messages-control .secret-key { display: none; font-size: 12px; diff --git a/css/style.css b/css/style.css index 01a8e17..b22c18d 100644 --- a/css/style.css +++ b/css/style.css @@ -147,6 +147,31 @@ button.follow:hover, button.unfollow:hover, .following-list button.private:hover margin-right: 10px; } +.a-button { + color: dimgrey; + background-color: whitesmoke; + border: none; + font-size: 12px; + text-align: center; + width: auto; + padding: 4px 12px; + vertical-align: middle; + transition: all .1s linear; +} + +.a-button:hover { + color: #000; + background: #fff; +} + +.a-button:disabled { + opacity: .9; +} + +.a-button:disabled:hover { + color: dimgrey; +} + .b-buttons { text-align: right; padding: 4px; diff --git a/following.html b/following.html index 3cd5175..998eace 100644 --- a/following.html +++ b/following.html @@ -424,7 +424,11 @@
-
+
+ + + +
diff --git a/home.html b/home.html index b9640a7..46d0eea 100644 --- a/home.html +++ b/home.html @@ -516,7 +516,11 @@
-
+
+ + + +
diff --git a/js/interface_common.js b/js/interface_common.js index 15b57db..762a686 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -154,7 +154,10 @@ function openGroupProfileModalWithNameHandler(groupAlias) { groupMsgGetGroupInfo(groupAlias, function(req, ret) { if (ret) { - req.modal.content.find('.profile-bio').text(ret.description); + req.modal.content.find('.profile-bio .group-description') + .val(ret.description) + .attr('val-origin', ret.description) + ; if (ret.members.indexOf(defaultScreenName) !== -1) req.modal.content.find('.group-messages-control').children('button').attr('disabled', false); @@ -1567,6 +1570,39 @@ function initInterfaceCommon() { replaceDashboards(); $(window).resize(replaceDashboards); + $('.profile-card .profile-bio .group-description') + .on('focus', function (event) { + $(event.target) + .siblings('.save').show() + .siblings('.cancel').show() + ; + }) + .on('input', + {parentSelector: '.profile-bio', enterSelector: '.save'}, inputEnterActivator) + .siblings('.save').on('click', function (event) { + var elemEvent = $(event.target); + var descElem = elemEvent.siblings('.group-description'); + + groupMsgSetGroupDescription(elemEvent.closest('.profile-card').attr('data-screen-name'), + descElem.val().trim(), + function(req) { + req.descElem.attr('val-origin', req.descElem.val().trim()) + .siblings('.save').hide() + .siblings('.cancel').hide() + ; + }, {descElem: descElem} + ); + }) + .siblings('.cancel').on('click', function (event) { // FIXME it would be nice to bind some 'clickoutside' event instead and remove cancel button, but current implementation of that doesn't unbind events when element dies + var descElem = $(event.target).hide() + .siblings('.save').hide() + .siblings('.group-description') + ; + + descElem.val(descElem.attr('val-origin')); + }) + ; + $('.tox-ctc').on('click', promptCopyAttrData); $('.bitmessage-ctc').on('click', promptCopyAttrData); diff --git a/js/twister_directmsg.js b/js/twister_directmsg.js index b47ce1a..f51883b 100644 --- a/js/twister_directmsg.js +++ b/js/twister_directmsg.js @@ -392,6 +392,17 @@ function doGroupMsgInviteToGroup() { ); } +function groupMsgSetGroupDescription(groupAlias, description, cbFunc, cbArgs) { + twisterRpc('newgroupdescription', + [defaultScreenName, lastPostId + 1, groupAlias, description], + function (req) { + incLastPostId(); + req.cbFunc(req.cbArgs); + }, {cbFunc: cbFunc, cbArgs: cbArgs}, + function(req, ret) {alert(polyglot.t('error', {error: 'can\'t set group description — ' + ret.message}));}, null + ); +} + function groupMsgLeaveGroup(groupAlias, cbFunc, cbArgs) { twisterRpc('leavegroup', [defaultScreenName, groupAlias], cbFunc, cbArgs, diff --git a/theme_calm/css/profile.css b/theme_calm/css/profile.css index 8bd3930..2367547 100644 --- a/theme_calm/css/profile.css +++ b/theme_calm/css/profile.css @@ -382,6 +382,27 @@ h2.profile-screen-name { display: none; } +.profile-card .profile-bio .group-description { + color: #43464d; + background: rgba(0, 0, 0, 0); + border: none; + text-align: center; + padding: 4px; + vertical-align: middle; +} + +.profile-card .profile-bio .group-description:focus, +.profile-card .profile-bio .group-description:hover { + color: #fff; + background: #e18881; + opacity: .8; +} + +.profile-card .profile-bio .save, .profile-card .profile-bio .cancel { + display: none; + margin-left: 2px; +} + .group-messages-control .invite-form, .group-messages-control .secret-key { display: none; font-size: 12px; diff --git a/theme_calm/css/style.css b/theme_calm/css/style.css index af6745c..b637d45 100644 --- a/theme_calm/css/style.css +++ b/theme_calm/css/style.css @@ -168,6 +168,36 @@ button.unfollow:hover { margin-right: 10px; } +.a-button { + color: whitesmoke; + background-color: #6d83bd; + border: none; + font-size: 12px; + text-align: center; + width: auto; + padding: 4px 12px; + vertical-align: middle; + transition: all .1s linear; +} + +.a-button:hover { + color: #FFF; + background: #B2D67B; +} + +.a-button:disabled { + opacity: .7; +} + +.a-button:disabled:hover { + color: #fff; +} + +.b-buttons { + text-align: right; + padding: 4px; +} + .b-buttons { text-align: right; padding: 4px; diff --git a/theme_nin/css/style.css b/theme_nin/css/style.css index 301a0b3..c2b7d58 100644 --- a/theme_nin/css/style.css +++ b/theme_nin/css/style.css @@ -3005,6 +3005,27 @@ ol.toptrends-list a:hover { } +.profile-card .profile-bio .group-description { + border: none; + text-align: center; + width: 60%; + padding: 4px; + vertical-align: middle; +} + +.profile-card .profile-bio .group-description:focus { + border: 1px solid rgba(0, 0, 0, .1); + border-bottom: solid 1px #B4C669; +} + +.profile-card .profile-bio .group-description:hover { + border-bottom: solid 1px #B4C669; +} + +.profile-card .profile-bio .save, .profile-card .profile-bio .cancel { + display: none; +} + .group-messages-control .invite-form, .group-messages-control .secret-key { display: none; font-size: 12px; From d5bbe2c6f135418d9623a43609ed81c95e7aaf57 Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Sat, 24 Oct 2015 01:39:22 +0500 Subject: [PATCH 2/3] =?UTF-8?q?replace=20.parents()=20method=20with=20.clo?= =?UTF-8?q?sest()=20=E2=80=94=20need=20only=20first=20ancestor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/interface_common.js | 32 ++++++++++++++++---------------- js/mobile_abstract.js | 4 ++-- js/twister_directmsg.js | 12 ++++++------ 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/js/interface_common.js b/js/interface_common.js index 762a686..7966766 100644 --- a/js/interface_common.js +++ b/js/interface_common.js @@ -479,7 +479,7 @@ function reTwistPopup(event, post, textArea) { } if (typeof post === 'undefined') - post = $.evalJSON($(event.target).parents('.post-data').attr('data-userpost')); + post = $.evalJSON($(event.target).closest('.post-data').attr('data-userpost')); var modal = openModal({ classBase: '.prompt-wrapper', @@ -495,7 +495,7 @@ 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).parents('form').find('textarea').detach());}).bind(post)) + $(event.target).closest('form').find('textarea').detach());}).bind(post)) ; var replyArea = modal.content.find('.post-area .post-area-new'); @@ -533,7 +533,7 @@ 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).parents('form').find('textarea').detach())}).bind(post)) + $(event.target).closest('form').find('textarea').detach())}).bind(post)) ; var replyArea = modal.content.find('.post-area .post-area-new').addClass('open'); @@ -661,7 +661,7 @@ function postReplyClick(e) { if (!post.hasClass('original')) replyInitPopup(e, $.evalJSON(post.find('.post-data').attr('data-userpost'))); else { - if (!post.parents('.post.open').length) + if (!post.closest('.post.open').length) postExpandFunction(e, post); composeNewPost(e, post.find('.post-area-new')); } @@ -743,12 +743,12 @@ var usePostSpliting = false; function replyTextInput(event) { var textArea = $(event.target); - var textAreaForm = textArea.parents('form'); + var textAreaForm = textArea.closest('form'); if (textAreaForm.length) { if ($.Options.unicodeConversion.val !== 'disable') textArea.val(convert2Unicodes(textArea.val(), textArea)); - if (usePostSpliting && !textArea.parents('.directMessages').length) { + if (usePostSpliting && !textArea.closest('.directMessages').length) { var caretPos = textArea.caret(); var reply_to = textArea.attr('data-reply-to'); var tas = textAreaForm.find('textarea'); @@ -875,12 +875,12 @@ function replyTextUpdateRemaining(ta) { ta = ta.target; if (ta === document.activeElement) { var textArea = $(ta); - var textAreaForm = textArea.parents('form'); + var textAreaForm = textArea.closest('form'); if (textAreaForm.length) { var remainingCount = textAreaForm.find('.post-area-remaining'); var c = replyTextCountRemaining(ta); - if (usePostSpliting && !textArea.parents('.directMessages').length && splitedPostsCount > 1) + if (usePostSpliting && !textArea.closest('.directMessages').length && splitedPostsCount > 1) remainingCount.text((textAreaForm.find('textarea').index(ta) + 1).toString() + '/' + splitedPostsCount.toString() + ': ' + c.toString()); else @@ -913,8 +913,8 @@ function replyTextCountRemaining(ta) { var textArea = $(ta); var c; - if (usePostSpliting && !textArea.parents('.directMessages').length && splitedPostsCount > 1) { - c = 140 - ta.value.length - (textArea.parents('form').find('textarea').index(ta) + 1).toString().length - splitedPostsCount.toString().length - 4; + if (usePostSpliting && !textArea.closest('.directMessages').length && splitedPostsCount > 1) { + c = 140 - ta.value.length - (textArea.closest('form').find('textarea').index(ta) + 1).toString().length - splitedPostsCount.toString().length - 4; var reply_to = textArea.attr('data-reply-to'); if (typeof reply_to !== 'undefined' && !checkPostForMentions(ta.value, reply_to, 140 -c -reply_to.length)) @@ -931,7 +931,7 @@ function replyTextKeySend(event) { $('.dropdown-menu').css('display') === 'none') || ((event.metaKey || event.ctrlKey) && $.Options.keysSend.val === 'ctrlenter')) { var textArea = $(event.target); - var textAreaForm = textArea.parents('form'); + var textAreaForm = textArea.closest('form'); var buttonSend = textAreaForm.find('.post-submit'); if (!buttonSend.length) buttonSend = textAreaForm.find('.dm-submit'); @@ -1413,11 +1413,11 @@ function postSubmit(e, oldLastPostId) { return; } - if (btnPostSubmit.parents('.prompt-wrapper').length) + if (btnPostSubmit.closest('.prompt-wrapper').length) closePrompt(); else { textArea.val('').attr('placeholder', polyglot.t('Your message was sent!')); - var tweetForm = btnPostSubmit.parents('form'); + var tweetForm = btnPostSubmit.closest('form'); var remainingCount = tweetForm.find('.post-area-remaining'); remainingCount.text(140); @@ -1639,7 +1639,7 @@ function elemFitNextIntoParentHeight(elem) { function inputEnterActivator(event) { var elemEvent = $(event.target); - elemEvent.parents(event.data.parentSelector).find(event.data.enterSelector) + elemEvent.closest(event.data.parentSelector).find(event.data.enterSelector) .attr('disabled', elemEvent.val().trim() === ''); } @@ -1652,7 +1652,7 @@ function setTextcompleteOnEventTarget(event) { function setTextcompleteOnElement(elem, req) { elem = $(elem); elem.textcomplete(req, { - appendTo: (elem.parents('.dashboard').length) ? elem.parent() : $('body'), + appendTo: (elem.closest('.dashboard').length) ? elem.parent() : $('body'), listPosition: setTextcompleteDropdownListPos }); } @@ -1666,7 +1666,7 @@ function unsetTextcompleteOnEventTarget(event) { function setTextcompleteDropdownListPos(position) { position = this._applyPlacement(position); - if (this.option.appendTo.parents('.dashboard').length > 0) { + if (this.option.appendTo.closest('.dashboard').length > 0) { position.position = 'fixed'; position.top = (parseFloat(position.top) - window.pageYOffset).toString() + 'px'; } else diff --git a/js/mobile_abstract.js b/js/mobile_abstract.js index 8fe3e14..f168655 100644 --- a/js/mobile_abstract.js +++ b/js/mobile_abstract.js @@ -47,7 +47,7 @@ var MAL = function() $dmChatList.listview('refresh'); $.mobile.silentScroll( $(".dm-form").offset().top ); } else { - var modalContent = dmConvo.parents(".modal-content"); + var modalContent = dmConvo.closest(".modal-content"); modalContent.scrollTop(modalContent[0].scrollHeight); } } @@ -498,7 +498,7 @@ var MAL = function() if ($.hasOwnProperty('mobile')) { return postLi.siblings().length; } else { - return postLi.parents('.module.post.original.open').find('.post.related').length; + return postLi.closest('.module.post.original.open').find('.post.related').length; } }; } diff --git a/js/twister_directmsg.js b/js/twister_directmsg.js index f51883b..18fbb92 100644 --- a/js/twister_directmsg.js +++ b/js/twister_directmsg.js @@ -270,7 +270,7 @@ function openGroupMessagesNewGroupModal() { ; modal.content.find('.create').on('click', function (event) { var elemEvent = $(event.target); - var elemForm = elemEvent.parents('.module') + var elemForm = elemEvent.closest('.module'); var peersToInvite = elemForm.find('.invite').val().toLowerCase().match(/@\w+/g); if (peersToInvite) @@ -307,9 +307,9 @@ function openGroupMessagesJoinGroupModal() { .attr('data-screen-name', groupChatAliases[i]) .on('click', function (event) { var elemEvent = $(event.target); - elemEvent.parents('.module').find('.join') + elemEvent.closest('.module').find('.join') .attr('disabled', - !elemEvent.parents('.groups-list').find('input:checked').length); + !elemEvent.closest('.groups-list').find('input:checked').length); }) ; item.find('.twister-user-name') @@ -325,7 +325,7 @@ function openGroupMessagesJoinGroupModal() { modal.content.find('.join').on('click', function (event) { var elemEvent = $(event.target); - var groups = elemEvent.parents('.module').find('.groups-list input:checked'); + var groups = elemEvent.closest('.module').find('.groups-list input:checked'); for (var i = 0; i < groups.length; i++) groupMsgInviteToGroup(groups[i].getAttribute('data-screen-name'), [defaultScreenName]); @@ -335,7 +335,7 @@ function openGroupMessagesJoinGroupModal() { modal.content.find('.secret-key-import, .username-import').on('input', importSecretKeypress); modal.content.find('.import-secret-key').on('click', function (event) { - var elemModule = $(event.target).parents('.module'); + var elemModule = $(event.target).closest('.module'); var groupAlias = elemModule.find('.username-import').val().toLowerCase(); var secretKey = elemModule.find('.secret-key-import').val(); @@ -490,7 +490,7 @@ function initInterfaceDirectMsg() { peersToInvite); elemInput.val(''); - elemEvent.parents('.invite-form').toggle(); + elemEvent.closest('.invite-form').toggle(); // TODO reload group members list }); From 1afe26afb3ebf0166131fee7265e3adf6675967e Mon Sep 17 00:00:00 2001 From: Simon Grim Date: Sat, 24 Oct 2015 02:10:58 +0500 Subject: [PATCH 3/3] fix check for emptiness of input in htmlFormatMsg() --- js/twister_formatpost.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/js/twister_formatpost.js b/js/twister_formatpost.js index 4489050..77e1e10 100644 --- a/js/twister_formatpost.js +++ b/js/twister_formatpost.js @@ -603,6 +603,11 @@ function htmlFormatMsg(msg) { return msg.str; } + if (!msg) { + console.warn('htmlFormatMsg() error: input string is empty'); + return {html: '', mentions: []}; + } + var mentionsChars = 'abcdefghijklmnopqrstuvwxyz_0123456789'; var stopCharsTrailing = '/\\*~_-`.,:;?!%\'"[](){}^|«»…\u201C\u201D\u2026\u2014\u4E00\u3002\uFF0C\uFF1A\uFF1F\uFF01\u3010\u3011\u2047\u2048\u2049'; var stopCharsTrailingUrl = stopCharsTrailing.slice(1);