yarii-cloudinary 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +34 -0
  4. data/Rakefile +32 -0
  5. data/app/controllers/yarii_cloudinary/application_controller.rb +6 -0
  6. data/app/controllers/yarii_cloudinary/media_controller.rb +33 -0
  7. data/app/helpers/yarii_cloudinary/application_helper.rb +9 -0
  8. data/app/javascript/controllers/cloudinary_browse_media_controller.js +21 -0
  9. data/app/javascript/controllers/cloudinary_multiple_media_controller.js +164 -0
  10. data/app/javascript/controllers/cloudinary_single_media_controller.js +73 -0
  11. data/app/javascript/controllers/index.js +11 -0
  12. data/app/javascript/packs/application.js +2 -0
  13. data/app/jobs/yarii_cloudinary/application_job.rb +4 -0
  14. data/app/styles/index.scss +43 -0
  15. data/app/views/yarii_cloudinary/application/yarii_cloudinary_head.erb +2 -0
  16. data/app/views/yarii_cloudinary/media/_browse_thumbnail.html.erb +3 -0
  17. data/app/views/yarii_cloudinary/media/_form_thumbnail.html.erb +3 -0
  18. data/app/views/yarii_cloudinary/media/_modal.html.erb +4 -0
  19. data/app/views/yarii_cloudinary/media/_multiple_form_item.html.erb +25 -0
  20. data/app/views/yarii_cloudinary/media/index.html.erb +22 -0
  21. data/app/views/yarii_editor/editor/_cloudinary.html.erb +42 -0
  22. data/app/views/yarii_editor/editor/_cloudinary_multiple.html.erb +50 -0
  23. data/config/routes.rb +8 -0
  24. data/config/webpack/development.js +5 -0
  25. data/config/webpack/environment.js +3 -0
  26. data/config/webpack/production.js +5 -0
  27. data/config/webpack/staging.js +5 -0
  28. data/config/webpack/test.js +5 -0
  29. data/config/webpacker.yml +110 -0
  30. data/db/migrate/20190923000809_create_yarii_sites.rb +12 -0
  31. data/lib/tasks/yarii_cloudinary_tasks.rake +61 -0
  32. data/lib/yarii-cloudinary/engine.rb +12 -0
  33. data/lib/yarii-cloudinary/version.rb +3 -0
  34. data/lib/yarii-cloudinary.rb +15 -0
  35. metadata +118 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ee27d8a27036bdb708e1a7113769e2ce31ff1cdd7264af66ddb93f9aefd22b86
