Improved image viewer
authorAlexander Ebert <ebert@woltlab.com>
Sat, 22 Feb 2014 13:55:10 +0000 (14:55 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Sat, 22 Feb 2014 13:55:10 +0000 (14:55 +0100)
com.woltlab.wcf/templates/imageViewer.tpl
wcfsetup/install/files/js/WCF.ImageViewer.js
wcfsetup/install/files/lib/data/IImageViewerAction.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 82fc48e3c414d4c5cd1e30d61986cb80cb33df95..a56bf3e63a4589946ae1c05b3258945569585269 100644 (file)
@@ -8,6 +8,7 @@
                        WCF.Language.addObject({
                                'wcf.imageViewer.button.enlarge': '{lang}wcf.imageViewer.button.enlarge{/lang}',
                                'wcf.imageViewer.button.full': '{lang}wcf.imageViewer.button.full{/lang}',
+                               'wcf.imageViewer.seriesIndex': '{lang}wcf.imageViewer.seriesIndex{/lang}',
                                'wcf.imageViewer.counter': '{lang}wcf.imageViewer.counter{/lang}',
                                'wcf.imageViewer.close': '{lang}wcf.imageViewer.close{/lang}',
                                'wcf.imageViewer.enlarge': '{lang}wcf.imageViewer.enlarge{/lang}',
index fe0b11cc9a0381f9467c8f4a254f4e43a37d250f..f3fbc91229e8bc6bf648081ef2f7245b69202045 100644 (file)
@@ -146,6 +146,12 @@ $.widget('ui.wcfImageViewer', {
         */
        _didInit: false,
        
+       /**
+        * overrides slideshow settings unless explicitly enabled by user
+        * @var boolean
+        */
+       _disableSlideshow: false,
+       
        /**
         * list of available images
         * @var array<object>
@@ -259,6 +265,7 @@ $.widget('ui.wcfImageViewer', {
                this._activeImage = null;
                this._container = null;
                this._didInit = false;
+               this._disableSlideshow = (this.element.data('disableSlideshow'));
                this._images = [ ];
                this._isOpen = false;
                this._items = -1;
@@ -291,7 +298,7 @@ $.widget('ui.wcfImageViewer', {
                }
                
                if (this._images.length === 0) {
-                       this._loadNextImages();
+                       this._loadNextImages(true);
                }
                else {
                        this._render();
@@ -336,10 +343,12 @@ $.widget('ui.wcfImageViewer', {
         * @return      boolean
         */
        startSlideshow: function() {
-               if (this._slideshowEnabled) {
+               if (this._disableSlideshow || this._slideshowEnabled) {
                        return false;
                }
                
+               console.debug(new Error().stack);
+               
                if (this._timer === null) {
                        this._timer = new WCF.PeriodicalExecuter($.proxy(function() {
                                var $index = this._active + 1;
@@ -386,19 +395,30 @@ $.widget('ui.wcfImageViewer', {
         * Renders the image viewer UI.
         * 
         * @param       boolean         initialized
+        * @param       integer         targetImageID
         */
-       _render: function(initialized) {
+       _render: function(initialized, targetImageID) {
                this._container.addClass('open');
                
                if (initialized) {
-                       var $thumbnail = this._ui.imageList.children('li:eq(0)');;
+                       var $thumbnail = this._ui.imageList.children('li:eq(0)');
                        this._thumbnailMarginRight = parseInt($thumbnail.css('marginRight').replace(/px$/, '')) || 0;
                        this._thumbnailWidth = $thumbnail.outerWidth(true);
                        this._thumbnailContainerWidth = this._ui.imageList.parent().innerWidth();
                        
+                       if (targetImageID) {
+                               this._ui.imageList.children('li').each(function(index, item) {
+                                       var $item = $(item);
+                                       if ($item.data('objectID') == targetImageID) {
+                                               $thumbnail = $item;
+                                               return false;
+                                       }
+                               });
+                       }
+                       
                        $thumbnail.trigger('click');
                        
-                       if (this._items > 1 && this.options.enableSlideshow) {
+                       if (this._items > 1 && this.options.enableSlideshow && !targetImageID) {
                                this.startSlideshow();
                        }
                }
@@ -416,7 +436,7 @@ $.widget('ui.wcfImageViewer', {
                if (this._images.length < this._items) {
                        var $thumbnailsWidth = this._images.length * this._thumbnailWidth;
                        if ($thumbnailsWidth - this._thumbnailOffset < this._thumbnailContainerWidth) {
-                               this._loadNextImages();
+                               this._loadNextImages(false);
                        }
                }
        },
@@ -491,7 +511,7 @@ $.widget('ui.wcfImageViewer', {
                if ($image.series.link) $seriesTitle = '<a href="' + $image.series.link + '">' + $seriesTitle + '</a>';
                this._ui.header.find('> div > h2').html($seriesTitle);
                
-               this._ui.header.find('> div > h3').text(($image.listItem.data('index') + 1) + " von " + this._items);
+               this._ui.header.find('> div > h3').text(WCF.Language.get('wcf.imageViewer.seriesIndex').replace(/{x}/, $image.listItem.data('index') + 1).replace(/{y}/, this._items));
                
                this._ui.slideshow.full.data('link', ($image.image.fullURL ? $image.image.fullURL : $image.image.url));
                
@@ -620,6 +640,7 @@ $.widget('ui.wcfImageViewer', {
                                this.stopSlideshow(true);
                        }
                        else {
+                               this._disableSlideshow = false;
                                this.startSlideshow();
                        }
                }, this));
@@ -799,7 +820,7 @@ $.widget('ui.wcfImageViewer', {
                        var $image = images[$i];
                        
                        var $listItem = $('<li class="loading pointer"><img src="' + $image.thumbnail.url + '" /></li>').appendTo(this._ui.imageList);
-                       $listItem.data('index', this._images.length).click($.proxy(this._showImage, this));
+                       $listItem.data('index', this._images.length).data('objectID', $image.objectID).click($.proxy(this._showImage, this));
                        var $img = $listItem.children('img');
                        if ($img.get(0).complete) {
                                // thumbnail is read from cache
@@ -816,8 +837,10 @@ $.widget('ui.wcfImageViewer', {
        
        /**
         * Loads the next images via AJAX.
+        * 
+        * @param       boolean         init
         */
-       _loadNextImages: function() {
+       _loadNextImages: function(init) {
                this._proxy.setOption('data', {
                        actionName: 'loadNextImages',
                        className: this.options.className,
@@ -826,7 +849,8 @@ $.widget('ui.wcfImageViewer', {
                        parameters: {
                                maximumHeight: this._maxDimensions.height,
                                maximumWidth: this._maxDimensions.width,
-                               offset: this._images.length
+                               offset: this._images.length,
+                               targetImageID: (init && this.element.data('targetImageID') ? this.element.data('targetImageID') : 0)
                        }
                });
                this._proxy.setOption('showLoadingOverlay', false);
@@ -849,6 +873,7 @@ $.widget('ui.wcfImageViewer', {
                
                this._createThumbnails(data.returnValues.images);
                
-               this._render($initialized);
+               var $targetImageID = (data.returnValues.targetImageID ? data.returnValues.targetImageID : 0);
+               this._render($initialized, $targetImageID);
        }
 });
index 8e55a8a83553b64872bf020899c0fe146fbb0ccb..2bd02a4cb6b387f9fc108442aaa3680a0ba4353f 100644 (file)
@@ -25,6 +25,7 @@ interface IImageViewerAction {
         *  - offset: number of already loaded image
         *  - maximumHeight: image provided in 'url' must be as close as possible to this value
         *  - maximumWidth: see above
+        *  - targetImageID: preload all images which are before the target image id as well as the next X images (optional, always present but might be '0')
         * 
         * Each image can specify a link which should not point to the image itself, instead it should provide a viewable
         * page directly related to the image (e.g. photo page). The 'fullURL' parameter is optional and results in the
index a7cb41a19fcbd03cf5eb56762f11d3b06849a2cd..0cd1625f38d923017277c0777ef422e734784fdf 100644 (file)
@@ -1791,6 +1791,7 @@ Fehler sind beispielsweise:
                <item name="wcf.imageViewer.button.enlarge"><![CDATA[Vollbild-Modus]]></item>
                <item name="wcf.imageViewer.button.full"><![CDATA[Originalversion aufrufen]]></item>
                <item name="wcf.imageViewer.button.openSlideshow"><![CDATA[Slideshow]]></item>
+               <item name="wcf.imageViewer.seriesIndex"><![CDATA[{literal}{x} von {y}{/literal}]]></item>
                
                <item name="wcf.imageViewer.close"><![CDATA[Schließen]]></item>
                <item name="wcf.imageViewer.counter"><![CDATA[{literal}Bild {x} von {y}{/literal}]]></item>
index 7342d100fce5c704ab7f380ef6a9b0fcc08b1993..b72a0ca62a7985b6e4e9a92757f7b9d1cb81c838 100644 (file)
@@ -1790,6 +1790,7 @@ Errors are:
                <item name="wcf.imageViewer.button.enlarge"><![CDATA[Fullscreen Mode]]></item>
                <item name="wcf.imageViewer.button.full"><![CDATA[View Source Image]]></item>
                <item name="wcf.imageViewer.button.openSlideshow"><![CDATA[Slideshow]]></item>
+               <item name="wcf.imageViewer.seriesIndex"><![CDATA[{literal}{x} of {y}{/literal}]]></item>
                
                <item name="wcf.imageViewer.close"><![CDATA[Close]]></item>
                <item name="wcf.imageViewer.counter"><![CDATA[{literal}Image {x} of {y}{/literal}]]></item>