Merge branch 'master' of github.com:diaspora/diaspora into rails_rc
This commit is contained in:
commit
2b165df85c
12 changed files with 1144 additions and 273 deletions
|
|
@ -9,8 +9,30 @@ class PhotosController < ApplicationController
|
||||||
album = Album.find_by_id params[:album_id]
|
album = Album.find_by_id params[:album_id]
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
|
######################## dealing with local files #############
|
||||||
|
# get file name
|
||||||
|
file_name = params[:qqfile]
|
||||||
|
# get file content type
|
||||||
|
att_content_type = (request.content_type.to_s == "") ? "application/octet-stream" : request.content_type.to_s
|
||||||
|
# create temporal file
|
||||||
|
file = Tempfile.new(file_name)
|
||||||
|
# put data into this file from raw post request
|
||||||
|
file.print request.raw_post
|
||||||
|
|
||||||
|
# create several required methods for this temporal file
|
||||||
|
Tempfile.send(:define_method, "content_type") {return att_content_type}
|
||||||
|
Tempfile.send(:define_method, "original_filename") {return file_name}
|
||||||
|
|
||||||
|
##############
|
||||||
|
|
||||||
|
|
||||||
|
params[:user_file] = file
|
||||||
@photo = current_user.post(:photo, params)
|
@photo = current_user.post(:photo, params)
|
||||||
respond_with @photo
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.json{render(:layout => false , :json => {"success" => true, "data" => @photo}.to_json )}
|
||||||
|
end
|
||||||
|
|
||||||
rescue TypeError
|
rescue TypeError
|
||||||
message = "Photo upload failed. Are you sure an image was added?"
|
message = "Photo upload failed. Are you sure an image was added?"
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ class Photo < Post
|
||||||
before_destroy :ensure_user_picture
|
before_destroy :ensure_user_picture
|
||||||
|
|
||||||
def self.instantiate(params = {})
|
def self.instantiate(params = {})
|
||||||
image_file = params[:user_file].first
|
image_file = params[:user_file]
|
||||||
params.delete :user_file
|
params.delete :user_file
|
||||||
|
|
||||||
photo = Photo.new(params)
|
photo = Photo.new(params)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
- content_for :head do
|
:javascript
|
||||||
= javascript_include_tag 'photos', 'jquery.html5_upload'
|
$(document).ready(function(){
|
||||||
|
$(".image_thumb img").load( function() {
|
||||||
|
$(this).fadeIn("slow");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
.album_id{:id => @album.id, :style => "display:hidden;"}
|
.album_id{:id => @album.id, :style => "display:hidden;"}
|
||||||
.back= link_to '⇧ albums', albums_path
|
.back= link_to '⇧ albums', albums_path
|
||||||
|
|
@ -13,6 +18,8 @@
|
||||||
= image_tag 'ajax-loader.gif'
|
= image_tag 'ajax-loader.gif'
|
||||||
= link_to 'Add Photos', '#new_photo_pane', :class => 'button', :id => "add_photo_button"
|
= link_to 'Add Photos', '#new_photo_pane', :class => 'button', :id => "add_photo_button"
|
||||||
|
|
||||||
|
=render 'photos/new_photo'
|
||||||
|
|
||||||
.yo{:style => "display:none;"}
|
.yo{:style => "display:none;"}
|
||||||
#new_photo_pane
|
#new_photo_pane
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,14 @@
|
||||||
= stylesheet_link_tag "application", "ui", 'bubble'
|
= stylesheet_link_tag "application", "ui", 'bubble'
|
||||||
|
|
||||||
= stylesheet_link_tag "/../javascripts/fancybox/jquery.fancybox-1.3.1"
|
= stylesheet_link_tag "/../javascripts/fancybox/jquery.fancybox-1.3.1"
|
||||||
|
= stylesheet_link_tag "fileuploader"
|
||||||
|
|
||||||
/= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"
|
/= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"
|
||||||
= javascript_include_tag 'jquery-1.4.2.min', 'rails', 'google'
|
= javascript_include_tag 'jquery-1.4.2.min', 'rails', 'google'
|
||||||
= javascript_include_tag 'jquery.infieldlabel', 'jquery.cycle/jquery.cycle.min.js'
|
= javascript_include_tag 'jquery.infieldlabel', 'jquery.cycle/jquery.cycle.min.js'
|
||||||
|
|
||||||
= javascript_include_tag 'fancybox/jquery.fancybox-1.3.1.pack'
|
= javascript_include_tag 'fancybox/jquery.fancybox-1.3.1.pack'
|
||||||
|
= javascript_include_tag 'fileuploader'
|
||||||
|
|
||||||
= javascript_include_tag 'view', 'image_picker', 'group_nav', 'stream'
|
= javascript_include_tag 'view', 'image_picker', 'group_nav', 'stream'
|
||||||
= render 'js/websocket_js'
|
= render 'js/websocket_js'
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,12 @@
|
||||||
:javascript
|
:javascript
|
||||||
$(function() {
|
function createUploader(){
|
||||||
$("#photo_image").html5_upload({
|
var uploader = new qq.FileUploader({
|
||||||
// WE INSERT ALBUM_ID PARAM HERE
|
element: document.getElementById('file-upload'),
|
||||||
url: "/photos?album_id=#{@album.id}",
|
params: {'album_id' : "#{@album.id}"},
|
||||||
sendBoundary: window.FormData || $.browser.mozilla,
|
allowedExtensions: ['jpg', 'jpeg', 'png'],
|
||||||
onStart: function(event, total) {
|
action: "/photos"
|
||||||
return confirm("You are about to upload " + total + " photos. Are you sure?");
|
});
|
||||||
},
|
|
||||||
onFinish: function(event, total){
|
|
||||||
$("#add_photo_button .button").html( "Add Photos" );
|
|
||||||
$("#add_photo_loader").fadeOut(400);
|
|
||||||
},
|
|
||||||
onStart: function(event, total){
|
|
||||||
$("#add_photo_pane").fadeOut(400);
|
|
||||||
$("#add_photo_button .button").html( "Uploading Photos" );
|
|
||||||
$("#add_photo_loader").fadeIn(400);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
});
|
window.onload = createUploader;
|
||||||
});
|
|
||||||
|
|
||||||
%h1
|
#file-upload
|
||||||
%span{:id=>"photo_title_status"}
|
|
||||||
Add photos to
|
|
||||||
%i= @album.name
|
|
||||||
= form_for @photo, :html => {:multipart => true} do |f|
|
|
||||||
= f.error_messages
|
|
||||||
= f.hidden_field :album_id, :value => @album.id
|
|
||||||
= f.file_field :image, :multiple => 'multiple'
|
|
||||||
|
|
||||||
#progress_report{ :style => "display:none;text-align:center;" }
|
|
||||||
= image_tag "ajax-loader.gif"
|
|
||||||
#progress_report_name
|
|
||||||
#progress_report_status
|
|
||||||
|
|
|
||||||
1067
public/javascripts/fileuploader.js
Executable file
1067
public/javascripts/fileuploader.js
Executable file
File diff suppressed because it is too large
Load diff
|
|
@ -1,210 +0,0 @@
|
||||||
(function($) {
|
|
||||||
jQuery.fn.html5_upload = function(options) {
|
|
||||||
|
|
||||||
var available_events = ['onStart', 'onStartOne', 'onProgress', 'onFinishOne', 'onFinish', 'onError'];
|
|
||||||
var options = jQuery.extend({
|
|
||||||
onStart: function(event, total) {
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
onStartOne: function(event, name, number, total) {
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
onProgress: function(event, progress, name, number, total) {
|
|
||||||
},
|
|
||||||
onFinishOne: function(event, response, name, number, total) {
|
|
||||||
},
|
|
||||||
onFinish: function(event, total) {
|
|
||||||
},
|
|
||||||
onError: function(event, name, error) {
|
|
||||||
},
|
|
||||||
onBrowserIncompatible: function() {
|
|
||||||
alert("Sorry, but your browser is incompatible with uploading files using HTML5 (at least, with current preferences.\n Please install the latest version of Firefox, Safari or Chrome");
|
|
||||||
},
|
|
||||||
autostart: true,
|
|
||||||
autoclear: true,
|
|
||||||
stopOnFirstError: false,
|
|
||||||
sendBoundary: false,
|
|
||||||
fieldName: 'user_file[]',//ignore if sendBoundary is false
|
|
||||||
|
|
||||||
STATUSES: {
|
|
||||||
'STARTED': 'Started',
|
|
||||||
'PROGRESS': 'Uploading',
|
|
||||||
'LOADED': 'Processing',
|
|
||||||
'FINISHED': 'Finished!'
|
|
||||||
},
|
|
||||||
|
|
||||||
setName: function(text) {},
|
|
||||||
setStatus: function(text) {},
|
|
||||||
setProgress: function(value) {},
|
|
||||||
|
|
||||||
genName: function(file, number, total) {
|
|
||||||
return file + "(" + (number+1) + " of " + total + ")";
|
|
||||||
},
|
|
||||||
genStatus: function(progress, finished) {
|
|
||||||
if (finished) {
|
|
||||||
return options.STATUSES['FINISHED'];
|
|
||||||
}
|
|
||||||
if (progress == 0) {
|
|
||||||
return options.STATUSES['STARTED'];
|
|
||||||
}
|
|
||||||
else if (progress == 1) {
|
|
||||||
return options.STATUSES['LOADED'];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return options.STATUSES['PROGRESS'];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
genProgress: function(loaded, total) {
|
|
||||||
return loaded / total;
|
|
||||||
}
|
|
||||||
}, options);
|
|
||||||
|
|
||||||
function upload() {
|
|
||||||
var files = this.files;
|
|
||||||
var total = files.length;
|
|
||||||
var $this = $(this);
|
|
||||||
if (!$this.triggerHandler('html5_upload.onStart', [total])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
this.disabled = true;
|
|
||||||
var uploaded = 0;
|
|
||||||
var xhr = this.html5_upload['xhr'];
|
|
||||||
this.html5_upload['continue_after_abort'] = true;
|
|
||||||
function upload_file(number) {
|
|
||||||
if (number == total) {
|
|
||||||
$this.trigger('html5_upload.onFinish', [total]);
|
|
||||||
options.setStatus(options.genStatus(1, true));
|
|
||||||
$this.attr("disabled", false);
|
|
||||||
if (options.autoclear) {
|
|
||||||
$this.val("");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var file = files[number];
|
|
||||||
if (!$this.triggerHandler('html5_upload.onStartOne', [file.fileName, number, total])) {
|
|
||||||
return upload_file(number+1);
|
|
||||||
}
|
|
||||||
options.setStatus(options.genStatus(0));
|
|
||||||
options.setName(options.genName(file.fileName, number, total));
|
|
||||||
options.setProgress(options.genProgress(0, file.fileSize));
|
|
||||||
xhr.upload['onprogress'] = function(rpe) {
|
|
||||||
$this.trigger('html5_upload.onProgress', [rpe.loaded / rpe.total, file.fileName, number, total]);
|
|
||||||
options.setStatus(options.genStatus(rpe.loaded / rpe.total));
|
|
||||||
options.setProgress(options.genProgress(rpe.loaded, rpe.total));
|
|
||||||
};
|
|
||||||
xhr.onload = function(load) {
|
|
||||||
$this.trigger('html5_upload.onFinishOne', [xhr.responseText, file.fileName, number, total]);
|
|
||||||
options.setStatus(options.genStatus(1, true));
|
|
||||||
options.setProgress(options.genProgress(file.fileSize, file.fileSize));
|
|
||||||
upload_file(number+1);
|
|
||||||
};
|
|
||||||
xhr.onabort = function() {
|
|
||||||
if ($this[0].html5_upload['continue_after_abort']) {
|
|
||||||
upload_file(number+1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this.attr("disabled", false);
|
|
||||||
if (options.autoclear) {
|
|
||||||
$this.val("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xhr.onerror = function(e) {
|
|
||||||
$this.trigger('html5_upload.onError', [file.fileName, e]);
|
|
||||||
if (!options.stopOnFirstError) {
|
|
||||||
upload_file(number+1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xhr.open("post", typeof(options.url) == "function" ? options.url() : options.url, true);
|
|
||||||
xhr.setRequestHeader("Cache-Control", "no-cache");
|
|
||||||
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
|
||||||
xhr.setRequestHeader("X-File-Name", file.fileName);
|
|
||||||
xhr.setRequestHeader("X-File-Size", file.fileSize);
|
|
||||||
|
|
||||||
if (!options.sendBoundary) {
|
|
||||||
xhr.setRequestHeader("Content-Type", "multipart/form-data");
|
|
||||||
xhr.send(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window.FormData) {//Many thanks to scottt.tw
|
|
||||||
var f = new FormData();
|
|
||||||
f.append(typeof(options.fieldName) == "function" ? options.fieldName() : options.fieldName, file);
|
|
||||||
xhr.send(f);
|
|
||||||
}
|
|
||||||
else if (file.getAsBinary) {//Thanks to jm.schelcher
|
|
||||||
var boundary = '------multipartformboundary' + (new Date).getTime();
|
|
||||||
var dashdash = '--';
|
|
||||||
var crlf = '\r\n';
|
|
||||||
|
|
||||||
/* Build RFC2388 string. */
|
|
||||||
var builder = '';
|
|
||||||
|
|
||||||
builder += dashdash;
|
|
||||||
builder += boundary;
|
|
||||||
builder += crlf;
|
|
||||||
|
|
||||||
builder += 'Content-Disposition: form-data; name="'+(typeof(options.fieldName) == "function" ? options.fieldName() : options.fieldName)+'"';
|
|
||||||
builder += '; filename="' + file.fileName + '"';
|
|
||||||
builder += crlf;
|
|
||||||
|
|
||||||
builder += 'Content-Type: application/octet-stream';
|
|
||||||
builder += crlf;
|
|
||||||
builder += crlf;
|
|
||||||
|
|
||||||
/* Append binary data. */
|
|
||||||
builder += file.getAsBinary();
|
|
||||||
builder += crlf;
|
|
||||||
|
|
||||||
/* Write boundary. */
|
|
||||||
builder += dashdash;
|
|
||||||
builder += boundary;
|
|
||||||
builder += crlf;
|
|
||||||
|
|
||||||
builder += dashdash;
|
|
||||||
builder += boundary;
|
|
||||||
builder += dashdash;
|
|
||||||
builder += crlf;
|
|
||||||
|
|
||||||
xhr.setRequestHeader('content-type', 'multipart/form-data; boundary=' + boundary);
|
|
||||||
xhr.sendAsBinary(builder);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
options.onBrowserIncompatible();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
upload_file(0);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.each(function() {
|
|
||||||
this.html5_upload = {
|
|
||||||
xhr: new XMLHttpRequest(),
|
|
||||||
continue_after_abort: true
|
|
||||||
};
|
|
||||||
if (options.autostart) {
|
|
||||||
$(this).bind('change', upload);
|
|
||||||
}
|
|
||||||
for (event in available_events) {
|
|
||||||
if (options[available_events[event]]) {
|
|
||||||
$(this).bind("html5_upload."+available_events[event], options[available_events[event]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$(this)
|
|
||||||
.bind('html5_upload.start', upload)
|
|
||||||
.bind('html5_upload.cancelOne', function() {
|
|
||||||
this.html5_upload['xhr'].abort();
|
|
||||||
})
|
|
||||||
.bind('html5_upload.cancelAll', function() {
|
|
||||||
this.html5_upload['continue_after_abort'] = false;
|
|
||||||
this.html5_upload['xhr'].abort();
|
|
||||||
})
|
|
||||||
.bind('html5_upload.destroy', function() {
|
|
||||||
this.html5_upload['continue_after_abort'] = false;
|
|
||||||
this.xhr.abort();
|
|
||||||
delete this.html5_upload;
|
|
||||||
$(this).unbind('html5_upload.*').unbind('change', upload);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
})(jQuery);
|
|
||||||
|
|
||||||
|
|
@ -1,25 +1 @@
|
||||||
$(document).ready(function(){
|
|
||||||
reset_photo_fancybox();
|
|
||||||
|
|
||||||
$("#add_photo_button").fancybox({
|
|
||||||
'onClosed' : function(){
|
|
||||||
if($("#add_photo_button").hasClass("uploading_complete")){
|
|
||||||
$("#add_photo_button").removeClass("uploading_complete");
|
|
||||||
reset_photo_fancybox();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(".image_thumb img").load( function() {
|
|
||||||
$(this).fadeIn("slow");
|
|
||||||
});
|
|
||||||
|
|
||||||
});//end document ready
|
|
||||||
|
|
||||||
function reset_photo_fancybox(){
|
|
||||||
album_id = $(".album_id")[0].id;
|
|
||||||
ajax = $.get("/photos/new?album_id=" + album_id, function(){
|
|
||||||
$("#new_photo_pane").html(ajax.responseText)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -412,8 +412,6 @@ h1.big_text {
|
||||||
float: right; }
|
float: right; }
|
||||||
|
|
||||||
.back {
|
.back {
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: normal; }
|
font-weight: normal; }
|
||||||
|
|
||||||
|
|
|
||||||
31
public/stylesheets/fileuploader.css
Executable file
31
public/stylesheets/fileuploader.css
Executable file
|
|
@ -0,0 +1,31 @@
|
||||||
|
.qq-uploader { position:relative; width: 100%;}
|
||||||
|
|
||||||
|
.qq-upload-button {
|
||||||
|
display:block; /* or inline-block */
|
||||||
|
width: 105px; padding: 7px 0; text-align:center;
|
||||||
|
background:#880000; border-bottom:1px solid #ddd;color:#fff;
|
||||||
|
}
|
||||||
|
.qq-upload-button-hover {background:#cc0000;}
|
||||||
|
.qq-upload-button-focus {outline:1px dotted black;}
|
||||||
|
|
||||||
|
.qq-upload-drop-area {
|
||||||
|
position:absolute; top:0; left:0; width:100%; height:100%; min-height: 70px; z-index:2;
|
||||||
|
background:#FF9797; text-align:center;
|
||||||
|
}
|
||||||
|
.qq-upload-drop-area span {
|
||||||
|
display:block; position:absolute; top: 50%; width:100%; margin-top:-8px; font-size:16px;
|
||||||
|
}
|
||||||
|
.qq-upload-drop-area-active {background:#FF7171;}
|
||||||
|
|
||||||
|
.qq-upload-list {margin:15px 35px; padding:0; list-style:disc;}
|
||||||
|
.qq-upload-list li { margin:0; padding:0; line-height:15px; font-size:12px;}
|
||||||
|
.qq-upload-file, .qq-upload-spinner, .qq-upload-size, .qq-upload-cancel, .qq-upload-failed-text {
|
||||||
|
margin-right: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qq-upload-file {}
|
||||||
|
.qq-upload-spinner {display:inline-block; background: url("loading.gif"); width:15px; height:15px; vertical-align:text-bottom;}
|
||||||
|
.qq-upload-size,.qq-upload-cancel {font-size:11px;}
|
||||||
|
|
||||||
|
.qq-upload-failed-text {display:none;}
|
||||||
|
.qq-upload-fail .qq-upload-failed-text {display:inline;}
|
||||||
BIN
public/stylesheets/loading.gif
Executable file
BIN
public/stylesheets/loading.gif
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
|
|
@ -561,6 +561,7 @@ h1.big_text
|
||||||
img
|
img
|
||||||
:display none
|
:display none
|
||||||
|
|
||||||
|
|
||||||
.image_cycle
|
.image_cycle
|
||||||
img
|
img
|
||||||
:display none
|
:display none
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue