(function ()()

in src/main/resources/static/gr-imagare-upload.js [15:374]


(function () {
  'use strict';

  function preventDefaultFn(event) {
    event.preventDefault();
  }

  Polymer({
    is: 'gr-imagare-upload',

    properties: {
      _loading: {
        type: Boolean,
        value: true,
      },
      _allUploaded: {
        type: Boolean,
        value: false,
      },
      _imageProject: String,
      _defaultImageProject: String,
      _images: {
        type: Map,
        value: () => new Map(),
      },
      _stageImages: {
        type: Boolean,
        value: true,
      },
      _undefinedFileCounter: {
        type: Number,
        value: 0,
      },
      _query: {
        type: Function,
        value() {
          return this._queryProjects.bind(this);
        },
      },
    },

    listeners: {
      clear: '_handleClearImage',
      delete: '_handleDeleteImage',
      editName: '_handleEditImageName',
      upload: '_handleUploadImage',
    },

    attached() {
      this.fire('title-change', { title: 'Image Upload' });

      window.addEventListener('dragover', preventDefaultFn, false);
      window.addEventListener('drop', preventDefaultFn, false);
      this.$.dragDropArea.addEventListener('paste', preventDefaultFn, false);

      this._getUserPreferences();
    },

    detached() {
      window.removeEventListener('dragover', preventDefaultFn, false);
      window.removeEventListener('drop', preventDefaultFn, false);
      this.$.dragDropArea.removeEventListener('paste', preventDefaultFn, false);
    },

    _computeFilenameWithCorrectType(filedata, filename) {
      let realFiletype = filedata.slice(
        filedata.indexOf('/') + 1,
        filedata.indexOf(';'));

      let givenFiletype;

      if (filename.indexOf(".") !== -1) {
        givenFiletype = filename.split('.').pop();
      }

      if (!givenFiletype || realFiletype !== givenFiletype) {
        filename += `.${realFiletype}`;
      }

      return filename;
    },

    _computeLoadingClass(loading) {
      return loading ? 'loading' : '';
    },

    _computeSettingsUrl() {
      return `${location.origin}/settings#ImagarePreferences`;
    },

    _computeUploadAllDisabled() {
      if (this._images) {
        for (let value of this._images.values()) {
          if (!value.uploaded) {
            this._allUploaded = false;
            return;
          }
        }
      }

      this._allUploaded = true;
    },

    _createImageObject(name, data, url, list_entry, uploaded, ref) {
      return {
        data: data,
        list_entry: list_entry,
        name: name,
        ref: ref,
        url: url,
        uploaded: uploaded,
      }
    },

    _createListEntry(name, data, url) {
      let imagePanel = document.createElement('gr-imagare-list-item');
      imagePanel.setAttribute("image-name", name);

      if (data) {
        imagePanel.setAttribute("image-data", data);
      }

      if (url) {
        imagePanel.setAttribute("image-url", url);
        imagePanel.uploaded = true;
      } else {
        imagePanel.uploaded = false;
      }

      this.$.imageList.appendChild(imagePanel);

      return imagePanel;
    },

    _deleteImage(image) {
      this.plugin.restApi('/projects')
        .delete(`/${this._imageProject}/imagare~images/${image.ref}`)
        .then(() => {
          image.list_entry.remove();
          this._images.delete(image.name);
          if (!this.$.imageList.hasChildNodes()) {
            this.$.imageListContainer.hidden = true;
          }
        }).catch(response => {
          this.fire('show-error', { message: response });
        });
    },

    _extractImageRef(url) {
      return url.split('/').slice(-2)[0];
    },

    _getUserPreferences() {
      this.plugin.restApi('/accounts/self/')
        .get(`imagare~preference`)
        .then(config => {
          if (!config) {
            return;
          }

          this._defaultImageProject = config.default_project;
          this._imageProject = config.default_project;
          this._stageImages = config.stage;
          this._loading = false;
        });
    },

    _handleClearAllImages() {
      while (this.$.imageList.firstChild) {
        this.$.imageList.removeChild(this.$.imageList.firstChild);
      }
      this.$.imageListContainer.hidden = true;

      this._images.clear()
    },

    _handleClearImage(event) {
      event.stopPropagation();
      this._images.delete(event.target.imageName);
      event.target.remove();
      if (!this.$.imageList.hasChildNodes()) {
        this.$.imageListContainer.hidden = true;
      }
    },

    _handleDeleteImage(event) {
      event.stopPropagation();
      this._deleteImage(this._images.get(event.target.imageName));
    },

    _handleDrop(event) {
      event.preventDefault();
      event.stopPropagation();

      for (let file of event.dataTransfer.files) {
        if (!file.type.match('image/.*')) {
          this.fire('show-error', { message: `No image file: ${file.name}` });
        }
        let fr = new FileReader();
        fr.file = file;
        fr.onload = fileLoadEvent => this._handleFileLoadEvent(
          fr.file.name, fileLoadEvent);
        fr.readAsDataURL(file);
      }
    },

    _handleEditImageName(event) {
      event.stopPropagation();
      let editedImage = this._images.get(event.detail.oldName);
      if (this._images.has(event.detail.newName)) {
        this.fire('show-error', { message: 'An image with the same name was already staged.' });
        editedImage.list_entry.setAttribute("image-name", event.detail.oldName);
      } else {
        editedImage.name = event.detail.newName;
        this._images.set(editedImage.name, editedImage);
        this._images.delete(event.detail.oldName);
      }
    },

    _handleFileLoadEvent(filename, event) {
      let correctedFilename = this._computeFilenameWithCorrectType(
        event.target.result, filename);
      if (this._stageImages) {
        this._stageImage(correctedFilename, event.target.result);
      } else {
        let image = this._createImageObject(correctedFilename, event.target.result);
        this._images.set(correctedFilename, image);
        this._uploadImage(image);
      }
    },

    _handleKeyPress(event) {
      let ctrlDown = event.ctrlKey || event.metaKey;
      if (!ctrlDown) {
        event.preventDefault();
        event.stopPropagation();
      }
    },

    _handleImagePathChanged(event) {
      for (let file of event.target.files) {
        let fr = new FileReader();
        fr.file = file;
        fr.onload = fileLoadEvent => this._handleFileLoadEvent(
          fr.file.name, fileLoadEvent);
        fr.readAsDataURL(file);
      }

      event.target.value = '';
    },

    _handlePaste(event) {
      let clipboardData = event.clipboardData || event.originalEvent.clipboardData;
      let items = clipboardData.items;
      if (JSON.stringify(items)) {
        let blob;
        for (let item of items) {
          if (item.type.indexOf("image") === 0) {
            blob = item.getAsFile();
          }
        }
        if (blob) {
          let fr = new FileReader();
          fr.onload = fileLoadEvent => {
            let filename = `undefined-${this._undefinedFileCounter}`;
            this._undefinedFileCounter++;
            this._handleFileLoadEvent(filename, fileLoadEvent);
          };
          fr.readAsDataURL(blob);
        } else {
          event.preventDefault();
          this.fire('show-error', { message: `No image file` });
        }
      }
    },

    _handleUploadAllImages() {
      for (let image of this._images.values()) {
        this._uploadImage(image);
      }
    },

    _handleUploadImage(event) {
      event.stopPropagation();
      let image = this._createImageObject(
        event.target.imageName,
        event.target.imageData,
        null,
        event.target);
      this._images.set(image.name, image);
      this._uploadImage(image);
    },

    _queryProjects(input) {
      let query;
      if (!input || input === this._defaultImageProject) {
        query = '';
      } else {
        query = `?prefix=${input}`;
      }

      return this.plugin.restApi('/a/projects/').get(query)
        .then(response => {
          const projects = [];
          for (const key in response) {
            if (!response.hasOwnProperty(key)) { continue; }
            projects.push({
              name: key,
              value: decodeURIComponent(response[key].id),
            });
          }
          return projects;
        });
    },

    _stageImage(name, data) {
      if (this._images.has(name)) {
        let fileName = name.slice(0, name.lastIndexOf('.'));
        let fileExtension = name.slice(name.lastIndexOf('.'));
        name = `${fileName}-${this._undefinedFileCounter}${fileExtension}`;
        this._undefinedFileCounter++;
      }
      let imagePanel = this._createListEntry(name, data, null);
      this._images.set(name, this._createImageObject(name, data, null, imagePanel));
      this.$.imageListContainer.hidden = false;
      this._computeUploadAllDisabled();
    },

    _uploadImage(image) {
      if (image && image.uploaded) {
        return;
      }

      this.plugin.restApi('/projects')
        .post(`/${this._imageProject}/imagare~images`, {
          image_data: image.data,
          file_name: image.name,
        })
        .then(response => {
          if (!image.list_entry) {
            image.list_entry = this._createListEntry(image.name, image.data, response.url);
          } else {
            image.list_entry.setAttribute("image-url", response.url);
            image.list_entry.uploaded = true;
          }

          this._images.set(
            image.name,
            this._createImageObject(
              image.name, image.data, response.url, image.list_entry, true,
              this._extractImageRef(response.url)));

          this.$.imageListContainer.hidden = false;
          this._computeUploadAllDisabled();
        }).catch(response => {
          this.fire('show-error', { message: response });
        });
    }
  });
})();