oxen_media 0.0.6 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
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