jenkins-bot has submitted this change and it was merged. Change subject: Story 1072: KeepGoing CTA ......................................................................
Story 1072: KeepGoing CTA * Introduce sticky CTA which allows user to continue editing * Show CTA after a successful first edit or when campaign=mobile-keepgoing is present in query string * Allow new editor to try other articles * dismissing cta exits the campaign (although if you refresh it will show again) * EventLogging via mobileWebCta.js Change-Id: I4c022df9634e55a6dedcf9237ba3318a66f5677b --- M MobileFrontend.i18n.php M includes/Resources.php M javascripts/common/Drawer.js A javascripts/loggingSchemas/mobileWebCta.js M javascripts/modules/editor/EditorOverlay.js A javascripts/modules/keepgoing/KeepGoingDrawer.js A javascripts/modules/keepgoing/keepgoing.js M less/common/drawer.less M templates/ctaDrawer.html A templates/keepgoing/KeepGoingDrawer.html 10 files changed, 197 insertions(+), 9 deletions(-) Approvals: JGonera: Looks good to me, approved jenkins-bot: Verified diff --git a/MobileFrontend.i18n.php b/MobileFrontend.i18n.php index 0f70f93..73e9cbf 100644 --- a/MobileFrontend.i18n.php +++ b/MobileFrontend.i18n.php @@ -12,6 +12,14 @@ $messages = array(); $messages['en'] = array ( + // KeepGoingCta + 'mobilefrontend-keepgoing-ask' => "Well done! You're getting the hang of this! Do you want to try editing another page?", + 'mobilefrontend-keepgoing-ask-first' => 'Congratulations on making your first edit! Do you want to try editing another page?', + 'mobilefrontend-keepgoing-explain' => 'Great! Another user said this page needs help. Try this one, or try another one.', + 'mobilefrontend-keepgoing-cancel' => 'No, thanks', + 'mobilefrontend-keepgoing-suggest' => 'Yes, please', + 'mobilefrontend-keepgoing-suggest-again' => 'Try another', + /** special pages */ 'nearby' => 'Pages near you', @@ -346,6 +354,16 @@ * @author 아라 */ $messages['qqq'] = array( + // KeepGoingCta + 'mobilefrontend-keepgoing-ask' => "Congratulations message shown to a user who has completed an edit in the keepgoing campaign. Prompts them to edit again.", + 'mobilefrontend-keepgoing-ask-first' => 'Congratulate user on first edit. Ask them if they want to edit again.', + 'mobilefrontend-keepgoing-explain' => 'Message explaining that the page they are looking at has issues. Gives them the option to try another.', + 'mobilefrontend-keepgoing-cancel' => 'Label for button that user can express a desire to no longer edit.', + 'mobilefrontend-keepgoing-suggest' => 'Label for button that user can answer question posed in {{msg-mw|Mobilefrontend-keepgoing-ask-first}} +or {{msg-mw|Mobilefrontend-keepgoing-ask}}.', + 'mobilefrontend-keepgoing-suggest-again' => 'Label for a button that allows uer to try another page as a response to +{{msg-mw|Mobilefrontend-keepgoing-explain}}.', + 'nearby' => '{{doc-special|Nearby}}', 'mobile-frontend-desc' => '{{desc|name=Mobile Frontend|url=https://www.mediawiki.org/wiki/Extension:MobileFrontend}}', 'mobile.css' => '{{optional}} diff --git a/includes/Resources.php b/includes/Resources.php index d943c87..3c53b3b 100644 --- a/includes/Resources.php +++ b/includes/Resources.php @@ -277,6 +277,28 @@ ), ), + 'mobile.keepgoing' => $wgMFMobileResourceBoilerplate + array( + 'dependencies' => array( + 'mobile.beta', + 'mobile.templates', + ), + 'templates' => array( + 'keepgoing/KeepGoingDrawer', + ), + 'messages' => array( + 'mobilefrontend-keepgoing-suggest', + 'mobilefrontend-keepgoing-suggest-again', + 'mobilefrontend-keepgoing-cancel', + 'mobilefrontend-keepgoing-ask', + 'mobilefrontend-keepgoing-ask-first', + 'mobilefrontend-keepgoing-explain', + ), + 'scripts' => array( + 'javascripts/loggingSchemas/mobileWebCta.js', + 'javascripts/modules/keepgoing/KeepGoingDrawer.js', + ), + ), + 'mobile.beta' => $wgMFMobileResourceBoilerplate + array( 'dependencies' => array( 'mobile.stable', @@ -293,6 +315,7 @@ 'javascripts/modules/tutorials/PageActionOverlay.js', 'javascripts/modules/tutorials/newbie.js', 'javascripts/modules/lastModifiedBeta.js', + 'javascripts/modules/keepgoing/keepgoing.js', ), 'position' => 'bottom', 'messages' => array( diff --git a/javascripts/common/Drawer.js b/javascripts/common/Drawer.js index 88745ae..6b3610d 100644 --- a/javascripts/common/Drawer.js +++ b/javascripts/common/Drawer.js @@ -10,6 +10,7 @@ postRender: function() { var self = this; + // FIXME: Standardise on either close or cancel to be consistent with Overlay.js this.$( '.close' ).click( function( ev ) { ev.preventDefault(); self.hide(); diff --git a/javascripts/loggingSchemas/mobileWebCta.js b/javascripts/loggingSchemas/mobileWebCta.js new file mode 100644 index 0000000..65d89a9 --- /dev/null +++ b/javascripts/loggingSchemas/mobileWebCta.js @@ -0,0 +1,38 @@ +( function( M, $ ) { + + function log( status, campaign, step ) { + var + username = mw.config.get( 'wgUserName' ), + data = { + status: status, + campaign: campaign || M.query.campaign, + campaignStep: step, + mobileMode: mw.config.get( 'wgMFMode' ) + }; + + if ( username ) { + data.username = username; + data.userEditCount = mw.config.get( 'wgUserEditCount' ); + } + + return M.log( 'MobileWebCta', data ); + } + + // FIXME: Turn into common component shared with MobileWebClickTracking ? + function hijackLink( $el, status, campaign, step ) { + function linkHandler( ev ) { + ev.preventDefault(); + var href = $( this ).attr( 'href' ); + log( status, campaign, step ).always( function() { + window.location.href = href; + } ); + } + $el.on( M.tapEvent( 'click' ), linkHandler ); + } + + M.define( 'loggingSchemas/mobileWebCta', { + log: log, + hijackLink: hijackLink + } ); + +} )( mw.mobileFrontend, jQuery ); diff --git a/javascripts/modules/editor/EditorOverlay.js b/javascripts/modules/editor/EditorOverlay.js index dd680d6..0ae537e 100644 --- a/javascripts/modules/editor/EditorOverlay.js +++ b/javascripts/modules/editor/EditorOverlay.js @@ -4,8 +4,11 @@ Page = M.require( 'Page' ), popup = M.require( 'notifications' ), api = M.require( 'api' ), + inBetaOrAlpha = mw.config.get( 'wgMFMode' ) !== 'stable', + inKeepGoingCampaign = M.query.campaign === 'mobile-keepgoing', Section = M.require( 'Section' ), EditorApi = M.require( 'modules/editor/EditorApi' ), + KeepGoingDrawer, EditorOverlay; EditorOverlay = Overlay.extend( { @@ -35,7 +38,7 @@ action: action, section: this.sectionId, namespace: mw.config.get( 'wgNamespaceNumber' ), - userEditCount: parseInt( mw.config.get( 'wgUserEditCount' ), 10 ), + userEditCount: mw.config.get( 'wgUserEditCount' ), isTestA: M.isTestA, pageId: mw.config.get( 'wgArticleId' ), username: mw.config.get( 'wgUserName' ), @@ -56,6 +59,8 @@ } ); this.sectionId = options.sectionId; this.isNewEditor = options.isNewEditor; + this.editCount = mw.config.get( 'wgUserEditCount' ); + this.isFirstEdit = this.editCount === 0; this._super( options ); }, @@ -116,6 +121,13 @@ this.scrollTop = $( 'body' ).scrollTop(); this.$content.hide(); this.$spinner.show(); + + // pre-fetch keep going with expectation user will go on to save + if ( inBetaOrAlpha && ( this.isFirstEdit || inKeepGoingCampaign ) ) { + mw.loader.using( 'mobile.keepgoing', function() { + KeepGoingDrawer = M.require( 'KeepGoingDrawer' ); + } ); + } api.post( { action: 'parse', @@ -218,6 +230,12 @@ this.captchaShown = true; }, + _updateEditCount: function() { + this.isFirstEdit = false; + this.editCount += 1; + mw.config.set( 'wgUserEditCount', this.editCount ); + }, + _save: function() { var self = this, className = 'toast landmark', options = { summary: this.$( '.summary' ).val() }, @@ -233,8 +251,8 @@ this.api.save( options ). done( function() { - var title = self.options.title, - editCount = mw.config.get( 'wgUserEditCount' ); + var title = self.options.title; + // log success! self.log( 'success' ); M.pageApi.invalidatePage( title ); @@ -247,10 +265,14 @@ className = 'toast'; msg = 'mobile-frontend-editor-success'; } - // update edit count - // FIXME: this should be an integer (see bug 51633) - mw.config.set( 'wgUserEditCount', ( parseInt( editCount, 10 ) + 1 ).toString() ); - popup.show( mw.msg( msg ), className ); + self._updateEditCount(); + // double check it was successfully pre-fetched during preview phase + if ( KeepGoingDrawer ) { + new KeepGoingDrawer( { isFirstEdit: self.isFirstEdit } ); + } else { + // just show a toast + popup.show( mw.msg( msg ), className ); + } } ). fail( function( data ) { var msg; diff --git a/javascripts/modules/keepgoing/KeepGoingDrawer.js b/javascripts/modules/keepgoing/KeepGoingDrawer.js new file mode 100644 index 0000000..9135993 --- /dev/null +++ b/javascripts/modules/keepgoing/KeepGoingDrawer.js @@ -0,0 +1,62 @@ +/** + * This creates the drawer at the bottom of the screen that appears when an anonymous + * user tries to perform an action that requires being logged in. It presents the user + * with options to log in or sign up for a new account. + */ +( function( M ) { + M.assertMode( [ 'beta', 'alpha' ] ); + + var Drawer = M.require( 'Drawer' ), + mobileWebCta = M.require( 'loggingSchemas/mobileWebCta' ), + KeepGoingDrawer, + campaign = 'mobile-keepgoing', + api = M.require( 'api' ); + + KeepGoingDrawer = Drawer.extend( { + locked: true, + defaults: { + step: 0, + cancel: mw.msg( 'mobilefrontend-keepgoing-cancel' ) + }, + template: M.template.get( 'keepgoing/KeepGoingDrawer' ), + log: function( status ) { + mobileWebCta.log( status, campaign, this.options.step ); + }, + initialize: function( options ) { + options = options || {}; + if ( options.tryAgain ) { + options.msg = mw.msg( 'mobilefrontend-keepgoing-explain' ); + options.nextLabel = mw.msg( 'mobilefrontend-keepgoing-suggest-again' ); + } else { + options.msg = options.isFirstEdit ? mw.msg( 'mobilefrontend-keepgoing-ask-first' ) : mw.msg( 'mobilefrontend-keepgoing-ask' ); + options.nextLabel = mw.msg( 'mobilefrontend-keepgoing-suggest' ); + } + this._super( options ); + }, + // FIXME: Juliusz would like to revisit this - a little messy + render: function( options ) { + var self = this, + step = options.step, + nextStep = step + 1, + _super = self._super; + options = options || {}; + api.get( { action: 'query', list: 'random', rnnamespace: '0', rnlimit: 1 } ).done( function( resp ) { + var page = resp.query.random[0], + url = mw.util.wikiGetlink( page.title, { campaign: campaign, campaign_step: nextStep } ); + + options.nextUrl = url; + _super.call( self, options ); + self.show(); + mobileWebCta.hijackLink( self.$( '.continue' ), 'keepgoing-success', campaign, step ); + self.$( '.close' ).on( 'click', function() { + self.log( 'keepgoing-exit' ); + } ); + } ); + this.log( 'keepgoing-shown' ); + } + } ); + + M.define( 'modules/keepgoing/KeepGoingDrawer', KeepGoingDrawer ); + +}( mw.mobileFrontend ) ); + diff --git a/javascripts/modules/keepgoing/keepgoing.js b/javascripts/modules/keepgoing/keepgoing.js new file mode 100644 index 0000000..d6f52a9 --- /dev/null +++ b/javascripts/modules/keepgoing/keepgoing.js @@ -0,0 +1,9 @@ +( function( M ) { + if ( M.query.campaign === 'mobile-keepgoing' ) { + mw.loader.using( 'mobile.keepgoing', function() { + var KeepGoingDrawer = M.require( 'modules/keepgoing/KeepGoingDrawer' ); + // deal with case when campaign_step is undefined + new KeepGoingDrawer( { tryAgain: true, step: parseInt( M.query.campaign_step, 10 ) || 0 } ); + } ); + } +}( mw.mobileFrontend ) ); diff --git a/less/common/drawer.less b/less/common/drawer.less index f243dbc..d4887c6 100644 --- a/less/common/drawer.less +++ b/less/common/drawer.less @@ -26,8 +26,11 @@ background: url(../modules/images/show.png) 50% 8px no-repeat; } - a.button { + .button.wide { display: block; + } + + a.button { margin: 1em @contentMarginLeft; } @@ -39,3 +42,10 @@ margin: .9em 0 0; } } + +// When overlays are opened drawers do not look good +.overlay-enabled { + .drawer { + display: none; + } +} \ No newline at end of file diff --git a/templates/ctaDrawer.html b/templates/ctaDrawer.html index 9f02fec..cabed04 100644 --- a/templates/ctaDrawer.html +++ b/templates/ctaDrawer.html @@ -1,6 +1,6 @@ <a class="close" href="#">{{cancelMessage}}</a> <p>{{content}}</p> <div class="buttonBar"> - <a class="button" href="{{loginUrl}}">{{loginCaption}}</a> + <a class="button wide" href="{{loginUrl}}">{{loginCaption}}</a> <a class="signup" href="{{signupUrl}}">{{signupCaption}}</a> </div> diff --git a/templates/keepgoing/KeepGoingDrawer.html b/templates/keepgoing/KeepGoingDrawer.html new file mode 100644 index 0000000..96e8cc7 --- /dev/null +++ b/templates/keepgoing/KeepGoingDrawer.html @@ -0,0 +1,5 @@ +<p>{{msg}}</p> +<div class="buttonBar"> + <button class="inline close">{{cancel}}</button> + <a class="continue button" href="{{nextUrl}}">{{{nextLabel}}}</a> +</div> -- To view, visit https://gerrit.wikimedia.org/r/87426 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4c022df9634e55a6dedcf9237ba3318a66f5677b Gerrit-PatchSet: 9 Gerrit-Project: mediawiki/extensions/MobileFrontend Gerrit-Branch: master Gerrit-Owner: Jdlrobson <jrob...@wikimedia.org> Gerrit-Reviewer: JGonera <jgon...@wikimedia.org> Gerrit-Reviewer: Jdlrobson <jrob...@wikimedia.org> Gerrit-Reviewer: Siebrand <siebr...@wikimedia.org> Gerrit-Reviewer: jenkins-bot _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits