Skip to content

Commit 1714eff

Browse files
committed
Finish server sync
1 parent 56d13cf commit 1714eff

1 file changed

Lines changed: 53 additions & 15 deletions

File tree

src/widgets/peoplePicker.js

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ export class PeoplePicker {
6363
.then(({groupNode, graphNode}) => {
6464
new GroupBuilder(
6565
this.element,
66+
bookBaseUrl,
6667
graphNode,
6768
groupNode,
6869
this.onSelectGroup
@@ -133,10 +134,19 @@ export class PeoplePicker {
133134
// might fail.
134135
const patchPromises = [graphNode, groupIndexNode]
135136
.map(namedGraph => {
136-
const typeStatement = rdf.st(groupNode, ns.rdf('type'), ns.vcard('Group'), namedGraph)
137-
const nameStatement = rdf.st(groupNode, ns.vcard('fn'), 'Untitled Group', namedGraph)
138-
return webClient.patch(namedGraph.value, [], [typeStatement, nameStatement])
139-
.then(() => kb.add([typeStatement, nameStatement]))
137+
const typeStatement = rdf.st(groupNode, ns.rdf('type'), ns.vcard('Group'))
138+
const nameStatement = rdf.st(groupNode, ns.vcard('fn'), rdf.literal('Untitled Group'))
139+
const includesGroupStatement = rdf.st(rdf.namedNode(`${bookBaseUrl}book.ttl#this`), ns.vcard('includesGroup'), groupNode)
140+
const toIns = namedGraph.equals(groupIndexNode)
141+
? [typeStatement, nameStatement, includesGroupStatement]
142+
: [typeStatement, nameStatement]
143+
return patch(namedGraph.value, {toIns})
144+
.then(() => {
145+
toIns.forEach(st => {
146+
st.why = namedGraph
147+
kb.add(st)
148+
})
149+
})
140150
})
141151
return Promise.all(patchPromises)
142152
.then(() => ({groupNode, graphNode}))
@@ -224,8 +234,9 @@ export class Group {
224234
}
225235

226236
export class GroupBuilder {
227-
constructor (element, groupGraph, groupNode, doneBuildingCb, groupChangedCb) {
237+
constructor (element, bookBaseUrl, groupGraph, groupNode, doneBuildingCb, groupChangedCb) {
228238
this.element = element
239+
this.bookBaseUrl = bookBaseUrl
229240
this.groupGraph = groupGraph
230241
this.groupNode = groupNode
231242
this.onGroupChanged = (err, changeType, agent) => {
@@ -263,8 +274,13 @@ export class GroupBuilder {
263274
const groupNameInput = document.createElement('input')
264275
groupNameInput.type = 'text'
265276
groupNameInput.value = getWithDefault(this.groupNode, ns.vcard('fn'), 'Untitled Group')
266-
groupNameInput.addEventListener('input', event => {
277+
groupNameInput.addEventListener('change', event => {
267278
this.setGroupName(event.target.value)
279+
.catch(err => {
280+
this.element.appendChild(
281+
errorMessageBlock(document, `Error changing group name. (${err})`)
282+
)
283+
})
268284
})
269285
const groupNameLabel = document.createElement('label')
270286
groupNameLabel.textContent = escape('Group Name:')
@@ -316,12 +332,13 @@ export class GroupBuilder {
316332
return resolve(webIdNode)
317333
})
318334
}).then(webIdNode => {
319-
const statement = rdf.st(this.groupNode, ns.vcard('hasMember'), webIdNode, this.groupGraph)
335+
const statement = rdf.st(this.groupNode, ns.vcard('hasMember'), webIdNode)
320336
if (kb.holdsStatement(statement)) {
321337
return webIdNode
322338
}
323-
return webClient.patch(this.groupGraph.value, [], [statement])
339+
return patch(this.groupGraph.value, {toIns: [statement]})
324340
.then(() => {
341+
statement.why = this.groupGraph
325342
kb.add(statement)
326343
this.onGroupChanged(null, 'added', webIdNode)
327344
this.render()
@@ -331,8 +348,8 @@ export class GroupBuilder {
331348

332349
handleRemove (webIdNode) {
333350
return event => {
334-
const statement = rdf.st(this.groupNode, ns.vcard('hasMember'), webIdNode, this.groupGraph)
335-
return webClient.patch(this.groupGraph.value, [statement], [])
351+
const statement = rdf.st(this.groupNode, ns.vcard('hasMember'), webIdNode)
352+
return patch(this.groupGraph.value, {toDel: [statement]})
336353
.then(() => {
337354
kb.remove(statement)
338355
this.onGroupChanged(null, 'removed', webIdNode)
@@ -350,11 +367,20 @@ export class GroupBuilder {
350367
}
351368

352369
setGroupName (name) {
353-
kb.match(this.groupNode, ns.vcard('fn')).forEach(st => {
354-
kb.remove(st)
355-
kb.add(this.groupNode, ns.vcard('fn'), rdf.literal(name), st.why)
356-
// TODO: sync
357-
})
370+
// TODO: refactor this bookmark footprint URL logic into a helper function, only pass `bookBaseUrl` between components
371+
const groupIndexUrl = `${this.bookBaseUrl}groups.ttl`
372+
const updatePromises = [this.groupGraph, rdf.namedNode(groupIndexUrl)]
373+
.map(namedGraph => {
374+
const oldNameStatements = kb.match(this.groupNode, ns.vcard('fn'), null, namedGraph)
375+
const newNameStatement = rdf.st(this.groupNode, ns.vcard('fn'), rdf.literal(name))
376+
return patch(namedGraph.value, {toDel: oldNameStatements, toIns: [newNameStatement]})
377+
.then(solidResponse => {
378+
kb.removeStatements(oldNameStatements)
379+
newNameStatement.why = namedGraph
380+
kb.add(newNameStatement)
381+
})
382+
})
383+
return Promise.all(updatePromises)
358384
}
359385
}
360386

@@ -407,3 +433,15 @@ function getWithDefault (subject, predicate, defaultValue) {
407433
const object = kb.any(subject, predicate)
408434
return object ? object.value : defaultValue
409435
}
436+
437+
function patch (url, {toDel, toIns}) {
438+
return webClient.patch(url, toDel, toIns)
439+
.then(solidResponse => {
440+
const status = solidResponse.xhr.status
441+
if (status < 200 || status >= 400) {
442+
const err = new Error(`PATCH failed for resource <${solidResponse.url}>`)
443+
err.solidResponse = solidResponse
444+
throw err
445+
}
446+
})
447+
}

0 commit comments

Comments
 (0)