oxen_media 0.0.6 → 0.3.4

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/components/dropzone.js.jsx.coffee +298 -0
  3. data/app/assets/javascripts/components/photocard.js.jsx.coffee +77 -0
  4. data/app/assets/javascripts/components/photos.js.jsx.coffee +68 -0
  5. data/app/assets/javascripts/oxen_media.js +1 -3
  6. data/app/assets/stylesheets/oxen_media/drop_zone.css +86 -0
  7. data/app/assets/stylesheets/oxen_media.css +3 -0
  8. data/app/controllers/photos_controller.rb +26 -0
  9. data/app/models/ox_photo.rb +17 -0
  10. data/app/policies/ox_photo_policy.rb +3 -0
  11. data/app/uploaders/photo_uploader.rb +53 -0
  12. data/app/views/photos/_photo.html.haml +11 -0
  13. data/app/views/photos/create.js.haml +1 -0
  14. data/app/views/photos/index.json.jbuilder +5 -0
  15. data/lib/oxen_media/version.rb +1 -1
  16. data/lib/oxen_media.rb +1 -1
  17. data/oxen_media.gemspec +4 -4
  18. metadata +15 -86
  19. data/app/assets/javascripts/jsrender.min.js +0 -4
  20. data/app/assets/javascripts/jsrender.min.js.map +0 -463
  21. data/app/assets/javascripts/oxen_media/carrier_wave_cropper.js.coffee +0 -22
  22. data/app/assets/javascripts/oxen_media/media.js.coffee +0 -469
  23. data/app/assets/javascripts/oxen_media/medium_pane.js.coffee +0 -107
  24. data/app/assets/javascripts/templates/selected_files.html +0 -35
  25. data/app/assets/stylesheets/media.css +0 -10
  26. data/app/assets/stylesheets/scaffold.css +0 -56
  27. data/app/controllers/media_controller.rb +0 -106
  28. data/app/helpers/media_helper.rb +0 -2
  29. data/app/models/medium.rb +0 -25
  30. data/app/policies/oxen_medium_policy.rb +0 -12
  31. data/app/uploaders/medium_uploader.rb +0 -153
  32. data/app/views/media/_fields.html.haml +0 -42
  33. data/app/views/media/_form.html.haml +0 -48
  34. data/app/views/media/_media.html.haml +0 -18
  35. data/app/views/media/_medium.html.haml +0 -25
  36. data/app/views/media/_medium_fields.html.haml +0 -4
  37. data/app/views/media/create.js.haml +0 -2
  38. data/app/views/media/crop.html.haml +0 -3
  39. data/app/views/media/edit.html.haml +0 -2
  40. data/app/views/media/index.html.haml +0 -29
  41. data/app/views/media/index.json.jbuilder +0 -4
  42. data/app/views/media/new.html.erb +0 -5
  43. data/app/views/media/show.html.haml +0 -21
  44. data/app/views/media/show.json.jbuilder +0 -1
  45. data/app/views/media/update_crop.js.haml +0 -1
  46. /data/app/assets/javascripts/{oxen_media/.keep → components/.gitkeep} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c7273afa8eefee9afc142d6c7c766d95949469fe
4
- data.tar.gz: 4ec25f27d0c7d62d86f1e6c65def1b56897d7fd1
3
+ metadata.gz: 969f6e62d5ffc5306313af425df4ad912e833635
4
+ data.tar.gz: 38d1dab4be570218ac019416769bbc0b0bfd6db4
5
5
  SHA512:
