diff --git a/app/assets/javascripts/assets.js b/app/assets/javascripts/assets.js
index 4e863d5c7..c0fa1e265 100644
--- a/app/assets/javascripts/assets.js
+++ b/app/assets/javascripts/assets.js
@@ -26,9 +26,12 @@ function setupAssetsLoading() {
if (data.type === "image") {
$el.html(
- "" +
- " " +
- data.filename + " " +
+ data.filename + '
" +
+ "
" + data.filename + "
" ); } else { diff --git a/app/assets/javascripts/protocols/steps.js.erb b/app/assets/javascripts/protocols/steps.js.erb index ea89accf1..715b4071b 100644 --- a/app/assets/javascripts/protocols/steps.js.erb +++ b/app/assets/javascripts/protocols/steps.js.erb @@ -79,6 +79,7 @@ function applyCancelCallBack() { setTimeout(function() { initStepsComments(); + initPreviewModal(); }, 1000); }) @@ -103,6 +104,7 @@ function applyEditCallBack() { toggleButtons(false); initializeCheckboxSorting(); animateSpinner(null, false); + initPreviewModal(); $("#new-step-checklists fieldset.nested_step_checklists ul").each(function () { enableCheckboxSorting(this); @@ -567,6 +569,7 @@ $(document).ready(function() { expandAllSteps(); setupAssetsLoading(); initStepsComments(); + initPreviewModal(); $(function () { diff --git a/app/assets/javascripts/results/result_assets.js b/app/assets/javascripts/results/result_assets.js index 1b51b4814..e489f02cc 100644 --- a/app/assets/javascripts/results/result_assets.js +++ b/app/assets/javascripts/results/result_assets.js @@ -37,6 +37,7 @@ function applyEditResultAssetCallback() { $form.remove(); applyEditResultAssetCallback(); toggleResultEditButtons(true); + initPreviewModal(); }); toggleResultEditButtons(false); @@ -64,6 +65,7 @@ function formAjaxResultAsset($form) { expandResult($newResult); $imgs = $newResult.find("img"); reloadImages($imgs); + initPreviewModal(); }) .on("ajax:error", function(e, data) { $form.renderFormErrors("result", data.errors, true, e); @@ -71,3 +73,4 @@ function formAjaxResultAsset($form) { } applyEditResultAssetCallback(); +initPreviewModal(); diff --git a/app/assets/javascripts/sitewide/image_preview.js b/app/assets/javascripts/sitewide/image_preview.js new file mode 100644 index 000000000..c761bfc00 --- /dev/null +++ b/app/assets/javascripts/sitewide/image_preview.js @@ -0,0 +1,41 @@ +function initPreviewModal() { + $('.image-preview-link').off(); + $('.image-preview-link').click(function(e) { + e.preventDefault(); + var name = $(this).find('p').text(); + var url = $(this).find('img').data('preview-url'); + var downloadUrl = $(this).attr('href'); + var description = $(this).data('description'); + openPreviewModal(name, url, downloadUrl, description); + }); +} + +function openPreviewModal(name, url, downloadUrl, description) { + var modal = $('#imagePreviewModal'); + $.ajax({ + url: url, + type: 'GET', + dataType: 'json', + success: function(data) { + modal.find('.image-name').text(name); + var link = modal.find('.image-download-link'); + link.attr('href', downloadUrl); + link.attr('data-no-turbolink', true); + link.attr('data-status', 'asset-present'); + var image = modal.find('.modal-body img'); + image.attr('src', data['large-preview-url']); + image.attr('alt', name); + image.click(function(ev) { + ev.stopPropagation(); + }); + modal.find('.modal-footer .image-description').text(description); + modal.find('.modal-body').click(function() { + modal.modal('hide'); + }); + modal.modal(); + }, + error: function(ev) { + // TODO + } + }); +} diff --git a/app/assets/stylesheets/my_modules.scss b/app/assets/stylesheets/my_modules.scss index 250029f54..31ec3c6c5 100644 --- a/app/assets/stylesheets/my_modules.scss +++ b/app/assets/stylesheets/my_modules.scss @@ -2,6 +2,8 @@ // They will automatically be included in application.css. // You can use Sass (SCSS) here: http://sass-lang.com/ +@import 'constants'; + /* Results index page */ #results { @@ -28,3 +30,80 @@ word-wrap: break-word; } } + +.modal-image-preview { + background: transparent; + font-size: 16px; + padding-right: 0 !important; + + .preview-close { + background: transparent; + border: 0; + color: $color-white; + display: inline-block; + float: right; + } + + .modal-dialog { + height: 100%; + margin: 0; + padding: 0; + width: auto; + } + + .modal-content { + background: transparent; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + color: $color-white; + height: 100%; + width: auto; + } + + img { + left: 50%; + margin-right: -50%; + max-height: 100%; + position: absolute; + top: 50%; + transform: translate(-50%, -50%); + width: auto; + } + + .modal-header { + background: $color-black; + border: 0; + } + + .modal-body { + height: 85%; + position: relative; + width: auto; + } + + .modal-footer { + background: $color-black; + border: 0; + bottom: 0; + position: fixed; + text-align: center; + width: 100%; + } + + .image-download-link { + color: $color-white; + display: inline-block; + float: right; + margin-right: 20px; + } +} + +.modal-backdrop.modal-image-preview { + background: $color-black; + + .in { + filter: alpha(opacity = 99); + opacity: .99; + } +} diff --git a/app/controllers/assets_controller.rb b/app/controllers/assets_controller.rb index a5d19c8d5..badb98a9a 100644 --- a/app/controllers/assets_controller.rb +++ b/app/controllers/assets_controller.rb @@ -19,7 +19,9 @@ class AssetsController < ApplicationController # If check permission passes, return :ok render json: { - 'preview-url' => @asset.url(:medium), + 'asset-id' => @asset.id, + 'image-tag-url' => @asset.url(:medium), + 'preview-url' => large_image_url_asset_path(@asset), 'filename' => truncate(@asset.file_file_name, length: Constants::FILENAME_TRUNCATION_LENGTH), @@ -31,11 +33,18 @@ class AssetsController < ApplicationController end end - def preview - if @asset.is_image? - redirect_to @asset.url(:medium), status: 307 - else - render_400 + def large_image_url + respond_to do |format| + format.json do + render json: { + 'large-preview-url' => @asset.url(:large), + 'filename' => truncate(@asset.file_file_name, + length: + Constants::FILENAME_TRUNCATION_LENGTH), + 'download-url' => download_asset_path(@asset), + 'type' => (@asset.is_image? ? 'image' : 'file') + } + end end end diff --git a/app/models/asset.rb b/app/models/asset.rb index 04322221f..1ff696c60 100644 --- a/app/models/asset.rb +++ b/app/models/asset.rb @@ -7,7 +7,8 @@ class Asset < ActiveRecord::Base # Paperclip validation has_attached_file :file, - styles: { medium: [Constants::MEDIUM_PIC_FORMAT, :jpg] }, + styles: { large: [Constants::LARGE_PIC_FORMAT, :jpg], + medium: [Constants::MEDIUM_PIC_FORMAT, :jpg] }, convert_options: { medium: '-quality 70 -strip' } validates_attachment :file, @@ -28,7 +29,7 @@ class Asset < ActiveRecord::Base %r{^image/#{ Regexp.union( Constants::WHITELISTED_IMAGE_TYPES ) }} - [:medium] + [:large, :medium] else {} end diff --git a/app/views/my_modules/protocols.html.erb b/app/views/my_modules/protocols.html.erb index ff4b97a1a..f40199dbe 100644 --- a/app/views/my_modules/protocols.html.erb +++ b/app/views/my_modules/protocols.html.erb @@ -43,5 +43,8 @@ <%= render partial: "protocols/import_export/import_elements.html.erb" %> + +<%= render partial: "shared/image_preview_modal.html.erb" %> + <%= stylesheet_link_tag 'datatables' %> <%= javascript_include_tag("my_modules/protocols") %> diff --git a/app/views/my_modules/results.html.erb b/app/views/my_modules/results.html.erb index 8d90a8007..cd9eecd0b 100644 --- a/app/views/my_modules/results.html.erb +++ b/app/views/my_modules/results.html.erb @@ -39,6 +39,8 @@ +<%= render partial: "shared/image_preview_modal.html.erb" %> +<%= truncate(result.asset.file_file_name, - length: Constants::FILENAME_TRUNCATION_LENGTH) %>
+ <% if result.asset.is_image? %> + <%= link_to download_asset_path(result.asset), + class: 'image-preview-link', + id: "modal_link#{result.asset.id}", + data: {no_turbolink: true, description: "#{result.name}"} do %> + <%= image_tag result.asset.url(:medium), data: {'preview-url': large_image_url_asset_path(result.asset)} %> +<%= truncate(result.asset.file_file_name, + length: Constants::FILENAME_TRUNCATION_LENGTH) %>
+ <% end %> + <% else %> + <%= link_to download_asset_path(result.asset), data: {no_turbolink: true} do %> +<%= truncate(result.asset.file_file_name, + length: Constants::FILENAME_TRUNCATION_LENGTH) %>
+ <% end %> <% end %> <% end %> <% else %> @@ -18,7 +28,7 @@ <%= image_tag 'medium/processing.gif' %> <% else %> - <%= image_tag(preview_asset_path result.asset) if result.asset.is_image? %> + <%= image_tag result.asset.url(:medium) if result.asset.is_image? %><%= result.asset.file_file_name %>
<% end %> <% end %> diff --git a/app/views/shared/_image_preview_modal.html.erb b/app/views/shared/_image_preview_modal.html.erb new file mode 100644 index 000000000..9baac98c1 --- /dev/null +++ b/app/views/shared/_image_preview_modal.html.erb @@ -0,0 +1,19 @@ + diff --git a/app/views/steps/_empty_step.html.erb b/app/views/steps/_empty_step.html.erb index d189c52ab..dd2c1c0a4 100644 --- a/app/views/steps/_empty_step.html.erb +++ b/app/views/steps/_empty_step.html.erb @@ -42,7 +42,7 @@<%= ff.object.file_file_name %>
+ <% if ff.object.is_image? %> + <%= link_to download_asset_path(ff.object), + class: 'image-preview-link', + id: "modal_link#{ff.object.id}", + data: {no_turbolink: true, id: true, status: "asset-present", description: "#{step.position + 1}. #{step.name}"} do %> + <%= image_tag ff.object.url(:medium), data: {'preview-url': large_image_url_asset_path(ff.object)} %> +<%= truncate(ff.object.file_file_name, + length: Constants::FILENAME_TRUNCATION_LENGTH) %>
+ <% end %> + <% else %> + <%= link_to download_asset_path(ff.object), data: {no_turbolink: true} do %> + <%= image_tag ff.object.url(:medium) if ff.object.is_image? %> +<%= truncate(ff.object.file_file_name, + length: Constants::FILENAME_TRUNCATION_LENGTH) %>
+ <% end %> <% end %> <% else %> - <%= image_tag(preview_asset_path ff.object) if ff.object.is_image? %> + <%= image_tag image_tag ff.object.url(:medium) if ff.object.is_image? %><%= ff.object.file_file_name %>
<% end %> <% else %> <%= ff.file_field :file %> <% end %><%= truncate(asset.file_file_name, + length: Constants::FILENAME_TRUNCATION_LENGTH) %>
+ <% end %> <% else %> - <%= image_tag preview_asset_path(asset) if asset.is_image? %> + <%= link_to download_asset_path(asset), data: {no_turbolink: true} do %> +<%= truncate(asset.file_file_name, + length: Constants::FILENAME_TRUNCATION_LENGTH) %>
+ <% end %> <% end %> -<%= truncate(asset.file_file_name, - length: Constants::FILENAME_TRUNCATION_LENGTH) %>
<% end %> <% else %> <% else %> - <%= image_tag preview_asset_path(asset) if asset.is_image? %> + <%= image_tag asset.url(:medium) if asset.is_image? %> <% end %><%= truncate(asset.file_file_name, length: Constants::FILENAME_TRUNCATION_LENGTH) %>
diff --git a/config/initializers/constants.rb b/config/initializers/constants.rb index c967bdb3e..f80545adf 100644 --- a/config/initializers/constants.rb +++ b/config/initializers/constants.rb @@ -72,6 +72,7 @@ class Constants #============================================================================= # Picture size formats + LARGE_PIC_FORMAT = '800x600>'.freeze MEDIUM_PIC_FORMAT = '300x300>'.freeze THUMB_PIC_FORMAT = '100x100>'.freeze ICON_PIC_FORMAT = '40x40>'.freeze diff --git a/config/routes.rb b/config/routes.rb index a2f8e2447..d40158a37 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -282,8 +282,10 @@ Rails.application.routes.draw do # We cannot use 'resources :assets' because assets is a reserved route # in Rails (assets pipeline) and causes funky behavior get "files/:id/present", to: "assets#file_present", as: "file_present_asset" + get 'files/:id/large_url', + to: 'assets#large_image_url', + as: 'large_image_url_asset' get "files/:id/download", to: "assets#download", as: "download_asset" - get "files/:id/preview", to: "assets#preview", as: "preview_asset" post 'asset_signature' => 'assets#signature' devise_scope :user do