UNPKG

solid-app-set

Version:
187 lines (165 loc) 7.46 kB
/* Folder pane ** ** This outline pane lists the members of a folder */ /* global FileReader */ var UI = require('solid-ui') var ns = UI.ns module.exports = { icon: UI.icons.iconBase + 'noun_973694_expanded.svg', name: 'folder', // Create a new folder in a Solid system, mintNew: function (newPaneOptions) { var kb = UI.store var newInstance = newPaneOptions.newInstance || kb.sym(newPaneOptions.newBase) var u = newInstance.uri if (u.endsWith('/')) { u = u.slice(0, -1) // chop off trailer }// { throw new Error('URI of new folder must end in "/" :' + u) } newPaneOptions.newInstance = kb.sym(u + '/') // @@@@ kludge until we can get the solid-client version working // Force the folder by saving a dummy file insie it return kb.fetcher.webOperation('PUT', newInstance.uri + '.dummy') .then(function () { console.log('New folder created: ' + newInstance.uri) return kb.fetcher.delete(newInstance.uri + '.dummy') }) .then(function () { console.log('Dummy file deleted : ' + newInstance.uri + '.dummy') /* return kb.fetcher.createContainer(parentURI, folderName) // Not BOTH ways }) .then(function () { */ console.log('New container created: ' + newInstance.uri) return newPaneOptions }) }, label: function (subject) { var kb = UI.store var n = kb.each(subject, ns.ldp('contains')).length if (n > 0) { return 'Contents (' + n + ')' // Show how many in hover text } if (kb.holds(subject, ns.rdf('type'), ns.ldp('Container'))) { // It is declared as being a container return 'Container (0)' } return null // Suppress pane otherwise }, // Render a file folder in a LDP/solid system render: function (subject, dom) { var outliner = UI.panes.getOutliner(dom) var kb = UI.store var mainTable // This is a live synced table var complain = function complain (message, color) { var pre = dom.createElement('pre') console.log(message) pre.setAttribute('style', 'background-color: ' + color || '#eed' + ';') div.appendChild(pre) pre.appendChild(dom.createTextNode(message)) } var div = dom.createElement('div') div.setAttribute('class', 'instancePane') div.setAttribute('style', ' border-top: solid 1px #777; border-bottom: solid 1px #777; margin-top: 0.5em; margin-bottom: 0.5em ') // If this is an LDP container just list the directory var noHiddenFiles = function (obj) { // @@ This hiddenness should actually be server defined var pathEnd = obj.uri.slice(obj.dir().uri.length) return !(pathEnd.startsWith('.') || pathEnd.endsWith('.acl') || pathEnd.endsWith('~')) } let thisDir = subject.uri.endsWith('/') ? subject.uri : subject.uri + '/' let indexThing = kb.sym(thisDir + 'index.ttl#this') if (kb.holds(subject, ns.ldp('contains'), indexThing.doc())) { console.log('View of folder with be view of indexThing. Loading ' + indexThing) let packageDiv = div.appendChild(dom.createElement('div')) packageDiv.style.cssText = 'border-top: 0.2em solid #ccc;' // Separate folder views above from package views below kb.fetcher.load(indexThing.doc()).then(function () { mainTable = packageDiv.appendChild(dom.createElement('table')) UI.outline.GotoSubject(indexThing, true, undefined, false, undefined, mainTable) }) return div } else { mainTable = div.appendChild(dom.createElement('table')) var refresh = function () { var objs = kb.each(subject, ns.ldp('contains')).filter(noHiddenFiles) objs = objs.map(obj => [ UI.utils.label(obj).toLowerCase(), obj ]) objs.sort() // Sort by label case-insensitive objs = objs.map(pair => pair[1]) UI.utils.syncTableToArray(mainTable, objs, function (obj) { let st = kb.statementsMatching(subject, ns.ldp('contains'), obj)[0] let defaultpropview = outliner.VIEWAS_boring_default let tr = outliner.propertyTR(dom, st, false) tr.firstChild.textContent = '' // Was initialized to 'Contains' tr.firstChild.style.cssText += 'min-width: 3em;' tr.appendChild(outliner.outlineObjectTD(obj, defaultpropview, undefined, st)) // UI.widgets.makeDraggable(tr, obj) return tr }) } mainTable.refresh = refresh refresh() } // Allow user to create new things within the folder var creationDiv = div.appendChild(dom.createElement('div')) var me = UI.authn.currentUser() var creationContext = {folder: subject, div: creationDiv, dom: dom, statusArea: creationDiv, me: me} creationContext.refreshTarget = mainTable UI.create.newThingUI(creationContext, UI.panes) // Have to pass panes down newUI // /////////// Allow new file to be Uploaded var droppedFileHandler = function (files) { var f for (var i = 0; files[i]; i++) { f = files[i] console.log(' folder: dropped filename: ' + f.name + ', type: ' + (f.type || 'n/a') + ' size: ' + f.size + ' bytes, last modified: ' + (f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a') ) var reader = new FileReader() reader.onload = (function (theFile) { return function (e) { var data = e.target.result console.log(' File read byteLength : ' + data.byteLength) if (!subject.uri.endsWith('/')) { console.log('FAIL: - folder name should end in /') return } // Check it does not already exist var destination = kb.sym(subject.uri + encodeURIComponent(theFile.name)) // encode spaces etc if (kb.holds(subject, ns.ldp('contains'), destination)) { complain('Sorry, ' + subject.uri + ' already has something called ' + theFile.name) console.log('Drag-drop upload aborted: folder already contains ' + destination) return } UI.store.fetcher.webOperation('PUT', destination, {data: data, contentType: theFile.type}) .then(function () { console.log(' Upload: put OK: ' + destination) kb.add(subject, ns.ldp('contains'), destination, subject.doc()) mainTable.refresh() // @@ reload the container file? // @@ Restore the target style after ALL files are done }) .catch(function (error) { complain(' Upload: FAILED ' + destination + ', Error: ' + error) }) } })(f) reader.readAsArrayBuffer(f) } } UI.aclControl.preventBrowserDropEvents(dom) const explictDropIcon = false var target if (explictDropIcon) { let iconStyleFound = creationDiv.firstChild.style.cssText target = creationDiv.insertBefore(dom.createElement('img'), creationDiv.firstChild) target.style.cssText = iconStyleFound target.setAttribute('src', UI.icons.iconBase + 'noun_748003.svg') target.setAttribute('style', 'width: 2em; height: 2em') // Safari says target.style is read-only } else { target = creationDiv.firstChild // Overload drop target semantics onto the plus sign } UI.widgets.makeDropTarget(target, null, droppedFileHandler) return div } } // ends