Bladeren bron

Merge pull request #1379 from transloadit/website/add-markdown-snippets-example

Website: add markdown snippets example
Artur Paikin 6 jaren geleden
bovenliggende
commit
a8d919a8c9

+ 13 - 0
examples/transloadit-textarea/index.html

@@ -96,6 +96,19 @@
       .snippet {
         margin-top: 25px;
       }
+
+      /* temp uppy fix, there was a typo in class name */
+      /* remove after uppy@>0.30.3 */
+      .uppy-DashboardAddFiles {
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        flex-direction: column;
+        height: 100%;
+        position: relative;
+        text-align: center;
+        flex: 1;
+      }
     </style>
   </head>
   <body>

+ 2 - 2
website/_config.yml

@@ -15,7 +15,7 @@ logo_icon: /images/logos/uppy-dog-head-arrow.png
 description: >
     Sleek, modular file uploader that integrates seamlessly with any website or app.
     It fetches files from local disk, Google Drive, Dropbox, Instagram, remote URLs, cameras etc, and then uploads them to the final destination.
-    It’s fast, easy to use and let's you worry about more important problems than building a file uploader.
+    It’s fast, easy to use and lets you worry about more important problems than building a file uploader.
 descriptionWho: >
   Uppy is brought to you by the people
   behind <a href="https://transloadit.com">Transloadit</a>, and as such will have first class support
@@ -152,4 +152,4 @@ alias:
 
 include_markdown:
   dir: "src/_template"   # Base directory of template markdown
-  verbose : true    
+  verbose : true    

+ 38 - 14
website/package-lock.json

