]> git.0d.be Git - panikdb.git/commitdiff
wiki: image upload
authorFrédéric Péters <fpeters@0d.be>
Thu, 11 Jun 2020 16:23:53 +0000 (18:23 +0200)
committerFrédéric Péters <fpeters@0d.be>
Thu, 11 Jun 2020 16:23:53 +0000 (18:23 +0200)
panikdb/static/css/style.scss
panikdb/static/js/combo.wiki.js
panikdb/urls.py
panikdb/wiki/views.py

index 81d679d3ed3ccbdf1e1bc1972a1665b10596530c..a52f223bf4fa8e704f717beaf90d124ec34fa7a8 100644 (file)
@@ -754,6 +754,24 @@ div.wiki-section {
                        margin-top: 0;
                }
        }
+       [contenteditable=true] div.figure {
+               cursor: pointer;
+       }
+       div.figure {
+               background: #eee;
+               min-height: 50px;
+               text-align: center;
+               img {
+                       max-width: 90%;
+               }
+               span.empty::before {
+                       padding: 1rem;
+                       font-size: 200px;
+                       content: "\f03e";
+                       color: #aaa;
+                       font-family: FontAwesome;
+               }
+       }
 }
 
 div#content div.wiki-section h4.intertitle {
index ca557b8f78095b2fa56e3a102d77e1f9d6b38b9c..c80e4a177e57693df674f5a352983e7f00a44f85 100644 (file)
@@ -37,6 +37,7 @@ function auto_anchors() {
   var Phylly = {
     BLOCKS: [
           {name: 'intertitre', tag: 'h4', klass: 'intertitle'},
+          {name: 'illustration', special: 'img', tag: 'DIV', subtag: true, klass: 'figure'},
           {name: 'code', tag: 'PRE', klass: 'code'},
           {name: 'note', tag: 'DIV', subtag: true, klass: 'note'},
     ],
@@ -71,9 +72,19 @@ function auto_anchors() {
           $(style_popup).hide();
         }
       });
+      var $image_upload = $('<input type="file" nam="image" id="image-upload">');
+      $image_upload.on('change', upload_image);
+      $image_upload.appendTo(document.body);
+
+      $(document).on('click', 'div.figure', function() {
+        window.active_figure = this;
+        $('#image-upload').trigger('click');
+        return true;
+      });
     },
 
     off: function() {
+      $('#image-upload').remove();
       $(document).off('selectionchange');
     },
 
@@ -90,6 +101,19 @@ function auto_anchors() {
   }
   window.Phylly = Phylly;
 
+  function upload_image() {
+    if ($(this).prop('files').length > 0) {
+      var file = $(this).prop('files')[0];
+      var params = new FormData();
+      params.append('image', file);
+      $.post({url: '/wiki/ajax/image/', processData: false, data: params, contentType: false}).success(function(data) {
+        var img = document.createElement('IMG');
+        img.src = data.url;
+        $(window.active_figure).empty().append(img);
+      });
+    }
+  }
+
   function get_contenteditable_subnode(node) {
     if (node === null) return null;
     if (node.parentNode.contentEditable === 'true') return node;
@@ -109,6 +133,20 @@ function auto_anchors() {
   function block_style() {
     var sel = window.getSelection();
     var current_anchor = sel.anchorNode;
+    if (this.action_block.special == 'img') {
+      action = 'insertHTML';
+      param = '<div class="figure"><span class="empty"></span></div><p id="new-p"></p>';
+      document.execCommand(action, false, param);
+      current_anchor = $('#new-p')[0];
+      $(current_anchor).attr('id', null);
+      var range = document.createRange();
+      range.setStart(current_anchor, 0);
+      sel.removeAllRanges();
+      sel.addRange(range);
+      update_block_style_popup();
+
+      return;
+    }
     if (this.classList.contains('on')) { // toggle off
       if (this.action_block.subtag) {
         // unwrap
index d1e09304cd9591417956e6096671c5979b309b14..eff62c0758c317e6fccf04927e82ca5130df87c0 100644 (file)
@@ -85,6 +85,7 @@ urlpatterns = [
 
     url(r'^wiki/newpage/$', wiki_views.new_page),
     url(r'^wiki/ajax/newpage/$', wiki_views.ajax_new_page),
+    url(r'^wiki/ajax/image/$', wiki_views.ajax_image),
     url(r'^wiki/', combo.public.views.page),
     url(r'^ajax/cell/(?P<page_pk>\d+)/(?P<cell_reference>[\w_]+-\d+)/$',
         combo.public.views.ajax_page_cell, name='combo-public-ajax-page-cell'),
index bfaeddabed7310544bc7f673f1bff62253b75b8b..43cd686e54a3560a139fd1e4ee4f2b09f8059308 100644 (file)
@@ -1,4 +1,5 @@
 from django.contrib.auth.decorators import login_required
+from django.core.files.storage import default_storage
 from django.db.models import Q
 from django.http import JsonResponse
 from django.utils.text import slugify
@@ -49,3 +50,11 @@ def ajax_new_page(request, *args, **kwargs):
         'url': page.get_online_url(),
         'request_id': request.POST['request_id'],
     })
+
+
+@csrf_exempt
+def ajax_image(request, *args, **kwargs):
+    img = request.FILES['image']
+    # TODO: resize if necessary, and store both original and resized images
+    saved_path = default_storage.save('wiki/images/%s' % img.name, img)
+    return JsonResponse({'url': '/media/' + saved_path})