From e09ddef36152175f0cda35be7e115517fb81622b Mon Sep 17 00:00:00 2001 From: danielgrippi Date: Sat, 9 Jul 2011 19:43:04 -0700 Subject: [PATCH 1/2] DH DG; lightboxin wip --- app/views/layouts/_header.html.haml | 10 ++ .../status_messages/_status_message.haml | 6 +- config/assets.yml | 6 +- public/javascripts/diaspora.js | 12 +- public/javascripts/widgets/lightbox.js | 106 +++++++++++++++ public/stylesheets/sass/lightbox.scss | 125 ++++++++++++++++++ 6 files changed, 257 insertions(+), 8 deletions(-) create mode 100644 public/javascripts/widgets/lightbox.js create mode 100644 public/stylesheets/sass/lightbox.scss diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index f5c0d084d..4cab6a35f 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -63,6 +63,16 @@ .footer_container .hashtags + #lightbox + #lightbox-content + = link_to "[x] close", '#', :id => 'lightbox-close-link' + %img#lightbox-image + #lightbox-imageset + + + #lightbox-backdrop + + %ul#user_menu.dropdown %li .right diff --git a/app/views/status_messages/_status_message.haml b/app/views/status_messages/_status_message.haml index fd1b26c3f..1d857fac5 100644 --- a/app/views/status_messages/_status_message.haml +++ b/app/views/status_messages/_status_message.haml @@ -5,14 +5,14 @@ - if photos.size > 0 .photo_attachments - = link_to (image_tag photos.first.url(:scaled_full)), photo_path(photos.first), :class => "big_stream_photo" + = link_to (image_tag photos.first.url(:scaled_full), :class => "stream-photo", 'data-small-photo' => photos.first.url(:thumb_medium), 'data-full-photo' => photos.first.url), photo_path(photos.first), :class => "big_stream_photo" - if photos.size > 1 - if photos.size >= 8 - for photo in photos[1..8] - = link_to (image_tag photo.url(:thumb_small), :class => 'thumb_small'), photo_path(photo) + = link_to (image_tag photo.url(:thumb_small), :class => 'stream-photo thumb_small', 'data-small-photo' => photo.url(:thumb_medium), 'data-full-photo' => photo.url), photo_path(photo) - else - for photo in photos[1..photos.size] - = link_to (image_tag photo.url(:thumb_small), :class => 'thumb_small'), photo_path(photo) + = link_to (image_tag photo.url(:thumb_small), :class => 'stream-photo thumb_small', 'data-small-photo' => photo.url(:thumb_medium), 'data-full-photo' => photo.url), photo_path(photo) %p{ :class => direction_for(post.text) } = markdownify(post.text, :youtube_maps => post[:youtube_titles]) diff --git a/config/assets.yml b/config/assets.yml index b177c7231..969d1b299 100644 --- a/config/assets.yml +++ b/config/assets.yml @@ -36,12 +36,14 @@ javascripts: - public/javascripts/widgets/flashes.js - public/javascripts/widgets/post.js - public/javascripts/widgets/hovercard.js + - public/javascripts/widgets/lightbox.js - public/javascripts/widgets/notifications-badge.js - public/javascripts/view.js - public/javascripts/stream.js - public/javascripts/content-updater.js - public/javascripts/search.js - public/javascripts/contact-edit.js + - public/javascripts/contact-list.js login: - public/javascripts/login.js mobile: @@ -61,14 +63,11 @@ javascripts: - public/javascripts/vendor/mailchimp/jquery.form.js - public/javascripts/vendor/mailchimp/jquery.validate.js - public/javascripts/vendor/mailchimp/jquery126.min.js - aspects: - - public/javascripts/contact-list.js finder: - public/javascripts/friend-finder.js home: - public/javascripts/publisher.js - public/javascripts/aspect-filters.js - - public/javascripts/contact-list.js - public/javascripts/aspect-edit-pane.js - public/javascripts/fileuploader-custom.js people: @@ -85,6 +84,7 @@ stylesheets: default: - public/stylesheets/application.css - public/stylesheets/ui.css + - public/stylesheets/lightbox.css - public/stylesheets/autocomplete.css - public/stylesheets/tags.css - public/stylesheets/vendor/facebox.css diff --git a/public/javascripts/diaspora.js b/public/javascripts/diaspora.js index 55a4bf509..c1e9348ec 100644 --- a/public/javascripts/diaspora.js +++ b/public/javascripts/diaspora.js @@ -16,8 +16,10 @@ this.eventsContainer = $({}); }; - Diaspora.WidgetCollection.prototype.add = function(widgetId, widget) { - this[widgetId] = this.collection[widgetId] = new widget(); + Diaspora.WidgetCollection.prototype.add = function(widgetId, Widget) { + $.extend(Widget.prototype, Diaspora.BaseWidget); + + this[widgetId] = this.collection[widgetId] = new Widget(); if(this.initialized) { this.collection[widgetId].start(); } @@ -49,6 +51,12 @@ this.eventsContainer.trigger(id, args); }; + Diaspora.BaseWidget = { + require: function(widgetName) { + this[widgetName] = Diaspora.widgets[widgetName]; + } + }; + Diaspora.widgets = new Diaspora.WidgetCollection(); window.Diaspora = Diaspora; diff --git a/public/javascripts/widgets/lightbox.js b/public/javascripts/widgets/lightbox.js new file mode 100644 index 000000000..ddeef2daf --- /dev/null +++ b/public/javascripts/widgets/lightbox.js @@ -0,0 +1,106 @@ +/* Copyright (c) 2011, Diaspora Inc. This file is + * licensed under the Affero General Public License version 3 or later. See + * the COPYRIGHT file. + */ + + +jQuery.fn.center = (function() { + var $window = $(window); + return function () { + this.css({ + position: "absolute", + top: ($window.height() - this.height()) / 2 + $window.scrollTop() + "px", + left:($window.width() - this.width()) / 2 + $window.scrollLeft() + "px" + }); + return this; + }; +})(); + +(function() { + var Lightbox = function() { + var self = this; + + this.start = function() { + $.extend(self, { + lightbox: $("#lightbox"), + imageset: $("#lightbox-imageset"), + backdrop: $("#lightbox-backdrop"), + image: $("#lightbox-image"), + stream: $("#main_stream"), + body: $(document.body), + window: $(window) + }); + + self.stream.delegate("a", "click", self.lightboxImageClicked); + self.imageset.delegate("img", "click", self.imagesetImageClicked); + + self.window.resize(function() { + self.lightbox.css("max-height", (self.window.height() - 100) + "px"); + }).trigger("resize"); + + self.body.keydown(function(evt) { + if(evt.keyCode == 27){ + self.resetLightbox(); + } + }); + }; + + this.lightboxImageClicked = function(evt) { + evt.preventDefault(); + + var selectedImage = $(this).find("img.stream-photo"), + imageUrl = selectedImage.attr("data-full-photo"), + images = selectedImage.parents('.stream_element').find('img.stream-photo'), + imageThumb; + + self.imageset.html(""); + images.each(function(index, image) { + image = $(image); + var thumb = $("", { + src: image.attr("data-small-photo"), + "data-full-photo": image.attr("data-full-photo") + }); + + if(image.attr("data-full-photo") == imageUrl) { + imageThumb = thumb; + }; + + self.imageset.append(thumb); + }); + + self + .selectImage(imageThumb) + .revealLightbox(); + }; + + this.imagesetImageClicked = function(evt) { + evt.preventDefault(); + + self.selectImage($(this)); + }; + + this.selectImage = function(imageThumb) { + $(".selected", self.imageset).removeClass("selected"); + imageThumb.addClass("selected"); + self.image.attr("src", imageThumb.attr("data-full-photo")); + + return self; + }; + + this.revealLightbox = function() { + self.body.addClass("lightboxed"); + self.lightbox + .css("max-height", (self.window.height() - 100) + "px") + .show(); + + return self; + }; + + this.resetLightbox = function() { + self.lightbox.hide(); + self.body.removeClass("lightboxed"); + }; + }; + + Diaspora.widgets.add("lightbox", Lightbox); +})(); diff --git a/public/stylesheets/sass/lightbox.scss b/public/stylesheets/sass/lightbox.scss new file mode 100644 index 000000000..817d06d10 --- /dev/null +++ b/public/stylesheets/sass/lightbox.scss @@ -0,0 +1,125 @@ +// licensed under the Affero General Public License version 3 or later. See +// the COPYRIGHT file. + +@import 'mixins'; + +#lightbox{ + z-index: 30; + position: fixed; + top: 0; + right: 0; + display: none; + overflow-y: auto; + width: 100%; + text-align: center; + padding-top: 80px; + padding-bottom: 20px; + + color: #666; + text-shadow: none; + font-size: 12px; + + &.show{ + position: absolute; + display: block; + } + + #lightbox-image{ + @include box-shadow(0, 10px, 20px, black); + top: 0; + display: block; + max-width: 800px; + max-height: 800px; + } + + #lightbox-content{ + text-align: left; + display: inline-block; + } + + #lightbox-links{ + margin-top: 12px; + + .attribution{ + float: right; + } + + #lightbox-attribution-link{ + color: #999; + font-weight: bold; + &:hover{ + color: #eee; + } + } + } + + #lightbox-close-link, + #lightbox-attribution-link, + #lightbox-short-link{ + display: inline-block; + color: #333; + text-decoration: none; + line-height: 14px; + + &:hover{ + color: #eee; + } + } + + #lightbox-close-link{ + color: #666; + margin-bottom: 12px; + } +} + +#lightbox-backdrop{ + -moz-box-shadow:inset 0 0 50px #000000; + -webkit-box-shadow:inset 0 0 50px #000000; + box-shadow:inset 0 0 50px #000000; + + z-index: 29; + position: fixed; + height: 100%; + width: 100%; + top: 0; + left: 0; + background-color: rgba(0,0,0,0.85); + display: none; +} + +#lightbox-imageset{ + z-index: 30; + position: fixed; + width: 100%; + left: 0; + bottom: 0; + display: none; + text-align: center; + background-color: rgba(0,0,0,0.4); + padding: 5px 0; + + img{ + @include transition(opacity, 0.2s); + @include opacity(0.2); + height: 70px; + width: 70px; + margin-right: 5px; + + &:last-child{ + margin-right: 0; + } + + &.selected{ + @include opacity(1); + } + } +} + +body.lightboxed{ + overflow: hidden; + #lightbox-backdrop, + #lightbox-imageset{ + display: block; + } +} + From 776368d45e0ea3d92ec0f30a9965174595df9546 Mon Sep 17 00:00:00 2001 From: danielgrippi Date: Sun, 10 Jul 2011 20:46:58 -0700 Subject: [PATCH 2/2] added left/right arrow events to the lightbox; lightbox only on stream element images for now --- app/views/services/finder.html.haml | 4 +- app/views/shared/_stream_element.html.haml | 2 +- .../status_messages/_status_message.haml | 8 ++-- public/javascripts/widgets/lightbox.js | 41 +++++++++++++++++-- 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/app/views/services/finder.html.haml b/app/views/services/finder.html.haml index 4b9fc19e4..c8b5e7158 100644 --- a/app/views/services/finder.html.haml +++ b/app/views/services/finder.html.haml @@ -3,9 +3,7 @@ -# the COPYRIGHT file. - content_for :head do - = include_javascripts :aspects - -= include_javascripts :finder + = include_javascripts :finder #aspect_edit_pane.larger.friend_finder #facebox_header diff --git a/app/views/shared/_stream_element.html.haml b/app/views/shared/_stream_element.html.haml index faf31bcb2..3ae4e2b39 100644 --- a/app/views/shared/_stream_element.html.haml +++ b/app/views/shared/_stream_element.html.haml @@ -26,7 +26,7 @@ = link_to(how_long_ago(post), post_path(post)) - if post.activity_streams? - = link_to image_tag(post.image_url), post.object_url + = link_to image_tag(post.image_url, 'data-small-photo' => post.image_url), post.object_url, :class => "stream-photo-link" - else = render 'status_messages/status_message', :post => post, :photos => post.photos diff --git a/app/views/status_messages/_status_message.haml b/app/views/status_messages/_status_message.haml index 1d857fac5..5dcce8a85 100644 --- a/app/views/status_messages/_status_message.haml +++ b/app/views/status_messages/_status_message.haml @@ -5,14 +5,14 @@ - if photos.size > 0 .photo_attachments - = link_to (image_tag photos.first.url(:scaled_full), :class => "stream-photo", 'data-small-photo' => photos.first.url(:thumb_medium), 'data-full-photo' => photos.first.url), photo_path(photos.first), :class => "big_stream_photo" + = link_to (image_tag photos.first.url(:scaled_full), :class => "stream-photo", 'data-small-photo' => photos.first.url(:thumb_medium), 'data-full-photo' => photos.first.url), photo_path(photos.first), :class => "stream-photo-link big_stream_photo" - if photos.size > 1 - if photos.size >= 8 - for photo in photos[1..8] - = link_to (image_tag photo.url(:thumb_small), :class => 'stream-photo thumb_small', 'data-small-photo' => photo.url(:thumb_medium), 'data-full-photo' => photo.url), photo_path(photo) + = link_to (image_tag photo.url(:thumb_small), :class => 'stream-photo thumb_small', 'data-small-photo' => photo.url(:thumb_medium), 'data-full-photo' => photo.url), photo_path(photo), :class => 'stream-photo-link' - else - for photo in photos[1..photos.size] - = link_to (image_tag photo.url(:thumb_small), :class => 'stream-photo thumb_small', 'data-small-photo' => photo.url(:thumb_medium), 'data-full-photo' => photo.url), photo_path(photo) + = link_to (image_tag photo.url(:thumb_small), :class => 'stream-photo thumb_small', 'data-small-photo' => photo.url(:thumb_medium), 'data-full-photo' => photo.url), photo_path(photo), :class => 'stream-photo-link' -%p{ :class => direction_for(post.text) } +%p{:class => direction_for(post.text)} = markdownify(post.text, :youtube_maps => post[:youtube_titles]) diff --git a/public/javascripts/widgets/lightbox.js b/public/javascripts/widgets/lightbox.js index ddeef2daf..a61d30e48 100644 --- a/public/javascripts/widgets/lightbox.js +++ b/public/javascripts/widgets/lightbox.js @@ -25,26 +25,58 @@ jQuery.fn.center = (function() { lightbox: $("#lightbox"), imageset: $("#lightbox-imageset"), backdrop: $("#lightbox-backdrop"), + closelink: $("#lightbox-close-link"), image: $("#lightbox-image"), - stream: $("#main_stream"), + stream: $(".stream_container"), body: $(document.body), window: $(window) }); - self.stream.delegate("a", "click", self.lightboxImageClicked); + self.stream.delegate("a.stream-photo-link", "click", self.lightboxImageClicked); self.imageset.delegate("img", "click", self.imagesetImageClicked); self.window.resize(function() { self.lightbox.css("max-height", (self.window.height() - 100) + "px"); }).trigger("resize"); + self.closelink.click(self.resetLightbox); + self.body.keydown(function(evt) { - if(evt.keyCode == 27){ + + var imageThumb = self.imageset.find("img.selected"); + + switch(evt.keyCode) { + case 27: self.resetLightbox(); + break; + case 37: + //left + self.selectImage(self.prevImage(imageThumb)); + break; + case 39: + //right + self.selectImage(self.nextImage(imageThumb)); + break; } }); }; + this.nextImage = function(thumb){ + var next = thumb.next(); + if (next.length == 0) { + next = self.imageset.find("img").first(); + } + return(next); + }; + + this.prevImage = function(thumb){ + var prev = thumb.prev(); + if (prev.length == 0) { + prev = self.imageset.find("img").last(); + } + return(prev); + }; + this.lightboxImageClicked = function(evt) { evt.preventDefault(); @@ -75,7 +107,8 @@ jQuery.fn.center = (function() { this.imagesetImageClicked = function(evt) { evt.preventDefault(); - + + self.selectImage($(this)); };