profile-pane 3.2.0 → 3.2.2-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 +50 -0
- package/icons-png/discord.png +0 -0
- package/icons-png/dribbble.png +0 -0
- package/icons-png/facebook.png +0 -0
- package/icons-png/instagram.png +0 -0
- package/icons-png/linkedin.png +0 -0
- package/icons-png/pinterest.png +0 -0
- package/icons-png/sharechat.png +0 -0
- package/icons-png/signup.png +0 -0
- package/icons-png/snapchat.png +0 -0
- package/icons-png/spotify.png +0 -0
- package/icons-png/telegram.png +0 -0
- package/icons-png/tiktok.png +0 -0
- package/icons-png/whatsapp.png +0 -0
- package/icons-png/x.png +0 -0
- package/icons-png/youtube.png +0 -0
- package/lib/303.profile-pane.js +1362 -0
- package/lib/303.profile-pane.js.map +1 -0
- package/lib/303.profile-pane.min.js +2 -0
- package/lib/303.profile-pane.min.js.map +1 -0
- package/lib/ProfileView.css +1090 -0
- package/lib/ProfileView.d.ts +2 -1
- package/lib/ProfileView.d.ts.map +1 -1
- package/lib/ProfileView.js +64 -36
- package/lib/buttonsHelper.d.ts +1 -1
- package/lib/buttonsHelper.d.ts.map +1 -1
- package/lib/buttonsHelper.js +2 -1
- package/lib/editProfilePane/EditCVCard.js +1 -1
- package/lib/editProfilePane/EditCommunitiesCard.js +1 -1
- package/lib/editProfilePane/EditFriendsCard.js +1 -1
- package/lib/editProfilePane/EditProfileView.d.ts +1 -1
- package/lib/editProfilePane/EditProfileView.d.ts.map +1 -1
- package/lib/editProfilePane/EditProfileView.js +4 -5
- package/lib/editProfilePane/editProfilePresenter.d.ts.map +1 -1
- package/lib/editProfilePane/editProfilePresenter.js +5 -4
- package/lib/icons-svg/profileIcons.d.ts +1 -1
- package/lib/icons-svg/profileIcons.d.ts.map +1 -1
- package/lib/icons-svg/profileIcons.js +9 -17
- package/lib/index.d.ts +1 -8
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +74 -40
- package/lib/ontology/otherPreferencesForm.ttl +32 -0
- package/lib/ontology/resumeForm.ttl +349 -0
- package/lib/ontology/socialMedia.ttl +433 -0
- package/lib/profile-pane.js +32266 -13247
- package/lib/profile-pane.js.map +1 -1
- package/lib/profile-pane.min.js +2315 -935
- package/lib/profile-pane.min.js.map +1 -1
- package/lib/rdfFormsHelper.d.ts +13 -1
- package/lib/rdfFormsHelper.d.ts.map +1 -1
- package/lib/rdfFormsHelper.js +13 -1
- package/lib/sections/bio/BioEditDialog.d.ts.map +1 -1
- package/lib/sections/bio/BioEditDialog.js +7 -7
- package/lib/sections/bio/BioSection.css +300 -0
- package/lib/sections/bio/BioSection.d.ts +3 -2
- package/lib/sections/bio/BioSection.d.ts.map +1 -1
- package/lib/sections/bio/BioSection.js +26 -19
- package/lib/sections/bio/mutations.d.ts.map +1 -1
- package/lib/sections/bio/mutations.js +14 -3
- package/lib/sections/contactInfo/ContactInfoEditDialog.css +354 -0
- package/lib/sections/contactInfo/ContactInfoEditDialog.d.ts +3 -1
- package/lib/sections/contactInfo/ContactInfoEditDialog.d.ts.map +1 -1
- package/lib/sections/contactInfo/ContactInfoEditDialog.js +183 -98
- package/lib/sections/contactInfo/ContactInfoSection.css +125 -0
- package/lib/sections/contactInfo/ContactInfoSection.d.ts +2 -0
- package/lib/sections/contactInfo/ContactInfoSection.d.ts.map +1 -1
- package/lib/sections/contactInfo/ContactInfoSection.js +64 -41
- package/lib/sections/contactInfo/mutations.d.ts.map +1 -1
- package/lib/sections/contactInfo/mutations.js +51 -16
- package/lib/sections/education/EducationEditDialog.d.ts +3 -1
- package/lib/sections/education/EducationEditDialog.d.ts.map +1 -1
- package/lib/sections/education/EducationEditDialog.js +170 -92
- package/lib/sections/education/EducationSection.css +133 -0
- package/lib/sections/education/EducationSection.d.ts +3 -2
- package/lib/sections/education/EducationSection.d.ts.map +1 -1
- package/lib/sections/education/EducationSection.js +32 -25
- package/lib/sections/education/mutations.d.ts.map +1 -1
- package/lib/sections/education/mutations.js +14 -3
- package/lib/sections/heading/HeadingEditDialog.d.ts +4 -1
- package/lib/sections/heading/HeadingEditDialog.d.ts.map +1 -1
- package/lib/sections/heading/HeadingEditDialog.js +287 -162
- package/lib/sections/heading/HeadingSection.css +862 -0
- package/lib/sections/heading/HeadingSection.d.ts +3 -2
- package/lib/sections/heading/HeadingSection.d.ts.map +1 -1
- package/lib/sections/heading/HeadingSection.js +63 -32
- package/lib/sections/heading/imageHelpers.d.ts +1 -0
- package/lib/sections/heading/imageHelpers.d.ts.map +1 -1
- package/lib/sections/heading/imageHelpers.js +40 -1
- package/lib/sections/heading/mutations.d.ts.map +1 -1
- package/lib/sections/heading/mutations.js +86 -23
- package/lib/sections/heading/selectors.d.ts.map +1 -1
- package/lib/sections/heading/selectors.js +14 -3
- package/lib/sections/heading/types.d.ts +1 -2
- package/lib/sections/heading/types.d.ts.map +1 -1
- package/lib/sections/languages/LanguageEditDialog.d.ts +3 -1
- package/lib/sections/languages/LanguageEditDialog.d.ts.map +1 -1
- package/lib/sections/languages/LanguageEditDialog.js +202 -119
- package/lib/sections/languages/LanguageSection.css +53 -0
- package/lib/sections/languages/LanguageSection.d.ts +2 -0
- package/lib/sections/languages/LanguageSection.d.ts.map +1 -1
- package/lib/sections/languages/LanguageSection.js +42 -31
- package/lib/sections/languages/mutations.d.ts.map +1 -1
- package/lib/sections/languages/mutations.js +60 -161
- package/lib/sections/languages/selectors.d.ts.map +1 -1
- package/lib/sections/languages/selectors.js +1 -2
- package/lib/sections/projects/ProjectEditDialog.d.ts +2 -1
- package/lib/sections/projects/ProjectEditDialog.d.ts.map +1 -1
- package/lib/sections/projects/ProjectEditDialog.js +13 -24
- package/lib/sections/projects/ProjectSection.css +368 -0
- package/lib/sections/projects/ProjectSection.d.ts +2 -1
- package/lib/sections/projects/ProjectSection.d.ts.map +1 -1
- package/lib/sections/projects/ProjectSection.js +116 -34
- package/lib/sections/projects/mutations.d.ts.map +1 -1
- package/lib/sections/projects/mutations.js +109 -132
- package/lib/sections/projects/selectors.d.ts.map +1 -1
- package/lib/sections/projects/selectors.js +4 -45
- package/lib/{QRCodeCard.d.ts → sections/qrcode/QRCodeCard.d.ts} +2 -1
- package/lib/sections/qrcode/QRCodeCard.d.ts.map +1 -0
- package/lib/{QRCodeCard.js → sections/qrcode/QRCodeCard.js} +59 -11
- package/lib/sections/qrcode/QRCodeSection.css +108 -0
- package/lib/sections/qrcode/QRCodeSection.d.ts +4 -0
- package/lib/sections/qrcode/QRCodeSection.d.ts.map +1 -0
- package/lib/sections/qrcode/QRCodeSection.js +17 -0
- package/lib/sections/resume/ResumeEditDialog.d.ts +10 -1
- package/lib/sections/resume/ResumeEditDialog.d.ts.map +1 -1
- package/lib/sections/resume/ResumeEditDialog.js +531 -149
- package/lib/sections/resume/ResumeSection.css +350 -0
- package/lib/sections/resume/ResumeSection.d.ts +3 -2
- package/lib/sections/resume/ResumeSection.d.ts.map +1 -1
- package/lib/sections/resume/ResumeSection.js +78 -49
- package/lib/sections/resume/mutations.d.ts.map +1 -1
- package/lib/sections/resume/mutations.js +17 -3
- package/lib/sections/resume/selectors.d.ts.map +1 -1
- package/lib/sections/resume/selectors.js +1 -0
- package/lib/sections/resume/types.d.ts +1 -0
- package/lib/sections/resume/types.d.ts.map +1 -1
- package/lib/sections/shared/collapsibleSection.d.ts.map +1 -1
- package/lib/sections/shared/collapsibleSection.js +1 -0
- package/lib/sections/shared/phoneCountries.d.ts +1 -1
- package/lib/sections/shared/phoneCountries.d.ts.map +1 -1
- package/lib/sections/shared/phoneCountries.js +2 -2
- package/lib/sections/shared/projectCommunityNodes.d.ts +6 -0
- package/lib/sections/shared/projectCommunityNodes.d.ts.map +1 -0
- package/lib/sections/shared/projectCommunityNodes.js +56 -0
- package/lib/sections/shared/rdfMutationHelpers.d.ts +35 -2
- package/lib/sections/shared/rdfMutationHelpers.d.ts.map +1 -1
- package/lib/sections/shared/rdfMutationHelpers.js +290 -14
- package/lib/sections/shared/sectionCardHelpers.d.ts.map +1 -1
- package/lib/sections/shared/sectionCardHelpers.js +80 -11
- package/lib/sections/shared/types.d.ts +24 -0
- package/lib/sections/shared/types.d.ts.map +1 -1
- package/lib/sections/skills/SkillsEditDialog.d.ts +3 -1
- package/lib/sections/skills/SkillsEditDialog.d.ts.map +1 -1
- package/lib/sections/skills/SkillsEditDialog.js +136 -115
- package/lib/sections/skills/SkillsSection.css +173 -0
- package/lib/sections/skills/SkillsSection.d.ts +2 -0
- package/lib/sections/skills/SkillsSection.d.ts.map +1 -1
- package/lib/sections/skills/SkillsSection.js +107 -47
- package/lib/sections/skills/mutations.d.ts.map +1 -1
- package/lib/sections/skills/mutations.js +25 -21
- package/lib/sections/skills/selectors.d.ts.map +1 -1
- package/lib/sections/skills/selectors.js +5 -3
- package/lib/sections/social/SocialEditDialog.d.ts +3 -1
- package/lib/sections/social/SocialEditDialog.d.ts.map +1 -1
- package/lib/sections/social/SocialEditDialog.js +170 -62
- package/lib/sections/social/SocialSection.css +194 -0
- package/lib/sections/social/SocialSection.d.ts +4 -3
- package/lib/sections/social/SocialSection.d.ts.map +1 -1
- package/lib/sections/social/SocialSection.js +59 -43
- package/lib/sections/social/mutations.d.ts.map +1 -1
- package/lib/sections/social/mutations.js +23 -132
- package/lib/specialButtons/AddMeToYourFriends.css +54 -0
- package/lib/specialButtons/addContact/AddMeToYourContacts.css +1118 -0
- package/lib/specialButtons/addContact/ContactCreationDialog.d.ts +10 -0
- package/lib/specialButtons/addContact/ContactCreationDialog.d.ts.map +1 -0
- package/lib/specialButtons/addContact/ContactCreationDialog.js +1123 -0
- package/lib/specialButtons/addContact/addMeToYourContacts.d.ts +16 -0
- package/lib/specialButtons/addContact/addMeToYourContacts.d.ts.map +1 -0
- package/lib/specialButtons/addContact/addMeToYourContacts.js +136 -0
- package/lib/specialButtons/addContact/contactsErrors.d.ts +8 -0
- package/lib/specialButtons/addContact/contactsErrors.d.ts.map +1 -0
- package/lib/specialButtons/addContact/contactsErrors.js +106 -0
- package/lib/specialButtons/addContact/contactsTypes.d.ts +43 -0
- package/lib/specialButtons/addContact/contactsTypes.d.ts.map +1 -0
- package/lib/specialButtons/addContact/contactsTypes.js +5 -0
- package/lib/specialButtons/addContact/helpers.d.ts +7 -0
- package/lib/specialButtons/addContact/helpers.d.ts.map +1 -0
- package/lib/specialButtons/addContact/helpers.js +103 -0
- package/lib/specialButtons/addContact/mutations.d.ts +16 -0
- package/lib/specialButtons/addContact/mutations.d.ts.map +1 -0
- package/lib/specialButtons/addContact/mutations.js +300 -0
- package/lib/specialButtons/addContact/selectors.d.ts +10 -0
- package/lib/specialButtons/addContact/selectors.d.ts.map +1 -0
- package/lib/specialButtons/addContact/selectors.js +163 -0
- package/lib/{addMeToYourFriends.d.ts → specialButtons/addMeToYourFriends.d.ts} +6 -4
- package/lib/specialButtons/addMeToYourFriends.d.ts.map +1 -0
- package/lib/{addMeToYourFriends.js → specialButtons/addMeToYourFriends.js} +46 -11
- package/lib/styles/CollapsibleSection.css +519 -0
- package/lib/styles/EditDialogs.css +506 -686
- package/lib/styles/EditDialogs.responsive.css +989 -0
- package/lib/texts/buttonTexts.d.ts +9 -0
- package/lib/texts/buttonTexts.d.ts.map +1 -0
- package/lib/texts/buttonTexts.js +14 -0
- package/lib/texts/dialogTexts.d.ts +14 -0
- package/lib/texts/dialogTexts.d.ts.map +1 -0
- package/lib/texts/dialogTexts.js +19 -0
- package/lib/texts/messageTexts.d.ts +42 -0
- package/lib/texts/messageTexts.d.ts.map +1 -0
- package/lib/texts/messageTexts.js +47 -0
- package/lib/texts/profileTexts.d.ts +14 -0
- package/lib/texts/profileTexts.d.ts.map +1 -0
- package/lib/texts/profileTexts.js +19 -0
- package/lib/texts/qrCodeTexts.d.ts +2 -0
- package/lib/texts/qrCodeTexts.d.ts.map +1 -0
- package/lib/texts/qrCodeTexts.js +7 -0
- package/lib/texts.d.ts +5 -60
- package/lib/texts.d.ts.map +1 -1
- package/lib/texts.js +55 -70
- package/lib/ui/dialog.css +233 -0
- package/lib/ui/dialog.d.ts +15 -1
- package/lib/ui/dialog.d.ts.map +1 -1
- package/lib/ui/dialog.js +245 -45
- package/lib/ui/dialog.responsive.css +195 -0
- package/lib/ui/errors.d.ts.map +1 -1
- package/lib/ui/errors.js +2 -1
- package/lib/ui/spinner.d.ts +3 -0
- package/lib/ui/spinner.d.ts.map +1 -0
- package/lib/ui/spinner.js +13 -0
- package/lib/utils/debug.d.ts +5 -0
- package/lib/utils/debug.d.ts.map +1 -0
- package/lib/utils/debug.js +23 -0
- package/lib/utils/errorDisplay.d.ts +2 -0
- package/lib/utils/errorDisplay.d.ts.map +1 -0
- package/lib/utils/errorDisplay.js +19 -0
- package/package.json +34 -26
- package/lib/ChatWithMe.d.ts +0 -7
- package/lib/ChatWithMe.d.ts.map +0 -1
- package/lib/ChatWithMe.js +0 -90
- package/lib/QRCodeCard.d.ts.map +0 -1
- package/lib/addMeToYourFriends.d.ts.map +0 -1
- package/lib/sections/heading/camera.d.ts +0 -19
- package/lib/sections/heading/camera.d.ts.map +0 -1
- package/lib/sections/heading/camera.js +0 -199
- package/lib/styles/BioSection.css +0 -77
- package/lib/styles/CVCard.css +0 -142
- package/lib/styles/ChatWithMe.css +0 -6
- package/lib/styles/ContactInfoEditDialog.css +0 -153
- package/lib/styles/EducationCard.css +0 -103
- package/lib/styles/HeadingSection.css +0 -309
- package/lib/styles/ProfileCard.css +0 -66
- package/lib/styles/ProfileView.css +0 -65
- package/lib/styles/ProjectsCard.css +0 -206
- package/lib/styles/QRCodeCard.css +0 -43
- package/lib/styles/SocialCard.css +0 -89
- package/lib/styles/dialog.css +0 -209
- package/lib/styles/utilities.css +0 -740
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.addANewAddressBookUriToAddressBooks = addANewAddressBookUriToAddressBooks;
|
|
7
|
+
exports.addAddressToTypeIndex = addAddressToTypeIndex;
|
|
8
|
+
exports.addContactToAddressBook = addContactToAddressBook;
|
|
9
|
+
exports.addWebIDToExistingContact = addWebIDToExistingContact;
|
|
10
|
+
exports.createContactInAddressBook = createContactInAddressBook;
|
|
11
|
+
exports.handleAddressBookCreation = handleAddressBookCreation;
|
|
12
|
+
exports.updateAddressBookName = updateAddressBookName;
|
|
13
|
+
var _rdflib = require("rdflib");
|
|
14
|
+
var _solidUi = require("solid-ui");
|
|
15
|
+
var _solidLogic = require("solid-logic");
|
|
16
|
+
var _contactsPane = _interopRequireDefault(require("contacts-pane"));
|
|
17
|
+
var _ContactCreationDialog = require("./ContactCreationDialog");
|
|
18
|
+
var _contactsErrors = require("./contactsErrors");
|
|
19
|
+
var _dialog = require("../../ui/dialog");
|
|
20
|
+
var _texts = require("../../texts");
|
|
21
|
+
var _selectors = require("./selectors");
|
|
22
|
+
var _debug = require("../../utils/debug");
|
|
23
|
+
var _rdfMutationHelpers = require("../../sections/shared/rdfMutationHelpers");
|
|
24
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
25
|
+
async function addContactToAddressBook(context, contactsModule, contactData, addressBooksData, container) {
|
|
26
|
+
const launchButton = container.querySelector('#add-to-contacts-button');
|
|
27
|
+
if (launchButton) launchButton.disabled = true;
|
|
28
|
+
const form = (0, _ContactCreationDialog.createAddressBookContactCreationDialog)(context, contactsModule, contactData, addressBooksData);
|
|
29
|
+
const footer = (0, _ContactCreationDialog.createAddressBookContactCreationFooter)(context, contactsModule, addressBooksData, contactData);
|
|
30
|
+
await (0, _dialog.openInputDialog)({
|
|
31
|
+
title: 'Add contact to address book',
|
|
32
|
+
dom: context.dom,
|
|
33
|
+
form,
|
|
34
|
+
headerAction: {
|
|
35
|
+
type: 'none'
|
|
36
|
+
},
|
|
37
|
+
onOpen: () => {
|
|
38
|
+
const buttonsContainer = context.dom.querySelector('#modal-buttons');
|
|
39
|
+
if (!buttonsContainer) return;
|
|
40
|
+
const sharedButtons = Array.from(buttonsContainer.querySelectorAll(':scope > solid-ui-button'));
|
|
41
|
+
sharedButtons.forEach(button => {
|
|
42
|
+
button.hidden = true;
|
|
43
|
+
button.setAttribute('aria-hidden', 'true');
|
|
44
|
+
});
|
|
45
|
+
buttonsContainer.appendChild(footer);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
const refreshedButton = container.querySelector('#add-to-contacts-button');
|
|
49
|
+
if (refreshedButton?.refresh) {
|
|
50
|
+
refreshedButton.refresh();
|
|
51
|
+
} else if (refreshedButton) {
|
|
52
|
+
refreshedButton.disabled = false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function getAddressData(context, contactsModule, addressBookUri) {
|
|
56
|
+
const nextData = await (0, _selectors.getAddressBooksData)(context, contactsModule);
|
|
57
|
+
const matchingAddressBookUri = resolveAddressBookUri(nextData, addressBookUri);
|
|
58
|
+
const matchingAddressBook = matchingAddressBookUri ? nextData?.private.get(matchingAddressBookUri) || nextData?.public.get(matchingAddressBookUri) || null : null;
|
|
59
|
+
return {
|
|
60
|
+
nextData,
|
|
61
|
+
matchingAddressBook,
|
|
62
|
+
matchingAddressBookUri
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function getAddressBookUriCandidates(addressBookUri) {
|
|
66
|
+
if (!addressBookUri) return [];
|
|
67
|
+
const trimmedUri = addressBookUri.trim();
|
|
68
|
+
const candidates = new Set([trimmedUri]);
|
|
69
|
+
if (trimmedUri.endsWith('#this')) {
|
|
70
|
+
const withoutFragment = trimmedUri.slice(0, -5);
|
|
71
|
+
candidates.add(withoutFragment);
|
|
72
|
+
if (!withoutFragment.endsWith('index.ttl')) {
|
|
73
|
+
candidates.add(`${withoutFragment.replace(/\/?$/, '/')}index.ttl#this`.replace('/index.ttl#this', '/index.ttl#this'));
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
candidates.add(`${trimmedUri}#this`);
|
|
77
|
+
if (trimmedUri.endsWith('/')) {
|
|
78
|
+
candidates.add(`${trimmedUri}index.ttl#this`);
|
|
79
|
+
}
|
|
80
|
+
if (trimmedUri.endsWith('index.ttl')) {
|
|
81
|
+
candidates.add(`${trimmedUri}#this`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return Array.from(candidates);
|
|
85
|
+
}
|
|
86
|
+
function resolveAddressBookUri(addressBooksData, addressBookUri) {
|
|
87
|
+
if (!addressBooksData) return null;
|
|
88
|
+
const candidates = getAddressBookUriCandidates(addressBookUri);
|
|
89
|
+
for (const candidate of candidates) {
|
|
90
|
+
if (addressBooksData.private.has(candidate) || addressBooksData.public.has(candidate)) {
|
|
91
|
+
return candidate;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
async function addANewAddressBookUriToAddressBooks(context, contactsModule, _addressBooksData, enteredAddressBookUri) {
|
|
97
|
+
try {
|
|
98
|
+
const {
|
|
99
|
+
nextData,
|
|
100
|
+
matchingAddressBook,
|
|
101
|
+
matchingAddressBookUri
|
|
102
|
+
} = await getAddressData(context, contactsModule, enteredAddressBookUri);
|
|
103
|
+
if (!matchingAddressBook || !nextData || !matchingAddressBookUri) {
|
|
104
|
+
throw new Error('Address book was not found for the entered URI.');
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
addressBooksData: nextData,
|
|
108
|
+
addressBook: matchingAddressBook,
|
|
109
|
+
addressBookUri: matchingAddressBookUri
|
|
110
|
+
};
|
|
111
|
+
} catch (error) {
|
|
112
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async function addContactDetails(context, contactUri, contactData) {
|
|
116
|
+
const store = context.session.store;
|
|
117
|
+
const contactNode = new _rdflib.NamedNode(contactUri);
|
|
118
|
+
const detailDoc = contactNode.doc();
|
|
119
|
+
const max = 9999999999999;
|
|
120
|
+
const min = 1000000000000;
|
|
121
|
+
const createDetailNode = () => {
|
|
122
|
+
const randomId = Math.floor(Math.random() * (max - min + 1)) + min;
|
|
123
|
+
return (0, _rdflib.sym)(`${detailDoc.uri}#id${randomId}`);
|
|
124
|
+
};
|
|
125
|
+
const insertions = [];
|
|
126
|
+
try {
|
|
127
|
+
if (contactData.nickname) {
|
|
128
|
+
insertions.push((0, _rdflib.st)(contactNode, _solidUi.ns.foaf('nick'), (0, _rdflib.literal)(contactData.nickname), detailDoc));
|
|
129
|
+
}
|
|
130
|
+
if (contactData.preferredSubjectPronoun) {
|
|
131
|
+
insertions.push((0, _rdflib.st)(contactNode, _solidUi.ns.solid('preferredSubjectPronoun'), (0, _rdflib.literal)(contactData.preferredSubjectPronoun), detailDoc));
|
|
132
|
+
}
|
|
133
|
+
if (contactData.preferredObjectPronoun) {
|
|
134
|
+
insertions.push((0, _rdflib.st)(contactNode, _solidUi.ns.solid('preferredObjectPronoun'), (0, _rdflib.literal)(contactData.preferredObjectPronoun), detailDoc));
|
|
135
|
+
}
|
|
136
|
+
if (contactData.preferredRelativePronoun) {
|
|
137
|
+
insertions.push((0, _rdflib.st)(contactNode, _solidUi.ns.solid('preferredRelativePronoun'), (0, _rdflib.literal)(contactData.preferredRelativePronoun), detailDoc));
|
|
138
|
+
}
|
|
139
|
+
contactData.emails.map(emailInfo => {
|
|
140
|
+
const node = createDetailNode();
|
|
141
|
+
insertions.push((0, _rdflib.st)(contactNode, _solidUi.ns.vcard('hasEmail'), node, detailDoc));
|
|
142
|
+
insertions.push((0, _rdflib.st)(node, _solidUi.ns.rdf('type'), emailInfo.type, detailDoc));
|
|
143
|
+
insertions.push((0, _rdflib.st)(node, _solidUi.ns.vcard('value'), emailInfo.email, detailDoc));
|
|
144
|
+
});
|
|
145
|
+
contactData.phoneNumbers.map(phoneInfo => {
|
|
146
|
+
const node = createDetailNode();
|
|
147
|
+
insertions.push((0, _rdflib.st)(contactNode, _solidUi.ns.vcard('hasTelephone'), node, detailDoc));
|
|
148
|
+
insertions.push((0, _rdflib.st)(node, _solidUi.ns.rdf('type'), phoneInfo.type, detailDoc));
|
|
149
|
+
insertions.push((0, _rdflib.st)(node, _solidUi.ns.vcard('value'), phoneInfo.phoneNumber, detailDoc));
|
|
150
|
+
});
|
|
151
|
+
await (0, _rdfMutationHelpers.runDirectUpdaterUpdate)(store, [], insertions, _texts.errorContactCreation);
|
|
152
|
+
} catch (error) {
|
|
153
|
+
(0, _contactsErrors.addErrorToErrorDisplay)(context, error);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
async function createContactInAddressBook(context, contactsModule, contactData, selectedAddressBookUris) {
|
|
157
|
+
let contactUri = null;
|
|
158
|
+
const store = context.session.store;
|
|
159
|
+
const newContact = {
|
|
160
|
+
name: contactData.name
|
|
161
|
+
};
|
|
162
|
+
try {
|
|
163
|
+
const groupUris = selectedAddressBookUris.groupUris.length ? selectedAddressBookUris.groupUris : undefined;
|
|
164
|
+
if (groupUris) {
|
|
165
|
+
contactUri = await contactsModule.createNewContact({
|
|
166
|
+
addressBookUri: selectedAddressBookUris.addressBookUri,
|
|
167
|
+
contact: newContact,
|
|
168
|
+
groupUris
|
|
169
|
+
});
|
|
170
|
+
} else {
|
|
171
|
+
(0, _contactsErrors.addErrorToErrorDisplay)(context, _texts.groupIsRequired);
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
await context.session.store.fetcher.load(contactUri);
|
|
175
|
+
const contactNode = new _rdflib.NamedNode(contactUri);
|
|
176
|
+
await addWebIDToContactCard(store, contactNode, contactData.webID, _solidUi.ns.vcard('WebID'));
|
|
177
|
+
if (contactData.emails.length || contactData.phoneNumbers.length || contactData.nickname || contactData.preferredSubjectPronoun || contactData.preferredObjectPronoun || contactData.preferredRelativePronoun) {
|
|
178
|
+
await addContactDetails(context, contactUri, contactData);
|
|
179
|
+
}
|
|
180
|
+
return contactUri;
|
|
181
|
+
} catch (error) {
|
|
182
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
183
|
+
}
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
async function addAddressToTypeIndex(context, typeOfIndex, addressBookUri) {
|
|
187
|
+
const store = context.session.store;
|
|
188
|
+
const me = _solidLogic.authn.currentUser();
|
|
189
|
+
let typeIndexNode = null;
|
|
190
|
+
try {
|
|
191
|
+
await store.fetcher.load(me);
|
|
192
|
+
const typeIndexes = await _solidLogic.solidLogicSingleton.typeIndex.loadTypeIndexesFor(me);
|
|
193
|
+
if (!typeIndexes.length) {
|
|
194
|
+
throw new Error('No type index found for the current user');
|
|
195
|
+
}
|
|
196
|
+
typeIndexes.map(typeIndex => {
|
|
197
|
+
if (typeIndex.label === typeOfIndex) typeIndexNode = typeIndex.index;
|
|
198
|
+
});
|
|
199
|
+
if (typeIndexNode) {
|
|
200
|
+
const registration = await _solidLogic.solidLogicSingleton.typeIndex.registerInTypeIndex((0, _rdflib.sym)(addressBookUri), typeIndexNode, _solidUi.ns.vcard('AddressBook'));
|
|
201
|
+
if (registration) return true;
|
|
202
|
+
}
|
|
203
|
+
} catch (error) {
|
|
204
|
+
(0, _contactsErrors.addErrorToErrorDisplay)(context, error);
|
|
205
|
+
}
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
async function addWebIDToExistingContact(context, contactData, contactUri) {
|
|
209
|
+
const store = context.session.store;
|
|
210
|
+
try {
|
|
211
|
+
await context.session.store.fetcher.load(contactUri);
|
|
212
|
+
const contactNode = new _rdflib.NamedNode(contactUri);
|
|
213
|
+
await addWebIDToContactCard(store, contactNode, contactData.webID, _solidUi.ns.vcard('WebID'));
|
|
214
|
+
} catch (error) {
|
|
215
|
+
const rootError = error instanceof Error ? error : new Error(String(error));
|
|
216
|
+
(0, _debug.error)(_texts.addContactWebIdSaveFailedDebugText, rootError);
|
|
217
|
+
throw new Error(_texts.errorAddingContactWebIDToAddressBook, {
|
|
218
|
+
cause: rootError
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
async function updateAcrossDocuments(store, deletions, insertions = []) {
|
|
223
|
+
(0, _rdfMutationHelpers.ensureStandardMutationPrefixes)(store);
|
|
224
|
+
const docs = deletions.concat(insertions).map(statement => statement.why);
|
|
225
|
+
const uniqueDocKeys = new Set();
|
|
226
|
+
const uniqueDocs = docs.filter(doc => {
|
|
227
|
+
const key = 'value' in doc ? doc.value : '__default__';
|
|
228
|
+
if (uniqueDocKeys.has(key)) return false;
|
|
229
|
+
uniqueDocKeys.add(key);
|
|
230
|
+
return true;
|
|
231
|
+
});
|
|
232
|
+
await Promise.all(uniqueDocs.map(doc => (0, _rdfMutationHelpers.runDirectUpdaterUpdate)(store, deletions.filter(statement => ('value' in statement.why ? statement.why.value : '__default__') === ('value' in doc ? doc.value : '__default__')), insertions.filter(statement => ('value' in statement.why ? statement.why.value : '__default__') === ('value' in doc ? doc.value : '__default__')), _texts.errorAddingContactWebIDToAddressBook)));
|
|
233
|
+
}
|
|
234
|
+
async function addWebIDToContactCard(store, contactNode, webId, urlType) {
|
|
235
|
+
try {
|
|
236
|
+
new URL(webId);
|
|
237
|
+
} catch {
|
|
238
|
+
throw new Error(`WebID: ${webId} is not a valid url.`);
|
|
239
|
+
}
|
|
240
|
+
const vcardUrlNode = store.bnode();
|
|
241
|
+
const insertions = [(0, _rdflib.st)(contactNode, _solidUi.ns.vcard('url'), vcardUrlNode, contactNode.doc()), (0, _rdflib.st)(vcardUrlNode, _solidUi.ns.rdf('type'), urlType, contactNode.doc()), (0, _rdflib.st)(vcardUrlNode, _solidUi.ns.vcard('value'), (0, _rdflib.literal)(webId), contactNode.doc())];
|
|
242
|
+
let deletions = [];
|
|
243
|
+
const groups = store.each(null, _solidUi.ns.vcard('hasMember'), contactNode);
|
|
244
|
+
groups.forEach(group => {
|
|
245
|
+
deletions = deletions.concat(store.statementsMatching(group, _solidUi.ns.vcard('hasMember'), contactNode, group.doc()));
|
|
246
|
+
insertions.push((0, _rdflib.st)(group, _solidUi.ns.vcard('hasMember'), (0, _rdflib.sym)(webId), group.doc()));
|
|
247
|
+
insertions.push((0, _rdflib.st)((0, _rdflib.sym)(webId), _solidUi.ns.owl('sameAs'), contactNode, group.doc()));
|
|
248
|
+
});
|
|
249
|
+
await updateAcrossDocuments(store, deletions, insertions);
|
|
250
|
+
}
|
|
251
|
+
function sanitizeAlphaNumericSpaces(input) {
|
|
252
|
+
return (input || '').replace(/[^a-zA-Z0-9 ]+/g, '').replace(/\s+/g, ' ').trim();
|
|
253
|
+
}
|
|
254
|
+
async function updateAddressBookName(context, addressBookUri, newName) {
|
|
255
|
+
const store = context.session.store;
|
|
256
|
+
const addressBookNode = (0, _rdflib.sym)(addressBookUri);
|
|
257
|
+
const addressBookDoc = addressBookNode.doc();
|
|
258
|
+
const trimmedName = newName?.trim();
|
|
259
|
+
if (!trimmedName) return;
|
|
260
|
+
try {
|
|
261
|
+
await store.fetcher.load(addressBookDoc);
|
|
262
|
+
const deletions = [...store.statementsMatching(addressBookNode, _solidUi.ns.dc('title'), null, addressBookDoc), ...store.statementsMatching(addressBookNode, _solidUi.ns.vcard('fn'), null, addressBookDoc)];
|
|
263
|
+
const insertions = [(0, _rdflib.st)(addressBookNode, _solidUi.ns.dc('title'), (0, _rdflib.literal)(trimmedName), addressBookDoc), (0, _rdflib.st)(addressBookNode, _solidUi.ns.vcard('fn'), (0, _rdflib.literal)(trimmedName), addressBookDoc)];
|
|
264
|
+
await (0, _rdfMutationHelpers.runDirectUpdaterUpdate)(store, deletions, insertions, _texts.errorAddressBookCreation);
|
|
265
|
+
} catch (error) {
|
|
266
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
async function handleAddressBookCreation(dataBrowserContext, containerName, enteredAddressName) {
|
|
270
|
+
const me = _solidLogic.authn.currentUser();
|
|
271
|
+
const newAddressContainer = me?.site()?.value;
|
|
272
|
+
let addressBookUri = null;
|
|
273
|
+
const div = dataBrowserContext.dom.getElementById('new-addressbook-form');
|
|
274
|
+
try {
|
|
275
|
+
if (!me || !newAddressContainer) {
|
|
276
|
+
throw new Error(_texts.errorUnableToDetermineUserWorkspace);
|
|
277
|
+
}
|
|
278
|
+
const sanitizedAddressName = sanitizeAlphaNumericSpaces(enteredAddressName);
|
|
279
|
+
if (!sanitizedAddressName) {
|
|
280
|
+
throw new Error('Address book name can only contain letters, numbers, and spaces');
|
|
281
|
+
}
|
|
282
|
+
const sanitizedContainerName = sanitizeAlphaNumericSpaces(containerName);
|
|
283
|
+
const normalizedContainer = newAddressContainer.endsWith('/') ? newAddressContainer : `${newAddressContainer}/`;
|
|
284
|
+
const addressBookSlug = (sanitizedContainerName || 'address-book').trim().toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]+/g, '-').replace(/^-+|-+$/g, '') || 'address-book';
|
|
285
|
+
const newBase = `${normalizedContainer}${addressBookSlug}/`;
|
|
286
|
+
const mintResult = await _contactsPane.default.mintNew(dataBrowserContext, {
|
|
287
|
+
me,
|
|
288
|
+
dom: dataBrowserContext.dom,
|
|
289
|
+
div,
|
|
290
|
+
newBase,
|
|
291
|
+
instanceClass: _solidUi.ns.vcard('AddressBook'),
|
|
292
|
+
instanceName: sanitizedAddressName
|
|
293
|
+
});
|
|
294
|
+
addressBookUri = mintResult?.newInstance?.uri || `${newBase}index.ttl#this`;
|
|
295
|
+
await updateAddressBookName(dataBrowserContext, addressBookUri, sanitizedAddressName);
|
|
296
|
+
} catch (error) {
|
|
297
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
298
|
+
}
|
|
299
|
+
return addressBookUri;
|
|
300
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { LiveStore, NamedNode } from 'rdflib';
|
|
2
|
+
import ContactsModuleRdfLib from '@solid-data-modules/contacts-rdflib';
|
|
3
|
+
import { DataBrowserContext } from 'pane-registry';
|
|
4
|
+
import { AddressBooksData, ContactData } from './contactsTypes';
|
|
5
|
+
declare function getAddressBooksData(context: DataBrowserContext, contactModule: ContactsModuleRdfLib): Promise<AddressBooksData>;
|
|
6
|
+
declare function getContactData(store: LiveStore, subject: NamedNode): Promise<ContactData>;
|
|
7
|
+
declare function checkIfContactExistsByWebID(addressBooksData: AddressBooksData, subjectUri: string): boolean;
|
|
8
|
+
declare function checkIfContactExistsByName(addressBooksData: AddressBooksData, name: string): string | null;
|
|
9
|
+
export { getAddressBooksData, getContactData, checkIfContactExistsByWebID, checkIfContactExistsByName };
|
|
10
|
+
//# sourceMappingURL=selectors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selectors.d.ts","sourceRoot":"","sources":["../../../src/specialButtons/addContact/selectors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,oBAAoB,MAAM,qCAAqC,CAAA;AAEtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAA8B,MAAM,iBAAiB,CAAA;AA+G3F,iBAAe,mBAAmB,CAChC,OAAO,EAAE,kBAAkB,EAC3B,aAAa,EAAE,oBAAoB,GAClC,OAAO,CAAC,gBAAgB,CAAC,CAW3B;AAED,iBAAe,cAAc,CAC3B,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,WAAW,CAAC,CAsCtB;AAED,iBAAS,2BAA2B,CAClC,gBAAgB,EAAE,gBAAgB,EAClC,UAAU,EAAE,MAAM,GACjB,OAAO,CAGT;AAED,iBAAS,0BAA0B,CACjC,gBAAgB,EAAE,gBAAgB,EAClC,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,IAAI,CAYf;AAED,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,2BAA2B,EAC3B,0BAA0B,EAC3B,CAAA"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.checkIfContactExistsByName = checkIfContactExistsByName;
|
|
7
|
+
exports.checkIfContactExistsByWebID = checkIfContactExistsByWebID;
|
|
8
|
+
exports.getAddressBooksData = getAddressBooksData;
|
|
9
|
+
exports.getContactData = getContactData;
|
|
10
|
+
var _rdflib = require("rdflib");
|
|
11
|
+
var _solidUi = require("solid-ui");
|
|
12
|
+
var _solidLogic = require("solid-logic");
|
|
13
|
+
var _texts = require("../../texts");
|
|
14
|
+
var _contactsErrors = require("./contactsErrors");
|
|
15
|
+
async function getAddressData(context, contactsModule, addressBookUri) {
|
|
16
|
+
let result = null;
|
|
17
|
+
try {
|
|
18
|
+
result = await contactsModule.readAddressBook(addressBookUri);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
(0, _contactsErrors.addErrorToErrorDisplay)(context, `${_texts.errorReadingAddressBook}\n${error}`);
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
async function getWebID(context, contact) {
|
|
25
|
+
let webID = null;
|
|
26
|
+
let node = null;
|
|
27
|
+
let webIDNode = null;
|
|
28
|
+
try {
|
|
29
|
+
await context.session.store.fetcher.load(contact.uri.substring(0, contact.uri.length - 5));
|
|
30
|
+
node = new _rdflib.NamedNode(contact.uri);
|
|
31
|
+
webIDNode = context.session.store.any(node, _solidUi.ns.vcard('url'), undefined, node.doc());
|
|
32
|
+
if (webIDNode) {
|
|
33
|
+
webID = context.session.store.anyValue(webIDNode, _solidUi.ns.vcard('value'), undefined, node.doc());
|
|
34
|
+
return {
|
|
35
|
+
webID,
|
|
36
|
+
uri: contact.uri
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
} catch (error) {
|
|
41
|
+
(0, _contactsErrors.addErrorToErrorDisplay)(context, `${_texts.errorLoadingContact}${contact.uri}\n${error}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async function processContactWebIDs(context, addressBooksData, allContacts) {
|
|
45
|
+
const contactPromises = allContacts.map(getWebID.bind(null, context));
|
|
46
|
+
const results = await Promise.all(contactPromises);
|
|
47
|
+
results.map(contact => {
|
|
48
|
+
if (contact?.webID) addressBooksData.contactWebIDs.set(contact.webID.trim(), contact.uri);
|
|
49
|
+
});
|
|
50
|
+
return addressBooksData;
|
|
51
|
+
}
|
|
52
|
+
async function getAddressBooks(context, contactsModule) {
|
|
53
|
+
const allContacts = [];
|
|
54
|
+
const me = _solidLogic.authn.currentUser();
|
|
55
|
+
let addressBooksData = {
|
|
56
|
+
public: new Map(),
|
|
57
|
+
private: new Map(),
|
|
58
|
+
contactWebIDs: new Map(),
|
|
59
|
+
contactNames: new Map()
|
|
60
|
+
};
|
|
61
|
+
try {
|
|
62
|
+
await context.session.store.fetcher.load(me);
|
|
63
|
+
const addressBookUris = await contactsModule.listAddressBooks(me.value);
|
|
64
|
+
const publicAddressBookPromises = addressBookUris.publicUris.map(addressBook => getAddressData(context, contactsModule, addressBook));
|
|
65
|
+
const publicAddressBooksData = await Promise.all(publicAddressBookPromises);
|
|
66
|
+
publicAddressBooksData.map(addressBook => {
|
|
67
|
+
if (!addressBook) return;
|
|
68
|
+
addressBooksData.public.set(addressBook.uri, {
|
|
69
|
+
name: addressBook.title,
|
|
70
|
+
groups: addressBook.groups,
|
|
71
|
+
contacts: addressBook.contacts
|
|
72
|
+
});
|
|
73
|
+
addressBook.contacts.map(contact => {
|
|
74
|
+
addressBooksData.contactNames.set(contact.name, contact.uri);
|
|
75
|
+
allContacts.push(contact);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
const privateAddressBookPromises = addressBookUris.privateUris.map(addressBook => getAddressData(context, contactsModule, addressBook));
|
|
79
|
+
const privateAddressBooksData = await Promise.all(privateAddressBookPromises);
|
|
80
|
+
privateAddressBooksData.map(addressBook => {
|
|
81
|
+
if (!addressBook) return;
|
|
82
|
+
addressBooksData.private.set(addressBook.uri, {
|
|
83
|
+
name: addressBook.title,
|
|
84
|
+
groups: addressBook.groups,
|
|
85
|
+
contacts: addressBook.contacts
|
|
86
|
+
});
|
|
87
|
+
addressBook.contacts.map(contact => {
|
|
88
|
+
addressBooksData.contactNames.set(contact.name, contact.uri);
|
|
89
|
+
allContacts.push(contact);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
addressBooksData = await processContactWebIDs(context, addressBooksData, allContacts);
|
|
93
|
+
} catch (error) {
|
|
94
|
+
(0, _contactsErrors.addErrorToErrorDisplay)(context, error);
|
|
95
|
+
}
|
|
96
|
+
return addressBooksData;
|
|
97
|
+
}
|
|
98
|
+
async function getAddressBooksData(context, contactModule) {
|
|
99
|
+
const me = _solidLogic.authn.currentUser();
|
|
100
|
+
if (!me) return null;
|
|
101
|
+
let addressBooksData = null;
|
|
102
|
+
try {
|
|
103
|
+
addressBooksData = await getAddressBooks(context, contactModule);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
(0, _contactsErrors.addErrorToErrorDisplay)(context, `${_texts.errorGettingAddressBooks}\n${error}`);
|
|
106
|
+
}
|
|
107
|
+
return addressBooksData;
|
|
108
|
+
}
|
|
109
|
+
async function getContactData(store, subject) {
|
|
110
|
+
const emails = [];
|
|
111
|
+
const phoneNumbers = [];
|
|
112
|
+
let type = null;
|
|
113
|
+
let email = null;
|
|
114
|
+
let phoneNumber = null;
|
|
115
|
+
const name = _solidUi.utils.label(subject);
|
|
116
|
+
const nickname = store.anyValue(subject, _solidUi.ns.foaf('nick'), null, subject.doc()) || undefined;
|
|
117
|
+
const preferredSubjectPronoun = store.anyValue(subject, _solidUi.ns.solid('preferredSubjectPronoun'), null, subject.doc()) || undefined;
|
|
118
|
+
const preferredObjectPronoun = store.anyValue(subject, _solidUi.ns.solid('preferredObjectPronoun'), null, subject.doc()) || undefined;
|
|
119
|
+
const preferredRelativePronoun = store.anyValue(subject, _solidUi.ns.solid('preferredRelativePronoun'), null, subject.doc()) || undefined;
|
|
120
|
+
const emailNodes = store.each(subject, _solidUi.ns.vcard('hasEmail'), null, subject.doc()) || null;
|
|
121
|
+
const phoneNodes = store.each(subject, _solidUi.ns.vcard('hasTelephone'), null, subject.doc()) || null;
|
|
122
|
+
emailNodes.map(node => {
|
|
123
|
+
email = store.any(node, _solidUi.ns.vcard('value'), null, subject.doc());
|
|
124
|
+
type = store.any(node, _solidUi.ns.rdf('type'), null, subject.doc());
|
|
125
|
+
emails.push({
|
|
126
|
+
type,
|
|
127
|
+
email
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
phoneNodes.map(node => {
|
|
131
|
+
phoneNumber = store.any(node, _solidUi.ns.vcard('value'), null, subject.doc());
|
|
132
|
+
type = store.any(node, _solidUi.ns.rdf('type'), null, subject.doc());
|
|
133
|
+
phoneNumbers.push({
|
|
134
|
+
type,
|
|
135
|
+
phoneNumber
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
const webID = subject.value;
|
|
139
|
+
return {
|
|
140
|
+
name,
|
|
141
|
+
nickname,
|
|
142
|
+
preferredSubjectPronoun,
|
|
143
|
+
preferredObjectPronoun,
|
|
144
|
+
preferredRelativePronoun,
|
|
145
|
+
emails,
|
|
146
|
+
phoneNumbers,
|
|
147
|
+
webID
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function checkIfContactExistsByWebID(addressBooksData, subjectUri) {
|
|
151
|
+
if (!subjectUri?.trim()) return false;
|
|
152
|
+
return addressBooksData.contactWebIDs.has(subjectUri.trim());
|
|
153
|
+
}
|
|
154
|
+
function checkIfContactExistsByName(addressBooksData, name) {
|
|
155
|
+
let normalizedContactName = null;
|
|
156
|
+
let contactUri = null;
|
|
157
|
+
const normalizedSubjectName = name.replace(/\s/g, '').toLowerCase().trim();
|
|
158
|
+
addressBooksData.contactNames.forEach((uri, contactName) => {
|
|
159
|
+
normalizedContactName = contactName.replace(/\s/g, '').toLowerCase().trim();
|
|
160
|
+
if (normalizedSubjectName === normalizedContactName) return contactUri = uri;
|
|
161
|
+
});
|
|
162
|
+
return contactUri;
|
|
163
|
+
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { TemplateResult } from 'lit-html';
|
|
2
|
+
import 'solid-ui/components/actions/button';
|
|
3
|
+
import type { Button as SolidUIButtonElement } from 'solid-ui/components/actions/button';
|
|
2
4
|
import { DataBrowserContext } from 'pane-registry';
|
|
3
5
|
import { LiveStore, NamedNode } from 'rdflib';
|
|
4
|
-
import { ViewerMode } from '
|
|
5
|
-
import './
|
|
6
|
-
declare const addMeToYourFriendsDiv: (subject: NamedNode, context: DataBrowserContext,
|
|
7
|
-
declare const createAddMeToYourFriendsButton: (subject: NamedNode, context: DataBrowserContext) =>
|
|
6
|
+
import { ViewerMode } from '../types';
|
|
7
|
+
import './AddMeToYourFriends.css';
|
|
8
|
+
declare const addMeToYourFriendsDiv: (subject: NamedNode, context: DataBrowserContext, _viewerMode: ViewerMode) => TemplateResult;
|
|
9
|
+
declare const createAddMeToYourFriendsButton: (subject: NamedNode, context: DataBrowserContext) => SolidUIButtonElement;
|
|
8
10
|
declare function saveNewThing(subject: NamedNode, context: DataBrowserContext, predicate: NamedNode): Promise<void>;
|
|
9
11
|
declare function checkIfThingExists(store: LiveStore, me: NamedNode, subject: NamedNode, predicate: NamedNode): Promise<boolean>;
|
|
10
12
|
export { addMeToYourFriendsDiv, createAddMeToYourFriendsButton, saveNewThing, checkIfThingExists };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addMeToYourFriends.d.ts","sourceRoot":"","sources":["../../src/specialButtons/addMeToYourFriends.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,cAAc,EAAE,MAAM,UAAU,CAAA;AAC/C,OAAO,oCAAoC,CAAA;AAC3C,OAAO,KAAK,EAAE,MAAM,IAAI,oBAAoB,EAAE,MAAM,oCAAoC,CAAA;AACxF,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAM,MAAM,QAAQ,CAAA;AASjD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAErC,OAAO,0BAA0B,CAAA;AAyBjC,QAAA,MAAM,qBAAqB,GACzB,SAAS,SAAS,EAClB,SAAS,kBAAkB,EAC3B,aAAa,UAAU,KACtB,cAkBF,CAAA;AAED,QAAA,MAAM,8BAA8B,GAClC,SAAS,SAAS,EAClB,SAAS,kBAAkB,KAC1B,oBA8DF,CAAA;AAED,iBAAe,YAAY,CACzB,OAAO,EAAE,SAAS,EAClB,OAAO,EAAE,kBAAkB,EAC3B,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,IAAI,CAAC,CAqBf;AAOD,iBAAe,kBAAkB,CAC/B,KAAK,EAAE,SAAS,EAChB,EAAE,EAAE,SAAS,EACb,OAAO,EAAE,SAAS,EAClB,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,OAAO,CAAC,CAKlB;AAED,OAAO,EACL,qBAAqB,EACrB,8BAA8B,EAC9B,YAAY,EACZ,kBAAkB,EACnB,CAAA"}
|
|
@@ -8,16 +8,36 @@ exports.checkIfThingExists = checkIfThingExists;
|
|
|
8
8
|
exports.createAddMeToYourFriendsButton = void 0;
|
|
9
9
|
exports.saveNewThing = saveNewThing;
|
|
10
10
|
var _litHtml = require("lit-html");
|
|
11
|
+
require("solid-ui/components/actions/button");
|
|
11
12
|
var _solidLogic = require("solid-logic");
|
|
12
13
|
var _rdflib = require("rdflib");
|
|
13
14
|
var _solidUi = require("solid-ui");
|
|
14
|
-
var _buttonsHelper = require("
|
|
15
|
-
var _texts = require("
|
|
16
|
-
require("
|
|
15
|
+
var _buttonsHelper = require("../buttonsHelper");
|
|
16
|
+
var _texts = require("../texts");
|
|
17
|
+
var _rdfMutationHelpers = require("../sections/shared/rdfMutationHelpers");
|
|
18
|
+
require("./AddMeToYourFriends.css");
|
|
17
19
|
let buttonContainer = document.createElement('section');
|
|
18
|
-
|
|
20
|
+
function setAddToFriendsButtonLabel(button, label) {
|
|
21
|
+
const labelWrapper = button.ownerDocument.createElement('span');
|
|
22
|
+
labelWrapper.className = 'profile__btn-friends-label profile__btn-friends-label--full';
|
|
23
|
+
labelWrapper.textContent = label;
|
|
24
|
+
if (label === _texts.friendExistsAlreadyButtonText) {
|
|
25
|
+
const shortLabelWrapper = button.ownerDocument.createElement('span');
|
|
26
|
+
shortLabelWrapper.className = 'profile__btn-friends-label profile__btn-friends-label--short';
|
|
27
|
+
shortLabelWrapper.setAttribute('aria-hidden', 'true');
|
|
28
|
+
shortLabelWrapper.setAttribute('data-short-label-text', 'Friends');
|
|
29
|
+
button.setAttribute('data-friends-short-label', 'true');
|
|
30
|
+
button.setAttribute('aria-label', label);
|
|
31
|
+
button.replaceChildren(labelWrapper, shortLabelWrapper);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
button.removeAttribute('data-friends-short-label');
|
|
35
|
+
button.removeAttribute('aria-label');
|
|
36
|
+
button.replaceChildren(labelWrapper);
|
|
37
|
+
}
|
|
38
|
+
const addMeToYourFriendsDiv = (subject, context, _viewerMode) => {
|
|
19
39
|
buttonContainer = context.dom.createElement('section');
|
|
20
|
-
buttonContainer.setAttribute('class', '
|
|
40
|
+
buttonContainer.setAttribute('class', 'profile-friends-button__section text-truncate text-center section-centered');
|
|
21
41
|
buttonContainer.setAttribute('aria-labelledby', 'add-me-to-your-friends-button-section');
|
|
22
42
|
buttonContainer.setAttribute('data-testid', 'button');
|
|
23
43
|
|
|
@@ -35,9 +55,11 @@ const addMeToYourFriendsDiv = (subject, context, viewerMode) => {
|
|
|
35
55
|
exports.addMeToYourFriendsDiv = addMeToYourFriendsDiv;
|
|
36
56
|
const createAddMeToYourFriendsButton = (subject, context) => {
|
|
37
57
|
let label = _texts.addMeToYourFriendsButtonText;
|
|
38
|
-
const button = context.dom.createElement('button');
|
|
39
|
-
button.type
|
|
40
|
-
button.
|
|
58
|
+
const button = context.dom.createElement('solid-ui-button');
|
|
59
|
+
button.setAttribute('type', 'button');
|
|
60
|
+
button.setAttribute('variant', 'secondary');
|
|
61
|
+
button.setAttribute('size', 'sm');
|
|
62
|
+
setAddToFriendsButtonLabel(button, label);
|
|
41
63
|
button.addEventListener('click', setButtonHandler);
|
|
42
64
|
function setButtonHandler(event) {
|
|
43
65
|
event.preventDefault();
|
|
@@ -57,19 +79,31 @@ const createAddMeToYourFriendsButton = (subject, context) => {
|
|
|
57
79
|
const store = context.session.store;
|
|
58
80
|
if (checkIfAnyUserLoggedIn(me)) {
|
|
59
81
|
button.disabled = false;
|
|
82
|
+
button.removeAttribute('disabled');
|
|
60
83
|
checkIfThingExists(store, me, subject, _solidUi.ns.foaf('knows')).then(friendExists => {
|
|
84
|
+
const isMobileLayout = context.environment?.layout === 'mobile';
|
|
61
85
|
if (friendExists) {
|
|
62
86
|
//logged in and friend exists or friend was just added
|
|
63
|
-
button
|
|
87
|
+
setAddToFriendsButtonLabel(button, _texts.friendExistsAlreadyButtonText);
|
|
88
|
+
button.disabled = true;
|
|
89
|
+
button.setAttribute('disabled', 'true');
|
|
90
|
+
buttonContainer.hidden = isMobileLayout;
|
|
91
|
+
buttonContainer.style.display = isMobileLayout ? 'none' : '';
|
|
64
92
|
} else {
|
|
65
93
|
//logged in and friend does not exist yet
|
|
66
|
-
button
|
|
94
|
+
setAddToFriendsButtonLabel(button, _texts.addMeToYourFriendsButtonText);
|
|
95
|
+
button.disabled = false;
|
|
96
|
+
button.removeAttribute('disabled');
|
|
97
|
+
buttonContainer.hidden = false;
|
|
98
|
+
buttonContainer.style.display = '';
|
|
67
99
|
}
|
|
68
100
|
});
|
|
69
101
|
} else {
|
|
70
102
|
//not logged in — disable and indicate login is required
|
|
71
|
-
button
|
|
103
|
+
setAddToFriendsButtonLabel(button, _texts.logInAddMeToYourFriendsButtonText);
|
|
72
104
|
button.disabled = true;
|
|
105
|
+
button.setAttribute('disabled', 'true');
|
|
106
|
+
buttonContainer.hidden = false;
|
|
73
107
|
}
|
|
74
108
|
}
|
|
75
109
|
return button;
|
|
@@ -85,6 +119,7 @@ async function saveNewThing(subject, context, predicate) {
|
|
|
85
119
|
const updater = store.updater;
|
|
86
120
|
const toBeInserted = [(0, _rdflib.st)(me, predicate, subject, me.doc())];
|
|
87
121
|
try {
|
|
122
|
+
(0, _rdfMutationHelpers.ensureStandardMutationPrefixes)(store);
|
|
88
123
|
await updater.update([], toBeInserted);
|
|
89
124
|
} catch (error) {
|
|
90
125
|
let errorMessage = error;
|