Florianschmidtwelzow has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/254776

Change subject: [WIP] Add link preview feature to beta mode
......................................................................

[WIP] Add link preview feature to beta mode

Linkpreview will try to fetch a text extract using the api and, if this
doesn't fail, show the extract as a drawer with a button "Continue to
article". If the query fails, it will redirect the user to the article
directly.

ToDo:
 * There should be an option to disable this feature (maybe in mobile
   settings, or in the drawer)

Bug: T113243
Change-Id: Idbaae9fe2decd89b73e623a25fbd39464c316fb2
---
M i18n/en.json
M i18n/qqq.json
M includes/Resources.php
A resources/mobile.linkpreview.init/initLinkPreview.js
A resources/mobile.linkpreview/LinkPreview.less
A resources/mobile.linkpreview/LinkPreviewApi.js
A resources/mobile.linkpreview/LinkPreviewDrawer.hogan
A resources/mobile.linkpreview/LinkPreviewDrawer.js
8 files changed, 265 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/MobileFrontend 
refs/changes/76/254776/1

diff --git a/i18n/en.json b/i18n/en.json
index d0d9be6..6c16ce7 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -205,6 +205,7 @@
        "mobile-frontend-last-modified-years": "Last edited {{PLURAL:$1|$1 
year|$1 years}} ago",
        "mobile-frontend-lead-image-tutorial-confirm": "Start uploading",
        "mobile-frontend-lead-image-tutorial-summary": "Ensure that your image 
can help illustrate the page. It should be an image that you created which does 
not violate copyright.",
+       "mobile-frontend-linkpreview-continue-to-article": "Continue to 
article",
        "mobile-frontend-logged-in-homepage-notification": 
"{{GENDER:$1|Welcome}}, $1!",
        "mobile-frontend-logged-in-toast-notification": "Logged in as $1.",
        "mobile-frontend-main-menu": "Main Menu",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index c223075..0c425e4 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -201,6 +201,7 @@
        "mobile-frontend-last-modified-years": "Text displayed on page to show 
how long ago the page was updated. Parameters:\n* $1 - number of 
years\n{{Related|Mobile-frontend-last-modified}}",
        "mobile-frontend-lead-image-tutorial-confirm": "Call to action that 
when clicked starts uploading an image to a page from tutorial.",
        "mobile-frontend-lead-image-tutorial-summary": "Briefly summarise that 
a lead image should illustrate the page whilst not violating copyright. Shown 
to new users after logging in",
+       "mobile-frontend-linkpreview-continue-to-article": "Button label 
visible in the link preview drawer. When clicked, the brwoser redirects to the 
target article.",
        "mobile-frontend-logged-in-homepage-notification": "Heading at top of 
homepage telling user they are logged in. Parameters:\n* $1 - username",
        "mobile-frontend-logged-in-toast-notification": "Message telling user 
that they are logged in. Shows as a notification at bottom of page\n*$1 - 
username",
        "mobile-frontend-main-menu": "Message that is displayed as a tooltip 
for the main menu icon in the header",
diff --git a/includes/Resources.php b/includes/Resources.php
index 684a59c..d7ee94b 100644
--- a/includes/Resources.php
+++ b/includes/Resources.php
@@ -1193,6 +1193,35 @@
                ),
        ),
 