4
+ data.tar.gz: a3d3c2406eb27d7bd4ceef17be39b550adf2145a2d05fd311343c79c1ffdf672
5
+ SHA512:
6
+ metadata.gz: 87de93d203977671798102933a7fc6f5053c75a9501ac68f1065b1742bde45d0e929562fc8edf9fab81646ee58ce118184a6f06761c48ab9dd4fb2ec27b628b4
7
+ data.tar.gz: bb980195588ace45c272b969cd59f38336f35ed7763183b2e4d83897095b0ec8ee8647e46e787840eb5a5915f4d4e60e6c5d6aa83f292bac2e49eb38c8917c4c
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Whitefusion
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # Yarii Cloudinary Plugin
2
+
3
+ Short description and motivation. Etc.
4
+
5
+ *Documentation TODO*:
6
+
7
+ * `yarii_editor` upload preset needed in Cloudinary (also media needs to be tagged 'yarii_editor')
8
+ * Add the modal to dashboard extras
9
+ * Add the head renderer (yarii_extra_head)
10
+ * Add the gem initializer
11
+ * Add the route
12
+
13
+ ## Usage
14
+
15
+ How to use my plugin.
16
+
17
+ ## Installation
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ ```ruby
22
+ gem 'yarii-cloudinary'
23
+ ```
24
+
25
+ And then execute:
26
+ ```bash
27
+ $ bundle
28
+ ```
29
+
30
+ ## Contributing
31
+ Contribution directions go here.
32
+
33
+ ## License
34
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Yariieditor'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+ load 'rails/tasks/statistics.rake'
21
+
22
+ require 'bundler/gem_tasks'
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'test'
28
+ t.pattern = 'test/**/*_test.rb'
29
+ t.verbose = false
30
+ end
31
+
32
+ task default: :test
@@ -0,0 +1,6 @@
1
+ module YariiCloudinary
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+ include YariiEditor::ControllerAuthorization
5
+ end
6
+ end
@@ -0,0 +1,33 @@
1
+ module YariiCloudinary
2
+ class MediaController < ApplicationController
3
+ def index
4
+ cloudinary_tag = ENV.fetch('yarii_cloudinary_tag', 'yarii_editor')
5
+ json_images = Cloudinary::Api.resources_by_tag(cloudinary_tag, cloud_name: ENV['yarii_cloudinary_cloud_name'], api_key: ENV['yarii_cloudinary_api_key'], api_secret: ENV['yarii_cloudinary_api_secret'], max_results: 200)['resources']
6
+
7
+ @images = json_images.map do |image|
8
+ {
9
+ path: "v#{image['version']}/#{image['public_id']}",
10
+ id: image['public_id'],
11
+ format: image['format']
12
+ }
13
+ end
14
+
15
+ render layout: false
16
+ end
17
+
18
+ def form_thumbnail
19
+ render partial: 'form_thumbnail', layout: nil, formats: [:html], locals: {public_id: params[:id]}
20
+ end
21
+
22
+ def multiple_form_item
23
+ render_locals = {
24
+ public_id: params[:id],
25
+ name: params[:name],
26
+ index: params[:index],
27
+ input_classes: params[:input_classes],
28
+ placeholder: params[:placeholder]
29
+ }
30
+ render partial: 'multiple_form_item', layout: nil, formats: [:html], locals: render_locals
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,9 @@
1
+ module YariiCloudinary
2
+ module ApplicationHelper
3
+ include ::Webpacker::Helper
4
+
5
+ def current_webpacker_instance
6
+ YariiCloudinary.webpacker
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ import { Controller } from "stimulus"
2
+ //import cloudinary from "cloudinary-core"
3
+
4
+ export default class extends Controller {
5
+ connect() {
6
+ // Not currently used…
7
+ /* this.cl = new cloudinary.Cloudinary({cloud_name: this.data.get("cloud"), secure: true}); */
8
+ console.log("Modal exists")
9
+ }
10
+
11
+ selectMedia(event) {
12
+ this.selectedPublicId = event.currentTarget.dataset.cloudinaryId
13
+ const customEvent = new CustomEvent('selectCloudinaryMedia', { bubbles: true, detail: this })
14
+ this.element.dispatchEvent(customEvent)
15
+ }
16
+
17
+ closeModal() {
18
+ const customEvent = new CustomEvent('closeCloudinaryMedia', { bubbles: true, detail: this })
19
+ this.element.dispatchEvent(customEvent)
20
+ }
21
+ }
@@ -0,0 +1,164 @@
1
+ import { Controller } from "stimulus"
2
+ import axios from "axios"
3
+
4
+ export default class extends Controller {
5
+ static targets = ["rows", "thumbnail", "input"]
6
+
7
+ connect() {
8
+ this.ids = []
9
+ this.currentIndex = -1
10
+ if (this.data.get('ids')) {
11
+ this.ids = this.data.get('ids').split(',')
12
+ }
13
+ this.updateIndex()
14
+
15
+ const uploadPreset = this.data.get('uploadPreset') || 'yarii_editor'
16
+
17
+ this.cloudinaryWidget = cloudinary.createUploadWidget({
18
+ cloudName: this.data.get('cloud'),
19
+ multiple: true,
20
+ sources: [
21
+ 'local',
22
+ 'url'
23
+ ],
24
+ uploadPreset: uploadPreset}, (error, result) => {
25
+ if (!error && result && result.event === "success") {
26
+ this.widgetSuccessCallback(result.info)
27
+ }
28
+ }
29
+ )
30
+ }
31
+
32
+ updateIndex() {
33
+ this.latestIndex = this.ids.length - 1
34
+ }
35
+
36
+ async widgetSuccessCallback(result) {
37
+ const publicId = result.public_id
38
+ if (this.currentIndex == -1) {
39
+ // When adding new images
40
+ this.ids.push(publicId)
41
+ this.updateIndex()
42
+ const formItemPath = this.data.get('formItemPath').replace('/0/', `/${encodeURIComponent(publicId)}/`)
43
+ try {
44
+ const response = await axios.get(formItemPath, {params: {
45
+ name: `${this.data.get('name')}[]`,
46
+ index: this.latestIndex,
47
+ input_classes: this.data.get('inputClasses'),
48
+ placeholder: this.data.get('placeholder')
49
+ }})
50
+ const newRow = document.createElement('template')
51
+ newRow.innerHTML = response.data
52
+ this.rowsTarget.append(newRow.content.cloneNode(true))
53
+ } catch (error) {
54
+ console.log(error)
55
+ }
56
+ }
57
+ else {
58
+ const formItemPath = this.data.get('formItemPath').replace('/0/', `/${encodeURIComponent(publicId)}/`)
59
+ try {
60
+ const response = await axios.get(formItemPath, {params: {
61
+ name: `${this.data.get('name')}[]`,
62
+ index: this.currentIndex,
63
+ input_classes: this.data.get('inputClasses'),
64
+ placeholder: this.data.get('placeholder')
65
+ }})
66
+ const newRow = document.createElement('template')
67
+ newRow.innerHTML = response.data
68
+ this.rowsTarget.replaceChild(newRow.content.cloneNode(true), this.rowsTarget.querySelector(`div[data-index="${this.currentIndex}"]`))
69
+ } catch (error) {
70
+ console.log(error)
71
+ }
72
+ }
73
+ }
74
+
75
+ open() {
76
+ this.currentIndex = parseInt(event.currentTarget.dataset.index, 10)
77
+ this.cloudinaryWidget.open()
78
+ }
79
+
80
+ add() {
81
+ this.currentIndex = -1
82
+ this.cloudinaryWidget.open()
83
+ }
84
+
85
+ remove(event) {
86
+ const indexToRemove = parseInt(event.currentTarget.dataset.index, 10)
87
+ if (confirm('Are you sure you wish to remove this media item?')) {
88
+ this.inputTargets[indexToRemove].value = ""
89
+ this.rowsTarget.querySelector(`div[data-index="${indexToRemove}"]`).classList.add('is-hidden')
90
+ }
91
+ }
92
+
93
+ async addBrowse() {
94
+ this.currentIndex = -1
95
+ const newPath = this.data.get('browsePath')
96
+ this.boundCallbacks = {
97
+ select: this.selectMediaCallback.bind(this),
98
+ close: this.closeMediaCallback.bind(this)
99
+ }
100
+ document.querySelector('#yarii-cloudinary--modal-wrapper').addEventListener('selectCloudinaryMedia', this.boundCallbacks.select)
101
+ document.querySelector('#yarii-cloudinary--modal-wrapper').addEventListener('closeCloudinaryMedia', this.boundCallbacks.close)
102
+
103
+ try {
104
+ const response = await axios.get(newPath)
105
+ document.querySelector('#yarii-cloudinary--modal-wrapper').innerHTML = response.data
106
+ } catch (error) {
107
+ console.log(error)
108
+ }
109
+ }
110
+
111
+ async browse(event) {
112
+ this.currentIndex = parseInt(event.currentTarget.dataset.index, 10)
113
+ const newPath = this.data.get('browsePath')
114
+ this.boundCallbacks = {
115
+ select: this.selectMediaCallback.bind(this),
116
+ close: this.closeMediaCallback.bind(this)
117
+ }
118
+ document.querySelector('#yarii-cloudinary--modal-wrapper').addEventListener('selectCloudinaryMedia', this.boundCallbacks.select)
119
+ document.querySelector('#yarii-cloudinary--modal-wrapper').addEventListener('closeCloudinaryMedia', this.boundCallbacks.close)
120
+
121
+ try {
122
+ const response = await axios.get(newPath)
123
+ document.querySelector('#yarii-cloudinary--modal-wrapper').innerHTML = response.data
124
+ } catch (error) {
125
+ console.log(error)
126
+ }
127
+ }
128
+
129
+ async selectMediaCallback(event) {
130
+ const browseController = event.detail
131
+ const publicId = browseController.selectedPublicId
132
+ if (this.currentIndex == -1) {
133
+ // when adding new images
134
+ this.ids.push(publicId)
135
+ this.updateIndex()
136
+ const formItemPath = this.data.get('formItemPath').replace('/0/', `/${encodeURIComponent(publicId)}/`)
137
+ try {
138
+ const response = await axios.get(formItemPath, {params: {
139
+ name: `${this.data.get('name')}[]`,
140
+ index: this.latestIndex,
141
+ input_classes: this.data.get('inputClasses'),
142
+ placeholder: this.data.get('placeholder')
143
+ }})
144
+ const newRow = document.createElement('template')
145
+ newRow.innerHTML = response.data
146
+ this.rowsTarget.append(newRow.content.cloneNode(true))
147
+ } catch (error) {
148
+ console.log(error)
149
+ }
150
+ } else {
151
+ const thumbnailImage = browseController.element.querySelector(`div[data-cloudinary-id="${publicId}"] figure`).innerHTML
152
+ this.thumbnailTargets[this.currentIndex].innerHTML = `<figure class="image is-128x128 mb-3">${thumbnailImage}</figure>`
153
+ this.inputTargets[this.currentIndex].value = publicId
154
+ }
155
+ browseController.closeModal()
156
+ }
157
+
158
+ closeMediaCallback(event) {
159
+ const browseController = event.detail
160
+ document.querySelector('#yarii-cloudinary--modal-wrapper').removeEventListener('selectCloudinaryMedia', this.boundCallbacks.select)
161
+ document.querySelector('#yarii-cloudinary--modal-wrapper').removeEventListener('closeCloudinaryMedia', this.boundCallbacks.close)
162
+ browseController.element.remove()
163
+ }
164
+ }
@@ -0,0 +1,73 @@
1
+ import { Controller } from "stimulus"
2
+ import axios from "axios"
3
+
4
+ export default class extends Controller {
5
+ static targets = ["thumbnail", "input"]
6
+
7
+ connect() {
8
+ const uploadPreset = this.data.get('uploadPreset') || 'yarii_editor'
9
+
10
+ this.cloudinaryWidget = cloudinary.createUploadWidget({
11
+ cloudName: this.data.get('cloud'),
12
+ multiple: false,
13
+ sources: [
14
+ 'local',
15
+ 'url'
16
+ ],
17
+ uploadPreset: uploadPreset}, (error, result) => {
18
+ if (!error && result && result.event === "success") {
19
+ this.widgetSuccessCallback(result.info)
20
+ }
21
+ }
22
+ )
23
+ }
24
+
25
+ async widgetSuccessCallback(result) {
26
+ const publicId = result.public_id
27
+ this.inputTarget.value = publicId
28
+ const formThumbnailPath = this.data.get('formThumbnailPath').replace('/0/', `/${encodeURIComponent(publicId)}/`)
29
+ try {
30
+ const response = await axios.get(formThumbnailPath)
31
+ this.thumbnailTarget.innerHTML = response.data
32
+ } catch (error) {
33
+ console.log(error)
34
+ }
35
+ }
36
+
37
+ open() {
38
+ this.cloudinaryWidget.open()
39
+ }
40
+
41
+ async browse() {
42
+ const newPath = this.data.get('browsePath')
43
+ this.boundCallbacks = {
44
+ select: this.selectMediaCallback.bind(this),
45
+ close: this.closeMediaCallback.bind(this)
46
+ }
47
+ document.querySelector('#yarii-cloudinary--modal-wrapper').addEventListener('selectCloudinaryMedia', this.boundCallbacks.select)
48
+ document.querySelector('#yarii-cloudinary--modal-wrapper').addEventListener('closeCloudinaryMedia', this.boundCallbacks.close)
49
+
50
+ try {
51
+ const response = await axios.get(newPath)
52
+ document.querySelector('#yarii-cloudinary--modal-wrapper').innerHTML = response.data
53
+ } catch (error) {
54
+ console.log(error)
55
+ }
56
+ }
57
+
58
+ selectMediaCallback(event) {
59
+ const browseController = event.detail
60
+ const publicId = browseController.selectedPublicId
61
+ const thumbnailImage = browseController.element.querySelector(`div[data-cloudinary-id="${publicId}"] figure`).innerHTML
62
+ this.thumbnailTarget.innerHTML = `<figure class="image is-128x128 mb-3">${thumbnailImage}</figure>`
63
+ this.inputTarget.value = publicId
64
+ browseController.closeModal()
65
+ }
66
+
67
+ closeMediaCallback(event) {
68
+ const browseController = event.detail
69
+ document.querySelector('#yarii-cloudinary--modal-wrapper').removeEventListener('selectCloudinaryMedia', this.boundCallbacks.select)
70
+ document.querySelector('#yarii-cloudinary--modal-wrapper').removeEventListener('closeCloudinaryMedia', this.boundCallbacks.close)
71
+ browseController.element.remove()
72
+ }
73
+ }
@@ -0,0 +1,11 @@
1
+ // Load all the controllers within this directory and all subdirectories.
2
+ // Controller files must be named *_controller.js.
3
+
4
+ import { Application } from "stimulus"
5
+ import { definitionsFromContext } from "stimulus/webpack-helpers"
6
+
7
+ const application = Application.start()
8
+ const context = require.context("controllers", true, /_controller\.js$/)
9
+ application.load(definitionsFromContext(context))
10
+
11
+ console.info("cloudinary II:!")
@@ -0,0 +1,2 @@
1
+ import '../../styles/index.scss'
2
+ import "controllers"
@@ -0,0 +1,4 @@
1
+ module YariiCloudinary
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,43 @@
1
+ @charset "utf-8";
2
+
3
+ @mixin thumbnail {
4
+ box-shadow: 0px 2px 5px rgba(0,0,0,0.25);
5
+ border: 1px solid rgba(0,0,0,0.5);
6
+ }
7
+
8
+ .yarii-cloudinary--field {
9
+ @media (min-width: 768px) {
10
+ .level-item {
11
+ padding-right: 10px;
12
+ &:last-of-type {
13
+ padding-right: 0px;
14
+ }
15
+ }
16
+ }
17
+ figure img {
18
+ @include thumbnail;
19
+ }
20
+ .button {
21
+ margin-right: 10px;
22
+ &:last-of-type {
23
+ margin-right: 0;
24
+ }
25
+ }
26
+ }
27
+
28
+ .input.yarii-cloudinary--text-input {
29
+ }
30
+
31
+ .yarii-cloudinary--browse-cell {
32
+ cursor: pointer;
33
+ &:hover {
34
+ background: rgba(0,0,0,0.05);
35
+ }
36
+ figure {
37
+ margin-bottom: 0.5rem;
38
+ img {
39
+ @include thumbnail;
40
+ }
41
+ }
42
+ }
43
+
@@ -0,0 +1,2 @@
1
+ <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
2
+ <%= stylesheet_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
@@ -0,0 +1,3 @@
1
+ <figure class="image is-128x128 m-auto">
2
+ <%= cl_image_tag public_id, cloud_name: ENV['yarii_cloudinary_cloud_name'], :width => 256, :height => 256, :crop => :thumb, :format => :jpg, :quality => 60 %>
3
+ </figure>
@@ -0,0 +1,3 @@
1
+ <figure class="image is-128x128 mb-3">
2
+ <%= cl_image_tag public_id, cloud_name: ENV['yarii_cloudinary_cloud_name'], :width => 256, :height => 256, :crop => :thumb, :format => :jpg, :quality => 60 %>
3
+ </figure>
@@ -0,0 +1,4 @@
1
+ <!-- Yarii::Cloudinary Media Modal -->
2
+ <script src="https://widget.cloudinary.com/v2.0/global/all.js" type="text/javascript"></script>
3
+ <div id="yarii-cloudinary--modal-wrapper">
4
+ </div>
@@ -0,0 +1,25 @@
1
+ <div data-index="<%= index %>" class="level">
2
+ <div class="level-item is-narrow">
3
+ <div data-target="cloudinary-multiple-media.thumbnail">
4
+ <% if public_id.present? %>
5
+ <%= render 'yarii_cloudinary/media/form_thumbnail', public_id: public_id %>
6
+ <% end %>
7
+ </div>
8
+ </div>
9
+ <div class="level-item">
10
+ <%= content_tag :input, nil, name: name, value: public_id, class: input_classes, type: 'text', placeholder: placeholder, data: {target: 'cloudinary-multiple-media.input'} %>
11
+ </div>
12
+ <div class="level-item is-narrow">
13
+ <button data-index="<%= index %>" data-action="cloudinary-multiple-media#open" class="button is-primary">
14
+ <span class="icon"><i class="fa fa-upload"></i></span>
15
+ <span>Upload</span>
16
+ </button>
17
+ <button data-index="<%= index %>" data-action="cloudinary-multiple-media#browse" class="button is-success">
18
+ <span class="icon"><i class="fa fa-picture-o"></i></span>
19
+ <span>Browse</span>
20
+ </button>
21
+ <button data-index="<%= index %>" data-action="cloudinary-multiple-media#remove" class="button is-danger">
22
+ <i class="fa fa-trash"></i>
23
+ </button>
24
+ </div>
25
+ </div>
@@ -0,0 +1,22 @@
1
+ <div data-controller="cloudinary-browse-media" id="yarii-cloudinary--modal" class="modal is-active">
2
+ <div class="modal-background"></div>
3
+ <div class="modal-card">
4
+ <header class="modal-card-head">
5
+ <p class="modal-card-title">Browse Cloudinary</p>
6
+ <button data-action="cloudinary-browse-media#closeModal" class="delete" aria-label="close"></button>
7
+ </header>
8
+ <section class="modal-card-body">
9
+ <div class="columns is-multiline is-mobile">
10
+ <% @images.each do |image| %>
11
+ <div data-action="click->cloudinary-browse-media#selectMedia" data-cloudinary-id="<%= image[:id] %>" role="button" class="yarii-cloudinary--browse-cell column is-one-third-tablet is-one-third-desktop is-half-mobile has-text-centered">
12
+ <%= render 'browse_thumbnail', public_id: image[:path] %>
13
+ <div class="image-name"><strong><%= image[:id] %></strong>.<%= image[:format] %></div>
14
+ </div>
15
+ <% end %>
16
+ </div>
17
+ </section>
18
+ <footer class="modal-card-foot">
19
+ <button data-action="cloudinary-browse-media#closeModal" class="button is-success">Done</button>
20
+ </footer>
21
+ </div>
22
+ </div>
@@ -0,0 +1,42 @@
1
+ <%-
2
+ input_classes = ['input yarii-cloudinary--text-input']
3
+ input_classes << className if local_assigns[:className]
4
+ name = name_from_variable(assigns)
5
+ value = value_from_variable(assigns)
6
+ %>
7
+ <div
8
+ data-controller="cloudinary-single-media"
9
+ data-cloudinary-single-media-cloud="<%= ENV['yarii_cloudinary_cloud_name'] %>"
10
+ <% if ENV['yarii_cloudinary_tag'] -%>data-cloudinary-single-media-upload-preset="<%= ENV['yarii_cloudinary_tag'] %>"<% end -%>
11
+ data-cloudinary-single-media-browse-path="<%= yarii_cloudinary.media_path %>"
12
+ data-cloudinary-single-media-form-thumbnail-path="<%= yarii_cloudinary.form_thumbnail_medium_path(0) %>"
13
+ class="yarii-cloudinary--field field"
14
+ >
15
+ <label class="label"><%= label %></label>
16
+ <div class="control">
17
+ <div class="level">
18
+ <div class="level-item is-narrow">
19
+ <div data-target="cloudinary-single-media.thumbnail">
20
+ <% if value.present? %>
21
+ <%= render 'yarii_cloudinary/media/form_thumbnail', public_id: value %>
22
+ <% else %>
23
+ <span class="icon is-medium has-text-info"><i class="fa fa-picture-o fa-lg"></i></span>
24
+ <% end %>
25
+ </div>
26
+ </div>
27
+ <div class="level-item">
28
+ <%= content_tag :input, nil, name: name, value: value, class: input_classes.join(' '), type: 'text', placeholder: placeholder, data: {target: 'cloudinary-single-media.input'} %>
29
+ </div>
30
+ <div class="level-item is-narrow">
31
+ <button data-action="cloudinary-single-media#open" class="button is-primary">
32
+ <span class="icon"><i class="fa fa-upload"></i></span>
33
+ <span>Upload</span>
34
+ </button>
35
+ <button data-action="cloudinary-single-media#browse" class="button is-success">
36
+ <span class="icon"><i class="fa fa-picture-o"></i></span>
37
+ <span>Browse</span>
38
+ </button>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ </div>
@@ -0,0 +1,50 @@
1
+ <%-
2
+ input_classes = ['input yarii-cloudinary--text-input']
3
+ input_classes << className if local_assigns[:className]
4
+ name = name_from_variable(local_assigns)
5
+ value = value_from_variable(local_assigns)
6
+ %>
7
+ <div
8
+ data-controller="cloudinary-multiple-media"
9
+ <% if value.is_a?(Array)
10
+ -%>data-cloudinary-multiple-media-ids="<%= value.join(',') %>"
11
+ <% end
12
+ -%>
13
+ data-cloudinary-multiple-media-cloud="<%= ENV['yarii_cloudinary_cloud_name'] %>"
14
+ <% if ENV['yarii_cloudinary_tag'] -%>data-cloudinary-multiple-media-upload-preset="<%= ENV['yarii_cloudinary_tag'] %>"<% end -%>
15
+ data-cloudinary-multiple-media-browse-path="<%= yarii_cloudinary.media_path %>"
16
+ data-cloudinary-multiple-media-form-item-path="<%= yarii_cloudinary.multiple_form_item_medium_path(0) %>"
17
+ data-cloudinary-multiple-media-name="<%= name %>"
18
+ data-cloudinary-multiple-media-input-classes="<%= input_classes.join(' ') %>"
19
+ data-cloudinary-multiple-media-placeholder="<%= placeholder.gsub(/"/, '&quot;') %>"
20
+ class="yarii-cloudinary--field field"
21
+ >
22
+ <label class="label"><%= label %></label>
23
+ <div class="control">
24
+ <div data-target="cloudinary-multiple-media.rows">
25
+ <% if value.is_a? Array %>
26
+ <% value.each_with_index do |public_id, index| %>
27
+ <%=
28
+ render 'yarii_cloudinary/media/multiple_form_item',
29
+ name: "#{name}[]",
30
+ public_id: public_id,
31
+ index: index,
32
+ input_classes: input_classes.join(' '),
33
+ placeholder: placeholder
34
+ %>
35
+ <% end %>
36
+ <% end %>
37
+ </div>
38
+
39
+ <div class="has-text-centered mt-6">
40
+ <button data-action="cloudinary-multiple-media#add" class="button is-primary">
41
+ <span class="icon"><i class="fa fa-upload"></i></span>
42
+ <span>Add via Upload</span>
43
+ </button>
44
+ <button data-action="cloudinary-multiple-media#addBrowse" class="button is-success">
45
+ <span class="icon"><i class="fa fa-picture-o"></i></span>
46
+ <span>Add via Browse</span>
47
+ </button>
48
+ </div>
49
+ </div>
50
+ </div>
data/config/routes.rb ADDED
@@ -0,0 +1,8 @@
1
+ YariiCloudinary::Engine.routes.draw do
2
+ resources :media do
3
+ member do
4
+ get 'form_thumbnail'
5
+ get 'multiple_form_item'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ process.env.NODE_ENV = process.env.NODE_ENV || 'development'
2
+
3
+ const environment = require('./environment')
4
+
5
+ module.exports = environment.toWebpackConfig()
@@ -0,0 +1,3 @@
1
+ const { environment } = require('@rails/webpacker')
2
+
3
+ module.exports = environment
@@ -0,0 +1,5 @@
1
+ process.env.NODE_ENV = process.env.NODE_ENV || 'production'
2
+
3
+ const environment = require('./environment')
4
+
5
+ module.exports = environment.toWebpackConfig()
@@ -0,0 +1,5 @@
1
+ process.env.NODE_ENV = process.env.NODE_ENV || 'staging'
2
+
3
+ const environment = require('./environment')
4
+
5
+ module.exports = environment.toWebpackConfig()
@@ -0,0 +1,5 @@
1
+ process.env.NODE_ENV = process.env.NODE_ENV || 'development'
2
+
3
+ const environment = require('./environment')
4
+
5
+ module.exports = environment.toWebpackConfig()
@@ -0,0 +1,110 @@
1
+ # Note: You must restart bin/webpack-dev-server for changes to take effect
2
+
3
+ default: &default
4
+ source_path: app/javascript
5
+ source_entry_path: packs
6
+ public_root_path: public
7
+ # use a different sub-folder name
8
+ public_output_path: yarii-cloudinary-packs
9
+
10
+ cache_path: tmp/cache/webpacker
11
+ check_yarn_integrity: false
12
+ webpack_compile_output: false
13
+
14
+ # Additional paths webpack should lookup modules
15
+ # ['app/assets', 'engine/foo/app/assets']
16
+ resolved_paths: []
17
+
18
+ # Reload manifest.json on all requests so we reload latest compiled packs
19
+ cache_manifest: false
20
+
21
+ # Extract and emit a css file
22
+ extract_css: true
23
+
24
+ static_assets_extensions:
25
+ - .jpg
26
+ - .jpeg
27
+ - .png
28
+ - .gif
29
+ - .tiff
30
+ - .ico
31
+ - .svg
32
+ - .eot
33
+ - .otf
34
+ - .ttf
35
+ - .woff
36
+ - .woff2
37
+
38
+ extensions:
39
+ - .mjs
40
+ - .js
41
+ - .sass
42
+ - .scss
43
+ - .css
44
+ - .module.sass
45
+ - .module.scss
46
+ - .module.css
47
+ - .png
48
+ - .svg
49
+ - .gif
50
+ - .jpeg
51
+ - .jpg
52
+
53
+ development:
54
+ <<: *default
55
+ compile: true
56
+
57
+ # Verifies that versions and hashed value of the package contents in the project's package.json
58
+ check_yarn_integrity: true
59
+
60
+ # Reference: https://webpack.js.org/configuration/dev-server/
61
+ dev_server:
62
+ https: false
63
+ host: localhost
64
+ port: 3035
65
+ public: localhost:3035
66
+ hmr: false
67
+ # Inline should be set to true if using HMR
68
+ inline: true
69
+ overlay: true
70
+ compress: true
71
+ disable_host_check: true
72
+ use_local_ip: false
73
+ quiet: false
74
+ headers:
75
+ 'Access-Control-Allow-Origin': '*'
76
+ watch_options:
77
+ ignored: '**/node_modules/**'
78
+
79
+
80
+ test:
81
+ <<: *default
82
+ compile: true
83
+
84
+ # Compile test packs to a separate directory
85
+ public_output_path: packs-test
86
+
87
+ staging:
88
+ <<: *default
89
+
90
+ # Staging, like Production, depends on precompilation of packs prior to booting for performance.
91
+ compile: false
92
+
93
+ # Extract and emit a css file
94
+ extract_css: true
95
+
96
+ # Cache manifest.json for performance
97
+ cache_manifest: true
98
+
99
+
100
+ production:
101
+ <<: *default
102
+
103
+ # Production depends on precompilation of packs prior to booting for performance.
104
+ compile: false
105
+
106
+ # Extract and emit a css file
107
+ extract_css: true
108
+
109
+ # Cache manifest.json for performance
110
+ cache_manifest: true
@@ -0,0 +1,12 @@
1
+ class CreateYariiSites < ActiveRecord::Migration[6.0]
2
+ def change
3
+ create_table :yarii_sites do |t|
4
+ t.string :title
5
+ t.string :preview_base_url
6
+ t.string :published_base_url
7
+ t.string :content_base_path
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,61 @@
1
+ def ensure_log_goes_to_stdout
2
+ old_logger = Webpacker.logger
3
+ Webpacker.logger = ActiveSupport::Logger.new(STDOUT)
4
+ yield
5
+ ensure
6
+ Webpacker.logger = old_logger
7
+ end
8
+
9
+
10
+ namespace :yarii_cloudinary do
11
+ namespace :webpacker do
12
+ desc "Install deps with yarn"
13
+ task :yarn_install do
14
+ Dir.chdir(File.join(__dir__, "../..")) do
15
+ system "yarn install --no-progress --production"
16
+ end
17
+ end
18
+
19
+ desc "Compile JavaScript packs using webpack for production with digests"
20
+ task compile: [:yarn_install, :environment] do
21
+ Webpacker.with_node_env("production") do
22
+ ensure_log_goes_to_stdout do
23
+ if YariiCloudinary.webpacker.commands.compile
24
+ # Successful compilation!
25
+ puts "YariiCloudinary Plugin -- Webpacker success"
26
+ else
27
+ # Failed compilation
28
+ puts "YariiCloudinary Plugin -- something's wrong with Webpacker!"
29
+ exit!
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ def yarn_install_available?
38
+ rails_major = Rails::VERSION::MAJOR
39
+ rails_minor = Rails::VERSION::MINOR
40
+
41
+ rails_major > 5 || (rails_major == 5 && rails_minor >= 1)
42
+ end
43
+
44
+ def enhance_assets_precompile
45
+ # yarn:install was added in Rails 5.1
46
+ deps = yarn_install_available? ? [] : ["yarii_cloudinary:webpacker:yarn_install"]
47
+ Rake::Task["assets:precompile"].enhance(deps) do
48
+ Rake::Task["yarii_cloudinary:webpacker:compile"].invoke
49
+ end
50
+ end
51
+
52
+ # Compile packs after we've compiled all other assets during precompilation
53
+ skip_webpacker_precompile = %w(no false n f).include?(ENV["WEBPACKER_PRECOMPILE"])
54
+
55
+ unless skip_webpacker_precompile
56
+ if Rake::Task.task_defined?("assets:precompile")
57
+ enhance_assets_precompile
58
+ else
59
+ Rake::Task.define_task("assets:precompile" => "yarii_cloudinary:webpacker:compile")
60
+ end
61
+ end
@@ -0,0 +1,12 @@
1
+ module YariiCloudinary
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace YariiCloudinary
4
+
5
+ ROOT_PATH = Pathname.new(File.join(__dir__, "..", ".."))
6
+
7
+ config.app_middleware.use(
8
+ Rack::Static,
9
+ urls: ["/yarii-cloudinary-packs"], root: ROOT_PATH.join("public")
10
+ )
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module YariiCloudinary
2
+ VERSION = '0.2.0'
3
+ end
@@ -0,0 +1,15 @@
1
+ require "yarii-cloudinary/engine"
2
+
3
+ module YariiCloudinary
4
+ ROOT_PATH = Pathname.new(File.join(__dir__, ".."))
5
+
6
+ class << self
7
+ def webpacker
8
+ @webpacker ||= ::Webpacker::Instance.new(
9
+ root_path: ROOT_PATH,
10
+ config_path: ROOT_PATH.join("config/webpacker.yml")
11
+ )
12
+ end
13
+ end
14
+ end
15
+
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yarii-cloudinary
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Jared White
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-04-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 6.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 6.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: webpacker
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: cloudinary
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.12'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.12'
55
+ description: Allows images to be loaded and viewed in Yarii via the Cloudinary service
56
+ email:
57
+ - jared@jaredwhite.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - LICENSE
63
+ - README.md
64
+ - Rakefile
65
+ - app/controllers/yarii_cloudinary/application_controller.rb
66
+ - app/controllers/yarii_cloudinary/media_controller.rb
67
+ - app/helpers/yarii_cloudinary/application_helper.rb
68
+ - app/javascript/controllers/cloudinary_browse_media_controller.js
69
+ - app/javascript/controllers/cloudinary_multiple_media_controller.js
70
+ - app/javascript/controllers/cloudinary_single_media_controller.js
71
+ - app/javascript/controllers/index.js
72
+ - app/javascript/packs/application.js
73
+ - app/jobs/yarii_cloudinary/application_job.rb
74
+ - app/styles/index.scss
75
+ - app/views/yarii_cloudinary/application/yarii_cloudinary_head.erb
76
+ - app/views/yarii_cloudinary/media/_browse_thumbnail.html.erb
77
+ - app/views/yarii_cloudinary/media/_form_thumbnail.html.erb
78
+ - app/views/yarii_cloudinary/media/_modal.html.erb
79
+ - app/views/yarii_cloudinary/media/_multiple_form_item.html.erb
80
+ - app/views/yarii_cloudinary/media/index.html.erb
81
+ - app/views/yarii_editor/editor/_cloudinary.html.erb
82
+ - app/views/yarii_editor/editor/_cloudinary_multiple.html.erb
83
+ - config/routes.rb
84
+ - config/webpack/development.js
85
+ - config/webpack/environment.js
86
+ - config/webpack/production.js
87
+ - config/webpack/staging.js
88
+ - config/webpack/test.js
89
+ - config/webpacker.yml
90
+ - db/migrate/20190923000809_create_yarii_sites.rb
91
+ - lib/tasks/yarii_cloudinary_tasks.rake
92
+ - lib/yarii-cloudinary.rb
93
+ - lib/yarii-cloudinary/engine.rb
94
+ - lib/yarii-cloudinary/version.rb
95
+ homepage: https://whitefusion.io
96
+ licenses:
97
+ - MIT
98
+ metadata: {}
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubygems_version: 3.0.8
115
+ signing_key:
116
+ specification_version: 4
117
+ summary: Allows images to be loaded and viewed in Yarii via the Cloudinary service
118
+ test_files: []