diff --git a/app/assets/javascripts/assets.js b/app/assets/javascripts/assets.js
index f69190ff8..600bdf3ca 100644
--- a/app/assets/javascripts/assets.js
+++ b/app/assets/javascripts/assets.js
@@ -1,6 +1,6 @@
function setupAssetsLoading() {
- var DELAY = 2000;
- var REPETITIONS = 15;
+ var DELAY = 2500;
+ var REPETITIONS = 60;
function refreshAssets() {
var elements = $("[data-status='asset-loading']");
@@ -12,7 +12,6 @@ function setupAssetsLoading() {
$.each(elements, function(_, el) {
var $el = $(el);
var spinner = $el.find(".asset-loading-spinner");
- var type = $el.data("type");
// Perform an AJAX call to present URL
// to check if file already exists
@@ -22,36 +21,41 @@ function setupAssetsLoading() {
dataType: "json",
success: function (data) {
$el.attr("data-status", "asset-loaded");
- $el.find(".asset-loading-spinner").spin(false);
+ $el.find('img').hide();
+ $el.next().hide();
$el.html("");
- if (type === "image") {
+ if (data.type === "image") {
$el.html(
- "" +
- " " +
+ data.filename + " " +
+ data.filename + "
" +
- $el.data("filename") + ""
+ "" +
+ "
" +
- $el.data("filename")
+ "
" + + data.filename + "
" ); } else { - $el.html($el.data("filename")); + $el.html("" + data.filename + "
"); } } else { // Do nothing, file is not yet present + animateSpinner(null, false); } } }); diff --git a/app/assets/javascripts/my_modules/protocols.js.erb b/app/assets/javascripts/my_modules/protocols.js.erb index 1d74cfcb5..e11845f4a 100644 --- a/app/assets/javascripts/my_modules/protocols.js.erb +++ b/app/assets/javascripts/my_modules/protocols.js.erb @@ -21,6 +21,7 @@ function init() { Comments.bindNewElement(); Comments.initialize(); initTutorial(); + setupAssetsLoading(); } // Initialize edit description modal window diff --git a/app/assets/javascripts/my_modules/results.js.erb b/app/assets/javascripts/my_modules/results.js.erb index 114244e38..b03bc1145 100644 --- a/app/assets/javascripts/my_modules/results.js.erb +++ b/app/assets/javascripts/my_modules/results.js.erb @@ -1,3 +1,4 @@ +//= require assets //= require comments /** @@ -108,6 +109,8 @@ function expandResult(result) { $(this).removeClass("glyphicon-collapse-down"); }); renderTable($(result).find("div.step-result-hot-table")); + animateSpinner(null, false); + setupAssetsLoading(); } function renderTable(table) { diff --git a/app/assets/javascripts/protocols/steps.js.erb b/app/assets/javascripts/protocols/steps.js.erb index 96531aaf2..b65a0e83a 100644 --- a/app/assets/javascripts/protocols/steps.js.erb +++ b/app/assets/javascripts/protocols/steps.js.erb @@ -102,6 +102,7 @@ function applyEditCallBack() { formEditAjax($form); toggleButtons(false); initializeCheckboxSorting(); + animateSpinner(null, false); $("#new-step-checklists fieldset.nested_step_checklists ul").each(function () { enableCheckboxSorting(this); @@ -209,6 +210,7 @@ function formEditAjax($form) { $new_step.find("[data-role='step-hot-table']").each(function() { renderTable($(this)); }); + setupAssetsLoading(); }) .on("ajax:error", function(e, xhr, status, error) { $form.renderFormErrors('step', xhr.responseJSON, true, e); @@ -245,6 +247,8 @@ function formNewAjax($form) { $new_step.find("div.step-result-hot-table").each(function() { $(this).handsontable("render"); }); + animateSpinner(null, false); + setupAssetsLoading(); }) .on("ajax:error", function(e, xhr, status, error) { $(this).after(xhr.responseJSON.html); @@ -257,6 +261,7 @@ function formNewAjax($form) { formCallback($form); formNewAjax($form); applyCancelOnNew(); + animateSpinner(null, false); }); } diff --git a/app/controllers/assets_controller.rb b/app/controllers/assets_controller.rb index 5a987b2ad..a5d19c8d5 100644 --- a/app/controllers/assets_controller.rb +++ b/app/controllers/assets_controller.rb @@ -1,37 +1,39 @@ class AssetsController < ApplicationController + include ActionView::Helpers::TextHelper before_action :load_vars before_action :check_read_permission, except: :file_present def file_present respond_to do |format| - format.json { - if @asset.file_present + format.json do + if @asset.file.processing? + render json: {}, status: 404 + else # Only if file is present, # check_read_permission check_read_permission # If check_read_permission already rendered error, # stop execution - if performed? then - return - end + return if performed? # If check permission passes, return :ok - render json: {}, status: 200 - else - render json: {}, status: 404 + render json: { + 'preview-url' => @asset.url(:medium), + 'filename' => truncate(@asset.file_file_name, + length: + Constants::FILENAME_TRUNCATION_LENGTH), + 'download-url' => download_asset_path(@asset), + 'type' => (@asset.is_image? ? 'image' : 'file') + }, status: 200 end - } + end end end def preview if @asset.is_image? - if @asset.file.processing? - redirect_to image_url('/images/processing.gif'), status: 307 - else - redirect_to @asset.url(:medium), status: 307 - end + redirect_to @asset.url(:medium), status: 307 else render_400 end diff --git a/app/controllers/steps_controller.rb b/app/controllers/steps_controller.rb index 21a4b6f38..f7380f2dd 100644 --- a/app/controllers/steps_controller.rb +++ b/app/controllers/steps_controller.rb @@ -67,12 +67,15 @@ class StepsController < ApplicationController # Update protocol timestamp update_protocol_ts(@step) - format.json { + format.json do render json: { - html: render_to_string({ - partial: "steps/step.html.erb", locals: {step: @step} - })}, status: :ok - } + html: render_to_string( + partial: 'steps/step.html.erb', + locals: { step: @step } + ) + }, + status: :ok + end else # On error, delete the newly added files from S3, as they were # uploaded on client-side (in case of client-side hacking of diff --git a/app/helpers/assets_helper.rb b/app/helpers/assets_helper.rb deleted file mode 100644 index 404819241..000000000 --- a/app/helpers/assets_helper.rb +++ /dev/null @@ -1,27 +0,0 @@ -module AssetsHelper - - def asset_loading_span(asset) - res = <<-eos - - - #{t('general.file.uploading', fileName: asset.file_file_name)} - - - eos - res.html_safe - end -end diff --git a/app/models/asset.rb b/app/models/asset.rb index bb506f2b0..7770fff2d 100644 --- a/app/models/asset.rb +++ b/app/models/asset.rb @@ -8,7 +8,7 @@ class Asset < ActiveRecord::Base # Paperclip validation has_attached_file :file, styles: { medium: [Constants::MEDIUM_PIC_FORMAT, :jpg] }, - convert_options: { medium: '-quality 20 -strip' } + convert_options: { medium: '-quality 70 -strip' } validates_attachment :file, presence: true, @@ -33,7 +33,7 @@ class Asset < ActiveRecord::Base {} end }, - processing_image_url: '/images/medium/processing.gif' + processing_image_url: '/images/:style/processing.gif' # Asset validation # This could cause some problems if you create empty asset and want to diff --git a/app/models/protocol.rb b/app/models/protocol.rb index c76dde60f..e3abb7ed3 100644 --- a/app/models/protocol.rb +++ b/app/models/protocol.rb @@ -265,6 +265,7 @@ class Protocol < ActiveRecord::Base asset2.save step2.assets << asset2 + asset2.file.delay.reprocess!(:medium) assets_to_clone << [asset.id, asset2.id] end diff --git a/app/views/results/_result_asset.html.erb b/app/views/results/_result_asset.html.erb index df02888f1..992b08562 100644 --- a/app/views/results/_result_asset.html.erb +++ b/app/views/results/_result_asset.html.erb @@ -1,10 +1,24 @@ <% if can_view_or_download_result_assets(result.my_module) %> - <%= link_to download_asset_path(result.asset), data: {no_turbolink: true} do %> - <%= image_tag(preview_asset_path result.asset) if result.asset.is_image? %> -<%= truncate(result.asset.file_file_name, - length: Constants::FILENAME_TRUNCATION_LENGTH) %>
+ <% if result.asset.file.processing? %> + + <%= image_tag 'medium/processing.gif' %> + + <% else %> + <%= link_to download_asset_path(result.asset), data: {no_turbolink: true} do %> + <%= image_tag(preview_asset_path result.asset) if result.asset.is_image? %> +<%= truncate(result.asset.file_file_name, + length: Constants::FILENAME_TRUNCATION_LENGTH) %>
+ <% end %> <% end %> <% else %> - <%= image_tag(preview_asset_path result.asset) if result.asset.is_image? %> -<%= result.asset.file_file_name %>
+ <% if result.asset.file.processing? %> + + <%= image_tag 'medium/processing.gif' %> + + <% else %> + <%= image_tag(preview_asset_path result.asset) if result.asset.is_image? %> +<%= result.asset.file_file_name %>
+ <% end %> <% end %> diff --git a/app/views/steps/_step.html.erb b/app/views/steps/_step.html.erb index 7bf224a51..df3ef201f 100644 --- a/app/views/steps/_step.html.erb +++ b/app/views/steps/_step.html.erb @@ -67,15 +67,32 @@ <% if can_view_or_download_step_assets(@protocol) %> <% if asset.file_present %> <%= link_to download_asset_path(asset), data: {no_turbolink: true, id: true, status: "asset-present"} do %> - <%= image_tag preview_asset_path(asset) if asset.is_image? %> + <% if asset.file.processing? %> + + <%= image_tag 'medium/processing.gif' %> + + <% else %> + <%= image_tag preview_asset_path(asset) if asset.is_image? %> + <% end %><%= truncate(asset.file_file_name, length: Constants::FILENAME_TRUNCATION_LENGTH) %>
<% end %> <% else %> - <%= asset_loading_span(asset) %> + + <%= image_tag 'medium/processing.gif' %> + <% end %> <% else %> - <%= image_tag preview_asset_path(asset) if asset.is_image? %> + <% if asset.file.processing? %> + + <%= image_tag 'medium/processing.gif' %> + + <% else %> + <%= image_tag preview_asset_path(asset) if asset.is_image? %> + <% end %><%= truncate(asset.file_file_name, length: Constants::FILENAME_TRUNCATION_LENGTH) %>
<% end %> diff --git a/db/migrate/20161208145354_add_processing_to_assets.rb b/db/migrate/20161208145354_add_processing_to_assets.rb new file mode 100644 index 000000000..97cff9034 --- /dev/null +++ b/db/migrate/20161208145354_add_processing_to_assets.rb @@ -0,0 +1,5 @@ +class AddProcessingToAssets < ActiveRecord::Migration + def change + add_column :assets, :file_processing, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index 9d3c132b9..9061c5f32 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20161012112900) do +ActiveRecord::Schema.define(version: 20161208145354) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -56,6 +56,7 @@ ActiveRecord::Schema.define(version: 20161012112900) do t.integer "last_modified_by_id" t.integer "estimated_size", default: 0, null: false t.boolean "file_present", default: false, null: false + t.boolean "file_processing" end add_index "assets", ["created_at"], name: "index_assets_on_created_at", using: :btree @@ -628,20 +629,20 @@ ActiveRecord::Schema.define(version: 20161012112900) do add_index "user_projects", ["user_id"], name: "index_user_projects_on_user_id", using: :btree create_table "users", force: :cascade do |t| - t.string "full_name", null: false - t.string "initials", null: false - t.string "email", default: "", null: false - t.string "encrypted_password", default: "", null: false + t.string "full_name", null: false + t.string "initials", null: false + t.string "email", default: "", null: false + t.string "encrypted_password", default: "", null: false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.integer "sign_in_count", default: 0, null: false + t.integer "sign_in_count", default: 0, null: false t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" t.string "current_sign_in_ip" t.string "last_sign_in_ip" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "avatar_file_name" t.string "avatar_content_type" t.integer "avatar_file_size" @@ -650,7 +651,7 @@ ActiveRecord::Schema.define(version: 20161012112900) do t.datetime "confirmed_at" t.datetime "confirmation_sent_at" t.string "unconfirmed_email" - t.string "time_zone", default: "UTC" + t.string "time_zone", default: "UTC" t.string "invitation_token" t.datetime "invitation_created_at" t.datetime "invitation_sent_at" @@ -658,16 +659,18 @@ ActiveRecord::Schema.define(version: 20161012112900) do t.integer "invitation_limit" t.integer "invited_by_id" t.string "invited_by_type" - t.integer "invitations_count", default: 0 - t.integer "tutorial_status", default: 0, null: false - t.boolean "assignments_notification", default: true - t.boolean "recent_notification", default: true - t.boolean "assignments_notification_email", default: false - t.boolean "recent_notification_email", default: false + t.integer "invitations_count", default: 0 + t.integer "tutorial_status", default: 0, null: false + t.boolean "assignments_notification", default: true + t.boolean "recent_notification", default: true + t.boolean "assignments_notification_email", default: false + t.boolean "recent_notification_email", default: false t.integer "current_organization_id" - t.boolean "system_message_notification_email", default: false + t.boolean "system_message_notification_email", default: false + t.string "authentication_token", limit: 30 end + add_index "users", ["authentication_token"], name: "index_users_on_authentication_token", unique: true, using: :btree add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree add_index "users", ["invitation_token"], name: "index_users_on_invitation_token", unique: true, using: :btree