6
- metadata.gz: 1341019df0518f36be9fb803a97797cfcb87ab20da2d2bc0365ec356bb6a000ef5da8df6ba3c4e03fdf51c85da98dee892aaca3a72006f91c9f62ec3464b4df6
7
- data.tar.gz: 2ec4a44ac2bb5b7bf1431f4f1866d224242978cf0f0a4f6806c1f8efb0529c69792e8cbce951ff04aa86ec2239a104c380302bac2c11e80bb626a1be1937c736
6
+ metadata.gz: f36442f070349750f997d8579c6900551572c0ca1dbf22b29d81544efad8ef441ff8f337ff11c1d7e645e2204d4f4a2d4a04efe24beb4f2de5915dcda71e6a25
7
+ data.tar.gz: 97ae113d18282e2d85dd2e9a61f6a1c875c1058c2f2369d1ec252d28f5058151b9d3643ecd7ff7c26527d572362bc035f943d98703d2b93f74c70891955925c2
@@ -0,0 +1,298 @@
1
+ { div, input } = React.DOM
2
+
3
+ BLANK_FUNCTION = () ->
4
+
5
+
6
+ class @DropZone extends React.Component
7
+ constructor: (props) ->
8
+ super props
9
+ @state =
10
+ entity: props.entity
11
+ key: props.key
12
+ record: props.record
13
+ reader: null
14
+ shared: new App.Shared()
15
+ url: props.url
16
+
17
+ # filesID: {}
18
+
19
+ @propTypes =
20
+ # record: React.PropTypes.node
21
+ entity: React.PropTypes.string
22
+ key: React.PropTypes.number
23
+ id: React.PropTypes.string
24
+ classes: React.PropTypes.string
25
+ url: React.PropTypes.string
26
+ onDragStart: React.PropTypes.func
27
+ onDragEnter: React.PropTypes.func
28
+ onDrop: React.PropTypes.func
29
+ disabled: React.PropTypes.bool
30
+
31
+ @defaultProps: ->
32
+ disabled: true
33
+ entity: 'stock_item'
34
+ record: ''
35
+ classes: ''
36
+ id: 'dropzone'
37
+ key: 0
38
+ onDragStart: BLANK_FUNCTION
39
+ onDragEnter: BLANK_FUNCTION
40
+ onDrop: BLANK_FUNCTION
41
+
42
+ # reader = () ->
43
+ #
44
+ # currentFile: (f) =>
45
+ # #
46
+ # # if (i>-1)
47
+ # # # remove element
48
+ # # ids = @state.filesID.slice() # copy array
49
+ # # ids.splice(i, 1) # remove element
50
+ # # @setState filesID: ids # update state
51
+ # # else
52
+ # # @setState filesID:
53
+
54
+ progressPercentElement = ''
55
+
56
+ abortRead: () =>
57
+ @reader.abort()
58
+
59
+ preventDefaultClick: (e) =>
60
+ e.preventDefault()
61
+ e.stopPropagation()
62
+
63
+ onDragStart: (e) =>
64
+ @preventDefaultClick(e)
65
+
66
+ onDragOver: (e) =>
67
+ @preventDefaultClick(e)
68
+ # if(this.containerAcceptsDropData(e.dataTransfer.types)) { e.preventDefault(); }
69
+ # var over = parseInt(e.currentTarget.dataset.key);
70
+ # if(e.clientY - e.currentTarget.offsetTop > e.currentTarget.offsetHeight / 2) { over++; }
71
+ # if(over !== this.state.hoverOver) { this.setState({ hoverOver: over }); }
72
+ e.dataTransfer.dropEffect = 'copy';
73
+ return false;
74
+
75
+ onDragEnter: (e) =>
76
+ @preventDefaultClick(e)
77
+ $('#drop_zone_upload_bay').addClass('hovering_files')
78
+
79
+ onDragLeave: (e) =>
80
+ @preventDefaultClick(e)
81
+ $('#drop_zone_upload_bay').removeClass('hovering_files')
82
+
83
+ onDrop: (e) =>
84
+ @preventDefaultClick(e)
85
+ dt = e.dataTransfer
86
+ @handleFiles(dt.files)
87
+
88
+ clickDropZone: (e) =>
89
+ $('#file_browser').trigger('click')
90
+
91
+ changeDropZone: (e) =>
92
+ dt = e.target
93
+ @handleFiles(dt.files)
94
+
95
+
96
+ # .drop_zone.delimiter
97
+ # .drop_zone.upload_bay.stitched
98
+ # .drop_zone.file_browser
99
+ # %input{ type: "file", multiple: true, id: "file_browser" }
100
+ # .drop_zone.user_notice
101
+ # %span
102
+ # træk dine filer her; eller tryk og vælg
103
+ # .drop_zone.file_hangar
104
+ #
105
+ # :coffeescript
106
+ # $('.drop_zone.user_notice').on 'dragenter', (e) =>
107
+ # $('.drop_zone.upload_bay').addClass 'hovering_files'
108
+ # $('.drop_zone.user_notice').on 'dragleave', (e) =>
109
+ # $('.drop_zone.upload_bay').removeClass 'hovering_files'
110
+ # $('.drop_zone.user_notice').on 'click', (e) =>
111
+ # $('#file_browser').trigger 'click'
112
+
113
+ render: ->
114
+
115
+ photos = React.createElement( Photos, url: @props.url, pollInterval: 2000, id: 'existing_photos', classes: 'drop_zone existing_file_hangar', entity: @props.entity )
116
+
117
+ if @props.disabled
118
+ div
119
+ className: 'drop_zone file_hangar row'
120
+ id: 'photos'
121
+ photos
122
+ else
123
+ try
124
+
125
+ div
126
+ className: 'drop_zone delimiter'
127
+ div
128
+ className: 'drop_zone upload_bay row stitched'
129
+ id: 'drop_zone_upload_bay'
130
+ onClick: @clickDropZone
131
+ div
132
+ className: 'drop_zone file_browser'
133
+ input
134
+ className: "file_browser"
135
+ type: "file"
136
+ id: "file_browser"
137
+ name: "files"
138
+ multiple: 'true'
139
+ onChange: @changeDropZone
140
+ div
141
+ className: 'drop_zone user_notice'
142
+ onDragOver: @onDragOver
143
+ onDragEnter: @onDragEnter
144
+ onDragLeave: @onDragLeave
145
+ # onClick: @clickDropZone
146
+ onDrop: @onDrop
147
+ 'træk dine billeder herover og slip dem; eller klik her og vælg dem!'
148
+ div
149
+ className: "progress"
150
+ id: "progress_bar"
151
+ div
152
+ className: "percent"
153
+ '0%'
154
+ div
155
+ className: 'drop_zone file_hangar row'
156
+ id: 'photos'
157
+ photos
158
+
159
+ catch
160
+ div
161
+ className: ''
162
+ @state.err
163
+
164
+ handleFiles: (files) =>
165
+ @bindDeleteActions()
166
+ count = 0
167
+ for file in files
168
+ count=count+1
169
+ # Only process image files.
170
+ continue if (!file.type.match('image.*'))
171
+
172
+ file.id=Date.now() + count
173
+
174
+ # place file in the dropzone
175
+ @placeFileInDOM(file)
176
+
177
+ # start uploading it
178
+ # @uploadFile(file)
179
+
180
+
181
+ bindDeleteActions: =>
182
+ $(document.body).unbind('click.delete_photo')
183
+ $(document.body).on 'click.delete_photo', 'i.delete.file_upload', @handleDelete
184
+
185
+ handleDelete: (e) =>
186
+ e.preventDefault()
187
+ id=$(e.target).closest('a').next('input').val()
188
+
189
+ jqxhr = $.ajax
190
+ method: 'DELETE'
191
+ url: "/photos/" + id + ".js"
192
+ dataType: 'html'
193
+ jqxhr.done (r) =>
194
+ $(e.target).closest('.card').fadeOut 'slow', () => #animate({ "opacity": "0" }, "slow" )
195
+ $(e.target).closest('.card').remove()
196
+ jqxhr.fail (e,msg) =>
197
+ swal "Fejl!", "Det var ikke muligt at slette billedet - fejlen er:\n" + msg, "error"
198
+
199
+ uploadFile: (f) =>
200
+
201
+ formData = new FormData()
202
+ formData.append 'photo[image]', f
203
+ $('#drop_zone_upload_bay').removeClass('hovering_files').addClass('loading_files')
204
+ jqxhr = $.ajax
205
+ url : '/photos.js'
206
+ type : 'POST'
207
+ data : formData
208
+ processData: false
209
+ contentType: false
210
+ dataType: 'html'
211
+
212
+ .done (r) =>
213
+ $('#drop_zone_upload_bay').removeClass('loading_files')
214
+ $('#photos_'+f.id+'_id').val(r.replace(/\s/g, ""))
215
+
216
+ .fail (e,msg) =>
217
+ $('#photos_'+f.id+'_id').closest('.card').remove()
218
+ $('#drop_zone_upload_bay').removeClass('loading_files')
219
+ $('#drop_zone_upload_bay').addClass('error_loading_files')
220
+ setTimeout(@removeLoadError,2000)
221
+ swal "Fejl!", "Der opstod desværre en fejl - beskrivelsen er:\n" + msg, "error"
222
+
223
+ errorHandler: (evt) =>
224
+ switch evt.target.error.code
225
+ when evt.target.error.NOT_FOUND_ERR then alert('File Not Found!')
226
+ when evt.target.error.NOT_READABLE_ERR then alert('File is not readable')
227
+ when evt.target.error.ABORT_ERR then console.log 'aborted!! line 227 in dropzone.js.jsx.coffee'
228
+ else alert('An error occurred reading this file.')
229
+
230
+ removeLoadError: (e) =>
231
+ $('#drop_zone_upload_bay').removeClass('error_loading_files')
232
+
233
+ showProgress: (p) =>
234
+ progressPercentElement = document.querySelector('.percent')
235
+ progressPercentElement.style.width = p + '%'
236
+ progressPercentElement.textContent = p + '%'
237
+ if p>99
238
+ @state.shared.fadeItOut document.getElementById('progress_bar')
239
+
240
+ updateProgress: (e) =>
241
+ # e is an ProgressEvent.
242
+ percentLoaded = 0
243
+ if (e.lengthComputable)
244
+ percentLoaded = Math.round((e.loaded / e.total) * 100)
245
+ # Increase the progress bar length.
246
+ @showProgress(percentLoaded) if (percentLoaded < 100)
247
+ @showProgress(100) if (percentLoaded > 99)
248
+
249
+
250
+ placeFileInDOM: (file) =>
251
+ # Reset progress indicator on new file selection.
252
+ # @updateProgress ''
253
+
254
+ @reader = new FileReader()
255
+ # @currentFile(file)
256
+
257
+ @reader.onerror = @errorHandler
258
+ @reader.onprogress = @updateProgress
259
+ @reader.onabort = (e) =>
260
+ alert('File read cancelled')
261
+
262
+ @reader.onloadstart = (e) =>
263
+ document.getElementById('progress_bar').className = 'loading'
264
+
265
+ @reader.onload = (e) =>
266
+
267
+ # Render thumbnail.
268
+ img = document.createElement('div')
269
+ img.className = "col sl12 m6 l3"
270
+ img.innerHTML = [ '<div class="card">',
271
+ '<div class="card-image waves-effect waves-block waves-light">',
272
+ '<div class="progress fileupload-progress fade" style="display: none">',
273
+ '<div class="determinate" style="width: 0%"></div>',
274
+ '</div>',
275
+ '<img class="thumb" src="', e.target.result, '" title="', escape(file.name), '"/>',
276
+ '<div class="row">',
277
+ '<div class="col s2">',
278
+ '<a class="delete file-upload" href="#!">',
279
+ '<i class="material-icons small delete file_upload red-text">',
280
+ 'delete',
281
+ '</i> </a>',
282
+ '</div>',
283
+ '<div class="col s10">',
284
+ window.build_drop_zone_photo file, @props.entity
285
+ '</div>',
286
+ '</div>',
287
+ '</div>'
288
+ ].join('')
289
+
290
+ document.getElementById('photos').appendChild(img, null)
291
+ @uploadFile file
292
+
293
+ # Ensure that the progress bar displays 100% at the end.
294
+ @showProgress(100)
295
+
296
+
297
+ # Read in the image file as a data URL.
298
+ @reader.readAsDataURL(file)
@@ -0,0 +1,77 @@
1
+ { div, img, input, a, i, label } = React.DOM
2
+
3
+ class @PhotoCard extends React.Component
4
+ constructor: (props) ->
5
+ super props
6
+ @state =
7
+ key: props.key
8
+ entity: props.entity
9
+ record: props.record
10
+
11
+ @propTypes =
12
+ # record: React.PropTypes.node
13
+ key: React.PropTypes.number
14
+ entity: React.PropTypes.string
15
+
16
+ @defaultProps: ->
17
+ record: ''
18
+ key: 0
19
+ entity: 'stock_item'
20
+
21
+ show_on_new: () =>
22
+ if @props.record.id == 0
23
+ ''
24
+ else
25
+ 'hide'
26
+
27
+ handleDelete: (e) =>
28
+ e.preventDefault()
29
+ jqxhr = $.ajax
30
+ method: 'DELETE'
31
+ url: "/photos/#{ @state.record.id }"
32
+ dataType: 'html'
33
+ jqxhr.done () =>
34
+ $(e.target).closest('.card').fadeOut 'slow', () => #animate({ "opacity": "0" }, "slow" )
35
+ @props.deleteRecord @state.record
36
+ jqxhr.fail (e,msg) =>
37
+ swal "Fejl!", "Det var ikke muligt at slette billedet - fejlen er:\n" + msg, "error"
38
+
39
+ render: ->
40
+
41
+ div
42
+ className: "col s12 m6 l3"
43
+ div
44
+ className: "card"
45
+ div
46
+ className: "card-image waves-effect waves-block waves-light"
47
+ div
48
+ className: "progress fileupload-progress fade"
49
+ style: display: 'none'
50
+ div
51
+ className: "determinate"
52
+ style: width: '0%'
53
+ img
54
+ className: "activator"
55
+ id: @props.key
56
+ src: @props.record.image.url
57
+ div
58
+ className: "row"
59
+ div
60
+ className: "col s2"
61
+ a
62
+ className: "delete file-upload"
63
+ href: "#!"
64
+ i
65
+ className: "material-icons small file_upload red-text"
66
+ onClick: @handleDelete
67
+ 'delete'
68
+ div
69
+ className: "col s10"
70
+ input
71
+ className: "files_uploaded"
72
+ id: "photos_#{@props.record.id}_id"
73
+ type: "hidden"
74
+ name: "#{@props.entity}[ps][#{@props.record.id}][id]"
75
+ value: "#{@props.record.id}"
76
+ @props.record.purpose || ""
77
+ @props.record.title || ""
@@ -0,0 +1,68 @@
1
+ { div, a, i } = React.DOM
2
+
3
+ class @Photos extends React.Component
4
+ constructor: (props) ->
5
+ super props
6
+ @state =
7
+ url: props.url
8
+ err: 'Indlæser billeder...'
9
+ entity: props.entity
10
+
11
+ @propTypes =
12
+ url: React.PropTypes.string
13
+ id: React.PropTypes.string
14
+ classes: React.PropTypes.string
15
+ entity: React.PropTypes.string
16
+
17
+ @defaultProps: ->
18
+ records: []
19
+ url: ''
20
+ id: 'oldphotos'
21
+ classes: 'drop_zone old_files_hangar'
22
+ entity: 'stock_item'
23
+
24
+ componentDidMount: ->
25
+ @loadPhotosFromServer()
26
+ # setInterval(@loadPhotosFromServer, @props.pollInterval); # use polling, can be other eg. WebSockets
27
+
28
+ addRecord: (record) ->
29
+ records = React.addons.update(@state.records, { $push: [record] })
30
+ @setState records: records
31
+
32
+ deleteRecord: (record) =>
33
+ index = @state.records.indexOf record
34
+ records = React.addons.update(@state.records, { $splice: [[index, 1]] })
35
+ @setState records: records
36
+
37
+ render: ->
38
+ try
39
+ cards = []
40
+ for record in @state.records
41
+ cards.push React.createElement PhotoCard, { key: record.id, record: record, deleteRecord: @deleteRecord, entity: @props.entity }
42
+
43
+ div
44
+ className: @props.classes
45
+ id: @props.id
46
+ div
47
+ cards
48
+
49
+ catch
50
+ div
51
+ className: ''
52
+ @state.err
53
+
54
+ loadPhotosFromServer: ->
55
+ $.ajax
56
+ url: @state.url,
57
+ dataType: 'json',
58
+ cache: false,
59
+ success: (data) =>
60
+ @setState {records: data}
61
+ error: (xhr, status, err) =>
62
+ @setState { err: err.toString() }
63
+
64
+ # $.ajax {
65
+ # url: @props.url,
66
+ # dataType: 'json',
67
+ # type: 'POST',
68
+ # data: comment,
@@ -1,3 +1 @@
1
- //= require_tree ./oxen_media
2
- //= require jsrender.min
3
- //= require jquery.jcrop
1
+ //= require_tree ./components
@@ -0,0 +1,86 @@
1
+ /* dropzone styling */
2
+ .thumb {
3
+ width: 100%;
4
+ }
5
+
6
+ #progress_bar {
7
+ margin: 50px 40px 0px 30px;
8
+ padding: 3px;
9
+ border: 1px solid grey;
10
+ font-size: 7px;
11
+ clear: both;
12
+ opacity: 0;
13
+ -moz-transition: opacity 1s linear;
14
+ -o-transition: opacity 1s linear;
15
+ -webkit-transition: opacity 1s linear;
16
+ }
17
+ #progress_bar.loading {
18
+ opacity: 1.0;
19
+ }
20
+ #progress_bar .percent {
21
+ background-color: #99ccff;
22
+ height: auto;
23
+ width: 0;
24
+ }
25
+
26
+ .drop_zone.delimiter {
27
+ height: 150px;
28
+ width: 100%;
29
+ padding: 0px;
30
+ margin: 0px;
31
+ position: relative
32
+ }
33
+ .drop_zone.upload_bay {
34
+ width: 100%;
35
+ height: 80px;
36
+ position: relative;
37
+ padding: 0px;
38
+ margin: 0px;
39
+ background-color: #26a69a;
40
+ border-radius: 8px;
41
+ }
42
+ .drop_zone.user_notice {
43
+ position: absolute;
44
+ top: 0px;
45
+ border: 0px;
46
+ width: 100%;
47
+ height: 100%;
48
+ padding: 30px;
49
+ }
50
+ .drop_zone.file_browser {
51
+ width: 100%;
52
+ height: 100%;
53
+ position: absolute;
54
+ top: 0px;
55
+ opacity: 0;
56
+ }
57
+ .drop_zone.file_hangar {
58
+ min-height: 100px;
59
+ height: 100%;
60
+ background-color: transparent;
61
+ }
62
+ .hovering_files {
63
+ background-color: #0ABFBC !important;
64
+ }
65
+ .loading_files {
66
+ background-color: #f57c00 !important;
67
+ }
68
+ .error_loading_files {
69
+ background-color: red !important;
70
+ }
71
+ .stitched {
72
+ padding: 20px;
73
+ margin: 10px;
74
+ color: #fff;
75
+ font-size: 12px;
76
+ font-weight: 400;
77
+ line-height: 1.3em;
78
+ border: 1px dashed #fff;
79
+ border-radius: 8px;
80
+ box-shadow: 0 0 0 4px #26a69a, 2px 2px 6px 4px rgba(1, 1, 1, 0.25);
81
+ font-weight: normal;
82
+ }
83
+ .drop_zone .card .row {
84
+ margin-bottom: 0px
85
+ }
86
+ /* end of dropzone styling */
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require_tree ./oxen_media
3
+ */
@@ -0,0 +1,26 @@
1
+ class PhotosController < AbstractResourcesController
2
+
3
+ private
4
+
5
+ def resource_params
6
+ params.require(:photo).permit( :id, :image )
7
+ end
8
+
9
+ #
10
+ #
11
+ # find all resources
12
+ def find_all_resources options
13
+ return false unless policy_scope(resource_class)
14
+ policy_scope(resource_class)
15
+ end
16
+ #
17
+ #
18
+ # find queried resources collection - implement on each controller to customize
19
+ def find_resources_queried options={}
20
+ lot = parent? ? parent.send(resource_name) : resource_class
21
+ res = case params[:subtype]
22
+ when nil; Photo.search policy_scope(lot), params[:q]
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,17 @@
1
+ class OxPhoto < AbstractResource
2
+ self.table_name = "photos"
3
+
4
+ has_paper_trail
5
+ #photo belongs to album
6
+ # belongs_to :stock_item
7
+ # belongs_to :account
8
+
9
+ #validations
10
+ # validates :stock_item, presence: true
11
+
12
+ include Rails.application.routes.url_helpers
13
+
14
+ # Photo uploader using carrierwave
15
+ mount_uploader :image, PhotoUploader
16
+
17
+ end
@@ -0,0 +1,3 @@
1
+ class OxPhotoPolicy < AbstractResourcePolicy
2
+
3
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ class PhotoUploader < CarrierWave::Uploader::Base
4
+
5
+ # Include RMagick or MiniMagick support:
6
+ # include CarrierWave::RMagick
7
+ include CarrierWave::MiniMagick
8
+
9
+ # Choose what kind of storage to use for this uploader:
10
+ storage :file
11
+ #storage :fog
12
+ # Override the directory where uploaded files will be stored.
13
+ # This is a sensible default for uploaders that are meant to be mounted:
14
+ def store_dir
15
+ "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
16
+ end
17
+
18
+ # Provide a default URL as a default if there hasn't been a file uploaded:
19
+ def default_url
20
+ # For Rails 3.1+ asset pipeline compatibility:
21
+ # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
22
+
23
+ #{}"/images/fallback/" + [version_name, "default.png"].compact.join('_')
24
+ 'default_photo.png' #rails will look at 'app/assets/images/default_avatar.png'
25
+ end
26
+
27
+ # Process files as they are uploaded:
28
+ # process :scale => [200, 300]
29
+ #
30
+ # def scale(width, height)
31
+ # # do something
32
+ # end
33
+
34
+ # Create different versions of your uploaded files:
35
+ version :large_photo do
36
+ # returns a 150x150 image
37
+ process :resize_to_fill => [150, 150]
38
+ end
39
+ version :medium_photo do
40
+ # returns a 50x50 image
41
+ process :resize_to_fill => [50, 50]
42
+ end
43
+ version :small_photo do
44
+ # returns a 35x35 image
45
+ process :resize_to_fill => [35, 35]
46
+ end
47
+
48
+ # Add a white list of extensions which are allowed to be uploaded.
49
+ # For images you might use something like this:
50
+ def extension_white_list
51
+ %w(jpg jpeg gif png)
52
+ end
53
+ end
@@ -0,0 +1,11 @@
1
+ .col.s12.m6.l3
2
+ .card
3
+ .card-image
4
+ = image_tag photo.image_url
5
+ %span.card-title{ style: "padding: 0px"}
6
+ %a.start.file-upload{ href: '#!'}
7
+ %i.material-icons.medium.file_upload.green-text file_upload
8
+ /%a.cancel.file-upload{ href: '#!'}
9
+ / %i.material-icons.cancel.orange-text cancel
10
+ %a.delete.file-upload{ href: '#!'}
11
+ %i.material-icons.medium.delete.red-text delete
@@ -0,0 +1 @@
1
+ = resource.id
@@ -0,0 +1,5 @@
1
+ json.array!(resources) do |photo|
2
+ raise 'Implement index.json.jbuilder on your Model!'
3
+ json.extract! photo, :id, :account_id #, :stock_item_id, :title, :image, :lng_lat
4
+ json.url photo_url(photo, format: :json)
5
+ end
@@ -1,3 +1,3 @@
1
1
  module OxenMedia
2
- VERSION = "0.0.6"
2
+ VERSION = "0.3.4"
3
3
  end
data/lib/oxen_media.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require "oxen_media/version"
2
2
  require "oxen_media/engine"
3
- require "carrierwave/crop"
3
+ # require "carrierwave/crop"
4
4
  require "carrierwave"
5
5
 
6
6
  module OxenMedia