]> git.0d.be Git - panikdb.git/commitdiff
wiki: add document upload support
authorFrédéric Péters <fpeters@0d.be>
Mon, 6 Jul 2020 17:54:24 +0000 (19:54 +0200)
committerFrédéric Péters <fpeters@0d.be>
Mon, 6 Jul 2020 17:54:24 +0000 (19:54 +0200)
panikdb/static/css/style.scss
panikdb/static/js/combo.wiki.js
panikdb/urls.py
panikdb/wiki/views.py

index 5e8837dee4d84ee03565bb746e3f7a5cf87562ec..5ade30403808543501043d7f113e92edcf8884cf 100644 (file)
@@ -761,8 +761,8 @@ div.wiki-section {
        [contenteditable=true] div.figure {
                cursor: pointer;
        }
+       div.document,
        div.figure {
-               min-height: 50px;
                text-align: center;
                line-height: initial;
                img {
@@ -770,6 +770,7 @@ div.wiki-section {
                        max-height: 70vh;
                }
                span.empty::before {
+                       min-height: 50px;
                        margin: 0 auto;
                        display: block;
                        width: 90%;
@@ -781,6 +782,16 @@ div.wiki-section {
                        font-family: FontAwesome;
                }
        }
+       div.document a {
+               &::before {
+                       content: "\f019";
+                       font-family: FontAwesome;
+                       padding-right: 0.7em;
+               }
+       }
+       div.document span.empty::before {
+               content: "\f0f6";  // fa-file-text-o
+       }
        div[contenteditable] {
                a[href^="/wiki/"] {
                        box-shadow: inset 0 -8px 0 0 rgba(34, 27, 242,0.1);
@@ -828,6 +839,7 @@ div#content div.wiki-section h4.intertitle {
        top: 0px;
 }
 
+#document-upload,
 #image-upload {
        visibility: hidden;
 }
index a94d8cb6876a4913a62051a9ef2f96f6fb9cef51..d1464e3f7b145d3fd260029b27e0b6700b782c29 100644 (file)
@@ -39,6 +39,7 @@ function auto_anchors() {
           {name: 'intertitre', tag: 'H4', klass: 'intertitle'},
           {name: 'liste', special: 'list', tag: 'UL', klass: 'list'},
           {name: 'illustration', special: 'img', tag: 'DIV', subtag: true, klass: 'figure'},
+          {name: 'document', special: 'doc', tag: 'DIV', subtag: true, klass: 'document'},
           {name: 'code', tag: 'PRE', klass: 'code'},
           {name: 'note', tag: 'DIV', subtag: true, klass: 'note'},
     ],
@@ -133,20 +134,30 @@ function auto_anchors() {
           $(inline_style_toolbar).hide();
         }
       });
-      var $image_upload = $('<input type="file" nam="image" id="image-upload">');
+      var $image_upload = $('<input type="file" nam="image" id="image-upload" accept="image/*">');
       $image_upload.on('change', upload_image);
       $image_upload.appendTo(document.body);
 
+      var $document_upload = $('<input type="file" nam="document" id="document-upload">');
+      $document_upload.on('change', upload_document);
+      $document_upload.appendTo(document.body);
+
       document.execCommand('defaultParagraphSeparator', false, 'p');
       $(document).on('click', 'div.figure span.empty', function() {
         window.active_figure = this.parentNode;
         $('#image-upload').trigger('click');
         return true;
       });
+      $(document).on('click', 'div.document span.empty', function() {
+        window.active_document = this.parentNode;
+        $('#document-upload').trigger('click');
+        return true;
+      });
     },
 
     off: function() {
       $('#image-upload').remove();
+      $('#document-upload').remove();
       if (block_style_toolbar) { block_style_toolbar.hide(); }
       if (inline_style_toolbar) { inline_style_toolbar.hide(); }
       $(document).off('selectionchange');
@@ -184,8 +195,8 @@ function auto_anchors() {
     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) {
+      params.append('upload', file);
+      $.post({url: '/wiki/ajax/upload/', processData: false, data: params, contentType: false}).success(function(data) {
         var img = document.createElement('IMG');
         img.src = data.url;
         if (data.orig_url) {
@@ -196,6 +207,21 @@ function auto_anchors() {
     }
   }
 
+  function upload_document() {
+    if ($(this).prop('files').length > 0) {
+      var file = $(this).prop('files')[0];
+      var params = new FormData();
+      params.append('upload', file);
+      $.post({url: '/wiki/ajax/upload/', processData: false, data: params, contentType: false}).success(function(data) {
+        var doc_link = document.createElement('A');
+        doc_link.className = 'button';
+        doc_link.textContent = 'Télécharger ' + data.filename;
+        doc_link.href = data.url;
+        $(window.active_document).empty().append(doc_link);
+      });
+    }
+  }
+
   function get_contenteditable_subnode(node) {
     if (node === null) return null;
     if (node.contentEditable === 'true') return node;  // but we shouldn't arrive at root
@@ -232,7 +258,19 @@ function auto_anchors() {
       sel.removeAllRanges();
       sel.addRange(range);
       update_block_style_toolbar();
-
+      return;
+    }
+    if (this.action_block.special == 'doc') {
+      action = 'insertHTML';
+      param = '<div class="document"><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_toolbar();
       return;
     }
     if (this.action_block.special == 'list') {
index eff62c0758c317e6fccf04927e82ca5130df87c0..6208ed3e6baa62d1ff6f33f064aaff80ce601816 100644 (file)
@@ -85,7 +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/ajax/upload/$', wiki_views.ajax_upload),
     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 9457d8155d794b6c8a96d55cffa24254cff0b3f5..15df4813c697ed6b78a3637f7317005bd9dd5baf 100644 (file)
@@ -1,3 +1,5 @@
+import os
+
 from django.contrib.auth.decorators import login_required
 from django.core.files.storage import default_storage
 from django.db.models import Q
@@ -55,15 +57,19 @@ def ajax_new_page(request, *args, **kwargs):
 
 
 @csrf_exempt
-def ajax_image(request, *args, **kwargs):
-    img = request.FILES['image']
-    saved_path = default_storage.save('wiki/images/%s' % img.name, img)
+def ajax_upload(request, *args, **kwargs):
+    upload = request.FILES['upload']
+    upload_path = 'uploads'
+    if os.path.splitext(upload.name.lower())[-1] in ('.jpg', '.jpeg', '.png', '.gif', '.svg'):
+        upload_path = 'images'
+    saved_path = default_storage.save('wiki/%s/%s' % (upload_path, upload.name), upload)
     url = '/media/' + saved_path
-    response = {'url': url}
-    if default_storage.size(saved_path) > 500_000 and not img.name.endswith('.svg'):
-        response['orig_url'] = url
-        try:
-            response['url'] = get_thumbnail(saved_path, '1000', upscale=False).url
-        except OSError:
-            pass
+    response = {'url': url, 'filename': upload.name}
+    if upload_path == 'images':
+        if default_storage.size(saved_path) > 500_000 and not upload.name.endswith('.svg'):
+            response['orig_url'] = url
+            try:
+                response['url'] = get_thumbnail(saved_path, '1000', upscale=False).url
+            except OSError:
+                pass
     return JsonResponse(response)