From 8423974c6ae47f7ed2ad2af3223137127f271a3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20Tisza?= Date: Mon, 27 Oct 2014 16:17:49 +0000 Subject: [PATCH] Change above-the-fold layout - step 3 * make top of "below-the-fold" be actually above the fold * put all above-the-fold content except title and more details button into that area * kep below-the-fold area in fullscreen mode when title/credit gets untruncated * increase title length to 180 (140 before reducing font size) - works nicely on my 1600x900 laptop * remove old styles which were intended to make the button smaller when the panel is close but were mostly broken anyway and only caused the button to twitch To avoid redoing all the size calculation logic, we cheat and use a negative margin to pull the below-the-fold content above the fold. Change-Id: I18d7bdb7dbbdfb8201c0d66257731febfac31263 Mingle: https://wikimedia.mingle.thoughtworks.com/projects/multimedia/cards/833 --- resources/mmv/mmv.globals.less | 10 +++- resources/mmv/mmv.lightboxinterface.less | 14 ++--- resources/mmv/ui/img/time.svg | 34 +++++++++++- resources/mmv/ui/img/uploader-ltr.svg | 55 +++++++++++++++++++ resources/mmv/ui/img/uploader-rtl.svg | 55 +++++++++++++++++++ resources/mmv/ui/mmv.ui.metadataPanel.js | 11 ++-- resources/mmv/ui/mmv.ui.metadataPanel.less | 45 ++++++++++++--- resources/mmv/ui/mmv.ui.stripeButtons.less | 19 +------ tests/qunit/mmv/mmv.lightboxinterface.test.js | 16 ++++-- 9 files changed, 211 insertions(+), 48 deletions(-) create mode 100644 resources/mmv/ui/img/uploader-ltr.svg create mode 100644 resources/mmv/ui/img/uploader-rtl.svg diff --git a/resources/mmv/mmv.globals.less b/resources/mmv/mmv.globals.less index 9da7ffe09..7eb1def9a 100644 --- a/resources/mmv/mmv.globals.less +++ b/resources/mmv/mmv.globals.less @@ -1,8 +1,12 @@ // Height of the area of the metadata bar which is visible without scrolling. -@metadatabar-above-fold-height: 82px; +@metadatabar-above-fold-height: 86px; -// Height of the same area in fullscreen mode (which can be slightly less since it has less controls). -@metadatabar-above-fold-fullscreen-height: 64px; +// adjust for @metadatabar-below-fold-pushup-height wide bottom padding - that area will be overlapped +// by the revealed part of the below-the-fold content +@metadatabar-above-fold-inner-height: @metadatabar-above-fold-height - @metadatabar-below-fold-pushup-height; + +// Height of the top part of the "below-fold" content which is actually above the fold, as a scrolling affordance +@metadatabar-below-fold-pushup-height: 30px; // Height of the progress bar @progress-bar-height: 14px; diff --git a/resources/mmv/mmv.lightboxinterface.less b/resources/mmv/mmv.lightboxinterface.less index 06741a4ef..15d38ff46 100644 --- a/resources/mmv/mmv.lightboxinterface.less +++ b/resources/mmv/mmv.lightboxinterface.less @@ -56,25 +56,21 @@ height: auto; color: #333333; background-color: #ffffff; - min-height: (@metadatabar-above-fold-height + 1); + min-height: (@metadatabar-above-fold-inner-height + 1); z-index: 1005; } // above-the-fold part of the metadata panel .mw-mmv-above-fold { width: 100%; - height: @metadatabar-above-fold-height; + height: @metadatabar-above-fold-inner-height; // min-height is used when the height is changed to auto to display long texts, to make sure the layout // is not messed up wheen the text is short and does not fill the available place. It is also used by // Javascript to get the "default" height. - min-height: @metadatabar-above-fold-height; + min-height: @metadatabar-above-fold-inner-height; position: relative; - border-bottom: 1px solid #eee; - - .jq-fullscreened & { - height: @metadatabar-above-fold-fullscreen-height; - min-height: @metadatabar-above-fold-fullscreen-height; - } + // make sure there is no content in the part which is overlapped by the revealed part of the below-fold content + padding-bottom: @metadatabar-below-fold-pushup-height; .mw-mmv-untruncated & { height: auto; diff --git a/resources/mmv/ui/img/time.svg b/resources/mmv/ui/img/time.svg index bf579af6e..78ad8acba 100644 --- a/resources/mmv/ui/img/time.svg +++ b/resources/mmv/ui/img/time.svg @@ -1 +1,33 @@ - \ No newline at end of file + + + + + + + + image/svg+xml + + + + + + + + diff --git a/resources/mmv/ui/img/uploader-ltr.svg b/resources/mmv/ui/img/uploader-ltr.svg new file mode 100644 index 000000000..48ea6bb40 --- /dev/null +++ b/resources/mmv/ui/img/uploader-ltr.svg @@ -0,0 +1,55 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/resources/mmv/ui/img/uploader-rtl.svg b/resources/mmv/ui/img/uploader-rtl.svg new file mode 100644 index 000000000..357d9e3f5 --- /dev/null +++ b/resources/mmv/ui/img/uploader-rtl.svg @@ -0,0 +1,55 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/resources/mmv/ui/mmv.ui.metadataPanel.js b/resources/mmv/ui/mmv.ui.metadataPanel.js index 2a9c11783..69b5c4a20 100644 --- a/resources/mmv/ui/mmv.ui.metadataPanel.js +++ b/resources/mmv/ui/mmv.ui.metadataPanel.js @@ -25,7 +25,9 @@ * @extends mw.mmv.ui.Element * @constructor * @param {jQuery} $container The container for the panel (.mw-mmv-post-image). - * @param {jQuery} $aboveFold The always-visible part of the metadata panel (.mw-mmv-above-fold). + * @param {jQuery} $aboveFold The brighter headline of the metadata panel (.mw-mmv-above-fold). + * Called "aboveFold" for historical reasons, but actually a part of the next sibling of the element + * is also above the fold (bottom of the screen). * @param {Object} localStorage the localStorage object, for dependency injection * @param {mw.mmv.Config} config A configuration object. */ @@ -154,7 +156,7 @@ } ) .addClass( 'mw-mmv-title' ); - this.title = new mw.mmv.ui.TruncatableTextField( this.$titlePara, this.$title ); + this.title = new mw.mmv.ui.TruncatableTextField( this.$titlePara, this.$title, { max: 180, small: 140 } ); this.title.setTitle( mw.message( 'multimediaviewer-title-popup-text' ), mw.message( 'multimediaviewer-title-popup-text-more' ) @@ -687,7 +689,7 @@ this.title.grow(); this.creditField.grow(); if ( this.aboveFoldIsLargerThanNormal() && !noScroll ) { - this.scroller.scrollIntoView( this.$datetimeLi, 500 ); + this.scroller.scrollIntoView( this.description.$imageDescDiv, 500 ); } }; @@ -709,7 +711,8 @@ * calling revealTruncatedText(). */ MPP.aboveFoldIsLargerThanNormal = function () { - return this.$aboveFold.height() > parseInt( this.$aboveFold.css( 'min-height' ), 10 ); + return this.$aboveFold.height() > parseInt( this.$aboveFold.css( 'min-height' ), 10 ) || + this.$credit.height() > parseInt( this.$aboveFold.css( 'padding-bottom' ), 10 ); }; mw.mmv.ui.MetadataPanel = MetadataPanel; diff --git a/resources/mmv/ui/mmv.ui.metadataPanel.less b/resources/mmv/ui/mmv.ui.metadataPanel.less index 649192398..8996bdafa 100644 --- a/resources/mmv/ui/mmv.ui.metadataPanel.less +++ b/resources/mmv/ui/mmv.ui.metadataPanel.less @@ -4,9 +4,10 @@ @info-box-color: #FFFFFF; @info-box-border-color: #DDDDDD; @info-box-border-shadow-color: #C9C9C9; - @secondary-text-color: rgb(136, 136, 136); +@fold-separator-border-width: 1px; + .mw-mmv-info-box { display: inline-block; overflow: hidden; @@ -28,7 +29,12 @@ } .mw-mmv-credit { margin: 0; - padding: 5px 0; + color: #555; + padding: 0 0 5px; + font-size: 0.85em; + &.empty { + height: 0.85em; + } } .mw-mmv-title { @@ -36,16 +42,35 @@ max-width: 60%; } - .mw-mmv-image-metadata { width: 100%; - background-color: #f5f5f5; position: relative; - padding-top: 10px; + margin-top: -@metadatabar-below-fold-pushup-height; + border-top: @fold-separator-border-width solid #ddd; + background-color: #f5f5f5; + padding-top: 4px; + + .jq-fullscreened & { + // Make sure content fits into the screen. This assumes no paddings. + height: @metadatabar-below-fold-pushup-height - @fold-separator-border-width; + overflow: hidden; + } + .jq-fullscreened .mw-mmv-untruncated & { + height: auto; + } } -.jq-fullscreened .mw-mmv-image-metadata { - display: none; +.mw-mmv-author:before { + display: inline-block; + vertical-align: middle; + height: 16px; + width: 16px; + content: ' '; + margin-right: 5px; + background-size: contain; + background-position: center center; + background-repeat: no-repeat; + background-image: url(img/user-ltr.svg); } .mw-mmv-image-desc-div { @@ -64,7 +89,7 @@ } @littlefont: 0.85em; -@mediumfont: 1em; +@mediumfont: 0.95em; .mw-mmv-caption, .mw-mmv-image-desc { @@ -107,7 +132,9 @@ &.mw-mmv-username-li:before { /* @embed */ - background-image: url(img/user-ltr.svg); + background-image: url(img/uploader-ltr.svg); + width: 18px; + margin-right: 8px; } &.mw-mmv-location-li:before { diff --git a/resources/mmv/ui/mmv.ui.stripeButtons.less b/resources/mmv/ui/mmv.ui.stripeButtons.less index 5cc457b16..b422305ec 100644 --- a/resources/mmv/ui/mmv.ui.stripeButtons.less +++ b/resources/mmv/ui/mmv.ui.stripeButtons.less @@ -13,18 +13,7 @@ @button-text-color: rgb(136, 136, 136); float: right; - margin-top: @metadatabar-above-fold-height - ( @button-height + 2 * @button-vertical-padding ); - .jq-fullscreened & { - margin-top: @metadatabar-above-fold-fullscreen-height - ( @button-height + 2 * @button-vertical-padding ); - } - .mw-mmv-untruncated & { - margin-top: 0; - border: 0; - - .mw-mmv-stripe-button-text { - display: none; - } - } + margin-top: @metadatabar-above-fold-inner-height - ( @button-height + 2 * @button-vertical-padding ); .unselectable; font-size: 1.25em; @@ -56,9 +45,6 @@ } &.has-label:before { margin-right: 0.25em; - .mw-mmv-untruncated & { - margin-right: 0; - } } &.mw-mmv-description-page-button, @@ -66,7 +52,8 @@ &.mw-mmv-description-page-button:visited { border-radius: 4px; color: white; - margin: 0.5em 1em; + padding: 7px 16px; + margin: 7px 10px; } &.mw-mmv-description-page-button.mw-mmv-repo-button-commons:before { diff --git a/tests/qunit/mmv/mmv.lightboxinterface.test.js b/tests/qunit/mmv/mmv.lightboxinterface.test.js index cbbe68ac3..1a61748f5 100644 --- a/tests/qunit/mmv/mmv.lightboxinterface.test.js +++ b/tests/qunit/mmv/mmv.lightboxinterface.test.js @@ -133,12 +133,12 @@ } ); QUnit.test( 'Fullscreen mode', 8, function ( assert ) { - var lightbox = new mw.mmv.LightboxInterface(), + var buttonOffset, panelBottom, + oldRevealButtonsAndFadeIfNeeded, + lightbox = new mw.mmv.LightboxInterface(), viewer = new mw.mmv.MultimediaViewer(), oldFnEnterFullscreen = $.fn.enterFullscreen, - oldFnExitFullscreen = $.fn.exitFullscreen, - oldRevealButtonsAndFadeIfNeeded, - buttonOffset; + oldFnExitFullscreen = $.fn.exitFullscreen; stubScrollTo(); @@ -186,12 +186,16 @@ lightbox.buttons.revealAndFadeIfNeeded = $.noop; - assert.ok( !lightbox.panel.$imageMetadata.is( ':visible' ), 'Image metadata is hidden' ); + panelBottom = $('.mw-mmv-post-image').position().top + $('.mw-mmv-post-image').height(); + + assert.ok( panelBottom === $(window).height(), 'Image metadata does not extend beyond the viewport' ); // Exiting fullscreen lightbox.buttons.$fullscreen.click(); - assert.ok( lightbox.panel.$imageMetadata.is( ':visible' ), 'Image metadata is visible' ); + panelBottom = $('.mw-mmv-post-image').position().top + $('.mw-mmv-post-image').height(); + + assert.ok( panelBottom > $(window).height(), 'Image metadata extends beyond the viewport' ); assert.ok( !lightbox.isFullscreen, 'Lightbox knows that it\'s not in fullscreen mode' ); // Unattach lightbox from document