+       'mobile.linkpreview.init' => $wgMFResourceFileModuleBoilerplate + array(
+               'dependencies' => array(
+                       'mobile.context',
+                       'mobile.settings',
+               ),
+               'scripts' => array(
+                       'resources/mobile.linkpreview.init/initLinkPreview.js',
+               ),
+       ),
+
+       'mobile.linkpreview' => $wgMFResourceFileModuleBoilerplate + array(
+               'dependencies' => array(
+                       'mobile.linkpreview.init',
+                       'mobile.drawers',
+               ),
+               'scripts' => array(
+                       'resources/mobile.linkpreview/LinkPreviewDrawer.js'
+               ),
+               'templates' => array(
+                       'LinkPreviewDrawer.hogan' => 
'resources/mobile.linkpreview/LinkPreviewDrawer.hogan',
+               ),
+               'styles' => array(
+                       'resources/mobile.linkpreview/LinkPreview.less',
+               ),
+               'messages' => array(
+                       'mobile-frontend-linkpreview-continue-to-article',
+               ),
+       ),
+
        // Custom ResourceLoaderModule classes
        'mobile.site' => array(
                'dependencies' => array( 'mobile.startup' ),
@@ -1638,6 +1667,7 @@
                        // load code under certain conditions.
                        'mobile.search.beta',
                        'mobile.backtotop',
+                       'mobile.linkpreview.init',
                ),
                'scripts' => array(
                        
'resources/skins.minerva.beta.scripts/commonsCategory.js',
diff --git a/resources/mobile.linkpreview.init/initLinkPreview.js 
b/resources/mobile.linkpreview.init/initLinkPreview.js
new file mode 100644
index 0000000..02b16b3
--- /dev/null
+++ b/resources/mobile.linkpreview.init/initLinkPreview.js
@@ -0,0 +1,19 @@
+( function ( M, $ ) {
+       var context = M.require( 'mobile.context/context' ),
+               settings = M.require( 'mobile.settings/settings' );
+
+       if ( context.isBetaGroupMember() && !settings.get( 
'mf-disable-linkpreview' ) ) {
+               mw.loader.using( 'mobile.linkpreview' ).done( function () {
+                       var LinkPreviewDrawer = M.require( 
'mobile.linkpreview/LinkPreviewDrawer' ),
+                               drawer = new LinkPreviewDrawer();
+
+                       // show linkpreview only for internal and existing 
links. All others should work
+                       // like "normal" links (redirecting to the target)"
+                       $( '#bodyContent a:not(.new .external)' ).on( 'click', 
function ( ev ) {
+                               drawer.loadNew( ev.target.title );
+
+                               return false;
+                       } );
+               } );
+       }
+}( mw.mobileFrontend, jQuery ) );
diff --git a/resources/mobile.linkpreview/LinkPreview.less 
b/resources/mobile.linkpreview/LinkPreview.less
new file mode 100644
index 0000000..28dfdf5
--- /dev/null
+++ b/resources/mobile.linkpreview/LinkPreview.less
@@ -0,0 +1,33 @@
+.drawer.linkpreview {
+       position: fixed;
+       background-color: white;
+       text-align: left;
+       padding: 0 15px 20px;
+}
+
+.linkpreview-title {
+       font-family: Georgia;
+       font-size: 22px;
+       margin-top: 20px;
+}
+
+.linkpreview-content {
+       font-size: 15px;
+       margin-top: 20px;
+}
+
+.linkpreview-continue {
+       text-align: center;
+       margin-top: 20px;
+
+       .mw-ui-button {
+               margin-bottom: 0;
+       }
+}
+
+@media all and (min-width: @wgMFDeviceWidthTablet) {
+       .drawer.linkpreview {
+               padding-left: 30px;
+               padding-right: 30px;
+       }
+}
diff --git a/resources/mobile.linkpreview/LinkPreviewApi.js 
b/resources/mobile.linkpreview/LinkPreviewApi.js
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/resources/mobile.linkpreview/LinkPreviewApi.js
diff --git a/resources/mobile.linkpreview/LinkPreviewDrawer.hogan 
b/resources/mobile.linkpreview/LinkPreviewDrawer.hogan
new file mode 100644
index 0000000..571947b
--- /dev/null
+++ b/resources/mobile.linkpreview/LinkPreviewDrawer.hogan
@@ -0,0 +1,6 @@
+<div class="linkpreview">
+       <div class="linkpreview-title"></div>
+       <div class="linkpreview-content"></div>
+       <div 
class="linkpreview-continue">{{#continueButton}}{{>Button}}{{/continueButton}}</div>
+</div>
+{{{spinner}}}
diff --git a/resources/mobile.linkpreview/LinkPreviewDrawer.js 
b/resources/mobile.linkpreview/LinkPreviewDrawer.js
new file mode 100644
index 0000000..e2dd002
--- /dev/null
+++ b/resources/mobile.linkpreview/LinkPreviewDrawer.js
@@ -0,0 +1,175 @@
+( function ( M, $ ) {
+       var LinkPreviewDrawer,
+               Drawer = M.require( 'mobile.drawers/Drawer' ),
+               Button = M.require( 'mobile.startup/Button' ),
+               icons = M.require( 'mobile.startup/icons' );
+
+       LinkPreviewDrawer = Drawer.extend( {
+               /**
+                * @inheritdoc
+                * @cfg {Object} defaults Default options hash.
+                * @cfg {String} defaults.spinner html of spinner icon
+                * @cfg {Object} defaults.continueButton HTML of the continue 
button.
+                */
+               defaults: {
+                       spinner: icons.spinner().toHtmlString(),
+                       continueButton: new Button( {
+                               progressive: true,
+                               label: mw.msg( 
'mobile-frontend-linkpreview-continue-to-article' )
+                       } ).options
+               },
+
+               /**
+                * @inheritdoc
+                */
+               template: mw.template.get( 'mobile.linkpreview', 
'LinkPreviewDrawer.hogan' ),
+
+               /**
+                * @inheritdoc
+                */
+               templatePartials: {
+                       Button: Button.prototype.template
+               },
+
+               /**
+                * @inheritdoc
+                */
+               events: $.extend( {}, Drawer.prototype.events, {
+                       'click .linkpreview-continue a': 'onContinueClick'
+               } ),
+
+               /**
+                * @inheritdoc
+                */
+               className: 'drawer linkpreview',
+
+               /**
+                * @inheritdoc
+                */
+               closeOnScroll: false,
+
+               /**
+                * Cache for the api queries.
+                *
+                * @property {Object}
+                */
+               cache: {},
+
+               /**
+                * @inheritdoc
+                */
+               postRender: function () {
+                       Drawer.prototype.postRender.apply( this, arguments );
+
+                       this.$linkpreview = this.$( '.linkpreview' );
+                       this.$spinner = this.$( '.spinner' );
+                       this.api = new mw.Api();
+               },
+
+               /**
+                * Show the drawer with the initial spinner (and hide the 
content,
+                * that was (maybe) already added.
+                *
+                * @return {Object} this
+                */
+               showWithSpinner: function () {
+                       this.$spinner.removeClass( 'hidden' );
+                       this.$linkpreview.addClass( 'hidden' );
+                       this.show();
+
+                       return this;
+               },
+
+               /**
+                * Hide the spinner (if any) and show the content of the drawer.
+                *
+                * @return {Object} this
+                */
+               showContent: function () {
+                       this.$spinner.addClass( 'hidden' );
+                       this.$linkpreview.removeClass( 'hidden' );
+
+                       return this;
+               },
+
+               /**
+                * Load content from a given title, show it or redirect to this
+                * title if something went wrong.
+                *
+                * @param {String} title The target title
+                */
+               loadNew: function ( title ) {
+                       var self = this;
+
+                       this.showWithSpinner();
+                       this.title = title;
+
+                       if ( !this.cache[title] ) {
+                               this.api.get( {
+                                       action: 'query',
+                                       titles: title,
+                                       prop: 'extracts',
+                                       explaintext: true,
+                                       exintro: true,
+                                       exchars: 140,
+                                       formatversion: 2
+                               } ).done( function ( result ) {
+                                       var data;
+
+                                       if ( result.query.pages[0] ) {
+                                               data = result.query.pages[0];
+                                               self
+                                                       .setTitle( data.title )
+                                                       .setContent( 
data.extract )
+                                                       .showContent();
+
+                                               self.cache[title] = data;
+                                       } else {
+                                               self.onContinueClick();
+                                       }
+                               } ).fail( function () {
+                                       self.onContinueClick();
+                               } );
+                       } else {
+                               self
+                                       .setTitle( this.cache[title].title )
+                                       .setContent( this.cache[title].extract )
+                                       .showContent();
+                       }
+               },
+
+               /**
+                * Replace the current visible title with the given one.
+                *
+                * @param {String} title The new title (HTML isn't supported)
+                * @return {Object} this
+                */
+               setTitle: function ( title ) {
+                       this.$( '.linkpreview-title' ).text( title );
+
+                       return this;
+               },
+
+               /**
+                * Replace the current visible content with the given one.
+                *
+                * @param {String} content The new content (HTML isn't 
supported)
+                * @return {Object} this
+                */
+               setContent: function ( content ) {
+                       this.$( '.linkpreview-content' ).text( content );
+
+                       return this;
+               },
+
+               /**
+                * Handle the click on the "continue to article" button and 
redirect to the
+                * title (this.title).
+                */
+               onContinueClick: function () {
+                       window.location.href = mw.util.getUrl( this.title );
+               }
+       } );
+
+       M.define( 'mobile.linkpreview/LinkPreviewDrawer', LinkPreviewDrawer );
+}( mw.mobileFrontend, jQuery ) );

-- 
To view, visit https://gerrit.wikimedia.org/r/254776
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Idbaae9fe2decd89b73e623a25fbd39464c316fb2
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/MobileFrontend
Gerrit-Branch: master
Gerrit-Owner: Florianschmidtwelzow <florian.schmidt.stargatewis...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to