require 'mime/types' module Attachy class Viewer def initialize(method, object, options = {}, view = ActionController::Base.helpers) @method = method @object = object @options = options @view = view end def attachments [criteria].flatten end def button_label_options { text: '...' } end def button_label(html: button_label_options) html = htm(:button).merge(html) @view.content_tag :span, html.delete(:text), html end def content(html: {}) html = content_options.merge(html) return yield(html, attachments) if block_given? @view.content_tag :ul, nodes.join.html_safe, html end def content_options { class: :attachy__content, data: { crop: metadata[:crop], height: transform[:height], multiple: metadata[:multiple], width: transform[:width] } } end def field_options { class: :attachy } end def field(html: {}) html = field_options.merge(html) return yield(html) if block_given? @view.content_tag :div, content + file_button, html end def file_button_options { class: :attachy__button } end def file_button(html: htm(:button)) html = file_button_options.merge(html) return yield(html) if block_given? @view.content_tag :div, button_label + file_field + hidden_field, html end def file_field_options options = { class: :attachy__fileupload } accept = MIME::Types.type_for([metadata[:accept]].flatten.map(&:to_s)) options[:accept] = accept.join(',') if accept.present? options[:multiple] = true if metadata[:multiple] options end def file_field(html: file_field_options) options = { html: html, tags: [ENV_TAG, TMP_TAG] } options[:folder] = metadata[:folder] if metadata[:folder] @view.cl_image_upload_tag @method, options end def hidden_field @view.hidden_field @object.class.name.downcase, @method, value: value, id: nil end def image(file = criteria, t: transform, html: htm) url = file.url(t) html = html.reverse_merge(height: t[:height], width: t[:width]) html[:data] = file.transform(t) @view.image_tag url, html end def link_options { class: :attachy__link } end def link(file = criteria, t: transform, tl: { crop: :none }, html: {}) html = html.reverse_merge(link_options.merge(data: tl)) return yield(html, attachments) if block_given? @view.link_to image(file, t: t), file.url(tl), html end def node_options { class: :attachy__node } end def node(file = criteria, tl: { crop: :none }, t: transform, html: {}) html = html.reverse_merge(node_options) return yield(html, attachments) if block_given? value = [link(file, t: t, tl: tl)] value << remove_button unless @options[:destroy] == false @view.content_tag :li, value.join.html_safe, html end def nodes attachments.map { |file| node file } end def remove_button_options { class: :attachy__remove } end def remove_button(html: {}) html = html.reverse_merge(remove_button_options) return yield(html) if block_given? @view.content_tag :span, '×'.html_safe, html end def value [(default? ? [] : criteria)].flatten.to_json end private def criteria @criteria ||= @object.send(@method) end def default? attachments.size == 1 && attachments.last.public_id == Attachy::File.default.public_id end def htm(resource_type = :image) @options.dig(resource_type, :html) || {} end def metadata @metadata ||= @object.send("#{@method}_metadata") end def transform(path = [:t]) @options.dig(*path) || {} end end end