Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add support to favorite/delete images.

The way this works is that there's an edit button that toggles the
options on every pictures.
  • Loading branch information...
commit d0d4a5ed93e3db106a458783d99a538cf4884e1d 1 parent 607ef2e
Pier-Olivier Thibault authored
2  Gemfile.lock
View
@@ -25,7 +25,7 @@ GEM
multi_json (~> 1.3)
thread_safe (~> 0.1)
tzinfo (~> 0.3.37)
- arel (4.0.1)
+ arel (4.0.2)
atomic (1.1.14)
bcrypt-ruby (3.1.2)
builder (3.1.4)
28 app/assets/javascripts/admin/images/destroy.js.coffee
View
@@ -0,0 +1,28 @@
+class Destroy
+ constructor: ($element) ->
+ $element.on 'click', '.action.destroy.image', @toggle
+
+ toggle: ->
+ $this = $(this)
+ fd = new FormData()
+ fd.append('authenticity_token', $this.data('token'))
+ $.ajax
+ url: $this.attr('href'),
+ type: 'delete',
+ data: fd,
+ processData: false
+ contentType: false
+ false
+
+
+initializer = ($element) ->
+ window.Editor.imagesDestroy = new Destroy($element)
+
+if @Editor?
+ @Editor.imagesDestroy = initializer
+else
+ $(document).on 'editor:loaded', (event, editor) ->
+ window.Editor.imagesDestroy = initializer
+
+
+
5 app/assets/javascripts/admin/images.js.coffee → ...ts/javascripts/admin/images/draganddrop.js.coffee
View
@@ -38,11 +38,9 @@ class DragAndDrop
preview: (e) =>
$div = $("<div class='loading' id='submittingImageProgress'>")
- img = new Image()
- img.src = e.target.result
+ $div.get(0).style.backgroundImage = "url('#{e.target.result}')"
$progress = $("<div class='overlay'><progress value=0></progress></div>")
- $div.append(img)
$div.append($progress)
$(@element).prepend($div)
@@ -78,3 +76,4 @@ else
$(document).on 'editor:loaded', (event, editor) ->
editor.imageDropPad = initializer
+
28 app/assets/javascripts/admin/images/favorite.js.coffee
View
@@ -0,0 +1,28 @@
+class Favorite
+ constructor: ($element) ->
+ $element.on 'click', '.action.favorite.image', @toggle
+
+ toggle: ->
+ $this = $(this)
+ fd = new FormData()
+ fd.append('authenticity_token', $this.data('token'))
+ fd.append('admin_image[favorite]', $this.data('favorite'))
+ $.ajax
+ url: $this.attr('href'),
+ type: 'patch',
+ data: fd,
+ processData: false
+ contentType: false
+ false
+
+
+initializer = ($element) ->
+ window.Editor.imagesFavorite = new Favorite($element)
+
+if @Editor?
+ @Editor.imagesFavorite = initializer
+else
+ $(document).on 'editor:loaded', (event, editor) ->
+ window.Editor.imagesFavorite = initializer
+
+
1  ...assets/javascripts/admin/image_importer.js.coffee → ...ssets/javascripts/admin/images/importer.js.coffee
View
@@ -15,3 +15,4 @@ else
$(document).on 'editor:loaded', (event, editor) ->
window.Editor.imageImporter = new ImageImporter()
+
2  app/assets/javascripts/admin/partials.js
View
@@ -1,2 +0,0 @@
-// Place all the behaviors and hooks related to the matching controller here.
-// All this logic will automatically be available in application.js.
3  ...sets/javascripts/admin/partial_importer.js.coffee → ...ets/javascripts/admin/partials/importer.js.coffee
View
@@ -7,7 +7,7 @@ class PartialImporter
"<link rel='partial' href='#{$el.data('url')}' />"
showPreview: (e) ->
- $("#previewLink").click()
+ $("#previewlink").click()
if @Editor?
@Editor.partialImporter = new PartialImporter()
@@ -15,4 +15,3 @@ else
$(document).on 'editor:loaded', (event, editor) ->
window.Editor.partialImporter = new PartialImporter()
-
130 app/assets/stylesheets/admin/images.css.scss
View
@@ -1,12 +1,92 @@
+@mixin favorite {
+ &.favorite {
+ color: rgba(255, 255, 255, 0.5);
+
+ &.active {
+ color: rgba(229, 230, 22, 1);
+ }
+
+ &:not(.active):hover {
+ color: rgba(229, 230, 22, 0.8);
+ }
+ }
+}
+
+@mixin destroy {
+ &.destroy {
+ color: rgba(255, 147, 147, 0.7);
+ &:hover {
+ color: rgba(252, 107, 107, 1);
+ }
+ }
+}
+
+@mixin image {
+ li.image {
+ position: relative;
+ overflow: hidden;
+ display: inline-block;
+ width: 240px;
+ height: 240px;
+ margin: 12px 0 12px 12px;
+ border: 1px solid #B8B690;
+ border-radius: 6px;
+
+ & > div {
+ width: 100%;
+ height: 100%;
+ background-size: 100% auto;
+ background-repeat: no-repeat;
+ cursor: pointer;
+ }
+
+ & > sidebar.options {
+ position: absolute;
+ background: rgba(0, 0, 0, 0.4);
+ visibility: hidden;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+
+ .action {
+ width: 50%;
+ height: 100%;
+ cursor: pointer;
+ display: inline-block;
+ font-family: entypo;
+ font-size: 8rem;
+ line-height: 14rem;
+ text-shadow: 0px -1px 0px rgba(0, 0, 0, 0.5);
+ text-decoration: none;
+ text-align: center;
+
+ &:first-child {
+ border-right: 2px solid rgba(158, 158, 158, 0.6);
+ }
+
+ &:last-child {
+ border-left: 2px solid rgba(158, 158, 158, 0.6);
+ }
+
+
+ @include favorite;
+ @include destroy;
+ }
+ }
+ }
+}
+
#imageDropPad {
+ height: 100px;
margin: 12px;
+ padding: 8px;
border-radius: 6px;
border: 4px dashed #BABABA;
- min-height: 100px;
text-align: center;
.message {
- line-height: 90px;
+ line-height: 80px;
}
&.hover {
@@ -15,18 +95,19 @@
#submittingImageProgress {
height: 100%;
+ width: 100%;
+ background-size: auto 100%;
+ background-repeat: no-repeat;
+ background-position: 16px 0;
position: relative;
.overlay {
position: absolute;
box-sizing: border-box;
-moz-box-sizing: border-box;
- top: 30%;
+ top: 25%;
width: 60%;
left: 20%;
- background: rgba(26, 61, 134, 0.75);
- box-shadow: 0 1px 0 0 rgba(140, 163, 238, 0.49);
- border-radius: 8px;
padding: 12px 20px;
progress {
margin-bottom: 1px;
@@ -38,25 +119,26 @@
.images.items {
list-style-type: none;
- margin: 8px;
- li {
- display: inline-block;
- width: 240px;
- height: 240px;
- margin: 12px 0 12px 12px;
- background-size: 100% auto;
- background-repeat: no-repeat;
- cursor: pointer;
+ margin: 8px 52px 8px 8px;
- a {
- display: block;
- width: 100%;
- height: 100%;
+ @include image;
- img {
- width: 100%;
- height: 100%;
- }
- }
+}
+
+#imagesOptionsToggle {
+ position: absolute;
+ bottom: 4px;
+ right: 16px;
+ font-family: entypo;
+ font-size: 4rem;
+ cursor: pointer;
+ color: rgba(109, 100, 92, 0.5);
+
+ &:hover:not(.active) {
+ color: rgba(109, 100, 92, 1);
+ }
+
+ &.active {
+ color: rgba(109, 100, 92, 1);
}
}
14 app/controllers/admin/images_controller.rb
View
@@ -16,10 +16,24 @@ def create
end
end
+ def update
+ @image = Admin::Image.find(params[:id])
+ @image.update_attributes(image_params)
+ end
+
+ def destroy
+ @image = Admin::Image.find(params[:id])
+ @image.destroy
+ end
+
protected
def post
@post ||= Admin::Post.find_by_slug(params[:post_id])
end
+ def image_params
+ params.require(:admin_image).permit(:favorite)
+ end
+
end
45 app/decorators/admin/image_decorator.rb
View
@@ -1,14 +1,55 @@
module Admin
class ImageDecorator < Cubisme::Decorator::Base
def thumbnail(options)
- content_tag :li,
+ content_tag :li, class: %w(image), id: "image-#{record.id}" do
+ [
+ sidebar,
+ image,
+ ].join.html_safe
+ end
+ end
+
+ protected
+
+ def image
+ content_tag :div,
nil,
+ style: "background-image: url(#{record.url});",
draggable: true,
- style: "background-image: url('#{record.url}')",
'data-url' => record.url,
'data-alt' => record.key,
ondragstart: "window.Editor.imageImporter.configureEvent(event)",
ondragend: "window.Editor.imageImporter.showPreview(event)"
end
+
+ def sidebar
+ content_tag :sidebar, class: %w(options) do
+ [
+ favorite_button,
+ destroy_button,
+ ].join.html_safe
+ end
+ end
+
+ def destroy_button
+ link_to '&#59177;'.html_safe,
+ admin_image_path(record),
+ class: %w(destroy action image),
+ 'data-token' => form_authenticity_token
+ end
+
+ def favorite_button
+ css = %w(favorite action image)
+ css << 'active' if record.favorite?
+
+ path = admin_image_path(record)
+
+ link_to '&#9733;'.html_safe, path,
+ remote: true,
+ class: css,
+ 'data-token' => form_authenticity_token,
+ 'data-favorite' => !record.favorite?
+ end
+
end
end
2  app/views/admin/images/_images.html.erb
View
@@ -1,3 +1,5 @@
<ul class="images items">
<%= decorate images, :thumbnail %>
</ul>
+
+<span id="imagesOptionsToggle">&#9998;</span>
4 app/views/admin/images/create.js.erb
View
@@ -3,3 +3,7 @@ window.Editor.imageDropPad.showMessage()
var $image = $("<%= j decorate(@image, :thumbnail) %>").hide()
$image.prependTo($(".images.items")).show("slow")
+
+if ($('#imagesOptionsToggle').hasClass('active')) {
+ $image.find('sidebar.options').css('visibility', 'visible')
+}
3  app/views/admin/images/destroy.js.erb
View
@@ -0,0 +1,3 @@
+$("#image-<%= @image.id %>").fadeOut(function() {
+ $(this).remove()
+})
15 app/views/admin/images/index.js.erb
View
@@ -13,3 +13,18 @@ $("#imagesListLink").data('page', $div).on('click', function() {
$sidebar.empty().append($div)
return false
}).click()
+
+$("#imagesOptionsToggle").on('click', function() {
+ var $this = $(this)
+ var $element = $('sidebar.options')
+ if ($element.css('visibility') == 'visible') {
+ $this.removeClass('active')
+ $element.css('visibility', 'hidden');
+ } else {
+ $this.addClass('active')
+ $element.css('visibility', 'visible');
+ }
+})
+
+Editor.imagesFavorite($images)
+Editor.imagesDestroy($images)
1  app/views/admin/images/update.js.erb
View
@@ -0,0 +1 @@
+$("#image-<%= @image.id %>").find('.favorite.action.image').toggleClass('active')
Please sign in to comment.
Something went wrong with that request. Please try again.