Merge branch 'master' into stream-for-photos
Conflicts: app/assets/javascripts/app/views/stream_view.js
This commit is contained in:
commit
e379a6df0f
21 changed files with 277 additions and 159 deletions
25
README.md
25
README.md
|
|
@ -18,27 +18,32 @@ With Diaspora you can:
|
||||||
|
|
||||||
Documentation is available on our [wiki](https://github.com/diaspora/diaspora/wiki)
|
Documentation is available on our [wiki](https://github.com/diaspora/diaspora/wiki)
|
||||||
|
|
||||||
|
[Pull Request Guidelines](https://github.com/diaspora/diaspora/wiki/Pull-Request-Guidelines)
|
||||||
|
|
||||||
|
Before submitting code, feel free to sign our [Contributor License Agreement](https://github.com/diaspora/diaspora/wiki/New-CLA--12-13-10) [Sign Here](https://spreadsheets.google.com/a/joindiaspora.com/spreadsheet/viewform?formkey=dFdRTnY0TGtfaklKQXZNUndsMlJ2eGc6MQ)
|
||||||
|
|
||||||
## Quick Start:
|
## Quick Start:
|
||||||
|
|
||||||
Here's how you can get a development environment up and running. You can check out system-specific guides [here](https://github.com/diaspora/diaspora/wiki/Installation-Guides).
|
Here's how you can get a development environment up and running. You can check out system-specific guides [here](https://github.com/diaspora/diaspora/wiki/Installation-Guides).
|
||||||
|
|
||||||
### Step 1: Download the script
|
### Step 1: Download the script
|
||||||
```wget https://raw.github.com/diaspora/diaspora/ec5289bd3b9b5608d339b28e1e30272f380a9211/script/install.sh
|
```
|
||||||
|
curl https://raw.github.com/diaspora/diaspora/master/script/install.sh | /bin/sh
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 2: Set permissions and run
|
### Step 2: Follow the instructions
|
||||||
```chmod +x install.sh && install.sh
|
|
||||||
|
|
||||||
|
### Step 3: Run the the development server
|
||||||
|
```
|
||||||
|
rails s
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 3: Follow the instructions
|
then visit 'http://localhost:3000' in your browser.
|
||||||
|
|
||||||
|
### Step 4: Run tests
|
||||||
### Step 4: Run the test server
|
|
||||||
```rails s
|
|
||||||
```
|
```
|
||||||
|
rake
|
||||||
### Step 5: Run tests
|
|
||||||
```rake tests
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Resources:
|
## Resources:
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@
|
||||||
text = text.replace(linkRegex, function() {
|
text = text.replace(linkRegex, function() {
|
||||||
var unicodeUrl = arguments[3];
|
var unicodeUrl = arguments[3];
|
||||||
var addr = parse_url(unicodeUrl);
|
var addr = parse_url(unicodeUrl);
|
||||||
|
if( !addr.host ) addr.host = ""; // must not be 'undefined'
|
||||||
|
|
||||||
var asciiUrl = // rebuild the url
|
var asciiUrl = // rebuild the url
|
||||||
(!addr.scheme ? '' : addr.scheme +
|
(!addr.scheme ? '' : addr.scheme +
|
||||||
( (addr.scheme.toLowerCase()=="mailto") ? ':' : '://')) +
|
( (addr.scheme.toLowerCase()=="mailto") ? ':' : '://')) +
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,8 @@ app.Router = Backbone.Router.extend({
|
||||||
photos : function() {
|
photos : function() {
|
||||||
app.photos = new app.models.Stream([], {collection: app.collections.Photos});
|
app.photos = new app.models.Stream([], {collection: app.collections.Photos});
|
||||||
app.page = new app.views.Photos({model : app.photos});
|
app.page = new app.views.Photos({model : app.photos});
|
||||||
|
|
||||||
|
|
||||||
$("#main_stream").html(app.page.render().el);
|
$("#main_stream").html(app.page.render().el);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,8 @@ app.views.Base = Backbone.View.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
defaultPresenter : function(){
|
defaultPresenter : function(){
|
||||||
var modelJson = this.model ? _.clone(this.model.attributes) : {}
|
var modelJson = this.model && this.model.attributes ? _.clone(this.model.attributes) : {}
|
||||||
|
|
||||||
return _.extend(modelJson, {
|
return _.extend(modelJson, {
|
||||||
current_user : app.currentUser.attributes,
|
current_user : app.currentUser.attributes,
|
||||||
loggedIn : app.currentUser.authenticated()
|
loggedIn : app.currentUser.authenticated()
|
||||||
|
|
@ -71,3 +72,66 @@ app.views.Base = Backbone.View.extend({
|
||||||
$(".tooltip").remove();
|
$(".tooltip").remove();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Mixin to render a collection that fetches more via infinite scroll, for a view that has no template.
|
||||||
|
// Requires:
|
||||||
|
// a stream model, bound as this.stream
|
||||||
|
// a stream's posts, bound as this.collection
|
||||||
|
// a postClass to be declared
|
||||||
|
// a #paginate div in the layout
|
||||||
|
// a call to setupInfiniteScroll
|
||||||
|
|
||||||
|
app.views.infiniteScrollMixin = {
|
||||||
|
setupInfiniteScroll : function() {
|
||||||
|
this.postViews = this.postViews || []
|
||||||
|
|
||||||
|
this.bind("loadMore", this.fetchAndshowLoader, this)
|
||||||
|
this.stream.bind("fetched", this.hideLoader, this)
|
||||||
|
this.stream.bind("allPostsLoaded", this.unbindInfScroll, this)
|
||||||
|
this.collection.bind("add", this.addPost, this);
|
||||||
|
|
||||||
|
var throttledScroll = _.throttle(_.bind(this.infScroll, this), 200);
|
||||||
|
$(window).scroll(throttledScroll);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderTemplate : function() {
|
||||||
|
if(this.stream.isFetching()) { this.showLoader() }
|
||||||
|
},
|
||||||
|
|
||||||
|
addPost : function(post) {
|
||||||
|
var postView = new this.postClass({ model: post })
|
||||||
|
, placeInStream = (this.collection.at(0).id == post.id) ? "prepend" : "append";
|
||||||
|
|
||||||
|
this.$el[placeInStream](postView.render().el);
|
||||||
|
this.postViews.push(postView)
|
||||||
|
},
|
||||||
|
|
||||||
|
unbindInfScroll : function() {
|
||||||
|
$(window).unbind("scroll");
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchAndshowLoader : function(){
|
||||||
|
if(this.stream.isFetching()) { return false }
|
||||||
|
this.stream.fetch()
|
||||||
|
this.showLoader()
|
||||||
|
},
|
||||||
|
|
||||||
|
showLoader: function(){
|
||||||
|
$("#paginate .loader").removeClass("hidden")
|
||||||
|
},
|
||||||
|
|
||||||
|
hideLoader: function() {
|
||||||
|
$("#paginate .loader").addClass("hidden")
|
||||||
|
},
|
||||||
|
|
||||||
|
infScroll : function() {
|
||||||
|
var $window = $(window)
|
||||||
|
, distFromTop = $window.height() + $window.scrollTop()
|
||||||
|
, distFromBottom = $(document).height() - distFromTop
|
||||||
|
, bufferPx = 500;
|
||||||
|
|
||||||
|
if(distFromBottom < bufferPx) {
|
||||||
|
this.trigger("loadMore")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,52 +1,16 @@
|
||||||
app.views.Photos = Backbone.View.extend({
|
app.views.Photos = Backbone.View.extend(_.extend({
|
||||||
|
|
||||||
events : {},
|
|
||||||
|
|
||||||
initialize : function(options) {
|
initialize : function(options) {
|
||||||
this.photos = this.model;
|
this.stream = this.model;
|
||||||
this.collection = this.model.items;
|
this.collection = this.stream.items;
|
||||||
|
|
||||||
this.setupEvents();
|
// viable for extraction
|
||||||
this.setupLightbox();
|
this.stream.fetch();
|
||||||
|
|
||||||
|
this.setupLightbox()
|
||||||
|
this.setupInfiniteScroll()
|
||||||
},
|
},
|
||||||
|
|
||||||
setupEvents : function(){
|
postClass : app.views.Photo,
|
||||||
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 : "/assets/static-loader.png",
|
|
||||||
"class" : "loader"
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
removeLoader: function() {
|
|
||||||
$("#paginate").empty();
|
|
||||||
},
|
|
||||||
|
|
||||||
setupLightbox : function(){
|
setupLightbox : function(){
|
||||||
this.lightbox = Diaspora.BaseWidget.instantiate("Lightbox");
|
this.lightbox = Diaspora.BaseWidget.instantiate("Lightbox");
|
||||||
|
|
@ -55,6 +19,5 @@ app.views.Photos = Backbone.View.extend({
|
||||||
imageSelector: 'img.photo'
|
imageSelector: 'img.photo'
|
||||||
});
|
});
|
||||||
$(this.el).delegate("a.photo-link", "click", this.lightbox.lightboxImageClicked);
|
$(this.el).delegate("a.photo-link", "click", this.lightbox.lightboxImageClicked);
|
||||||
},
|
}
|
||||||
|
}, app.views.infiniteScrollMixin));
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -1,77 +1,27 @@
|
||||||
app.views.Stream = Backbone.View.extend({
|
app.views.Stream = Backbone.View.extend(_.extend({
|
||||||
initialize: function(options) {
|
initialize: function(options) {
|
||||||
this.stream = this.model
|
this.stream = this.model
|
||||||
this.collection = this.model.items
|
this.collection = this.stream.items
|
||||||
|
|
||||||
this.setupEvents()
|
|
||||||
this.setupInfiniteScroll()
|
|
||||||
this.setupLightbox()
|
|
||||||
this.postViews = []
|
this.postViews = []
|
||||||
|
|
||||||
|
this.setupNSFW()
|
||||||
|
this.setupLightbox()
|
||||||
|
this.setupInfiniteScroll()
|
||||||
},
|
},
|
||||||
|
|
||||||
setupEvents : function(){
|
postClass : app.views.StreamPost,
|
||||||
this.stream.bind("fetched", this.removeLoader, this)
|
|
||||||
this.stream.bind("allItemsLoaded", this.unbindInfScroll, this)
|
|
||||||
this.collection.bind("add", this.addPost, this);
|
|
||||||
|
|
||||||
app.currentUser.bind("nsfwChanged", reRenderPostViews, this)
|
|
||||||
function reRenderPostViews() {
|
|
||||||
_.map(this.postViews, function(view){ view.render() })
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
addPost : function(post) {
|
|
||||||
var postView = new app.views.StreamPost({ model: post })
|
|
||||||
, placeInStream = (this.collection.at(0).id == post.id) ? "prepend" : "append";
|
|
||||||
|
|
||||||
this.$el[placeInStream](postView.render().el);
|
|
||||||
this.postViews.push(postView)
|
|
||||||
},
|
|
||||||
|
|
||||||
unbindInfScroll : function() {
|
|
||||||
$(window).unbind("scroll");
|
|
||||||
},
|
|
||||||
|
|
||||||
render : function() {
|
|
||||||
if(this.stream.isFetching()) { this.appendLoader() }
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
fetchAndAppendLoader : function(){
|
|
||||||
if(this.stream.isFetching()) { return false }
|
|
||||||
this.stream.fetch()
|
|
||||||
this.appendLoader()
|
|
||||||
},
|
|
||||||
|
|
||||||
appendLoader: function(){
|
|
||||||
$("#paginate").html($("<img>", {
|
|
||||||
src : "/assets/static-loader.png",
|
|
||||||
"class" : "loader"
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
removeLoader: function() {
|
|
||||||
$("#paginate").empty();
|
|
||||||
},
|
|
||||||
|
|
||||||
setupLightbox : function(){
|
setupLightbox : function(){
|
||||||
this.lightbox = Diaspora.BaseWidget.instantiate("Lightbox");
|
this.lightbox = Diaspora.BaseWidget.instantiate("Lightbox");
|
||||||
this.$el.delegate("a.stream-photo-link", "click", this.lightbox.lightboxImageClicked);
|
this.$el.delegate("a.stream-photo-link", "click", this.lightbox.lightboxImageClicked);
|
||||||
},
|
},
|
||||||
|
|
||||||
setupInfiniteScroll : function() {
|
setupNSFW : function(){
|
||||||
var throttledScroll = _.throttle(_.bind(this.infScroll, this), 200);
|
app.currentUser.bind("nsfwChanged", reRenderPostViews, this)
|
||||||
$(window).scroll(throttledScroll);
|
|
||||||
},
|
|
||||||
|
|
||||||
infScroll : function() {
|
function reRenderPostViews() {
|
||||||
var $window = $(window)
|
_.map(this.postViews, function(view){ view.render() })
|
||||||
, distFromTop = $window.height() + $window.scrollTop()
|
|
||||||
, distFromBottom = $(document).height() - distFromTop
|
|
||||||
, bufferPx = 500;
|
|
||||||
|
|
||||||
if(distFromBottom < bufferPx) {
|
|
||||||
this.fetchAndAppendLoader()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}, app.views.infiniteScrollMixin));
|
||||||
|
|
|
||||||
|
|
@ -608,6 +608,8 @@ form.new_comment
|
||||||
img
|
img
|
||||||
:border none
|
:border none
|
||||||
|
|
||||||
|
:min-height 20px
|
||||||
|
|
||||||
#photo_container
|
#photo_container
|
||||||
:text
|
:text
|
||||||
:align center
|
:align center
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ require Rails.root.join("app", "presenters", "post_presenter")
|
||||||
class PostsController < ApplicationController
|
class PostsController < ApplicationController
|
||||||
include PostsHelper
|
include PostsHelper
|
||||||
|
|
||||||
before_filter :authenticate_user!, :except => [:show, :iframe]
|
before_filter :authenticate_user!, :except => [:show, :iframe, :oembed]
|
||||||
before_filter :set_format_if_malformed_from_status_net, :only => :show
|
before_filter :set_format_if_malformed_from_status_net, :only => :show
|
||||||
|
|
||||||
layout 'post'
|
layout 'post'
|
||||||
|
|
@ -24,13 +24,7 @@ class PostsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
key = params[:id].to_s.length <= 8 ? :id : :guid
|
@post = find_by_guid_or_id_with_current_user(params[:id])
|
||||||
|
|
||||||
if user_signed_in?
|
|
||||||
@post = current_user.find_visible_shareable_by_id(Post, params[:id], :key => key)
|
|
||||||
else
|
|
||||||
@post = Post.where(key => params[:id], :public => true).includes(:author, :comments => :author).first
|
|
||||||
end
|
|
||||||
|
|
||||||
if @post
|
if @post
|
||||||
# @commenting_disabled = can_not_comment_on_post?
|
# @commenting_disabled = can_not_comment_on_post?
|
||||||
|
|
@ -59,6 +53,17 @@ class PostsController < ApplicationController
|
||||||
render :text => post_iframe_url(params[:id]), :layout => false
|
render :text => post_iframe_url(params[:id]), :layout => false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def oembed
|
||||||
|
post_id = OEmbedPresenter.id_from_url(params.delete(:url))
|
||||||
|
post = find_by_guid_or_id_with_current_user(post_id)
|
||||||
|
if post.present?
|
||||||
|
oembed = OEmbedPresenter.new(post, params.slice(:format, :maxheight, :minheight))
|
||||||
|
render :json => oembed
|
||||||
|
else
|
||||||
|
render :nothing => true, :status => 404
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@post = current_user.posts.where(:id => params[:id]).first
|
@post = current_user.posts.where(:id => params[:id]).first
|
||||||
if @post
|
if @post
|
||||||
|
|
@ -76,6 +81,16 @@ class PostsController < ApplicationController
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def find_by_guid_or_id_with_current_user(id)
|
||||||
|
key = id.to_s.length <= 8 ? :id : :guid
|
||||||
|
if user_signed_in?
|
||||||
|
current_user.find_visible_shareable_by_id(Post, id, :key => key)
|
||||||
|
else
|
||||||
|
Post.where(key => id, :public => true).includes(:author, :comments => :author).first
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
def set_format_if_malformed_from_status_net
|
def set_format_if_malformed_from_status_net
|
||||||
request.format = :html if request.format == 'application/html+xml'
|
request.format = :html if request.format == 'application/html+xml'
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ module PostsHelper
|
||||||
def post_iframe_url(post_id, opts={})
|
def post_iframe_url(post_id, opts={})
|
||||||
opts[:width] ||= 516
|
opts[:width] ||= 516
|
||||||
opts[:height] ||= 315
|
opts[:height] ||= 315
|
||||||
"<iframe src='#{post_url(post_id)}' width='#{opts[:width]}px' height='#{opts[:height]}px' frameBorder='0'></iframe>".html_safe
|
host = AppConfig[:pod_uri].port ==80 ? AppConfig[:pod_uri].host : "#{AppConfig[:pod_uri].host}:#{AppConfig[:pod_uri].port}"
|
||||||
|
"<iframe src='#{Rails.application.routes.url_helpers.post_url(post_id, :host => host)}' width='#{opts[:width]}px' height='#{opts[:height]}px' frameBorder='0'></iframe>".html_safe
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
49
app/presenters/o_embed_presenter.rb
Normal file
49
app/presenters/o_embed_presenter.rb
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
require 'uri'
|
||||||
|
class OEmbedPresenter
|
||||||
|
include PostsHelper
|
||||||
|
include ActionView::Helpers::TextHelper
|
||||||
|
|
||||||
|
def initialize(post, opts = {})
|
||||||
|
@post = post
|
||||||
|
@opts = opts
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_json(opts={})
|
||||||
|
as_json(opts).to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
def as_json(opts={})
|
||||||
|
{
|
||||||
|
:provider_name => "Diaspora",
|
||||||
|
:provider_url => AppConfig[:pod_url],
|
||||||
|
:type => 'rich',
|
||||||
|
:version => '1.0',
|
||||||
|
:title => post_title,
|
||||||
|
:author_name => post_author,
|
||||||
|
:author_url => post_author_url,
|
||||||
|
:width => @opts.fetch(:maxwidth, 516),
|
||||||
|
:height => @opts.fetch(:maxheight, 320),
|
||||||
|
:html => iframe_html
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.id_from_url(url)
|
||||||
|
URI.parse(url).path.gsub(%r{\/posts\/|\/p\/}, '')
|
||||||
|
end
|
||||||
|
|
||||||
|
def post_title
|
||||||
|
post_page_title(@post)
|
||||||
|
end
|
||||||
|
|
||||||
|
def post_author
|
||||||
|
@post.author.name
|
||||||
|
end
|
||||||
|
|
||||||
|
def post_author_url
|
||||||
|
Rails.application.routes.url_helpers.person_url(@post.author, :host => AppConfig[:pod_uri].host)
|
||||||
|
end
|
||||||
|
|
||||||
|
def iframe_html
|
||||||
|
post_iframe_url(@post.id, :height => @opts[:maxheight], :width => @opts[:maxwidth])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#main_stream.stream
|
#main_stream.stream
|
||||||
|
|
||||||
#paginate
|
#paginate
|
||||||
|
= image_tag "static-loader.png", :height => 14, :width => 14, :class => "loader hidden"
|
||||||
|
|
||||||
- if current_user.contacts.size < 2
|
- if current_user.contacts.size < 2
|
||||||
= render 'aspects/no_contacts_message'
|
= render 'aspects/no_contacts_message'
|
||||||
|
|
@ -44,6 +44,8 @@
|
||||||
= set_asset_host
|
= set_asset_host
|
||||||
= translation_missing_warnings
|
= translation_missing_warnings
|
||||||
= current_user_atom_tag
|
= current_user_atom_tag
|
||||||
|
- if @post.present?
|
||||||
|
%link{:rel => 'alternate', :type => "application/json+oembed", :href => "#{oembed_url(:url => post_url(@post))}"}
|
||||||
|
|
||||||
= yield(:head)
|
= yield(:head)
|
||||||
= csrf_meta_tag
|
= csrf_meta_tag
|
||||||
|
|
|
||||||
|
|
@ -34,3 +34,4 @@
|
||||||
= t('.ignoring', :name => @person.first_name)
|
= t('.ignoring', :name => @person.first_name)
|
||||||
|
|
||||||
#paginate
|
#paginate
|
||||||
|
= image_tag "static-loader.png", :height => 14, :width => 14, :class => "loader hidden"
|
||||||
|
|
|
||||||
|
|
@ -47,4 +47,6 @@ Diaspora::Application.configure do
|
||||||
# This is necessary if your schema can't be completely dumped by the schema dumper,
|
# This is necessary if your schema can't be completely dumped by the schema dumper,
|
||||||
# like if you have constraints or database-specific column types
|
# like if you have constraints or database-specific column types
|
||||||
# config.active_record.schema_format = :sql
|
# config.active_record.schema_format = :sql
|
||||||
|
|
||||||
|
config.default_url_options = { :host => AppConfig[:pod_uri].host}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
16
config/initializers/silence_assets.rb
Normal file
16
config/initializers/silence_assets.rb
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
if Rails.env.development?
|
||||||
|
|
||||||
|
Rails.application.assets.logger = Logger.new('/dev/null')
|
||||||
|
|
||||||
|
Rails::Rack::Logger.class_eval do
|
||||||
|
def call_with_quiet_assets(env)
|
||||||
|
previous_level = Rails.logger.level
|
||||||
|
Rails.logger.level = Logger::ERROR if env['PATH_INFO'] =~ %r{^/assets/}
|
||||||
|
call_without_quiet_assets(env)
|
||||||
|
ensure
|
||||||
|
Rails.logger.level = previous_level
|
||||||
|
end
|
||||||
|
alias_method_chain :call, :quiet_assets
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
Diaspora::Application.routes.draw do
|
Diaspora::Application.routes.draw do
|
||||||
mount RailsAdmin::Engine => '/admin_panel', :as => 'rails_admin'
|
mount RailsAdmin::Engine => '/admin_panel', :as => 'rails_admin'
|
||||||
|
|
||||||
|
get 'oembed' => 'posts#oembed', :as => 'oembed'
|
||||||
# Posting and Reading
|
# Posting and Reading
|
||||||
resources :reshares
|
resources :reshares
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,19 @@ describe PostsController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'oembed' do
|
||||||
|
it 'works when you can see it' do
|
||||||
|
sign_in alice
|
||||||
|
get :oembed, :url => "/posts/#{@message.id}"
|
||||||
|
response.body.should match /iframe/
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns a 404 response when the post is not found' do
|
||||||
|
get :oembed, :url => "/posts/#{@message.id}"
|
||||||
|
response.should_not be_success
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#destroy' do
|
describe '#destroy' do
|
||||||
before do
|
before do
|
||||||
sign_in alice
|
sign_in alice
|
||||||
|
|
|
||||||
|
|
@ -2,27 +2,31 @@ describe("app.views.Photos", function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
loginAs({name: "alice", avatar : {small : "http://avatar.com/photo.jpg"}});
|
loginAs({name: "alice", avatar : {small : "http://avatar.com/photo.jpg"}});
|
||||||
|
|
||||||
this._photos = $.parseJSON(spec.readFixture("photos_json"))["photos"];
|
this.photos = $.parseJSON(spec.readFixture("photos_json"))["photos"];
|
||||||
|
|
||||||
this.photos = new app.models.Stream([], {collection: app.collections.Photos});
|
this.stream = new app.models.Stream([], {collection: app.collections.Photos});
|
||||||
this.photos.add(this._photos);
|
this.stream.add(this.photos);
|
||||||
|
|
||||||
this.view = new app.views.Photos({model : this.photos});
|
this.view = new app.views.Photos({model : this.stream});
|
||||||
|
|
||||||
// do this manually because we've moved loadMore into render??
|
// do this manually because we've moved loadMore into render??
|
||||||
this.view.render();
|
this.view.render();
|
||||||
_.each(this.view.collection.models, function(photo) {
|
_.each(this.view.collection.models, function(photo) {
|
||||||
this.view.addPhoto(photo);
|
this.view.addPost(photo);
|
||||||
}, this);
|
}, this);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("initialize", function() {
|
describe("initialize", function() {
|
||||||
// nothing there yet
|
it("binds an infinite scroll listener", function() {
|
||||||
|
spyOn($.fn, "scroll");
|
||||||
|
new app.views.Stream({model : this.stream});
|
||||||
|
expect($.fn.scroll).toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("#render", function() {
|
describe("#render", function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
this.photo = this.photos.items.models[0];
|
this.photo = this.stream.items.models[0];
|
||||||
this.photoElement = $(this.view.$("#" + this.photo.get("guid")));
|
this.photoElement = $(this.view.$("#" + this.photo.get("guid")));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -32,14 +36,4 @@ describe("app.views.Photos", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("removeLoader", function() {
|
|
||||||
it("emptys the pagination div when the stream is fetched", function() {
|
|
||||||
$("#jasmine_content").append($('<div id="paginate">OMG</div>'));
|
|
||||||
expect($("#paginate").text()).toBe("OMG");
|
|
||||||
this.view.photos.trigger("fetched");
|
|
||||||
expect($("#paginate")).toBeEmpty();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -43,19 +43,17 @@ describe("app.views.Stream", function() {
|
||||||
it("fetches moar when the user is at the bottom of the page", function() {
|
it("fetches moar when the user is at the bottom of the page", function() {
|
||||||
spyOn($.fn, "height").andReturn(0);
|
spyOn($.fn, "height").andReturn(0);
|
||||||
spyOn($.fn, "scrollTop").andReturn(100);
|
spyOn($.fn, "scrollTop").andReturn(100);
|
||||||
spyOn(this.view, "fetchAndAppendLoader");
|
spyOn(this.view.model, "fetch");
|
||||||
|
|
||||||
this.view.infScroll();
|
this.view.infScroll();
|
||||||
expect(this.view.fetchAndAppendLoader).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("removeLoader", function() {
|
waitsFor(function(){
|
||||||
it("emptys the pagination div when the stream is fetched", function() {
|
return this.view.model.fetch.wasCalled
|
||||||
$("#jasmine_content").append($('<div id="paginate">OMG</div>'));
|
}, "the infinite scroll function didn't fetch the stream")
|
||||||
expect($("#paginate").text()).toBe("OMG");
|
|
||||||
this.view.stream.trigger("fetched");
|
runs(function(){
|
||||||
expect($("#paginate")).toBeEmpty();
|
expect(this.view.model.fetch).toHaveBeenCalled()
|
||||||
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
35
spec/presenters/o_embed_presenter_spec.rb
Normal file
35
spec/presenters/o_embed_presenter_spec.rb
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
describe OEmbedPresenter do
|
||||||
|
before do
|
||||||
|
@oembed = OEmbedPresenter.new(Factory(:status_message))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is a hash' do
|
||||||
|
@oembed.as_json.should be_a Hash
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'required options from oembed spec' do
|
||||||
|
it 'supports maxheight + maxwidth(required)' do
|
||||||
|
oembed = OEmbedPresenter.new(Factory(:status_message), :maxwidth => 200, :maxheight => 300).as_json
|
||||||
|
oembed[:width].should == 200
|
||||||
|
oembed[:height].should == 300
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#iframe_html' do
|
||||||
|
it 'passes the height options to post_iframe_url' do
|
||||||
|
@oembed.should_receive(:post_iframe_url).with(instance_of(Fixnum), instance_of(Hash))
|
||||||
|
@oembed.iframe_html
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.id_from_url' do
|
||||||
|
it 'takes a long post url and gives you the id' do
|
||||||
|
OEmbedPresenter.id_from_url('http://localhost:400/posts/1').should == "1"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'takes a short post url and gives you the id' do
|
||||||
|
OEmbedPresenter.id_from_url('http://localhost:400/p/1').should == "1"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -200,9 +200,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function onInputBoxKeyPress(e) {
|
function onInputBoxKeyPress(e) {
|
||||||
|
if(e.keyCode != KEY.BACKSPACE) {
|
||||||
var typedValue = String.fromCharCode(e.which || e.keyCode);
|
var typedValue = String.fromCharCode(e.which || e.keyCode);
|
||||||
inputBuffer.push(typedValue);
|
inputBuffer.push(typedValue);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function onInputBoxKeyDown(e) {
|
function onInputBoxKeyDown(e) {
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue