* Filemanager/Expose view: enhancements

-Fullscreen feature
-Loading on thumbnail scrolling
-Fix thumbnail not being loaded for the first time
This commit is contained in:
Hadi Nategh 2015-01-30 15:50:57 +00:00
parent ec13220449
commit e9ebd97e78
7 changed files with 104 additions and 30 deletions

View File

@ -327,15 +327,14 @@ var et2_vfsMime = expose(et2_valueWidget.extend([et2_IDetachedDOM],
{
var base_url = egw.webserverUrl.match(/^\//,'ig')?egw(window).window.location.origin + egw.webserverUrl:egw.webserverUrl;
var mediaContent = [];
if (_value && _value.mime && _value.mime.match(/video|audio/,'ig'))
if (_value && _value.mime && _value.mime.match(/video\/|audio\//,'ig'))
{
mediaContent = [{
title: _value.name,
type: 'video/*',
sources:[{
href: base_url + _value.download_url,
type: _value.mime
}]
type: _value.mime,
poster:'', // TODO: Should be changed by correct video thumbnail later
thumbnail:this.egw().mime_icon(_value['mime'], _value['path']) ,
href: base_url + _value.download_url,
}];
}
else

View File

@ -12,7 +12,7 @@
/*egw:uses
jquery.jquery;
/phpgwapi/js/jquery/blueimp/js/jquery.blueimp-gallery.min.js;
/phpgwapi/js/jquery/blueimp/js/blueimp-gallery.min.js;
*/
/**
@ -48,7 +48,7 @@ function expose (widget)
};
// For filtering to only show things we can handle
var mime_regex = new RegExp(/video\/|image|audio\//);
var mime_regex = new RegExp(/video\/|image\/|audio\//);
// Only one gallery
var gallery = null;
@ -89,6 +89,7 @@ function expose (widget)
var read_from_nextmatch = function(nm, images, start_at)
{
if(!start_at) start_at = 0;
var image_index = start_at;
var stop = Math.max.apply(null,Object.keys(nm.controller._indexMap));
for(var i = start_at; i <= stop; i++)
@ -98,7 +99,7 @@ function expose (widget)
// Returning instead of using IMAGE_DEFAULT means we stop as
// soon as a hole is found, instead of getting everything that is
// available. The gallery can't fill in the holes.
images[i] = IMAGE_DEFAULT;
images[image_index++] = IMAGE_DEFAULT;
continue;
}
var uid = nm.controller._indexMap[i].uid;
@ -107,7 +108,7 @@ function expose (widget)
if(data && data.data && data.data.mime && mime_regex.test(data.data.mime))
{
var media = this.getMedia(data.data);
images.push(jQuery.extend({}, data.data, media[0]));
images[image_index++] = jQuery.extend({}, data.data, media[0]);
}
}
};
@ -133,9 +134,11 @@ function expose (widget)
// Don't bother with adding a default, we just did that
if(image.loading)
{
$j(gallery.slides[index])
.addClass(gallery.options.slideLoadingClass)
.removeClass(gallery.options.slideErrorClass);
//Add load class if it's really a slide with error
if (gallery.slidesContainer.find('[data-index="'+index+'"]').hasClass(gallery.options.slideErrorClass))
$j(gallery.slides[index])
.addClass(gallery.options.slideLoadingClass)
.removeClass(gallery.options.slideErrorClass);
return;
}
@ -234,6 +237,8 @@ function expose (widget)
closeClass: 'close',
// The class for the "play-pause" toggle control:
playPauseClass: 'play-pause',
// The class to add for fullscreen button option
fullscreenClass:'fullscreen',
// The list object property (or data attribute) with the object type:
typeProperty: 'type',
// The list object property (or data attribute) with the object title:
@ -305,6 +310,8 @@ function expose (widget)
thumbnailProperty: 'thumbnail',
// Defines if the gallery indicators should display a thumbnail:
thumbnailIndicators: true,
//thumbnail with image tag
thumbnailWithImgTag: true,
// Callback function executed when the Gallery is initialized.
// Is called with the gallery instance as "this" object:
onopen: jQuery.proxy(this.expose_onopen,this),
@ -347,7 +354,7 @@ function expose (widget)
// Gallery Main DIV container
var $expose_node = jQuery(document.createElement('div')).attr({id:"blueimp-gallery", class:"blueimp-gallery"});
// Create Gallery DOM NODE
$expose_node.append('<div class="slides"></div><h3 class="title"></h3><a class="prev"></a><a class="next"></a><a class="close">×</a><a class="play-pause"></a><ol class="indicator"></ol>');
$expose_node.append('<div class="slides"></div><h3 class="title"></h3><a class="prev"></a><a class="next"></a><a class="close">×</a><a class="play-pause"></a><a class="fullscreen"></a><ol class="indicator"></ol>');
// Append the gallery Node to DOM
$body.append($expose_node);
}
@ -419,6 +426,7 @@ function expose (widget)
expose_onopened: function (event){
// Check to see if we're in a nextmatch, do magic
var nm = find_nextmatch(this);
var self=this;
if(nm)
{
// Add scrolling to the indicator list
@ -428,9 +436,18 @@ function expose (widget)
gallery.container.find('.indicator').off()
.addClass('paginating')
.mousewheel(function(event, delta) {
if(delta > 0 && parseInt($j(this).css('left')) > gallery.container.width() / 2) return;
if(delta > 0 && parseInt($j(this).css('left')) > gallery.container.width() / 2) return;
//Reload next pictures into the gallery by scrolling on thumbnails
if (delta<0 && $j(this).width() + parseInt($j(this).css('left')) < gallery.container.width())
{
var nextIndex = gallery.indicatorContainer.find('[title="loading"]')[0];
if (nextIndex) self.expose_onslideend(gallery,nextIndex.dataset.index -1);
return;
}
// Move it about 5 indicators
$j(this).css('left',parseInt($j(this).css('left'))-(-delta*gallery.activeIndicator.width()*5)+'px');
event.preventDefault();
})
.swipe(function(event, direction, distance) {
@ -460,14 +477,20 @@ function expose (widget)
expose_onslide: function (gallery, index, slide){
// First let parent try
this._super.apply(this, arguments);
// Check to see if we're in a nextmatch, do magic
var nm = find_nextmatch(this);
if(nm)
{
// See if we need to move the indicator
var indicator = gallery.container.find('.indicator');
var current = $j('.active',indicator).position();
if (current.left == 0)
{
//As controlsClass activates indicators,
//we use it to make indicators available for the first time
//which helps to re-calculate the correct position of it, if it's not loaded yet
gallery.container.addClass(this.expose_options.controlsClass);
current = $j('.active',indicator).position();
}
if(current)
{
indicator.animate({left: (gallery.container.width() / 2)-current.left});
@ -484,7 +507,7 @@ function expose (widget)
var total_count = nm.controller._grid.getTotalCount();
// Already at the end, don't bother
if(index == total_count) return;
if(index == total_count -1 || index == 0) return;
// Try to determine direction from state of next & previous slides
var direction = 1;

View File

@ -163,11 +163,23 @@
.blueimp-gallery-playing > .play-pause {
background-position: -15px 0;
}
.blueimp-gallery > .fullscreen {
position: absolute;
right: 15px;
bottom: 30px;
width: 15px;
height: 15px;
background: url(../img/fullscreen.png) 0 0 no-repeat;
cursor: pointer;
opacity: 0.5;
display:none;
}
.blueimp-gallery > .prev:hover,
.blueimp-gallery > .next:hover,
.blueimp-gallery > .close:hover,
.blueimp-gallery > .title:hover,
.blueimp-gallery > .play-pause:hover {
.blueimp-gallery > .play-pause:hover,
.blueimp-gallery > .fullscreen:hover{
color: #fff;
opacity: 1;
}
@ -175,7 +187,8 @@
.blueimp-gallery-controls > .next,
.blueimp-gallery-controls > .close,
.blueimp-gallery-controls > .title,
.blueimp-gallery-controls > .play-pause {
.blueimp-gallery-controls > .play-pause,
.blueimp-gallery-controls > .fullscreen{
display: block;
/* Fix z-index issues (controls behind slide element) on Android: */
-webkit-transform: translateZ(0);
@ -195,7 +208,8 @@
.blueimp-gallery > .prev,
.blueimp-gallery > .next,
.blueimp-gallery > .close,
.blueimp-gallery > .play-pause {
.blueimp-gallery > .play-pause,
.blueimp-gallery > .fullscreen{
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;

File diff suppressed because one or more lines are too long

View File

@ -38,7 +38,11 @@
// used as alternative to a thumbnail child element:
thumbnailProperty: 'thumbnail',
// Defines if the gallery indicators should display a thumbnail:
thumbnailIndicators: true
thumbnailIndicators: true,
// The tag name of thumbnails indicators
thumbnailsTagIndicators: 'li',
//thumbnail with image tag
thumbnailWithImgTag: false
});
var initSlides = Gallery.prototype.initSlides,
@ -51,7 +55,7 @@
$.extend(Gallery.prototype, {
createIndicator: function (obj) {
var indicator = this.indicatorPrototype.cloneNode(false),
var indicator = this.indicatorPrototype.cloneNode(this.options.thumbnailWithImgTag),
title = this.getItemProperty(obj, this.options.titleProperty),
thumbnailProperty = this.options.thumbnailProperty,
thumbnailUrl,
@ -64,7 +68,18 @@
thumbnailUrl = this.getItemProperty(obj, thumbnailProperty);
}
if (thumbnailUrl) {
indicator.style.backgroundImage = 'url("' + thumbnailUrl + '")';
if (this.options.thumbnailsTagIndicators == 'img')
{
indicator.src = thumbnailUrl;
}
else if (this.options.thumbnailWithImgTag)
{
indicator.children[0].src = thumbnailUrl;
}
else
{
indicator.style.backgroundImage = 'url("' + thumbnailUrl + '")';
}
}
}
if (title) {
@ -100,8 +115,9 @@
this.options.indicatorContainer
);
if (this.indicatorContainer.length) {
this.indicatorPrototype = document.createElement('li');
this.indicators = this.indicatorContainer[0].children;
this.indicatorPrototype = document.createElement(this.options.thumbnailsTagIndicators);
if (this.options.thumbnailWithImgTag) this.indicatorPrototype.appendChild(document.createElement('img'));
this.indicators = this.indicatorContainer[0].children;
}
}
initSlides.call(this, reload);

View File

@ -91,6 +91,8 @@
closeClass: 'close',
// The class for the "play-pause" toggle control:
playPauseClass: 'play-pause',
// The class fullscreen button control
fullscreenClass:'fullscreen',
// The list object property (or data attribute) with the object type:
typeProperty: 'type',
// The list object property (or data attribute) with the object title:
@ -113,6 +115,8 @@
toggleControlsOnReturn: true,
// Toggle the automatic slideshow interval on pressing the Space key:
toggleSlideshowOnSpace: true,
// Toggle fullscreen mode when slideshow is running
toggleFullscreenOnSlideShow: true,
// Navigate the gallery by pressing left and right on the keyboard:
enableKeyboardNavigation: true,
// Close the gallery on pressing the Esc key:
@ -865,6 +869,10 @@
// Click on "play-pause" control
this.preventDefault(event);
this.toggleSlideshow();
}else if (isTarget(options.fullscreenClass)) {
// Click on "fullscreen" control
this.preventDefault(event);
this.toggleFullscreen();
} else if (parent === this.slidesContainer[0]) {
// Click on slide background
this.preventDefault(event);
@ -1128,11 +1136,25 @@
toggleSlideshow: function () {
if (!this.interval) {
this.play();
if (this.options.toggleFullscreenOnSlideShow) this.requestFullScreen(this.container[0]);
} else {
this.pause();
if (this.options.toggleFullscreenOnSlideShow) this.exitFullScreen();
}
},
toggleFullscreen: function ()
{
if (!this.getFullScreenElement())
{
this.requestFullScreen(this.container[0]);
}
else
{
this.exitFullScreen();
}
},
getNodeIndex: function (element) {
return parseInt(element.getAttribute('data-index'), 10);
},
@ -1338,4 +1360,4 @@
});
return Gallery;
}));
}));

File diff suppressed because one or more lines are too long