From 082d5c9fd40ec84cec969b844e0fbff2592512bb Mon Sep 17 00:00:00 2001
From: Florian Staudacher <florian_staudacher@yahoo.de>
Date: Thu, 9 Feb 2012 20:55:34 +0100
Subject: [PATCH] initial photo page functionality is back, featuring backbone
 and handlebars

---
 app/controllers/photos_controller.rb          |  9 ++-
 public/javascripts/app/collections/photos.js  | 12 ++++
 public/javascripts/app/models/photo.js        | 14 ++++
 public/javascripts/app/models/photos.js       | 65 +++++++++++++++++++
 public/javascripts/app/router.js              | 12 +++-
 .../app/templates/photo.handlebars            |  3 +
 public/javascripts/app/views/photo_view.js    | 13 ++++
 public/javascripts/app/views/photos_view.js   | 56 ++++++++++++++++
 8 files changed, 179 insertions(+), 5 deletions(-)
 create mode 100644 public/javascripts/app/collections/photos.js
 create mode 100644 public/javascripts/app/models/photo.js
 create mode 100644 public/javascripts/app/models/photos.js
 create mode 100644 public/javascripts/app/templates/photo.handlebars
 create mode 100644 public/javascripts/app/views/photo_view.js
 create mode 100644 public/javascripts/app/views/photos_view.js

diff --git a/app/controllers/photos_controller.rb b/app/controllers/photos_controller.rb
index 339848d339..efff2f0cd4 100644
--- a/app/controllers/photos_controller.rb
+++ b/app/controllers/photos_controller.rb
@@ -29,9 +29,12 @@ class PhotosController < ApplicationController
         @contacts_of_contact_count = 0
       end
 
-      @posts = current_user.photos_from(@person).paginate(:page => params[:page])
-
-      render 'people/show'
+      @posts = current_user.photos_from(@person)
+      
+      respond_to do |format|
+        format.all { render 'people/show' }
+        format.json{ render_for_api :backbone, :json => @posts, :root => :photos }
+      end
 
     else
       flash[:error] = I18n.t 'people.show.does_not_exist'
