solid-panes 4.4.0 → 4.4.1-test.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/RDFXMLPane.css +70 -0
- package/dist/RDFXMLPane.d.ts +13 -0
- package/dist/RDFXMLPane.d.ts.map +1 -0
- package/dist/RDFXMLPane.js +46 -5
- package/dist/dataContentPane.css +271 -0
- package/dist/dataContentPane.d.ts +14 -0
- package/dist/dataContentPane.d.ts.map +1 -0
- package/dist/dataContentPane.js +68 -101
- package/dist/defaultPane.css +97 -0
- package/dist/defaultPane.d.ts +14 -0
- package/dist/defaultPane.d.ts.map +1 -0
- package/dist/defaultPane.js +9 -2
- package/dist/form/formPane.css +120 -0
- package/dist/form/pane.d.ts +4 -0
- package/dist/form/pane.d.ts.map +1 -0
- package/dist/form/pane.js +120 -54
- package/dist/humanReadablePane.css +129 -0
- package/dist/humanReadablePane.d.ts +13 -0
- package/dist/humanReadablePane.d.ts.map +1 -0
- package/dist/humanReadablePane.js +29 -18
- package/dist/icons/signUp.svg +9 -0
- package/dist/imagePane.css +4 -0
- package/dist/imagePane.d.ts +12 -0
- package/dist/imagePane.d.ts.map +1 -0
- package/dist/imagePane.js +19 -21
- package/dist/internal/internalPane.css +14 -0
- package/dist/internal/internalPane.d.ts +1 -0
- package/dist/internal/internalPane.d.ts.map +1 -1
- package/dist/internal/internalPane.js +5 -6
- package/dist/mainPage/header.js +2 -2
- package/dist/mainPage/index.d.ts +2 -1
- package/dist/mainPage/index.d.ts.map +1 -1
- package/dist/mainPage/index.js +23 -0
- package/dist/mainPage/menu.d.ts.map +1 -1
- package/dist/mainPage/menu.js +29 -2
- package/dist/n3Pane.css +49 -0
- package/dist/n3Pane.d.ts +13 -0
- package/dist/n3Pane.d.ts.map +1 -0
- package/dist/n3Pane.js +36 -5
- package/dist/outline/manager.js +20 -1
- package/dist/pad/padPane.css +6 -2
- package/dist/pad/padPane.js +1 -1
- package/dist/registerPanes.js +8 -8
- package/dist/schedule/schedulePane.css +294 -0
- package/dist/schedule/schedulePane.d.ts +23 -0
- package/dist/schedule/schedulePane.d.ts.map +1 -0
- package/dist/schedule/schedulePane.js +161 -61
- package/dist/social/editProfileDetails.d.ts +3 -3
- package/dist/social/editProfileDetails.d.ts.map +1 -1
- package/dist/social/editProfileDetails.js +222 -127
- package/dist/social/icons.d.ts +2 -0
- package/dist/social/icons.d.ts.map +1 -1
- package/dist/social/icons.js +39 -4
- package/dist/social/socialPane.css +838 -178
- package/dist/social/socialPane.d.ts.map +1 -1
- package/dist/social/socialPane.js +136 -43
- package/dist/social/socialSections.d.ts +11 -0
- package/dist/social/socialSections.d.ts.map +1 -1
- package/dist/social/socialSections.js +138 -62
- package/dist/social/spinner.d.ts +3 -0
- package/dist/social/spinner.d.ts.map +1 -0
- package/dist/social/spinner.js +13 -0
- package/dist/social/triage.d.ts +17 -0
- package/dist/social/triage.d.ts.map +1 -0
- package/dist/social/triage.js +79 -0
- package/dist/solid-panes.js +25772 -9576
- package/dist/solid-panes.js.map +1 -1
- package/dist/solid-panes.min.js +2583 -927
- package/dist/solid-panes.min.js.map +1 -1
- package/dist/{style → styles}/tabbedtab.css +0 -157
- package/dist/styles/utilities.css +5 -0
- package/dist/versionInfo.js +13 -13
- package/package.json +27 -26
- package/dist/icons/signup.png +0 -0
|
@@ -6,14 +6,16 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.createAllFriendsSection = createAllFriendsSection;
|
|
7
7
|
exports.createHeaderSection = createHeaderSection;
|
|
8
8
|
exports.createMutualSection = createMutualSection;
|
|
9
|
+
exports.createRequestsSection = createRequestsSection;
|
|
9
10
|
var _profilePane = require("profile-pane");
|
|
11
|
+
var _rdflib = require("rdflib");
|
|
10
12
|
var _solidUi = require("solid-ui");
|
|
11
13
|
var _editProfileDetails = require("./editProfileDetails");
|
|
12
14
|
var _icons = require("./icons");
|
|
13
15
|
function createHeaderSection(context, subject, controls, stats, getProfileData) {
|
|
14
16
|
const dom = context.dom;
|
|
15
17
|
const kb = context.session.store;
|
|
16
|
-
const header =
|
|
18
|
+
const header = dom.createElement('header');
|
|
17
19
|
header.className = 'social-pane__header';
|
|
18
20
|
let headerControls = controls;
|
|
19
21
|
const renderHeader = function () {
|
|
@@ -21,34 +23,34 @@ function createHeaderSection(context, subject, controls, stats, getProfileData)
|
|
|
21
23
|
const profileData = getProfileData();
|
|
22
24
|
const headerContent = dom.createElement('div');
|
|
23
25
|
headerContent.className = 'social-pane__header-content';
|
|
26
|
+
const headerActions = dom.createElement('div');
|
|
27
|
+
headerActions.className = 'social-pane__header-actions profile__actions profile__heading-actions';
|
|
24
28
|
if (headerControls.canEdit) {
|
|
25
|
-
header
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
header,
|
|
30
|
-
onSaved: renderHeader
|
|
31
|
-
}));
|
|
32
|
-
} else if (headerControls.viewerMode === 'authenticated') {
|
|
29
|
+
// Hidden for now because the social pane header edit control does not match the new design.
|
|
30
|
+
// Revisit later if we decide to restore profile-link editing here.
|
|
31
|
+
} else if (headerControls.viewerMode === 'authenticated' && headerControls.showAddFriendAction) {
|
|
32
|
+
headerActions.classList.add('social-pane__header-actions--friend');
|
|
33
33
|
const addToFriendsButton = (0, _profilePane.createAddMeToYourFriendsButton)(subject, context);
|
|
34
|
-
addToFriendsButton.classList.add('
|
|
35
|
-
|
|
36
|
-
headerContent.appendChild(addToFriendsButton);
|
|
34
|
+
addToFriendsButton.classList.add('flex-center');
|
|
35
|
+
headerActions.appendChild(addToFriendsButton);
|
|
37
36
|
}
|
|
38
37
|
header.appendChild(headerContent);
|
|
39
38
|
const headerMedia = dom.createElement('div');
|
|
40
39
|
headerMedia.className = 'social-pane__header-media';
|
|
41
40
|
headerContent.appendChild(headerMedia);
|
|
42
41
|
if (profileData) {
|
|
43
|
-
headerMedia.appendChild(createImage(profileData.imageUrl, profileData.name));
|
|
42
|
+
headerMedia.appendChild(createImage(dom, profileData.imageUrl, profileData.name));
|
|
44
43
|
}
|
|
45
44
|
const headerDetails = dom.createElement('div');
|
|
46
45
|
headerDetails.className = 'social-pane__header-details';
|
|
47
46
|
headerContent.appendChild(headerDetails);
|
|
47
|
+
if (headerActions.childNodes.length > 0) {
|
|
48
|
+
headerContent.appendChild(headerActions);
|
|
49
|
+
}
|
|
48
50
|
const headerSummary = dom.createElement('div');
|
|
49
51
|
headerSummary.classList.add('social-pane__header-summary', 'flex-column');
|
|
50
52
|
headerDetails.appendChild(headerSummary);
|
|
51
|
-
const name = profileData?.name ||
|
|
53
|
+
const name = profileData?.name || _solidUi.utils.label(subject);
|
|
52
54
|
const h1 = dom.createElement('h1');
|
|
53
55
|
h1.classList.add('social-pane__header-name');
|
|
54
56
|
h1.appendChild(dom.createTextNode(name));
|
|
@@ -106,9 +108,9 @@ function createHeaderSection(context, subject, controls, stats, getProfileData)
|
|
|
106
108
|
renderHeader();
|
|
107
109
|
return header;
|
|
108
110
|
}
|
|
109
|
-
function createImage(src, alt = '') {
|
|
111
|
+
function createImage(dom, src, alt = '') {
|
|
110
112
|
if (src) {
|
|
111
|
-
const img =
|
|
113
|
+
const img = dom.createElement('img');
|
|
112
114
|
img.className = 'social-pane__header-hero';
|
|
113
115
|
img.src = src;
|
|
114
116
|
img.alt = alt;
|
|
@@ -117,12 +119,12 @@ function createImage(src, alt = '') {
|
|
|
117
119
|
img.loading = 'eager';
|
|
118
120
|
return img;
|
|
119
121
|
}
|
|
120
|
-
const fallback =
|
|
122
|
+
const fallback = dom.createElement('div');
|
|
121
123
|
fallback.className = 'social-pane__header-hero-alt flex-center';
|
|
122
124
|
fallback.setAttribute('role', 'img');
|
|
123
125
|
fallback.setAttribute('aria-label', alt);
|
|
124
126
|
fallback.tabIndex = 0;
|
|
125
|
-
const icon =
|
|
127
|
+
const icon = dom.createElement('span');
|
|
126
128
|
icon.classList.add('social-pane__header-hero-icon', 'inline-flex-row');
|
|
127
129
|
icon.innerHTML = _icons.personInCircleIcon;
|
|
128
130
|
fallback.appendChild(icon);
|
|
@@ -133,20 +135,20 @@ function createMutualSection(options) {
|
|
|
133
135
|
dom,
|
|
134
136
|
subject,
|
|
135
137
|
familiar,
|
|
138
|
+
me,
|
|
136
139
|
meUri,
|
|
137
140
|
incoming,
|
|
138
141
|
outgoing,
|
|
142
|
+
editable,
|
|
143
|
+
profile,
|
|
144
|
+
knows,
|
|
139
145
|
mutualConnections,
|
|
140
146
|
link,
|
|
141
147
|
text,
|
|
148
|
+
buildCheckboxForm,
|
|
142
149
|
renderSupportingInfo,
|
|
143
150
|
renderNameSuffix
|
|
144
151
|
} = options;
|
|
145
|
-
|
|
146
|
-
// Mutual confirm UI is intentionally hidden for now.
|
|
147
|
-
// The related options remain in the function contract so that block can be
|
|
148
|
-
// restored later without reshaping callers.
|
|
149
|
-
|
|
150
152
|
let refreshMutualFriends = function () {};
|
|
151
153
|
const mutualSection = dom.createElement('section');
|
|
152
154
|
mutualSection.className = 'social-pane__mutual-friends social-primary__panel';
|
|
@@ -174,49 +176,38 @@ function createMutualSection(options) {
|
|
|
174
176
|
if (!outgoing) {
|
|
175
177
|
const line = youAndThem();
|
|
176
178
|
line.appendChild(text(' have not said you know each other.'));
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
*/
|
|
179
|
+
} else {
|
|
180
|
+
const line = createRelationshipLine();
|
|
181
|
+
line.appendChild(link(text('You'), meUri));
|
|
182
|
+
line.appendChild(text(' know '));
|
|
183
|
+
line.appendChild(link(text(familiar), subject.uri));
|
|
184
|
+
line.appendChild(text(' (unconfirmed).'));
|
|
184
185
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
incomingLine.appendChild(text(' (unconfirmed).'))
|
|
194
|
-
*/
|
|
186
|
+
} else if (!outgoing) {
|
|
187
|
+
relationshipSummary.classList.add('social-mutual-summary--confirm');
|
|
188
|
+
const incomingLine = relationshipSummary.appendChild(dom.createElement('div'));
|
|
189
|
+
incomingLine.classList.add('social-mutual-summary-line');
|
|
190
|
+
incomingLine.appendChild(link(text(familiar), subject.uri));
|
|
191
|
+
incomingLine.appendChild(text(' knows '));
|
|
192
|
+
incomingLine.appendChild(link(text('you'), meUri));
|
|
193
|
+
incomingLine.appendChild(text(' (unconfirmed).'));
|
|
195
194
|
} else {
|
|
196
195
|
const line = youAndThem();
|
|
197
196
|
line.appendChild(text(' say you know each other.'));
|
|
198
197
|
}
|
|
199
|
-
|
|
200
|
-
/* NOTE: hiding the confirm-friend checkbox for now.
|
|
201
|
-
const shouldShowCheckboxPreview = editable || (Boolean(incoming) && !outgoing)
|
|
198
|
+
const shouldShowCheckboxPreview = Boolean(incoming) && !outgoing;
|
|
202
199
|
if (shouldShowCheckboxPreview) {
|
|
203
|
-
const confirmLabel = dom.createElement('span')
|
|
204
|
-
confirmLabel.
|
|
205
|
-
confirmLabel.appendChild(
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
-
)
|
|
215
|
-
relationshipForm.classList.add('social-mutual-checkbox-form')
|
|
216
|
-
mutualContent.appendChild(relationshipForm)
|
|
200
|
+
const confirmLabel = dom.createElement('span');
|
|
201
|
+
confirmLabel.className = 'social-mutual-confirm-prompt';
|
|
202
|
+
confirmLabel.appendChild(text('Confirm you know '));
|
|
203
|
+
confirmLabel.appendChild(link(text(familiar), subject.uri));
|
|
204
|
+
const relationshipForm = buildCheckboxForm(confirmLabel, new _rdflib.Statement(me, knows, subject, profile ?? undefined), Boolean(outgoing), {
|
|
205
|
+
disabled: !editable,
|
|
206
|
+
disabledTitle: !editable ? 'Your profile is not editable' : undefined
|
|
207
|
+
});
|
|
208
|
+
relationshipForm.classList.add('social-mutual-checkbox-form');
|
|
209
|
+
mutualContent.appendChild(relationshipForm);
|
|
217
210
|
}
|
|
218
|
-
*/
|
|
219
|
-
|
|
220
211
|
if (mutualConnections.length) {
|
|
221
212
|
const mutualFriendsTable = mutualContent.appendChild(dom.createElement('table'));
|
|
222
213
|
mutualFriendsTable.className = 'social-main social-friends-list social-friends-grid';
|
|
@@ -266,6 +257,11 @@ function createAllFriendsSection(options) {
|
|
|
266
257
|
modify: !!editable,
|
|
267
258
|
predicate: _solidUi.ns.foaf('knows'),
|
|
268
259
|
noun: 'friend',
|
|
260
|
+
// Social pane already owns the async refresh cycle for friend data in
|
|
261
|
+
// socialPane.ts. Leave attachmentList's generic follow-up rerender disabled
|
|
262
|
+
// here or each fetched friend profile will trigger an extra whole-table refresh
|
|
263
|
+
// on top of the pane's own batched updates.
|
|
264
|
+
refreshOnDocumentLoad: false,
|
|
269
265
|
renderSupportingInfo,
|
|
270
266
|
renderNameSuffix
|
|
271
267
|
});
|
|
@@ -276,14 +272,23 @@ function createAllFriendsSection(options) {
|
|
|
276
272
|
const friendsListRightCell = friendsListRow?.children?.[1];
|
|
277
273
|
const friendsHeaderActions = dom.createElement('div');
|
|
278
274
|
friendsHeaderActions.classList.add('social-friends-header-actions');
|
|
279
|
-
if (friendsListPromptCell instanceof
|
|
275
|
+
if (friendsListPromptCell instanceof HTMLTableCellElement) {
|
|
276
|
+
friendsListPromptCell.classList.add('social-friends-header-dropzone-cell');
|
|
277
|
+
const friendsHeaderDropzone = dom.createElement('table');
|
|
278
|
+
friendsHeaderDropzone.className = 'social-friends-header-dropzone';
|
|
279
|
+
friendsHeaderDropzone.setAttribute('role', 'presentation');
|
|
280
|
+
const friendsHeaderDropzoneBody = friendsHeaderDropzone.appendChild(dom.createElement('tbody'));
|
|
281
|
+
const friendsHeaderDropzoneRow = friendsHeaderDropzoneBody.appendChild(dom.createElement('tr'));
|
|
282
|
+
friendsHeaderDropzoneRow.appendChild(friendsListPromptCell);
|
|
283
|
+
friendsHeaderActions.appendChild(friendsHeaderDropzone);
|
|
284
|
+
} else if (friendsListPromptCell instanceof HTMLElement) {
|
|
280
285
|
while (friendsListPromptCell.firstChild) {
|
|
281
286
|
friendsHeaderActions.appendChild(friendsListPromptCell.firstChild);
|
|
282
287
|
}
|
|
283
288
|
friendsListPromptCell.remove();
|
|
284
289
|
}
|
|
285
|
-
|
|
286
|
-
|
|
290
|
+
const friendDropButtons = friendsHeaderActions.querySelectorAll('button');
|
|
291
|
+
if (editable && friendDropButtons.length > 0) {
|
|
287
292
|
friendDropButtons.forEach(button => {
|
|
288
293
|
button.setAttribute('title', 'Drop friend here');
|
|
289
294
|
button.setAttribute('aria-label', 'Drop friend here');
|
|
@@ -314,4 +319,75 @@ function createAllFriendsSection(options) {
|
|
|
314
319
|
mainTable,
|
|
315
320
|
friendsList
|
|
316
321
|
};
|
|
322
|
+
}
|
|
323
|
+
function createRequestsSection(options) {
|
|
324
|
+
const {
|
|
325
|
+
dom,
|
|
326
|
+
triage,
|
|
327
|
+
renderSupportingInfo,
|
|
328
|
+
renderNameSuffix
|
|
329
|
+
} = options;
|
|
330
|
+
const requestsSection = dom.createElement('section');
|
|
331
|
+
requestsSection.className = 'social-pane__requests social-primary__panel';
|
|
332
|
+
requestsSection.id = 'social-panel-requests';
|
|
333
|
+
requestsSection.setAttribute('role', 'tabpanel');
|
|
334
|
+
requestsSection.setAttribute('aria-labelledby', 'social-tab-requests');
|
|
335
|
+
const requestsContent = requestsSection.appendChild(dom.createElement('div'));
|
|
336
|
+
requestsContent.classList.add('social-main', 'social-main--requests', 'flex-column');
|
|
337
|
+
const note = requestsContent.appendChild(dom.createElement('p'));
|
|
338
|
+
note.className = 'social-requests__note';
|
|
339
|
+
note.textContent = 'Best effort preview: this view only reflects profile documents that are currently loaded. A dedicated inbox would still be needed for complete request discovery.';
|
|
340
|
+
const createRequestGroup = function (title, description, emptyText) {
|
|
341
|
+
const group = requestsContent.appendChild(dom.createElement('section'));
|
|
342
|
+
group.classList.add('social-requests__group', 'flex-column');
|
|
343
|
+
const header = group.appendChild(dom.createElement('div'));
|
|
344
|
+
header.className = 'social-requests__group-header';
|
|
345
|
+
const heading = header.appendChild(dom.createElement('h2'));
|
|
346
|
+
heading.className = 'social-requests__group-title';
|
|
347
|
+
heading.textContent = title;
|
|
348
|
+
const blurb = header.appendChild(dom.createElement('p'));
|
|
349
|
+
blurb.className = 'social-requests__group-description';
|
|
350
|
+
blurb.textContent = description;
|
|
351
|
+
const empty = group.appendChild(dom.createElement('p'));
|
|
352
|
+
empty.className = 'social-requests__empty';
|
|
353
|
+
empty.textContent = emptyText;
|
|
354
|
+
const table = group.appendChild(dom.createElement('table'));
|
|
355
|
+
table.className = 'social-main social-friends-list social-friends-grid social-requests__table';
|
|
356
|
+
return {
|
|
357
|
+
empty,
|
|
358
|
+
table
|
|
359
|
+
};
|
|
360
|
+
};
|
|
361
|
+
const incomingGroup = createRequestGroup('Incoming requests', 'People who say they know this profile, but have not been confirmed yet.', 'No incoming requests are visible from the currently loaded data.');
|
|
362
|
+
const pendingGroup = createRequestGroup('Awaiting confirmation', 'People this profile knows who have not linked back yet.', 'Nothing is waiting for confirmation right now.');
|
|
363
|
+
const createPersonRow = function (target) {
|
|
364
|
+
return _solidUi.widgets.personTR(dom, _solidUi.ns.foaf('knows'), target, {
|
|
365
|
+
renderSupportingInfo,
|
|
366
|
+
renderNameSuffix
|
|
367
|
+
});
|
|
368
|
+
};
|
|
369
|
+
const sortNodes = function (nodes) {
|
|
370
|
+
return [...nodes].sort((left, right) => {
|
|
371
|
+
const leftLabel = _solidUi.utils.label(left) || left.value;
|
|
372
|
+
const rightLabel = _solidUi.utils.label(right) || right.value;
|
|
373
|
+
return leftLabel.localeCompare(rightLabel);
|
|
374
|
+
});
|
|
375
|
+
};
|
|
376
|
+
const syncRequestGroup = function (group, nodes) {
|
|
377
|
+
const sortedNodes = sortNodes(nodes);
|
|
378
|
+
group.empty.hidden = sortedNodes.length > 0;
|
|
379
|
+
group.table.hidden = sortedNodes.length === 0;
|
|
380
|
+
_solidUi.utils.syncTableToArray(group.table, sortedNodes, createPersonRow, function (_row, thing) {
|
|
381
|
+
return createPersonRow(thing);
|
|
382
|
+
});
|
|
383
|
+
};
|
|
384
|
+
const refreshRequests = function (nextTriage) {
|
|
385
|
+
syncRequestGroup(incomingGroup, nextTriage.requests);
|
|
386
|
+
syncRequestGroup(pendingGroup, nextTriage.unconfirmed);
|
|
387
|
+
};
|
|
388
|
+
refreshRequests(triage);
|
|
389
|
+
return {
|
|
390
|
+
section: requestsSection,
|
|
391
|
+
refreshRequests
|
|
392
|
+
};
|
|
317
393
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/social/spinner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,cAAc,EAAE,MAAM,UAAU,CAAA;AAE/C,wBAAgB,aAAa,IAAK,cAAc,CAK/C"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createSpinner = createSpinner;
|
|
7
|
+
var _litHtml = require("lit-html");
|
|
8
|
+
function createSpinner() {
|
|
9
|
+
return (0, _litHtml.html)`
|
|
10
|
+
<span class="loading-spinner" aria-hidden="true"></span>
|
|
11
|
+
<span class="sr-only">Saving...</span>
|
|
12
|
+
`;
|
|
13
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { DataBrowserContext } from 'pane-registry';
|
|
2
|
+
import { IndexedFormula, NamedNode } from 'rdflib';
|
|
3
|
+
type FriendshipStore = IndexedFormula & {
|
|
4
|
+
fetcher?: {
|
|
5
|
+
load?: (target: NamedNode | string) => Promise<unknown>;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
export interface FriendshipTriage {
|
|
9
|
+
acquaintances: NamedNode[];
|
|
10
|
+
confirmed: NamedNode[];
|
|
11
|
+
unconfirmed: NamedNode[];
|
|
12
|
+
requests: NamedNode[];
|
|
13
|
+
}
|
|
14
|
+
export declare function triageFriends(store: FriendshipStore, subject: NamedNode): FriendshipTriage;
|
|
15
|
+
export declare function loadFriendshipTriage(context: DataBrowserContext, subject: NamedNode): Promise<FriendshipTriage>;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=triage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triage.d.ts","sourceRoot":"","sources":["../../src/social/triage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAGlD,KAAK,eAAe,GAAG,cAAc,GAAG;IACtC,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;KACxD,CAAA;CACF,CAAA;AAED,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,SAAS,EAAE,CAAA;IAC1B,SAAS,EAAE,SAAS,EAAE,CAAA;IACtB,WAAW,EAAE,SAAS,EAAE,CAAA;IACxB,QAAQ,EAAE,SAAS,EAAE,CAAA;CACtB;AAgBD,wBAAgB,aAAa,CAAE,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,GAAG,gBAAgB,CA+B3F;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,gBAAgB,CAAC,CAwC3B"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.loadFriendshipTriage = loadFriendshipTriage;
|
|
7
|
+
exports.triageFriends = triageFriends;
|
|
8
|
+
var _solidUi = require("solid-ui");
|
|
9
|
+
function uniqueNamedNodes(nodes) {
|
|
10
|
+
const seen = new Set();
|
|
11
|
+
const unique = [];
|
|
12
|
+
for (const node of nodes) {
|
|
13
|
+
const key = node?.value;
|
|
14
|
+
if (!key || seen.has(key)) continue;
|
|
15
|
+
seen.add(key);
|
|
16
|
+
unique.push(node);
|
|
17
|
+
}
|
|
18
|
+
return unique;
|
|
19
|
+
}
|
|
20
|
+
function triageFriends(store, subject) {
|
|
21
|
+
const outgoingFriends = uniqueNamedNodes(store.each(subject, _solidUi.ns.foaf('knows')));
|
|
22
|
+
const incomingFriends = uniqueNamedNodes(store.each(undefined, _solidUi.ns.foaf('knows'), subject));
|
|
23
|
+
const confirmed = [];
|
|
24
|
+
const unconfirmed = [];
|
|
25
|
+
const requests = [];
|
|
26
|
+
for (const friend of outgoingFriends) {
|
|
27
|
+
const isConfirmed = incomingFriends.some(incomingFriend => incomingFriend.sameTerm(friend));
|
|
28
|
+
if (isConfirmed) {
|
|
29
|
+
confirmed.push(friend);
|
|
30
|
+
} else {
|
|
31
|
+
unconfirmed.push(friend);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
for (const friend of incomingFriends) {
|
|
35
|
+
const isAlreadyOutgoing = outgoingFriends.some(outgoingFriend => outgoingFriend.sameTerm(friend));
|
|
36
|
+
if (!isAlreadyOutgoing) {
|
|
37
|
+
requests.push(friend);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
acquaintances: outgoingFriends,
|
|
42
|
+
confirmed,
|
|
43
|
+
unconfirmed,
|
|
44
|
+
requests
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
async function loadFriendshipTriage(context, subject) {
|
|
48
|
+
const store = context.session.store;
|
|
49
|
+
const fetcher = store.fetcher;
|
|
50
|
+
if (!fetcher || typeof fetcher.load !== 'function') {
|
|
51
|
+
return triageFriends(store, subject);
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
await fetcher.load(subject.doc());
|
|
55
|
+
} catch {
|
|
56
|
+
// Continue with the store snapshot we already have.
|
|
57
|
+
}
|
|
58
|
+
const initialTriage = triageFriends(store, subject);
|
|
59
|
+
const documentsToLoad = new Map();
|
|
60
|
+
documentsToLoad.set(subject.doc().value, subject.doc());
|
|
61
|
+
for (const friend of [...initialTriage.acquaintances, ...initialTriage.requests]) {
|
|
62
|
+
documentsToLoad.set(friend.doc().value, friend.doc());
|
|
63
|
+
}
|
|
64
|
+
const incomingStatements = store.statementsMatching(undefined, _solidUi.ns.foaf('knows'), subject);
|
|
65
|
+
for (const statement of incomingStatements) {
|
|
66
|
+
const why = statement.why;
|
|
67
|
+
if (why?.value) {
|
|
68
|
+
documentsToLoad.set(why.value, why);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
for (const target of documentsToLoad.values()) {
|
|
72
|
+
try {
|
|
73
|
+
await fetcher.load(target);
|
|
74
|
+
} catch {
|
|
75
|
+
// Keep partial results when one profile document fails to load.
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return triageFriends(store, subject);
|
|
79
|
+
}
|