Add the ability to upload photos from the mobile site
This commit is contained in:
parent
19b9b0edb8
commit
76b1e9b0dc
12 changed files with 338 additions and 9 deletions
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
* Deleting a post that was shared to Facebook now deletes it from Facebook too [#3980]( https://github.com/diaspora/diaspora/pull/3980)
|
||||
* Include reshares in a users public atom feed [#1781](https://github.com/diaspora/diaspora/issues/1781)
|
||||
* Add the ability to upload photos from the mobile site. [#4004](https://github.com/diaspora/diaspora/issues/4004)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
//= require mbp-respond.min
|
||||
//= require mbp-helper
|
||||
//= require jquery.autoSuggest.custom
|
||||
//= require fileuploader-custom
|
||||
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
|
|
@ -273,3 +273,85 @@ $(document).ready(function(){
|
|||
});
|
||||
|
||||
});
|
||||
|
||||
function createUploader(){
|
||||
|
||||
var aspectIds = gon.aspect_ids;
|
||||
|
||||
var uploader = new qq.FileUploaderBasic({
|
||||
element: document.getElementById('file-upload-publisher'),
|
||||
params: {'photo' : {'pending' : 'true', 'aspect_ids' : aspectIds},},
|
||||
allowedExtensions: ['jpg', 'jpeg', 'png', 'gif', 'tiff'],
|
||||
action: "/photos",
|
||||
debug: true,
|
||||
button: document.getElementById('file-upload-publisher'),
|
||||
sizeLimit: 4194304,
|
||||
|
||||
onProgress: function(id, fileName, loaded, total){
|
||||
var progress = Math.round(loaded / total * 100 );
|
||||
$('#fileInfo-publisher').text(fileName + ' ' + progress + '%');
|
||||
},
|
||||
|
||||
messages: {
|
||||
typeError: Diaspora.I18n.t("photo_uploader.invalid_ext"),
|
||||
sizeError: Diaspora.I18n.t("photos.new_photo.size_error"),
|
||||
emptyError: Diaspora.I18n.t("photos.new_photo.empty")
|
||||
},
|
||||
|
||||
onSubmit: function(id, fileName){
|
||||
$('#file-upload-publisher').addClass("loading");
|
||||
$('#publisher_textarea_wrapper').addClass("with_attachments");
|
||||
$('#photodropzone').append(
|
||||
"<li class='publisher_photo loading' style='position:relative;'>" +
|
||||
"<img alt=\"Ajax-loader2\" src=\"/assets/ajax-loader2.gif\" />" +
|
||||
"</li>"
|
||||
);
|
||||
},
|
||||
|
||||
onComplete: function(id, fileName, responseJSON) {
|
||||
$('#fileInfo-publisher').text(fileName + ' completed');
|
||||
var id = responseJSON.data.photo.id,
|
||||
url = responseJSON.data.photo.unprocessed_image.url,
|
||||
currentPlaceholder = $('li.loading').first();
|
||||
|
||||
$('#publisher_textarea_wrapper').addClass("with_attachments");
|
||||
$('#new_status_message').append("<input type='hidden' value='" + id + "' name='photos[]' />");
|
||||
|
||||
// replace image placeholders
|
||||
var img = currentPlaceholder.find('img');
|
||||
img.attr('src', url);
|
||||
img.attr('data-id', id);
|
||||
currentPlaceholder.removeClass('loading');
|
||||
currentPlaceholder.append("<div class='x'>X</div>" +
|
||||
"<div class='circle'></div>");
|
||||
////
|
||||
|
||||
var publisher = $('#publisher'),
|
||||
textarea = publisher.find('textarea');
|
||||
|
||||
publisher.find("input[type='submit']").removeAttr('disabled');
|
||||
|
||||
$('.x').bind('click', function(){
|
||||
var photo = $(this).closest('.publisher_photo');
|
||||
photo.addClass("dim");
|
||||
$.ajax({url: "/photos/" + photo.children('img').attr('data-id'),
|
||||
dataType: 'json',
|
||||
type: 'DELETE',
|
||||
success: function() {
|
||||
photo.fadeOut(400, function(){
|
||||
photo.remove();
|
||||
if ( $('.publisher_photo').length == 0){
|
||||
$('#publisher_textarea_wrapper').removeClass("with_attachments");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
onAllComplete: function(completed_files){
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
createUploader();
|
||||
|
|
|
|||
|
|
@ -553,7 +553,7 @@ footer {
|
|||
left: 0;
|
||||
border: none;
|
||||
margin: 10px 0;
|
||||
font-size: larger;
|
||||
font-size: 14px;
|
||||
padding: 0;
|
||||
min-width: 100%;
|
||||
}
|
||||
|
|
@ -1008,7 +1008,11 @@ form#update_profile_form {
|
|||
}
|
||||
|
||||
select#user_language, #user_auto_follow_back_aspect_id, #aspect_ids_ {
|
||||
padding: 3px;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
select#aspect_ids_ {
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
#file-upload-spinner {
|
||||
|
|
@ -1033,4 +1037,137 @@ select#user_language, #user_auto_follow_back_aspect_id, #aspect_ids_ {
|
|||
|
||||
input#q.search {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
#file-upload-publisher {
|
||||
bottom: 10px !important;
|
||||
display: inline-block;
|
||||
padding: 3px 12px;
|
||||
position: absolute !important;
|
||||
left: 20px;
|
||||
cursor: pointer;
|
||||
img {
|
||||
@include opacity(1);
|
||||
vertical-align: bottom;
|
||||
}
|
||||
&:hover {
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
|
||||
img {
|
||||
@include opacity(0.4);
|
||||
}
|
||||
}
|
||||
&:active {
|
||||
color: #444;
|
||||
text-shadow: 0 1px 0 #fafafa;
|
||||
|
||||
img {
|
||||
@include opacity(1);
|
||||
}
|
||||
}
|
||||
&.loading {
|
||||
@include opacity(1);
|
||||
}
|
||||
}
|
||||
|
||||
#publisher_textarea_wrapper {
|
||||
#hide_publisher {
|
||||
@include opacity(0.3);
|
||||
z-index: 5;
|
||||
padding: 3px;
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
top: 0;
|
||||
|
||||
&:hover {
|
||||
@include opacity(1);
|
||||
}
|
||||
}
|
||||
|
||||
@include border-radius(2px);
|
||||
|
||||
background: #fff;
|
||||
|
||||
&.active {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
position: relative;
|
||||
padding-right: 10px;
|
||||
|
||||
textarea {
|
||||
z-index: 2;
|
||||
border: none;
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
&.with_attachments {
|
||||
padding-bottom: 55px;
|
||||
border: 1px solid #CCCCCC;
|
||||
}
|
||||
|
||||
#photodropzone {
|
||||
z-index: 3;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: 0;
|
||||
margin: 0 !important;
|
||||
|
||||
li {
|
||||
display: table-cell;
|
||||
padding-right: 4px;
|
||||
img {
|
||||
max-height: 55px;
|
||||
}
|
||||
.circle {
|
||||
@include border-radius(20px);
|
||||
display: none;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
right: -7px;
|
||||
top: -5px;
|
||||
background-color: #333;
|
||||
width: 20px;
|
||||
max-width: 20px;
|
||||
height: 20px;
|
||||
max-height: 20px;
|
||||
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
.x {
|
||||
display: none;
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
top: -4px;
|
||||
right: -1px;
|
||||
font-size: small;
|
||||
font-weight: bold;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: default;
|
||||
.circle {
|
||||
display: block;
|
||||
}
|
||||
.x {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#fileInfo-publisher {
|
||||
font-size: small;
|
||||
margin: 5px 2px;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
text-align: right;
|
||||
bottom: 40px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ class StatusMessagesController < ApplicationController
|
|||
if @contact
|
||||
@aspects_with_person = @contact.aspects
|
||||
@aspect_ids = @aspects_with_person.map{|x| x.id}
|
||||
gon.aspect_ids = @aspect_ids
|
||||
@contacts_of_contact = @contact.contacts
|
||||
render :layout => nil
|
||||
end
|
||||
|
|
@ -30,6 +31,7 @@ class StatusMessagesController < ApplicationController
|
|||
@aspect = :all
|
||||
@aspects = current_user.aspects
|
||||
@aspect_ids = @aspects.map{ |a| a.id }
|
||||
gon.aspect_ids = @aspect_ids
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
- content_for :head do
|
||||
= javascript_include_tag :jquery
|
||||
= javascript_include_tag 'fileuploader-custom'
|
||||
|
||||
:javascript
|
||||
$(document).ready(function () {
|
||||
|
|
|
|||
|
|
@ -2,15 +2,18 @@
|
|||
-# licensed under the Affero General Public License version 3 or later. See
|
||||
-# the COPYRIGHT file.
|
||||
|
||||
- content_for :head do
|
||||
= jquery_include_tag
|
||||
= javascript_include_tag :main
|
||||
= load_javascript_locales
|
||||
= include_gon
|
||||
|
||||
- content_for :custom_css do
|
||||
:css
|
||||
body {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
- content_for :header_action do
|
||||
= submit_tag t('.share'), :class => 'btn primary', :id => "submit_new_message"
|
||||
|
||||
= form_for StatusMessage.new, {:data => {:ajax => false}} do |status|
|
||||
#message_container
|
||||
= status.hidden_field :provider_display_name, :value => 'mobile'
|
||||
|
|
@ -31,4 +34,18 @@
|
|||
|
||||
- current_user.aspects.each do |aspect|
|
||||
%option{:value => aspect.id}
|
||||
= "· #{aspect.name}"
|
||||
= "· #{aspect.name}"
|
||||
|
||||
%br
|
||||
%br
|
||||
|
||||
#fileInfo-publisher
|
||||
#publisher_textarea_wrapper
|
||||
%ul#photodropzone
|
||||
|
||||
#file-upload-publisher{:title => t('.upload_photos'), :class => 'btn'}
|
||||
= image_tag 'icons/camera.png', :style => "height: 14px; width: 19px;", :alt => t('.upload_photos').titleize
|
||||
#publisher_mobile
|
||||
= submit_tag t('.share'), :class => 'btn primary', :id => "submit_new_message", :style => "position: absolute; right: 20px; bottom: 10px"
|
||||
|
||||
#publisher_photo_upload
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@ en:
|
|||
photo_uploader:
|
||||
looking_good: "OMG, you look awesome!"
|
||||
completed: "<%= file %> completed"
|
||||
invalid_ext: "{file} has invalid extension. Only {extensions} are allowed."
|
||||
size_error: "{file} is too large, maximum file size is {sizeLimit}."
|
||||
empty: "{file} is empty, please select files again without it."
|
||||
tags:
|
||||
wasnt_that_interesting: "OK, I suppose #<%= tagName %> wasn't all that interesting..."
|
||||
people:
|
||||
|
|
|
|||
60
features/posts_from_main_page_mobile.feature
Normal file
60
features/posts_from_main_page_mobile.feature
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
@javascript
|
||||
Feature: posting from the main page
|
||||
In order to navigate Diaspora*
|
||||
As a mobile user
|
||||
I want to tell the world I am eating a yogurt
|
||||
|
||||
Background:
|
||||
Given following users exist:
|
||||
| username |
|
||||
| bob |
|
||||
| alice |
|
||||
And I visit the mobile home page
|
||||
And I sign in as "bob@bob.bob"
|
||||
And a user with username "bob" is connected with "alice"
|
||||
Given I have following aspects:
|
||||
| PostingTo |
|
||||
| NotPostingThingsHere |
|
||||
And I have user with username "alice" in an aspect called "PostingTo"
|
||||
And I have user with username "alice" in an aspect called "NotPostingThingsHere"
|
||||
|
||||
Scenario: posting some text
|
||||
Given I publisher mobile page
|
||||
And I append "I am eating yogurt" to the publisher mobile
|
||||
And I select "Unicorns" from "aspect_ids_"
|
||||
And I press "Share"
|
||||
When I visit the mobile stream page
|
||||
Then I should see "I am eating yogurt"
|
||||
|
||||
Scenario: post a photo without text
|
||||
Given I publisher mobile page
|
||||
When I attach the file "spec/fixtures/button.png" to hidden element "file" within "#file-upload-publisher"
|
||||
And I wait for the ajax to finish
|
||||
Then I should see an uploaded image within the photo drop zone
|
||||
When I press "Share"
|
||||
And I wait for the ajax to finish
|
||||
When I visit the mobile stream page
|
||||
Then I should see a "img" within ".stream_element div.photo_attachments"
|
||||
When I log out
|
||||
And I sign in as "alice@alice.alice"
|
||||
When I visit the mobile stream page
|
||||
Then I should see a "img" within ".stream_element div.photo_attachments"
|
||||
|
||||
Scenario: back out of posting a photo-only post
|
||||
Given I publisher mobile page
|
||||
When I attach the file "spec/fixtures/button.png" to hidden element "file" within "#file-upload-publisher"
|
||||
And I wait for the ajax to finish
|
||||
And I click to delete the first uploaded photo
|
||||
And I wait for the ajax to finish
|
||||
Then I should not see an uploaded image within the photo drop zone
|
||||
|
||||
Scenario: back out of uploading a picture when another has been attached
|
||||
Given I publisher mobile page
|
||||
And I append "I am eating yogurt" to the publisher mobile
|
||||
And I attach the file "spec/fixtures/button.gif" to hidden element "file" within "#file-upload-publisher"
|
||||
And I attach the file "spec/fixtures/button.png" to hidden element "file" within "#file-upload-publisher"
|
||||
And I wait for the ajax to finish
|
||||
And I click to delete the first uploaded photo
|
||||
And I wait for the ajax to finish
|
||||
Then I should see an uploaded image within the photo drop zone
|
||||
And the text area wrapper mobile should be with attachments
|
||||
|
|
@ -96,6 +96,10 @@ Then /^the publisher should be expanded$/ do
|
|||
find("#publisher")["class"].should_not include("closed")
|
||||
end
|
||||
|
||||
Then /^the text area wrapper mobile should be with attachments$/ do
|
||||
find("#publisher_textarea_wrapper")["class"].should include("with_attachments")
|
||||
end
|
||||
|
||||
When /^I append "([^"]*)" to the publisher$/ do |stuff|
|
||||
elem = find('#status_message_fake_text')
|
||||
elem.native.send_keys(' ' + stuff)
|
||||
|
|
@ -105,6 +109,15 @@ When /^I append "([^"]*)" to the publisher$/ do |stuff|
|
|||
end
|
||||
end
|
||||
|
||||
When /^I append "([^"]*)" to the publisher mobile$/ do |stuff|
|
||||
elem = find('#status_message_text')
|
||||
elem.native.send_keys(' ' + stuff)
|
||||
|
||||
wait_until do
|
||||
find('#status_message_text').value.include?(stuff)
|
||||
end
|
||||
end
|
||||
|
||||
And /^I want to mention (?:him|her) from the profile$/ do
|
||||
click_link("Mention")
|
||||
wait_for_ajax_to_finish
|
||||
|
|
|
|||
|
|
@ -1,3 +1,15 @@
|
|||
When /^I visit the mobile aspects page$/ do
|
||||
visit('/aspects.mobile')
|
||||
end
|
||||
|
||||
When /^I visit the mobile home page$/ do
|
||||
visit('/users/sign_in.mobile')
|
||||
end
|
||||
|
||||
Given /^I publisher mobile page$/ do
|
||||
visit('/status_messages/new.mobile')
|
||||
end
|
||||
|
||||
When /^I visit the mobile stream page$/ do
|
||||
visit('/stream.mobile')
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,4 +22,4 @@ When /^I click the show page link for "([^"]*)"$/ do |post_text|
|
|||
within(find_post_by_text(post_text)) do
|
||||
find("time").click
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1216,6 +1216,7 @@ qq.extend(qq.UploadHandlerXhr.prototype, {
|
|||
xhr.setRequestHeader("X-File-Name", encodeURIComponent(name));
|
||||
xhr.setRequestHeader("Content-Type", "application/octet-stream");
|
||||
xhr.setRequestHeader("X-CSRF-Token", $("meta[name='csrf-token']").attr("content"));
|
||||
xhr.setRequestHeader("Accept", "application/json");
|
||||
xhr.send(file);
|
||||
},
|
||||
_onComplete: function(id, xhr){
|
||||
Loading…
Reference in a new issue