-
Notifications
You must be signed in to change notification settings - Fork 4
/
folderPane.js
183 lines (164 loc) · 6.53 KB
/
folderPane.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/* Folder pane
**
** This outline pane lists the members of a folder
*/
const UI = require('solid-ui')
const style = UI.style
const 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 (context, newPaneOptions) {
const kb = context.session.store
const newInstance =
newPaneOptions.newInstance || kb.sym(newPaneOptions.newBase)
let 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 inside it
return kb.fetcher
.webOperation('PUT', newInstance.uri + '.dummy', { contentType: 'application/octet-stream' })
.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, context) {
const kb = context.session.store
const 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, context) {
function noHiddenFiles (obj) {
// @@ This hiddenness should actually be server defined
const pathEnd = obj.uri.slice(obj.dir().uri.length)
return !(
pathEnd.startsWith('.') ||
pathEnd.endsWith('.acl') ||
pathEnd.endsWith('~')
)
}
function refresh () {
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) {
const st = kb.statementsMatching(subject, ns.ldp('contains'), obj)[0]
const defaultpropview = outliner.VIEWAS_boring_default
const 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
})
}
const dom = context.dom
const outliner = context.getOutliner(dom)
const kb = context.session.store
var mainTable // This is a live synced table
const div = dom.createElement('div')
div.setAttribute('class', 'instancePane')
const paneStyle = style.folderPaneStyle || 'border-top: solid 1px #777; border-bottom: solid 1px #777; margin-top: 0.5em; margin-bottom: 0.5em;'
div.setAttribute('style', paneStyle)
// If this is an LDP container just list the directory
const thisDir = subject.uri.endsWith('/') ? subject.uri : subject.uri + '/'
const indexThing = kb.sym(thisDir + 'index.ttl#this')
if (kb.holds(subject, ns.ldp('contains'), indexThing.doc())) {
console.log(
'View of folder will be view of indexThing. Loading ' + indexThing
)
const 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'))
context
.getOutliner(dom)
.GotoSubject(indexThing, true, undefined, false, undefined, mainTable)
})
return div
} else {
mainTable = div.appendChild(dom.createElement('table'))
mainTable.refresh = refresh
refresh()
// addDownstreamChangeListener is a high level function which when oneone else changes the resource
// reloads it into the kb, and then calls us to be able to update the folder pane.
kb.updater.addDownstreamChangeListener(subject, refresh) // Update store and call me if folder changes
}
// Allow user to create new things within the folder
const creationDiv = div.appendChild(dom.createElement('div'))
const me = UI.authn.currentUser() // @@ respond to login events
const creationContext = {
folder: subject,
div: creationDiv,
dom: dom,
statusArea: creationDiv,
me: me
}
creationContext.refreshTarget = mainTable
UI.authn
.filterAvailablePanes(context.session.paneRegistry.list)
.then(function (relevantPanes) {
UI.create.newThingUI(creationContext, context, relevantPanes) // Have to pass panes down newUI
UI.aclControl.preventBrowserDropEvents(dom)
const explictDropIcon = false
let target
if (explictDropIcon) {
const 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
}
// /////////// Allow new file to be Uploaded
UI.widgets.makeDropTarget(target, null, droppedFileHandler)
})
return div
function droppedFileHandler (files) {
UI.widgets.uploadFiles(
kb.fetcher,
files,
subject.uri,
subject.uri,
function (file, uri) {
// A file has been uploaded
const destination = kb.sym(uri)
console.log(' Upload: put OK: ' + destination)
kb.add(subject, ns.ldp('contains'), destination, subject.doc())
mainTable.refresh()
}
)
}
}
}
// ends