summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorJacob Schatz <jschatz@gitlab.com>2017-04-05 14:00:44 +0000
committerJacob Schatz <jschatz@gitlab.com>2017-04-05 14:00:44 +0000
commitc71329299206543340b43f23634e1a32cd09f8cd (patch)
tree2c4c816414a9b8937cd8d36129cc73276434e4d1 /app
parent5771ee400f920cda668a182c9f2ad57576f40fb2 (diff)
parentfd8a40783d593993caa76925eae1d54e6fd95c4b (diff)
downloadgitlab-ce-c71329299206543340b43f23634e1a32cd09f8cd.tar.gz
Merge branch 'sketch-preview-files' into 'master'
Load a preview of Sketch 43 files See merge request !10470
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/blob/sketch/index.js73
-rw-r--r--app/assets/javascripts/blob/sketch_viewer.js8
-rw-r--r--app/models/blob.rb6
-rw-r--r--app/views/projects/blob/_sketch.html.haml7
4 files changed, 94 insertions, 0 deletions
diff --git a/app/assets/javascripts/blob/sketch/index.js b/app/assets/javascripts/blob/sketch/index.js
new file mode 100644
index 00000000000..0799991aa40
--- /dev/null
+++ b/app/assets/javascripts/blob/sketch/index.js
@@ -0,0 +1,73 @@
+import JSZip from 'jszip';
+import JSZipUtils from 'jszip-utils';
+
+export default class SketchLoader {
+ constructor(container) {
+ this.container = container;
+ this.loadingIcon = this.container.querySelector('.js-loading-icon');
+
+ this.load();
+ }
+
+ load() {
+ return this.getZipFile()
+ .then(data => JSZip.loadAsync(data))
+ .then(asyncResult => asyncResult.files['previews/preview.png'].async('uint8array'))
+ .then((content) => {
+ const url = window.URL || window.webkitURL;
+ const blob = new Blob([new Uint8Array(content)], {
+ type: 'image/png',
+ });
+ const previewUrl = url.createObjectURL(blob);
+
+ this.render(previewUrl);
+ })
+ .catch(this.error.bind(this));
+ }
+
+ getZipFile() {
+ return new JSZip.external.Promise((resolve, reject) => {
+ JSZipUtils.getBinaryContent(this.container.dataset.endpoint, (err, data) => {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(data);
+ }
+ });
+ });
+ }
+
+ render(previewUrl) {
+ const previewLink = document.createElement('a');
+ const previewImage = document.createElement('img');
+
+ previewLink.href = previewUrl;
+ previewLink.target = '_blank';
+ previewImage.src = previewUrl;
+ previewImage.className = 'img-responsive';
+
+ previewLink.appendChild(previewImage);
+ this.container.appendChild(previewLink);
+
+ this.removeLoadingIcon();
+ }
+
+ error() {
+ const errorMsg = document.createElement('p');
+
+ errorMsg.className = 'prepend-top-default append-bottom-default text-center';
+ errorMsg.textContent = `
+ Cannot show preview. For previews on sketch files, they must have the file format
+ introduced by Sketch version 43 and above.
+ `;
+ this.container.appendChild(errorMsg);
+
+ this.removeLoadingIcon();
+ }
+
+ removeLoadingIcon() {
+ if (this.loadingIcon) {
+ this.loadingIcon.remove();
+ }
+ }
+}
diff --git a/app/assets/javascripts/blob/sketch_viewer.js b/app/assets/javascripts/blob/sketch_viewer.js
new file mode 100644
index 00000000000..0640dd26855
--- /dev/null
+++ b/app/assets/javascripts/blob/sketch_viewer.js
@@ -0,0 +1,8 @@
+/* eslint-disable no-new */
+import SketchLoader from './sketch';
+
+document.addEventListener('DOMContentLoaded', () => {
+ const el = document.getElementById('js-sketch-viewer');
+
+ new SketchLoader(el);
+});
diff --git a/app/models/blob.rb b/app/models/blob.rb
index 95d2111a992..1c451a3976f 100644
--- a/app/models/blob.rb
+++ b/app/models/blob.rb
@@ -50,6 +50,10 @@ class Blob < SimpleDelegator
text? && language&.name == 'Jupyter Notebook'
end
+ def sketch?
+ binary? && extname.downcase.delete('.') == 'sketch'
+ end
+
def size_within_svg_limits?
size <= MAXIMUM_SVG_SIZE
end
@@ -69,6 +73,8 @@ class Blob < SimpleDelegator
'image'
elsif ipython_notebook?
'notebook'
+ elsif sketch?
+ 'sketch'
elsif text?
'text'
else
diff --git a/app/views/projects/blob/_sketch.html.haml b/app/views/projects/blob/_sketch.html.haml
new file mode 100644
index 00000000000..dad9369cb2a
--- /dev/null
+++ b/app/views/projects/blob/_sketch.html.haml
@@ -0,0 +1,7 @@
+- content_for :page_specific_javascripts do
+ = page_specific_javascript_bundle_tag('common_vue')
+ = page_specific_javascript_bundle_tag('sketch_viewer')
+
+.file-content#js-sketch-viewer{ data: { endpoint: namespace_project_raw_path(@project.namespace, @project, @id) } }
+ .js-loading-icon.text-center.prepend-top-default.append-bottom-default.js-loading-icon{ 'aria-label' => 'Loading Sketch preview' }
+ = icon('spinner spin 2x', 'aria-hidden' => 'true');