@@ -2853,7 +2853,8 @@
         },
         "ansi-regex": {
           "version": "2.1.1",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "aproba": {
           "version": "1.2.0",
@@ -2871,11 +2872,13 @@
         },
         "balanced-match": {
           "version": "1.0.0",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "brace-expansion": {
           "version": "1.1.11",
           "bundled": true,
+          "optional": true,
           "requires": {
             "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
@@ -2888,15 +2891,18 @@
         },
         "code-point-at": {
           "version": "1.1.0",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "concat-map": {
           "version": "0.0.1",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "console-control-strings": {
           "version": "1.1.0",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "core-util-is": {
           "version": "1.0.2",
@@ -2999,7 +3005,8 @@
         },
         "inherits": {
           "version": "2.0.3",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "ini": {
           "version": "1.3.5",
@@ -3009,6 +3016,7 @@
         "is-fullwidth-code-point": {
           "version": "1.0.0",
           "bundled": true,
+          "optional": true,
           "requires": {
             "number-is-nan": "^1.0.0"
           }
@@ -3021,17 +3029,20 @@
         "minimatch": {
           "version": "3.0.4",
           "bundled": true,
+          "optional": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
         },
         "minimist": {
           "version": "0.0.8",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "minipass": {
           "version": "2.2.4",
           "bundled": true,
+          "optional": true,
           "requires": {
             "safe-buffer": "^5.1.1",
             "yallist": "^3.0.0"
@@ -3048,6 +3059,7 @@
         "mkdirp": {
           "version": "0.5.1",
           "bundled": true,
+          "optional": true,
           "requires": {
             "minimist": "0.0.8"
           }
@@ -3120,7 +3132,8 @@
         },
         "number-is-nan": {
           "version": "1.0.1",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "object-assign": {
           "version": "4.1.1",
@@ -3130,6 +3143,7 @@
         "once": {
           "version": "1.4.0",
           "bundled": true,
+          "optional": true,
           "requires": {
             "wrappy": "1"
           }
@@ -3205,7 +3219,8 @@
         },
         "safe-buffer": {
           "version": "5.1.1",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "safer-buffer": {
           "version": "2.1.2",
@@ -3235,6 +3250,7 @@
         "string-width": {
           "version": "1.0.2",
           "bundled": true,
+          "optional": true,
           "requires": {
             "code-point-at": "^1.0.0",
             "is-fullwidth-code-point": "^1.0.0",
@@ -3252,6 +3268,7 @@
         "strip-ansi": {
           "version": "3.0.1",
           "bundled": true,
+          "optional": true,
           "requires": {
             "ansi-regex": "^2.0.0"
           }
@@ -3290,11 +3307,13 @@
         },
         "wrappy": {
           "version": "1.0.2",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "yallist": {
           "version": "3.0.2",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         }
       }
     },
@@ -3993,6 +4012,11 @@
         "strip-indent": "^2.0.0"
       },
       "dependencies": {
+        "marked": {
+          "version": "0.3.19",
+          "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz",
+          "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg=="
+        },
         "strip-indent": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz",
@@ -4925,9 +4949,9 @@
       }
     },
     "marked": {
-      "version": "0.3.12",
-      "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.12.tgz",
-      "integrity": "sha512-k4NaW+vS7ytQn6MgJn3fYpQt20/mOgYM5Ft9BYMfQJDz2QT6yEeS9XJ8k2Nw8JTeWK/znPPW2n3UJGzyYEiMoA=="
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/marked/-/marked-0.6.1.tgz",
+      "integrity": "sha512-+H0L3ibcWhAZE02SKMqmvYsErLo4EAVJxu5h3bHBBDvvjeWXtl92rGUSBYHL2++5Y+RSNgl8dYOAXcYe7lp1fA=="
     },
     "math-expression-evaluator": {
       "version": "1.2.17",

+ 1 - 0
website/package.json

@@ -26,6 +26,7 @@
     "hexo-tag-emojis": "^2.0.1",
     "hexo-util": "^0.6.3",
     "js-yaml": "^3.12.0",
+    "marked": "^0.6.1",
     "mkdirp": "0.5.1",
     "postcss-inline-svg": "^3.1.1",
     "prismjs": "^1.15.0"

+ 109 - 0
website/src/examples/markdown-snippets/app.css

@@ -0,0 +1,109 @@
+.form-snippetLabel {
+  font-size: 0.85em;
+  color: #000;
+  display: block;
+  margin-bottom: 5px;
+}
+
+.form-snippetTitle {
+  display: block;
+  margin-bottom: 15px;
+}
+
+.form-snippetTitle-input {
+  font-family: inherit;
+  font-size: 1em;
+  width: 100%;
+  border: 1px solid #b7b7b4;
+  padding: 8px;
+  border-radius: 5px;
+}
+
+.form-textarea {
+  font-family: inherit;
+  font-size: 1em;
+  box-sizing: border-box;
+  padding: 6px;
+  border-radius: 5px;
+  border: 1px solid #b7b7b4;
+  border-bottom: 1px dashed #b7b7b4;
+  min-height: 160px;
+  width: 100%;
+  resize: vertical;
+  font-family: inherit;
+  margin-bottom: 0;
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+}
+
+  .form-textarea:focus,
+  .form-snippetTitle-input:focus {
+    border-color: #7db9e5;
+    outline: none;
+    box-shadow: 0 0 1px 1px #7db9e5;
+  }
+
+  .form-textarea.drag {
+    background-color: #dee1e3;
+    border: 3px dashed #7f8a93;
+  }
+
+.form-createSnippet {
+  -webkit-appearance: none;
+  border: 0;
+  font-family: inherit;
+  font-size: 16px;
+  border-radius: 5px;
+  padding: 8px;
+  background-color: #0fb800;
+  color: #fff;
+  width: 100%;
+  cursor: pointer;
+  margin-top: 15px;
+  transition: background-color 0.2s;
+}
+
+  .form-createSnippet:hover {
+    background-color: #0b8600;
+  }
+
+.form-upload {
+  font-size: 0.95em;
+  box-sizing: border-box;
+  width: 100%;
+  border-radius: 0 0 5px 5px;
+  border: 1px solid #b7b7b4;
+  border-top-width: 0;
+  padding: 5px 8px;
+  cursor: pointer;
+  text-align: center;
+  transition: color 0.2s;
+  color: #374047;
+}
+
+  .form-upload:hover {
+    color: #97a1a7;
+  }
+
+.form-upload .error {
+  border-color: red;
+  color: red;
+}
+
+.form-upload .error .message {
+  margin-right: 8px;
+}
+
+.snippet {
+  margin-top: 25px;
+}
+
+.snippet-content img {
+  display: block;
+  margin: 5px 0;
+  max-width: 100%;
+}
+
+.snippet-content p {
+  margin-bottom: 10px;
+}

+ 193 - 0
website/src/examples/markdown-snippets/app.es6

@@ -0,0 +1,193 @@
+/* eslint-env browser */
+const marked = require('marked')
+const dragdrop = require('drag-drop')
+const robodog = require('@uppy/robodog')
+
+const TRANSLOADIT_EXAMPLE_KEY = '35c1aed03f5011e982b6afe82599b6a0'
+const TRANSLOADIT_EXAMPLE_TEMPLATE = '0b2ee2bc25dc43619700c2ce0a75164a'
+
+/**
+ * A textarea for markdown text, with support for file attachments.
+ *
+ * ## Usage
+ *
+ * ```js
+ * const element = document.querySelector('textarea')
+ * const mdtxt = new MarkdownTextarea(element)
+ * mdtxt.install()
+ * ```
+ */
+class MarkdownTextarea {
+  constructor (element) {
+    this.element = element
+    this.controls = document.createElement('div')
+    this.controls.classList.add('mdtxt-controls')
+    this.uploadLine = document.createElement('div')
+    this.uploadLine.classList.add('form-upload')
+
+    this.uploadLine.appendChild(
+      document.createTextNode('Tap here to upload an attachment'))
+  }
+
+  install () {
+    const { element } = this
+    const wrapper = document.createElement('div')
+    wrapper.classList.add('mdtxt')
+    element.parentNode.replaceChild(wrapper, element)
+    wrapper.appendChild(this.controls)
+    wrapper.appendChild(element)
+    wrapper.appendChild(this.uploadLine)
+
+    this.setupUploadLine()
+    this.setupTextareaDrop()
+  }
+
+  setupTextareaDrop () {
+    dragdrop(this.element, (files) => {
+      this.uploadFiles(files)
+    })
+  }
+
+  setupUploadLine () {
+    this.uploadLine.addEventListener('click', () => {
+      this.pickFiles()
+    })
+  }
+
+  reportUploadError (err) {
+    this.uploadLine.classList.add('error')
+    const message = document.createElement('span')
+    message.appendChild(document.createTextNode(err.message))
+    this.uploadLine.insertChild(message, this.uploadLine.firstChild)
+  }
+
+  unreportUploadError () {
+    this.uploadLine.classList.remove('error')
+    const message = this.uploadLine.querySelector('message')
+    if (message) {
+      this.uploadLine.removeChild(message)
+    }
+  }
+
+  insertAttachments (attachments) {
+    attachments.forEach((attachment) => {
+      const { file, thumb } = attachment
+      const link = `\n[LABEL](${file.ssl_url})\n`
+      const labelText = `View File ${file.basename}`
+      if (thumb) {
+        this.element.value += link.replace('LABEL', `![${labelText}](${thumb.ssl_url})`)
+      } else {
+        this.element.value += link.replace('LABEL', labelText)
+      }
+    })
+  }
+
+  matchFilesAndThumbs (results) {
+    const filesById = {}
+    const thumbsById = {}
+
+    results.forEach((result) => {
+      if (result.stepName === 'thumbnails') {
+        thumbsById[result.original_id] = result
+      } else {
+        filesById[result.original_id] = result
+      }
+    })
+
+    return Object.keys(filesById).reduce((acc, key) => {
+      const file = filesById[key]
+      const thumb = thumbsById[key]
+      acc.push({ file, thumb })
+      return acc
+    }, [])
+  }
+
+  uploadFiles (files) {
+    robodog.upload(files, {
+      waitForEncoding: true,
+      params: {
+        auth: { key: TRANSLOADIT_EXAMPLE_KEY },
+        template_id: TRANSLOADIT_EXAMPLE_TEMPLATE
+      }
+    }).then((result) => {
+      this.insertAttachments(
+        this.matchFilesAndThumbs(result.results)
+      )
+    }).catch((err) => {
+      console.error(err)
+      this.reportUploadError(err)
+    })
+  }
+
+  pickFiles () {
+    robodog.pick({
+      waitForEncoding: true,
+      params: {
+        auth: { key: TRANSLOADIT_EXAMPLE_KEY },
+        template_id: TRANSLOADIT_EXAMPLE_TEMPLATE
+      },
+      providers: [
+        'webcam',
+        'url',
+        'instagram',
+        'google-drive',
+        'dropbox'
+      ]
+    }).then((result) => {
+      this.insertAttachments(
+        this.matchFilesAndThumbs(result.results)
+      )
+    }).catch((err) => {
+      console.error(err)
+      this.reportUploadError(err)
+    })
+  }
+}
+
+const textarea = new MarkdownTextarea(
+  document.querySelector('#new textarea'))
+textarea.install()
+
+function renderSnippet (title, text) {
+  const template = document.querySelector('#snippet')
+  const newSnippet = document.importNode(template.content, true)
+  const titleEl = newSnippet.querySelector('.snippet-title')
+  const contentEl = newSnippet.querySelector('.snippet-content')
+
+  titleEl.appendChild(document.createTextNode(title))
+  contentEl.innerHTML = marked(text)
+
+  const list = document.querySelector('#snippets')
+  list.insertBefore(newSnippet, list.firstChild)
+}
+
+function saveSnippet (title, text) {
+  const id = parseInt(localStorage.numSnippets || 0, 10)
+  localStorage[`snippet_${id}`] = JSON.stringify({ title, text })
+  localStorage.numSnippets = id + 1
+}
+
+function loadSnippets () {
+  for (let id = 0; localStorage[`snippet_${id}`] != null; id += 1) {
+    const { title, text } = JSON.parse(localStorage[`snippet_${id}`])
+    renderSnippet(title, text)
+  }
+}
+
+document.querySelector('#new').addEventListener('submit', (event) => {
+  event.preventDefault()
+
+  const title = event.target.querySelector('input[name="title"]').value ||
+    'Unnamed Snippet'
+  const text = textarea.element.value
+
+  saveSnippet(title, text)
+  renderSnippet(title, text)
+
+  event.target.querySelector('input').value = ''
+  event.target.querySelector('textarea').value = ''
+})
+
+window.addEventListener('DOMContentLoaded', () => {
+  loadSnippets()
+})

+ 27 - 0
website/src/examples/markdown-snippets/app.html

@@ -0,0 +1,27 @@
+  <!-- Basic Uppy styles -->
+  <link rel="stylesheet" href="/uppy/robodog.min.css">
+  <form id="new" class="form-snippet">
+    <h2>Create a new snippet</h2>
+    <label class="form-snippetTitle">
+      <div class="form-snippetLabel">Snippet Title</div>
+      <input class="form-snippetTitle-input" type="text" name="title" placeholder="Enter snippet title">
+    </label>
+    <label class="form-snippetText">
+      <div class="form-snippetLabel">Snippet Content</div>
+      <textarea class="form-textarea" name="snippet" placeholder="Enter snippet content"></textarea>
+    </label>
+    <button class="form-createSnippet" type="submit">
+      Create
+    </button>
+  </form>
+
+  <h2>Previous snippets</h2>
+
+  <div id="snippets"></div>
+</main>
+<template id="snippet">
+  <div class="snippet">
+    <h3 class="snippet-title"></h3>
+    <div class="snippet-content"></div>
+  </div>
+</template>

+ 42 - 0
website/src/examples/markdown-snippets/index.ejs

@@ -0,0 +1,42 @@
+---
+title: Robodog Markdown Snippets
+layout: example
+type: examples
+order: 6
+---
+
+{% blockquote %}
+This is a demo app that works a bit like Github Gists or Pastebin. You can add markdown snippets, and add file attachments to each snippet.
+
+Uppy <a href="/docs/robodog/">Robodog</a> (using <a href="https://transloadit.com">Transloadit</a> internally) generates an inline preview image for images, videos, and audio files. 
+
+You can view the <a target="_blank" href="https://github.com/transloadit/uppy/blob/master/examples/transloadit-textarea/template.json">Transloadit Assembly Template</a> and the <a href="#snippet-example-code"> code for this demo</a>.
+{% endblockquote %}
+
+<p>
+ 
+</p>
+
+<p>
+⚠️ For this demo, snippets are stored locally in your browser. Attachments are stored in Transloadit’s temporary storage and <em>expire</em> after about 24 hours. In a real app, you can easily <a target="_blank" href="https://transloadit.com/docs/#17-saving-conversion-results">export files to a permanent storage solution</a>, like Amazon S3 or Google Cloud.
+</p>
+
+<link rel="stylesheet" href="app.css">
+<% include app.html %>
+<script src="app.js"></script>
+
+<hr />
+
+<p id="console-wrapper">
+  Console output (latest logs are at the top): <br />
+</p>
+
+<p id="snippet-example-code">
+  On this page we're using the following HTML snippet:
+</p>
+{% include_code lang:html markdown-snippets/app.html %}
+
+<p>
+  Along with this JavaScript:
+</p>
+{% include_code lang:js markdown-snippets/app.es6 %}

+ 1 - 1
website/src/examples/xhrupload/index.ejs

@@ -1,5 +1,5 @@
 ---
-title: XHRUpload (Multipart)
+title: XHR Upload
 layout: example
 type: examples
 order: 3

+ 1 - 1
website/themes/uppy/layout/layout.ejs

@@ -1,7 +1,7 @@
 <% var isIndex = page.path === 'index.html' %>
 <% var title = page.title ? page.title + ' — ' + config.title : config.title %>
 <% var excerpt = page.excerpt ? page.excerpt.replace(/(<([^>]+)>)/ig, '').substring(0, 400) : config.description %>
-<% var image = page.image ? page.image : 'http://uppy.io/images/uppy-social.jpg' %>
+<% var image = page.image ? page.image : 'http://uppy.io/images/uppy-social-pink.jpg' %>
 <% 
 if (page.series) {
   title = page.series + ': ' + page.title

BIN
website/themes/uppy/source/images/uppy-social-pink.jpg


+ 3 - 1
website/update.js

@@ -11,6 +11,7 @@ const touch = require('touch')
 
 const webRoot = __dirname
 const uppyRoot = path.join(__dirname, '../packages/uppy')
+const robodogRoot = path.join(__dirname, '../packages/@uppy/robodog')
 
 const configPath = path.join(webRoot, '/themes/uppy/_config.yml')
 const { version } = require(path.join(uppyRoot, '/package.json'))
@@ -112,7 +113,8 @@ async function updateSizes (config) {
 async function injectBuiltFiles () {
   const cmds = [
     `mkdir -p ${path.join(webRoot, '/themes/uppy/source/uppy')}`,
-    `cp -vfR ${path.join(uppyRoot, '/dist/*')} ${path.join(webRoot, '/themes/uppy/source/uppy/')}`
+    `cp -vfR ${path.join(uppyRoot, '/dist/*')} ${path.join(webRoot, '/themes/uppy/source/uppy/')}`,
+    `cp -vfR ${path.join(robodogRoot, '/dist/*')} ${path.join(webRoot, '/themes/uppy/source/uppy/')}`
   ].join(' && ')
 
   const { stdout } = await promisify(exec)(cmds)