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/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 fd1b26c3f..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)), 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 => '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), :class => 'stream-photo-link'
- 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), :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/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..a61d30e48
--- /dev/null
+++ b/public/javascripts/widgets/lightbox.js
@@ -0,0 +1,139 @@
+/* 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"),
+ closelink: $("#lightbox-close-link"),
+ image: $("#lightbox-image"),
+ stream: $(".stream_container"),
+ body: $(document.body),
+ window: $(window)
+ });
+
+ 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) {
+
+ 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();
+
+ 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;
+ }
+}
+