From 1b5f6490b4c1fc045f77bd073eaad16fe1e3d5ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Wed, 22 May 2013 12:14:42 +0200 Subject: [PATCH 1/3] use slideshow as image preview in files & public shares --- gallery/appinfo/app.php | 6 ++ gallery/css/slideshow.css | 101 +++++++++++++++++++ gallery/css/styles.css | 103 +------------------ gallery/index.php | 1 - gallery/js/gallery.js | 97 ++---------------- gallery/js/jquery.mousewheel-3.1.1.js | 107 ++++++++++++++++++++ gallery/js/slideshow.js | 137 ++++++++++++++++++++++++++ gallery/templates/index.php | 11 +-- gallery/templates/slideshow.html | 9 ++ 9 files changed, 369 insertions(+), 203 deletions(-) create mode 100644 gallery/css/slideshow.css create mode 100644 gallery/js/jquery.mousewheel-3.1.1.js create mode 100644 gallery/templates/slideshow.html diff --git a/gallery/appinfo/app.php b/gallery/appinfo/app.php index 40dd9bf355..ac871d5aae 100644 --- a/gallery/appinfo/app.php +++ b/gallery/appinfo/app.php @@ -36,9 +36,15 @@ 'name' => $l->t('Pictures')) ); +// make slideshow available in files and public shares +OCP\Util::addScript('gallery', 'jquery.mousewheel-3.1.1'); +OCP\Util::addScript( 'gallery', 'slideshow' ); +OCP\Util::addStyle( 'gallery', 'slideshow' ); +// register filesystem hooks to update thumbnails OCP\Util::connectHook('OC_Filesystem', 'post_write', 'OCA\Gallery\Thumbnail', 'writeHook'); OCP\Util::connectHook('OC_Filesystem', 'post_delete', 'OCA\Gallery\Thumbnail', 'removeHook'); +// register share backend OCP\Share::registerBackend('picture', 'OCA\Gallery\Share\Picture', null, array('gif', 'jpeg', 'jpg', 'png', 'svg', 'svgz')); OCP\Share::registerBackend('gallery', 'OCA\Gallery\Share\Gallery', 'picture'); diff --git a/gallery/css/slideshow.css b/gallery/css/slideshow.css new file mode 100644 index 0000000000..f4a577dc2d --- /dev/null +++ b/gallery/css/slideshow.css @@ -0,0 +1,101 @@ + +#slideshow { + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; + z-index: 1000; + display: none; + background-color: black; + background-repeat: no-repeat; + background-image: url("../img/progress.gif"); + background-size: 16px 16px; + background-position: center center; +} + +#slideshow>img { + position: relative; + vertical-align: middle; + display: block; + margin-left: auto; + margin-right: auto; +} + +#slideshow > input { + background: none; + border: 0 transparent; + outline: 0; + box-shadow: none; + width: 52px; + height: 52px; + position: absolute; + z-index: 1100; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)"; + filter: alpha(opacity=30); + opacity: .3; + background-position: center center; + background-repeat: no-repeat; +} + +#slideshow > * { + -webkit-transition: opacity 300ms; + -moz-transition: opacity 300ms; + -o-transition: opacity 300ms; + transition: opacity 300ms; +} + +#slideshow > input:hover { + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; + filter: alpha(opacity=60); + opacity: .6; +} + +#slideshow > .next, #slideshow > .previous { + top: 50%; + margin-top: -21px; +} + +#slideshow > .next { + right: 0; + background-image: url("%webroot%/core/img/actions/view-next.svg"); +} + +#slideshow > .previous { + left: 0; + background-image: url("%webroot%/core/img/actions/view-previous.svg"); +} + +#slideshow > .exit { + right: 0; + top: 0; + background-image: url("%webroot%/core/img/actions/view-close.svg"); +} + +#slideshow > .pause, #slideshow > .play { + bottom: 0; + right: 0; + margin-top: -21px; +} + +#slideshow > .play { + display: none; + background-image: url("%webroot%/core/img/actions/view-play.svg"); +} + +#slideshow > .pause { + background-image: url("%webroot%/core/img/actions/view-pause.svg"); +} + +#slideshow > .progress { + position: fixed; + bottom: 10px; + right: 10px; + background-position: 0 100%; + width: 32px; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)"; + background-image: url("%webroot%/core/img/actions/view-pause.svg"); + filter: alpha(opacity=30); + opacity: .3; + height: 0; +} diff --git a/gallery/css/styles.css b/gallery/css/styles.css index 894a5ba8b1..5423560d74 100644 --- a/gallery/css/styles.css +++ b/gallery/css/styles.css @@ -66,105 +66,4 @@ button.share { right: 0; margin-right: 0; border-bottom-right-radius: 0; -} - -#slideshow { - position: fixed; - left: 0; - top: 0; - width: 100%; - height: 100%; - z-index: 1000; - display: none; - background-color: black; - background-repeat: no-repeat; - background-image: url("../img/progress.gif"); - background-size: 16px 16px; - background-position: center center; -} - -#slideshow>img { - position: relative; - vertical-align: middle; - display: block; - margin-left: auto; - margin-right: auto; -} - -#slideshow > input { - background: none; - border: 0 transparent; - outline: 0; - box-shadow: none; - width: 52px; - height: 52px; - position: absolute; - z-index: 1100; - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)"; - filter: alpha(opacity=30); - opacity: .3; - background-position: center center; - background-repeat: no-repeat; -} - -#slideshow > * { - -webkit-transition: opacity 300ms; - -moz-transition: opacity 300ms; - -o-transition: opacity 300ms; - transition: opacity 300ms; -} - -#slideshow > input:hover { - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; - filter: alpha(opacity=60); - opacity: .6; -} - -#slideshow > .next, #slideshow > .previous { - top: 50%; - margin-top: -21px; -} - -#slideshow > .next { - right: 0; - background-image: url("%webroot%/core/img/actions/view-next.svg"); -} - -#slideshow > .previous { - left: 0; - background-image: url("%webroot%/core/img/actions/view-previous.svg"); -} - -#slideshow > .exit { - right: 0; - top: 0; - background-image: url("%webroot%/core/img/actions/view-close.svg"); -} - -#slideshow > .pause, #slideshow > .play { - bottom: 0; - right: 0; - margin-top: -21px; -} - -#slideshow > .play { - display: none; - background-image: url("%webroot%/core/img/actions/view-play.svg"); -} - -#slideshow > .pause { - background-image: url("%webroot%/core/img/actions/view-pause.svg"); -} - -#slideshow > .progress { - position: fixed; - bottom: 10px; - right: 10px; - background-position: 0 100%; - width: 32px; - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)"; - background-image: url("%webroot%/core/img/actions/view-pause.svg"); - filter: alpha(opacity=30); - opacity: .3; - height: 0; -} +} \ No newline at end of file diff --git a/gallery/index.php b/gallery/index.php index 616578c12b..5a9f6a0e61 100644 --- a/gallery/index.php +++ b/gallery/index.php @@ -11,7 +11,6 @@ OCP\App::setActiveNavigationEntry('gallery_index'); OCP\Util::addScript('gallery', 'gallery'); -OCP\Util::addScript('gallery', 'slideshow'); OCP\Util::addScript('gallery', 'thumbnail'); OCP\Util::addStyle('gallery', 'styles'); diff --git a/gallery/js/gallery.js b/gallery/js/gallery.js index f6903a43d2..222f0c1e77 100644 --- a/gallery/js/gallery.js +++ b/gallery/js/gallery.js @@ -103,7 +103,7 @@ Gallery.share = function (event) { event.preventDefault(); event.stopPropagation(); Gallery.getAlbumInfo(Gallery.currentAlbum).then(function (info) { - $('a.share').data('item', info.fileid) + $('a.share').data('item', info.fileid).data('link', true) .data('possible-permissions', info.permissions). click(); }); @@ -280,105 +280,22 @@ Gallery.view.showUsers = function () { } }; -Gallery.slideshow = {}; -Gallery.scrollLocation = 0; -Gallery.slideshow.start = function (start, options) { - var content = $('#content'); - start = start || 0; - Thumbnail.concurrent = 1; //make sure we can load the image and doesn't get blocked by loading thumbnail - if (content.is(":visible")) { - Gallery.scrollLocation = $(window).scrollTop(); - } - $('a.image').slideShow($('#slideshow'), start, options); - content.hide(); -}; - -Gallery.slideshow.end = function () { - jQuery.fn.slideShow.stop(); -}; - -Gallery.slideshow.next = function (event) { - if (event) { - event.stopPropagation(); - } - jQuery.fn.slideShow.hideImage(); - jQuery.fn.slideShow.next(); -}; - -Gallery.slideshow.previous = function (event) { - if (event) { - event.stopPropagation(); - } - jQuery.fn.slideShow.hideImage(); - jQuery.fn.slideShow.previous(); -}; - -Gallery.slideshow.pause = function (event) { - if (event) { - event.stopPropagation(); - } - $('#slideshow').children('.play').show(); - $('#slideshow').children('.pause').hide(); - Gallery.slideshow.playPause.playing = false; - jQuery.fn.slideShow.pause(); -}; - -Gallery.slideshow.play = function (event) { - if (event) { - event.stopPropagation(); - } - $('#slideshow').children('.play').hide(); - $('#slideshow').children('.pause').show(); - Gallery.slideshow.playPause.playing = true; - jQuery.fn.slideShow.play(); -}; - -Gallery.slideshow.playPause = function () { - if (Gallery.slideshow.playPause.playing) { - Gallery.slideshow.pause(); - } else { - Gallery.slideshow.play(); - } -}; -Gallery.slideshow.playPause.playing = true; - $(document).ready(function () { Gallery.fillAlbums().then(function () { Gallery.view.element = $('#gallery'); OC.Breadcrumb.container = $('#breadcrumbs'); - window.onhashchange() - - //close slideshow on esc - $(document).keyup(function (e) { - if (e.keyCode === 27) { // esc - Gallery.slideshow.end(); - } else if (e.keyCode == 37) { // left - Gallery.slideshow.previous(); - } else if (e.keyCode == 39) { // right - Gallery.slideshow.next(); - } else if (e.keyCode == 32) { // space - Gallery.slideshow.playPause(); - } - }); - var slideshow = $('#slideshow'); - slideshow.children('.next').click(Gallery.slideshow.next); - slideshow.children('.previous').click(Gallery.slideshow.previous); - slideshow.children('.exit').click(jQuery.fn.slideShow.stop); - slideshow.children('.pause').click(Gallery.slideshow.pause); - slideshow.children('.play').click(Gallery.slideshow.play); - slideshow.click(Gallery.slideshow.next); - + window.onhashchange(); $('button.share').click(Gallery.share); }); $('#gallery').on('click', 'a.image', function (event) { - var i = $('#gallery').children('a.image').index(this), + var images = $('#gallery').children('a.image'); + var i = images.index(this), image = $(this).data('path'); event.preventDefault(); location.hash = image; - Gallery.slideshow.start(i, {play: Gallery.slideshow.playPause.playing}); + Slideshow.start(images, i, {play: Slideshow.playPause.playing}); }); - $('body').append($('#slideshow')); //move the slideshow outside the content so we can hide the content jQuery.fn.slideShow.onstop = function () { $('#content').show(); @@ -395,10 +312,10 @@ window.onhashchange = function () { } console.log(OC.dirname(album)); if (Gallery.images.indexOf(album) === -1) { - Gallery.slideshow.end(); + Slideshow.end(); Gallery.view.viewAlbum(album); } else { Gallery.view.viewAlbum(OC.dirname(album)); - $('#gallery a.image[data-path="' + album + '"]').click(); + //$('#gallery a.image[data-path="' + album + '"]').click(); } }; diff --git a/gallery/js/jquery.mousewheel-3.1.1.js b/gallery/js/jquery.mousewheel-3.1.1.js new file mode 100644 index 0000000000..137742d6f3 --- /dev/null +++ b/gallery/js/jquery.mousewheel-3.1.1.js @@ -0,0 +1,107 @@ +/*! Copyright (c) 2013 Brandon Aaron (http://brandonaaron.net) + * Licensed under the MIT License (LICENSE.txt). + * + * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. + * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. + * Thanks to: Seamus Leahy for adding deltaX and deltaY + * + * Version: 3.1.1 + * + * Requires: 1.2.2+ + */ + +(function (factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else { + // Browser globals + factory(jQuery); + } +}(function ($) { + + var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll']; + var toBind = 'onwheel' in document || document.documentMode >= 9 ? ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll']; + var lowestDelta, lowestDeltaXY; + + if ($.event.fixHooks) { + for ( var i=toFix.length; i; ) { + $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks; + } + } + + $.event.special.mousewheel = { + setup: function() { + if ( this.addEventListener ) { + for ( var i=toBind.length; i; ) { + this.addEventListener( toBind[--i], handler, false ); + } + } else { + this.onmousewheel = handler; + } + }, + + teardown: function() { + if ( this.removeEventListener ) { + for ( var i=toBind.length; i; ) { + this.removeEventListener( toBind[--i], handler, false ); + } + } else { + this.onmousewheel = null; + } + } + }; + + $.fn.extend({ + mousewheel: function(fn) { + return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); + }, + + unmousewheel: function(fn) { + return this.unbind("mousewheel", fn); + } + }); + + + function handler(event) { + var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, deltaX = 0, deltaY = 0, absDelta = 0, absDeltaXY = 0, fn; + event = $.event.fix(orgEvent); + event.type = "mousewheel"; + + // Old school scrollwheel delta + if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta; } + if ( orgEvent.detail ) { delta = orgEvent.detail * -1; } + + // New school wheel delta (wheel event) + if ( orgEvent.deltaY ) { + deltaY = orgEvent.deltaY * -1; + delta = deltaY; + } + if ( orgEvent.deltaX ) { + deltaX = orgEvent.deltaX; + delta = deltaX * -1; + } + + // Webkit + if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY; } + if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = orgEvent.wheelDeltaX * -1; } + + // Look for lowest delta to normalize the delta values + absDelta = Math.abs(delta); + if ( !lowestDelta || absDelta < lowestDelta ) { lowestDelta = absDelta; } + absDeltaXY = Math.max( Math.abs(deltaY), Math.abs(deltaX) ); + if ( !lowestDeltaXY || absDeltaXY < lowestDeltaXY ) { lowestDeltaXY = absDeltaXY; } + + // Get a whole value for the deltas + fn = delta > 0 ? 'floor' : 'ceil'; + delta = Math[fn](delta/lowestDelta); + deltaX = Math[fn](deltaX/lowestDeltaXY); + deltaY = Math[fn](deltaY/lowestDeltaXY); + + // Add event and delta to the front of the arguments + args.unshift(event, delta, deltaX, deltaY); + + return ($.event.dispatch || $.event.handle).apply(this, args); + } + +})); \ No newline at end of file diff --git a/gallery/js/slideshow.js b/gallery/js/slideshow.js index 6dd8c5b774..8bcb9ef200 100644 --- a/gallery/js/slideshow.js +++ b/gallery/js/slideshow.js @@ -146,3 +146,140 @@ jQuery.fn.slideShow.hideImage = function () { }; jQuery.fn.slideShow.onstop = null; + +Slideshow = {}; +Slideshow.start = function (images, start, options) { + + var content = $('#content'); + start = start || 0; + Thumbnail.concurrent = 1; //make sure we can load the image and doesn't get blocked by loading thumbnail + if (content.is(":visible") && typeof Gallery!=='undefined') { + Gallery.scrollLocation = $(window).scrollTop(); + } + images.slideShow($('#slideshow'), start, options); + content.hide(); +}; + +Slideshow.end = function () { + jQuery.fn.slideShow.stop(); +}; + +Slideshow.next = function (event) { + if (event) { + event.stopPropagation(); + } + jQuery.fn.slideShow.hideImage(); + jQuery.fn.slideShow.next(); +}; + +Slideshow.previous = function (event) { + if (event) { + event.stopPropagation(); + } + jQuery.fn.slideShow.hideImage(); + jQuery.fn.slideShow.previous(); +}; + +Slideshow.pause = function (event) { + if (event) { + event.stopPropagation(); + } + $('#slideshow').children('.play').show(); + $('#slideshow').children('.pause').hide(); + Slideshow.playPause.playing = false; + jQuery.fn.slideShow.pause(); +}; + +Slideshow.play = function (event) { + if (event) { + event.stopPropagation(); + } + $('#slideshow').children('.play').hide(); + $('#slideshow').children('.pause').show(); + Slideshow.playPause.playing = true; + jQuery.fn.slideShow.play(); +}; +Slideshow.playPause = function () { + if (Slideshow.playPause.playing) { + Slideshow.pause(); + } else { + Slideshow.play(); + } +}; +Slideshow.playPause.playing = true; +Slideshow._getSlideshowTemplate = function() { + var defer = $.Deferred(); + if(!this.$slideshowTemplate) { + var self = this; + $.get(OC.filePath('gallery', 'templates', 'slideshow.html'), function(tmpl) { + self.$slideshowTemplate = $(tmpl); + defer.resolve(self.$slideshowTemplate); + }) + .fail(function() { + defer.reject(); + }); + } else { + defer.resolve(this.$slideshowTemplate); + } + return defer.promise(); +}; + +$(document).ready(function () { + + //close slideshow on esc + $(document).keyup(function (e) { + if (e.keyCode === 27) { // esc + Slideshow.end(); + } else if (e.keyCode == 37) { // left + Slideshow.previous(); + } else if (e.keyCode == 39) { // right + Slideshow.next(); + } else if (e.keyCode == 32) { // space + Slideshow.playPause(); + } + }); + + $.when(Slideshow._getSlideshowTemplate()).then(function($tmpl) { + $('body').append($tmpl); //move the slideshow outside the content so we can hide the content + + var slideshow = $('#slideshow'); + slideshow.children('.next').click(Slideshow.next); + slideshow.children('.previous').click(Slideshow.previous); + slideshow.children('.exit').click(jQuery.fn.slideShow.stop); + slideshow.children('.pause').click(Slideshow.pause); + slideshow.children('.play').click(Slideshow.play); + slideshow.click(Slideshow.next); + + if ($.fn.mousewheel) { + slideshow.bind('mousewheel.fb', function(e, delta) { + e.preventDefault(); + if ($(e.target).get(0).clientHeight == 0 || $(e.target).get(0).scrollHeight === $(e.target).get(0).clientHeight) { + if (delta > 0) { + Slideshow.previous(); + } else { + Slideshow.next(); + } + } + }); + } + }) + .fail(function() { + alert(t('core', 'Error loading slideshow template')); + }); + + + + if(typeof FileActions!=='undefined' && typeof Slideshow!=='undefined'){ + FileActions.register('image','View', OC.PERMISSION_READ, '',function(filename){ + var images = $('#fileList tr[data-mime^="image"] a.name'); + var start = 0; + $.each(images, function (i,e) { + if ($(e).parents('tr').data('file') == filename) { + start = i; + } + }); + images.slideShow($('#slideshow'), start); + }); + FileActions.setDefault('image','View'); + } +}); \ No newline at end of file diff --git a/gallery/templates/index.php b/gallery/templates/index.php index c2eda85c8b..3edfbcf442 100644 --- a/gallery/templates/index.php +++ b/gallery/templates/index.php @@ -6,13 +6,4 @@ data-possible-permissions="31"> - -
- - - - - - -
-
+ \ No newline at end of file diff --git a/gallery/templates/slideshow.html b/gallery/templates/slideshow.html new file mode 100644 index 0000000000..53367f1ebf --- /dev/null +++ b/gallery/templates/slideshow.html @@ -0,0 +1,9 @@ +
+ + + + + + +
+
\ No newline at end of file From 17f1a421f54128798cb30b41bd75c48704e07fde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Wed, 22 May 2013 13:35:44 +0200 Subject: [PATCH 2/3] commenting console log for now --- gallery/js/gallery.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gallery/js/gallery.js b/gallery/js/gallery.js index 222f0c1e77..b27126a7a2 100644 --- a/gallery/js/gallery.js +++ b/gallery/js/gallery.js @@ -310,7 +310,7 @@ window.onhashchange = function () { if (!album) { album = OC.currentUser; } - console.log(OC.dirname(album)); + //console.log(OC.dirname(album)); if (Gallery.images.indexOf(album) === -1) { Slideshow.end(); Gallery.view.viewAlbum(album); From 281764571f3e8304655e9224bdc38d9d64690088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Thu, 23 May 2013 11:03:06 +0200 Subject: [PATCH 3/3] fix navigation --- gallery/js/gallery.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gallery/js/gallery.js b/gallery/js/gallery.js index b27126a7a2..fe57e9ec58 100644 --- a/gallery/js/gallery.js +++ b/gallery/js/gallery.js @@ -293,8 +293,10 @@ $(document).ready(function () { var i = images.index(this), image = $(this).data('path'); event.preventDefault(); - location.hash = image; - Slideshow.start(images, i, {play: Slideshow.playPause.playing}); + if (location.hash != image) { + location.hash = image; + Slideshow.start(images, i, {play: Slideshow.playPause.playing}); + } }); jQuery.fn.slideShow.onstop = function () { @@ -310,12 +312,11 @@ window.onhashchange = function () { if (!album) { album = OC.currentUser; } - //console.log(OC.dirname(album)); if (Gallery.images.indexOf(album) === -1) { Slideshow.end(); Gallery.view.viewAlbum(album); } else { Gallery.view.viewAlbum(OC.dirname(album)); - //$('#gallery a.image[data-path="' + album + '"]').click(); + $('#gallery a.image[data-path="' + album + '"]').click(); } };