Audio and video files are not downloaded, but the element src is fetching the content directly from storage. Unfortunately, one cannot skip forward, when the RS server doesn't support content ranges.
178 lines
5.0 KiB
JavaScript
178 lines
5.0 KiB
JavaScript
import Component from '@ember/component';
|
|
import { inject as service } from '@ember/service';
|
|
import { observer } from '@ember/object';
|
|
import { alias, none, not } from '@ember/object/computed';
|
|
import { scheduleOnce } from '@ember/runloop';
|
|
import JSONTreeView from 'npm:json-tree-view';
|
|
|
|
export default Component.extend({
|
|
|
|
storage: service(),
|
|
|
|
classNames: ['file-preview'],
|
|
|
|
fileLoaded: false,
|
|
uploadingChanges: false,
|
|
|
|
showEditor: null,
|
|
hideEditor: not('showEditor'),
|
|
|
|
fileContent: null,
|
|
objectURL: null,
|
|
metaData: null,
|
|
isJSON: null,
|
|
type: alias('metaData.type'),
|
|
isBinary: alias('metaData.isBinary'),
|
|
|
|
isUnknownBinary: none('isImage', 'isAudio', 'isVideo'),
|
|
|
|
isImage: function() {
|
|
return this.get('type').match(/^image\/.+$/);
|
|
}.property('type'),
|
|
|
|
isAudio: function() {
|
|
return this.get('type').match(/^audio\/.+$/);
|
|
}.property('type'),
|
|
|
|
isVideo: function() {
|
|
return this.get('type').match(/^video\/.+$/);
|
|
}.property('type'),
|
|
|
|
isText: function() {
|
|
return !this.get('isBinary');
|
|
}.property('isBinary'),
|
|
|
|
loadFile: function() {
|
|
let path = this.get('metaData.path');
|
|
|
|
if (this.get('isAudio') || this.get('isVideo')) {
|
|
this.set('fileLoaded', true);
|
|
this.set('objectURL', this.get('storage.client')
|
|
.getItemURL(path));
|
|
return;
|
|
}
|
|
|
|
// TODO don't fetch is size above certain limit
|
|
|
|
console.debug(`[file-preview] Loading file ${this.get('metaData.name')}`)
|
|
this.get('storage.client').getFile(path).then(file => {
|
|
if (this.get('isImage')) {
|
|
let view = new window.Uint8Array(file.data);
|
|
let blob = new window.Blob([view], { type: file.contentType });
|
|
this.set('objectURL', window.URL.createObjectURL(blob));
|
|
} else {
|
|
this.set('fileContent', file.data);
|
|
}
|
|
|
|
this.set('fileLoaded', true);
|
|
});
|
|
}.on('didInsertElement'),
|
|
|
|
onFileLoaded: observer('fileLoaded', function(){
|
|
if (this.get('fileLoaded') && this.get('isJSON') && this.get('jsonShowTree')) {
|
|
scheduleOnce('afterRender', this, 'renderJsonTree');
|
|
}
|
|
}),
|
|
|
|
onJsonViewChanged: observer('jsonShowTree', function(){
|
|
if (this.get('fileLoaded') && this.get('isJSON') && this.get('jsonShowTree')) {
|
|
scheduleOnce('afterRender', this, 'renderJsonTree');
|
|
}
|
|
}),
|
|
|
|
renderJsonTree () {
|
|
let value = JSON.parse(this.get('fileContent'));
|
|
|
|
let view = new JSONTreeView('content', value);
|
|
// this.attachJsonTreeEventHandlers(view);
|
|
|
|
const containerElement = document.getElementById('json-tree-view');
|
|
containerElement.innerHTML = ''; // Throw away any existing treeviews
|
|
containerElement.appendChild(view.dom);
|
|
|
|
window.jsonview = view;
|
|
|
|
view.expand(true);
|
|
|
|
view.withRootName = false;
|
|
view.readonly = this.get('hideEditor');
|
|
|
|
this.set('jsonTreeView', view);
|
|
},
|
|
|
|
attachJsonTreeEventHandlers (view) {
|
|
view.on('change', function(self, key, oldValue, newValue){
|
|
console.log('change', key, oldValue, '=>', newValue);
|
|
});
|
|
view.on('rename', function(self, key, oldName, newName) {
|
|
console.log('rename', key, oldName, '=>', newName);
|
|
});
|
|
view.on('delete', function(self, key) {
|
|
console.log('delete', key);
|
|
});
|
|
view.on('append', function(self, key, nameOrValue, newValue) {
|
|
console.log('append', key, nameOrValue, '=>', newValue);
|
|
});
|
|
view.on('click', function(self, key, value) {
|
|
console.log('click', key, '=', value);
|
|
});
|
|
view.on('expand', function(self, key, value) {
|
|
console.log('expand', key, '=', value);
|
|
});
|
|
view.on('collapse', function(self, key, value) {
|
|
console.log('collapse', key, '=', value);
|
|
});
|
|
view.on('refresh', function(self, key, value) {
|
|
console.log('refresh', key, '=', value);
|
|
});
|
|
},
|
|
|
|
onShowEditor: observer('showEditor', function(){
|
|
if (this.get('fileLoaded') && this.get('isJSON') && this.get('jsonShowTree')) {
|
|
const showEditor = this.get('showEditor');
|
|
|
|
if (showEditor) {
|
|
this.set('jsonTreeView.readonly', false);
|
|
} else {
|
|
this.set('jsonTreeView.readonly', true);
|
|
this.renderJsonTree();
|
|
}
|
|
}
|
|
}),
|
|
|
|
actions: {
|
|
|
|
saveChanges () {
|
|
const path = this.get('metaData.path');
|
|
|
|
if (this.get('isJSON') && this.get('jsonShowTree')) {
|
|
const content = JSON.stringify(this.get('jsonTreeView.value'));
|
|
this.set('uploadingChanges', true);
|
|
|
|
this.get('storage.client')
|
|
.storeFile('application/json', path, content)
|
|
.then(etag => {
|
|
this.setProperties({
|
|
'metaData.etag': etag,
|
|
fileContent: content,
|
|
showEditor: false
|
|
});
|
|
}).catch(err => {
|
|
alert('Failed to update the file. Check the console for more info.');
|
|
console.error(err);
|
|
}).finally(() => {
|
|
this.set('uploadingChanges', false);
|
|
});
|
|
} else {
|
|
console.warn('not implemented');
|
|
}
|
|
},
|
|
|
|
cancelEditor () {
|
|
this.set('showEditor', false);
|
|
}
|
|
|
|
}
|
|
|
|
});
|