diff --git a/public/javascripts/app/collections/photos.js b/public/javascripts/app/collections/photos.js
new file mode 100644
index 0000000000..40c960b23c
--- /dev/null
+++ b/public/javascripts/app/collections/photos.js
@@ -0,0 +1,12 @@
+app.collections.Photos = Backbone.Collection.extend({
+  url : "/photos",
+
+  model: function(attrs, options) {
+    var modelClass = app.models.Photo
+    return new modelClass(attrs, options);
+  },
+
+  parse: function(resp){
+    return resp.photos;
+  }
+});
diff --git a/public/javascripts/app/models/photo.js b/public/javascripts/app/models/photo.js
new file mode 100644
index 0000000000..05b4a3c1ea
--- /dev/null
+++ b/public/javascripts/app/models/photo.js
@@ -0,0 +1,14 @@
+app.models.Photo = Backbone.Model.extend({
+  urlRoot : "/photos",
+
+  initialize : function() {},
+
+  createdAt : function() {
+    return this.timeOf("created_at");
+  },
+
+  timeOf: function(field) {
+    return new Date(this.get(field)) /1000;
+  },
+
+});
\ No newline at end of file
diff --git a/public/javascripts/app/models/photos.js b/public/javascripts/app/models/photos.js
new file mode 100644
index 0000000000..d50680e67e
--- /dev/null
+++ b/public/javascripts/app/models/photos.js
@@ -0,0 +1,65 @@
+app.models.Photos = Backbone.Model.extend({
+  initialize : function(){
+    this.photos = new app.collections.Photos([], this.photoOptions());
+  },
+
+  photoOptions :function(){
+      var order = this.sortOrder();
+      return {
+          comparator : function(photo) { return -photo[order](); }
+      }
+  },
+
+  url : function() {
+    return _.any(this.photos.models) ? this.timeFilteredPath() : this.basePath()
+  },
+
+  _fetching : false,
+
+  fetch : function(){
+    if(this._fetching) { return false; }
+    var self = this;
+
+    // we're fetching the collection... there is probably a better way to do this
+    self._fetching = true;
+
+    this.photos
+      .fetch({
+        add : true,
+        url : self.url()
+      })
+      .done(
+        function(resp){
+          // we're done fetching... there is probably a better way to handle this
+          self._fetching = false;
+
+          self.trigger("fetched", self);
+
+          // all loaded?
+          if(resp.photos && resp.photos.length == 0) {
+            self.trigger("allPostsLoaded", self);
+          }
+        }
+      );
+      
+    return this;
+  },
+  
+  basePath : function(){
+    return document.location.pathname;
+  },
+
+  timeFilteredPath : function(){
+   return this.basePath() + "?max_time=" + this.maxTime();
+  },
+
+  maxTime: function(){
+    var lastPost = _.last(this.photos.models);
+    return lastPost[this.sortOrder()]()
+  },
+
+  sortOrder : function() {
+    return "createdAt";
+  },
+
+});
\ No newline at end of file
diff --git a/public/javascripts/app/router.js b/public/javascripts/app/router.js
index 2277d69709..08003a583a 100644
--- a/public/javascripts/app/router.js
+++ b/public/javascripts/app/router.js
@@ -7,7 +7,8 @@ app.Router = Backbone.Router.extend({
     "liked": "stream",
     "mentions": "stream",
     "people/:id": "stream",
-      "u/:name": "stream",
+    "people/:id/photos": "photos",
+    "u/:name": "stream",
     "followed_tags": "stream",
     "tags/:name": "stream",
     "posts/:id": "stream",
@@ -15,7 +16,7 @@ app.Router = Backbone.Router.extend({
   },
 
   stream : function() {
-    app.stream = new app.models.Stream()
+    app.stream = new app.models.Stream();
     app.page = new app.views.Stream({model : app.stream}).render();
     app.publisher = app.publisher || new app.views.Publisher({collection : app.stream.posts});
 
@@ -23,6 +24,13 @@ app.Router = Backbone.Router.extend({
 
     $("#main_stream").html(app.page.el);
     $('#selected_aspect_contacts .content').html(streamFacesView.el);
+  },
+
+  photos : function() {
+    app.photos = new app.models.Photos();
+    app.page = new app.views.Photos({model : app.photos}).render();
+
+    $("#main_stream").html(app.page.el);
   }
 });
 
diff --git a/public/javascripts/app/templates/photo.handlebars b/public/javascripts/app/templates/photo.handlebars
new file mode 100644
index 0000000000..375d6869e4
--- /dev/null
+++ b/public/javascripts/app/templates/photo.handlebars
@@ -0,0 +1,3 @@
+<a href="#" class="photo-link">
+  <img src="{{sizes.large}}" class="photo big_photo" data-small-photo="{{sizes.small}}" data-full-photo="{{sizes.large}}" rel="lightbox">
+</a>
\ No newline at end of file
diff --git a/public/javascripts/app/views/photo_view.js b/public/javascripts/app/views/photo_view.js
new file mode 100644
index 0000000000..c672863d4d
--- /dev/null
+++ b/public/javascripts/app/views/photo_view.js
@@ -0,0 +1,13 @@
+app.views.Photo = app.views.StreamObject.extend({
+
+  templateName: "photo",
+
+  className : "photo loaded",
+
+  initialize : function() {
+    $(this.el).attr("id", this.model.get("guid"));
+    this.model.bind('remove', this.remove, this);
+    return this;
+  }
+  
+});
\ No newline at end of file
diff --git a/public/javascripts/app/views/photos_view.js b/public/javascripts/app/views/photos_view.js
new file mode 100644
index 0000000000..d9161356e0
--- /dev/null
+++ b/public/javascripts/app/views/photos_view.js
@@ -0,0 +1,56 @@
+app.views.Photos = Backbone.View.extend({
+
+  events : {},
+
+  initialize : function(options) {
+    this.photos = this.model;
+    this.collection = this.model.photos;
+
+    this.setupEvents();
+    //this.setupLightbox(); ERROR: "imageThumb is undefined" ...
+  },
+
+  setupEvents : function(){
+    this.photos.bind("fetched", this.removeLoader, this)
+    this.collection.bind("add", this.addPhoto, this);
+  },
+
+  addPhoto : function(photo) {
+    var photoView = new app.views.Photo({ model: photo });
+
+    $(this.el)[
+      (this.collection.at(0).id == photo.id)
+        ? "prepend"
+        : "append"
+    ](photoView.render().el);
+
+    return this;
+  },
+
+  render : function(evt) {
+    if(evt) {evt.preventDefault(); }
+
+    if(this.model.fetch()) {
+      this.appendLoader();
+    };
+    
+    return this;
+  },
+
+  appendLoader: function(){
+    $("#paginate").html($("<img>", {
+      src : "/images/static-loader.png",
+      "class" : "loader"
+    }));
+  },
+
+  removeLoader: function() {
+    $("#paginate").empty();
+  },
+
+  setupLightbox : function(){
+    this.lightbox = Diaspora.BaseWidget.instantiate("Lightbox");
+    $(this.el).delegate("a.photo-link", "click", this.lightbox.lightboxImageClicked);
+  },
+
+});
\ No newline at end of file
-- 
GitLab