User:SBisson (WMF)/story.js

var verbose = true; var log = verbose ? console.log : function {};

function isIncludedInExperiment { var action = mw.config.get( 'wgAction' ); if ( action !== 'view' ) { log( 'Article action should be view but it is', action ); return false; }	var ns = mw.config.get( 'wgNamespaceNumber' ); if ( ns !== 0 ) { log( 'Not the article ns:', ns ); return false; }	if ( mw.config.get('wgArticleId') === 0 ) { log( 'The current article does not exist.' ); return false; }	if ( Math.random > 0.5 ) { log( 'Control group' ); // return false; // This should return false so the control group doesn't see anything special }	return true; }

function makeStoryFromMediaList( title ) { var interestingItem = function( item ) { return item.type === 'image' && item.showInGallery && item.caption && item.caption.text; };	var toStoryFrame = function( item ) { return { src: item.srcset[0].src, text: item.caption.text };	};	var url = 'https://en.wikipedia.org/api/rest_v1/page/media-list/' + title; return fetch( url ).then( function( resp ) {		return resp.json;	}).then( function ( json ) {		var frames = json && json.items &&			json.items.filter( interestingItem )			.map( toStoryFrame );		if ( frames && frames.length >= 4 ) {			return frames;		}	}); }

function getStory( title ) { // The story can be stored on another page, or hardcoded here or generated // from various sources. // The media-list version used here is for illustration purposes only and // would not make sense for the readers experiment. return makeStoryFromMediaList( title ); }

function addStoryButton( onClick ) { var skin = mw.config.get( 'skin' ); if ( skin === 'vector' ) { var span = $( ' ' ).text( 'WikiStory' ); var button = $( '' ).append( span ).on( 'click', onClick ); var listItem = $( '' ).addClass( 'mw-list-item' ).attr( 'id', 'ca-story' ).append( button ); $( '#left-navigation .vector-menu-content-list' ).append( listItem ); } else if ( skin === 'minerva' ) { var tab = $( '' ).addClass( 'minerva__tab' ).text( 'WikiStory' ).on( 'click', onClick ); $( '.minerva__tab-container' ).append( tab ); } }

function createStoryViewer { return mw.loader.using( 'vue' ).done( function ( require ) {		var Vue = require( 'vue' );		Vue.component( 'frame', { template: ' ', props: [ 'src', 'text', 'click', 'current', 'total' ], computed: { styleDiv: function { return { backgroundImage: 'url(' + this.src + ')', position: 'relative', backgroundSize: 'cover', backgroundPosition: 'center', width: '80vw', height: '80vh' };				},				styleP: function { return { position: 'absolute', bottom: '10px', left: '10px', right: '10px', maxHeight: '80%', backgroundColor: 'white', borderRadius: '10px', textAlign: 'center', margin: 0, padding: '10px' };				},			}		} );		Vue.component( 'progressbar', { template: '  ', props: [ 'current', 'total' ], computed: { styleContainer: function { return { marginTop: '4px', height: '4px', width: '100%', display: 'flex' };				}			},			methods: { styleItem: function(n) { var cur = this.current + 1; var color = 'grey'; if ( n < cur) { // past color = 'blue'; } else if ( n > cur ) { // future color = 'red'; } else { // present color = 'white'; }					return { backgroundColor: color, margin: '0 4px', flex: '1 0 auto' };				}			}		} );		Vue.component( 'story-viewer', { template: ' ', props: [ 'story', 'visible', 'eventSubmit' ], data: function { return { show: this.visible, index: 0, interval: null };			},			computed: { frame: function { return this.story[ this.index ]; },				style: function { return { backgroundColor: 'black', position: 'absolute', top: 0, bottom: 0, right: 0, left: 0, zIndex: 101, display: 'flex', alignItems: 'center', justifyContent: 'center' };				}			},			methods: { overlayClick: function( e ) { if ( e.target.classList.contains('story-viewer') ) { this.close; }				},				nextFrame: function { if ( this.index < this.story.length - 1 ) { this.index++; } else { this.close; }				},				logEvent: function { this.eventSubmit('test.instrumentation', {						"$schema": "/analytics/test/2.0.0",						"test_string": "Inuka-WSRE-test1",						"test_map": {							"title": mw.config.get( 'wgPageName' ),							"story_frame_count": this.story.length,							"story_frame_read": this.index						}					}); },				close: function { this.logEvent; this.show = false; }			},			mountedNOT: function { this.interval = setInterval( function {					if ( this.index < this.story.length - 1 ) {						this.index++;					} else {						clearInterval( this.interval );						this.close;					}				}.bind( this ), 1000 ); }		} );

log('StoryViewer initialized' ); }); }

function launchStoryViewer( Vue, story ) { $( 'body' ).append ( $( ' ' ).addClass( 'story-container' ) ); new Vue( {		el: '.story-container',		render: function ( h ) {			return h( 'story-viewer', { props: { story: story, visible: true, eventSubmit: mw.eventLog.submit } } );		}	} ); }

if ( isIncludedInExperiment ) { var title = mw.config.get( 'wgPageName' ); getStory( title ).then( function( story ) {		if ( story ) {			var p = createStoryViewer;			addStoryButton( function { p.done( function( require ) {					launchStoryViewer( require( 'vue' ), story );				} ); } );		} else {			log( 'No story available for article', title );		}	}); }