profile-pane 3.1.4 → 3.2.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 +16 -0
- package/lib/04567ff683933c35c465.png +0 -0
- package/lib/10163fd9b5a0e00d63a0.png +0 -0
- package/lib/1234dcb2eec2e45f252b.png +0 -0
- package/lib/20899934157df4db56cb.png +0 -0
- package/lib/33760bf79f097f449da5.png +0 -0
- package/lib/578d2b6ed32e7624164e.png +0 -0
- package/lib/5f62a5b2b7e99b9640c7.png +0 -0
- package/lib/6525766ecd288ec60129.png +0 -0
- package/lib/7800be6f6c4b5b0f4f20.png +0 -0
- package/lib/976473cf5fe24d657d4b.png +0 -0
- package/lib/ChatWithMe.d.ts +2 -1
- package/lib/ChatWithMe.d.ts.map +1 -1
- package/lib/ChatWithMe.js +3 -3
- package/lib/ProfileView.d.ts +1 -1
- package/lib/ProfileView.d.ts.map +1 -1
- package/lib/ProfileView.js +71 -131
- package/lib/ProfileViewModelPresenter.d.ts +23 -0
- package/lib/ProfileViewModelPresenter.d.ts.map +1 -0
- package/lib/ProfileViewModelPresenter.js +37 -0
- package/lib/QRCodeCard.d.ts +3 -1
- package/lib/QRCodeCard.d.ts.map +1 -1
- package/lib/QRCodeCard.js +86 -66
- package/lib/addMeToYourFriends.d.ts +3 -3
- package/lib/addMeToYourFriends.d.ts.map +1 -1
- package/lib/addMeToYourFriends.js +14 -30
- package/lib/bda84f59e7216675a208.png +0 -0
- package/lib/buttonsHelper.js +1 -1
- package/lib/cd68e8f3990ba8b2139e.png +0 -0
- package/lib/e7074a7e2cb69e51cfd3.png +0 -0
- package/lib/editProfilePane/EditCVCard.d.ts +1 -0
- package/lib/editProfilePane/EditCVCard.d.ts.map +1 -1
- package/lib/editProfilePane/EditCVCard.js +2 -1
- package/lib/editProfilePane/EditCommunitiesCard.d.ts +1 -1
- package/lib/editProfilePane/EditCommunitiesCard.d.ts.map +1 -1
- package/lib/editProfilePane/EditCommunitiesCard.js +2 -1
- package/lib/editProfilePane/EditContactsCard.d.ts +1 -0
- package/lib/editProfilePane/EditContactsCard.d.ts.map +1 -1
- package/lib/editProfilePane/EditContactsCard.js +2 -0
- package/lib/editProfilePane/EditFriendsCard.d.ts +1 -1
- package/lib/editProfilePane/EditFriendsCard.d.ts.map +1 -1
- package/lib/editProfilePane/EditFriendsCard.js +2 -1
- package/lib/editProfilePane/EditOtherPreferences.d.ts +1 -0
- package/lib/editProfilePane/EditOtherPreferences.d.ts.map +1 -1
- package/lib/editProfilePane/EditOtherPreferences.js +1 -0
- package/lib/editProfilePane/EditProfileView.d.ts +1 -1
- package/lib/editProfilePane/EditProfileView.d.ts.map +1 -1
- package/lib/editProfilePane/EditProfileView.js +1 -1
- package/lib/editProfilePane/EditSocialCard.d.ts +1 -0
- package/lib/editProfilePane/EditSocialCard.d.ts.map +1 -1
- package/lib/editProfilePane/EditSocialCard.js +2 -1
- package/lib/editProfilePane/editProfilePresenter.d.ts +1 -0
- package/lib/editProfilePane/editProfilePresenter.d.ts.map +1 -1
- package/lib/editProfilePane/editProfilePresenter.js +2 -0
- package/lib/f3772696fb7ee53c23d8.png +0 -0
- package/lib/icons-svg/contactIcons.d.ts +3 -0
- package/lib/icons-svg/contactIcons.d.ts.map +1 -0
- package/lib/icons-svg/contactIcons.js +32 -0
- package/lib/icons-svg/profileIcons.d.ts +22 -0
- package/lib/icons-svg/profileIcons.d.ts.map +1 -0
- package/lib/icons-svg/profileIcons.js +309 -0
- package/lib/index.d.ts +1 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +42 -19
- package/lib/profile-pane.js +15629 -5666
- package/lib/profile-pane.js.map +1 -1
- package/lib/profile-pane.min.js +2171 -230
- package/lib/profile-pane.min.js.map +1 -1
- package/lib/rdfFormsHelper.d.ts +1 -0
- package/lib/rdfFormsHelper.d.ts.map +1 -1
- package/lib/rdfFormsHelper.js +2 -0
- package/lib/sections/bio/BioEditDialog.d.ts +6 -0
- package/lib/sections/bio/BioEditDialog.d.ts.map +1 -0
- package/lib/sections/bio/BioEditDialog.js +119 -0
- package/lib/sections/bio/BioSection.d.ts +7 -0
- package/lib/sections/bio/BioSection.d.ts.map +1 -0
- package/lib/sections/bio/BioSection.js +131 -0
- package/lib/sections/bio/mutations.d.ts +4 -0
- package/lib/sections/bio/mutations.d.ts.map +1 -0
- package/lib/sections/bio/mutations.js +43 -0
- package/lib/sections/bio/selectors.d.ts +4 -0
- package/lib/sections/bio/selectors.d.ts.map +1 -0
- package/lib/sections/bio/selectors.js +15 -0
- package/lib/sections/bio/types.d.ts +15 -0
- package/lib/sections/bio/types.d.ts.map +1 -0
- package/lib/sections/bio/types.js +5 -0
- package/lib/sections/contactInfo/ContactInfoEditDialog.d.ts +7 -0
- package/lib/sections/contactInfo/ContactInfoEditDialog.d.ts.map +1 -0
- package/lib/sections/contactInfo/ContactInfoEditDialog.js +658 -0
- package/lib/sections/contactInfo/ContactInfoSection.d.ts +5 -0
- package/lib/sections/contactInfo/ContactInfoSection.d.ts.map +1 -0
- package/lib/sections/contactInfo/ContactInfoSection.js +229 -0
- package/lib/sections/contactInfo/mutations.d.ts +4 -0
- package/lib/sections/contactInfo/mutations.d.ts.map +1 -0
- package/lib/sections/contactInfo/mutations.js +150 -0
- package/lib/sections/contactInfo/selectors.d.ts +4 -0
- package/lib/sections/contactInfo/selectors.d.ts.map +1 -0
- package/lib/sections/contactInfo/selectors.js +104 -0
- package/lib/sections/contactInfo/types.d.ts +44 -0
- package/lib/sections/contactInfo/types.d.ts.map +1 -0
- package/lib/sections/contactInfo/types.js +5 -0
- package/lib/sections/education/EducationEditDialog.d.ts +7 -0
- package/lib/sections/education/EducationEditDialog.d.ts.map +1 -0
- package/lib/sections/education/EducationEditDialog.js +459 -0
- package/lib/sections/education/EducationSection.d.ts +7 -0
- package/lib/sections/education/EducationSection.d.ts.map +1 -0
- package/lib/sections/education/EducationSection.js +126 -0
- package/lib/sections/education/mutations.d.ts +4 -0
- package/lib/sections/education/mutations.d.ts.map +1 -0
- package/lib/sections/education/mutations.js +60 -0
- package/lib/sections/education/selectors.d.ts +4 -0
- package/lib/sections/education/selectors.d.ts.map +1 -0
- package/lib/sections/education/selectors.js +64 -0
- package/lib/sections/education/types.d.ts +20 -0
- package/lib/sections/education/types.d.ts.map +1 -0
- package/lib/sections/education/types.js +5 -0
- package/lib/sections/heading/HeadingEditDialog.d.ts +6 -0
- package/lib/sections/heading/HeadingEditDialog.d.ts.map +1 -0
- package/lib/sections/heading/HeadingEditDialog.js +742 -0
- package/lib/sections/heading/HeadingSection.d.ts +9 -0
- package/lib/sections/heading/HeadingSection.d.ts.map +1 -0
- package/lib/sections/heading/HeadingSection.js +97 -0
- package/lib/sections/heading/camera.d.ts +19 -0
- package/lib/sections/heading/camera.d.ts.map +1 -0
- package/lib/sections/heading/camera.js +199 -0
- package/lib/sections/heading/dateHelpers.d.ts +4 -0
- package/lib/sections/heading/dateHelpers.d.ts.map +1 -0
- package/lib/sections/heading/dateHelpers.js +48 -0
- package/lib/sections/heading/imageHelpers.d.ts +4 -0
- package/lib/sections/heading/imageHelpers.d.ts.map +1 -0
- package/lib/sections/heading/imageHelpers.js +81 -0
- package/lib/sections/heading/mutations.d.ts +4 -0
- package/lib/sections/heading/mutations.d.ts.map +1 -0
- package/lib/sections/heading/mutations.js +190 -0
- package/lib/sections/heading/selectors.d.ts +5 -0
- package/lib/sections/heading/selectors.d.ts.map +1 -0
- package/lib/sections/heading/selectors.js +157 -0
- package/lib/sections/heading/types.d.ts +36 -0
- package/lib/sections/heading/types.d.ts.map +1 -0
- package/lib/sections/heading/types.js +5 -0
- package/lib/sections/languages/LanguageEditDialog.d.ts +7 -0
- package/lib/sections/languages/LanguageEditDialog.d.ts.map +1 -0
- package/lib/sections/languages/LanguageEditDialog.js +457 -0
- package/lib/sections/languages/LanguageSection.d.ts +5 -0
- package/lib/sections/languages/LanguageSection.d.ts.map +1 -0
- package/lib/sections/languages/LanguageSection.js +137 -0
- package/lib/sections/languages/mutations.d.ts +6 -0
- package/lib/sections/languages/mutations.d.ts.map +1 -0
- package/lib/sections/languages/mutations.js +296 -0
- package/lib/sections/languages/selectors.d.ts +5 -0
- package/lib/sections/languages/selectors.d.ts.map +1 -0
- package/lib/sections/languages/selectors.js +146 -0
- package/lib/sections/languages/types.d.ts +15 -0
- package/lib/sections/languages/types.d.ts.map +1 -0
- package/lib/sections/languages/types.js +5 -0
- package/lib/sections/projects/ProjectEditDialog.d.ts +7 -0
- package/lib/sections/projects/ProjectEditDialog.d.ts.map +1 -0
- package/lib/sections/projects/ProjectEditDialog.js +182 -0
- package/lib/sections/projects/ProjectSection.d.ts +6 -0
- package/lib/sections/projects/ProjectSection.d.ts.map +1 -0
- package/lib/sections/projects/ProjectSection.js +220 -0
- package/lib/sections/projects/mutations.d.ts +4 -0
- package/lib/sections/projects/mutations.d.ts.map +1 -0
- package/lib/sections/projects/mutations.js +188 -0
- package/lib/sections/projects/selectors.d.ts +5 -0
- package/lib/sections/projects/selectors.d.ts.map +1 -0
- package/lib/sections/projects/selectors.js +163 -0
- package/lib/sections/projects/types.d.ts +28 -0
- package/lib/sections/projects/types.d.ts.map +1 -0
- package/lib/sections/projects/types.js +8 -0
- package/lib/sections/resume/ResumeEditDialog.d.ts +7 -0
- package/lib/sections/resume/ResumeEditDialog.d.ts.map +1 -0
- package/lib/sections/resume/ResumeEditDialog.js +629 -0
- package/lib/sections/resume/ResumeSection.d.ts +7 -0
- package/lib/sections/resume/ResumeSection.d.ts.map +1 -0
- package/lib/sections/resume/ResumeSection.js +160 -0
- package/lib/sections/resume/mutations.d.ts +6 -0
- package/lib/sections/resume/mutations.d.ts.map +1 -0
- package/lib/sections/resume/mutations.js +172 -0
- package/lib/sections/resume/selectors.d.ts +4 -0
- package/lib/sections/resume/selectors.d.ts.map +1 -0
- package/lib/sections/resume/selectors.js +142 -0
- package/lib/sections/resume/types.d.ts +33 -0
- package/lib/sections/resume/types.d.ts.map +1 -0
- package/lib/sections/resume/types.js +8 -0
- package/lib/sections/shared/collapsibleSection.d.ts +2 -0
- package/lib/sections/shared/collapsibleSection.d.ts.map +1 -0
- package/lib/sections/shared/collapsibleSection.js +24 -0
- package/lib/sections/shared/contactTypeUtils.d.ts +7 -0
- package/lib/sections/shared/contactTypeUtils.d.ts.map +1 -0
- package/lib/sections/shared/contactTypeUtils.js +48 -0
- package/lib/sections/shared/idNodeFactory.d.ts +3 -0
- package/lib/sections/shared/idNodeFactory.d.ts.map +1 -0
- package/lib/sections/shared/idNodeFactory.js +14 -0
- package/lib/sections/shared/phoneCountries.d.ts +20 -0
- package/lib/sections/shared/phoneCountries.d.ts.map +1 -0
- package/lib/sections/shared/phoneCountries.js +1080 -0
- package/lib/sections/shared/rdfList.d.ts +3 -0
- package/lib/sections/shared/rdfList.d.ts.map +1 -0
- package/lib/sections/shared/rdfList.js +34 -0
- package/lib/sections/shared/rdfMutationHelpers.d.ts +12 -0
- package/lib/sections/shared/rdfMutationHelpers.d.ts.map +1 -0
- package/lib/sections/shared/rdfMutationHelpers.js +82 -0
- package/lib/sections/shared/rowState.d.ts +21 -0
- package/lib/sections/shared/rowState.d.ts.map +1 -0
- package/lib/sections/shared/rowState.js +52 -0
- package/lib/sections/shared/sanitizeUtils.d.ts +5 -0
- package/lib/sections/shared/sanitizeUtils.d.ts.map +1 -0
- package/lib/sections/shared/sanitizeUtils.js +22 -0
- package/lib/sections/shared/sectionCardHelpers.d.ts +11 -0
- package/lib/sections/shared/sectionCardHelpers.d.ts.map +1 -0
- package/lib/sections/shared/sectionCardHelpers.js +105 -0
- package/lib/sections/shared/types.d.ts +7 -0
- package/lib/sections/shared/types.d.ts.map +1 -0
- package/lib/sections/shared/types.js +5 -0
- package/lib/sections/skills/SkillsEditDialog.d.ts +7 -0
- package/lib/sections/skills/SkillsEditDialog.d.ts.map +1 -0
- package/lib/sections/skills/SkillsEditDialog.js +340 -0
- package/lib/sections/skills/SkillsSection.d.ts +5 -0
- package/lib/sections/skills/SkillsSection.d.ts.map +1 -0
- package/lib/sections/skills/SkillsSection.js +169 -0
- package/lib/sections/skills/mutations.d.ts +6 -0
- package/lib/sections/skills/mutations.d.ts.map +1 -0
- package/lib/sections/skills/mutations.js +110 -0
- package/lib/sections/skills/selectors.d.ts +6 -0
- package/lib/sections/skills/selectors.d.ts.map +1 -0
- package/lib/sections/skills/selectors.js +37 -0
- package/lib/sections/skills/types.d.ts +14 -0
- package/lib/sections/skills/types.d.ts.map +1 -0
- package/lib/sections/skills/types.js +5 -0
- package/lib/sections/social/SocialEditDialog.d.ts +7 -0
- package/lib/sections/social/SocialEditDialog.d.ts.map +1 -0
- package/lib/sections/social/SocialEditDialog.js +362 -0
- package/lib/sections/social/SocialSection.d.ts +8 -0
- package/lib/sections/social/SocialSection.d.ts.map +1 -0
- package/lib/sections/social/SocialSection.js +201 -0
- package/lib/sections/social/constants.d.ts +3 -0
- package/lib/sections/social/constants.d.ts.map +1 -0
- package/lib/sections/social/constants.js +16 -0
- package/lib/sections/social/helpers.d.ts +15 -0
- package/lib/sections/social/helpers.d.ts.map +1 -0
- package/lib/sections/social/helpers.js +316 -0
- package/lib/sections/social/mutations.d.ts +4 -0
- package/lib/sections/social/mutations.d.ts.map +1 -0
- package/lib/sections/social/mutations.js +298 -0
- package/lib/sections/social/selectors.d.ts +4 -0
- package/lib/sections/social/selectors.d.ts.map +1 -0
- package/lib/sections/social/selectors.js +43 -0
- package/lib/sections/social/types.d.ts +19 -0
- package/lib/sections/social/types.d.ts.map +1 -0
- package/lib/sections/social/types.js +5 -0
- package/lib/styles/BioSection.css +77 -0
- package/lib/styles/CVCard.css +107 -2
- package/lib/styles/ContactInfoEditDialog.css +153 -0
- package/lib/styles/EditDialogs.css +1028 -0
- package/lib/styles/EducationCard.css +103 -0
- package/lib/styles/HeadingSection.css +309 -0
- package/lib/styles/ProfileCard.css +10 -42
- package/lib/styles/ProfileView.css +53 -8
- package/lib/styles/ProjectsCard.css +206 -0
- package/lib/styles/QRCodeCard.css +29 -10
- package/lib/styles/SocialCard.css +41 -13
- package/lib/styles/dialog.css +209 -0
- package/lib/styles/utilities.css +638 -256
- package/lib/textUtils.d.ts +6 -0
- package/lib/textUtils.d.ts.map +1 -0
- package/lib/textUtils.js +44 -0
- package/lib/texts.d.ts +45 -4
- package/lib/texts.d.ts.map +1 -1
- package/lib/texts.js +46 -5
- package/lib/types.d.ts +2 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +5 -0
- package/lib/ui/dialog.d.ts +29 -0
- package/lib/ui/dialog.d.ts.map +1 -0
- package/lib/ui/dialog.js +269 -0
- package/lib/ui/errors.d.ts +2 -0
- package/lib/ui/errors.d.ts.map +1 -0
- package/lib/ui/errors.js +10 -0
- package/package.json +8 -6
- package/lib/CVCard.d.ts +0 -4
- package/lib/CVCard.d.ts.map +0 -1
- package/lib/CVCard.js +0 -114
- package/lib/CVPresenter.d.ts +0 -25
- package/lib/CVPresenter.d.ts.map +0 -1
- package/lib/CVPresenter.js +0 -119
- package/lib/FriendList.d.ts +0 -6
- package/lib/FriendList.d.ts.map +0 -1
- package/lib/FriendList.js +0 -27
- package/lib/ProfileCard.d.ts +0 -6
- package/lib/ProfileCard.d.ts.map +0 -1
- package/lib/ProfileCard.js +0 -62
- package/lib/SocialCard.d.ts +0 -5
- package/lib/SocialCard.d.ts.map +0 -1
- package/lib/SocialCard.js +0 -51
- package/lib/SocialPresenter.d.ts +0 -11
- package/lib/SocialPresenter.d.ts.map +0 -1
- package/lib/SocialPresenter.js +0 -117
- package/lib/StuffCard.d.ts +0 -10
- package/lib/StuffCard.d.ts.map +0 -1
- package/lib/StuffCard.js +0 -52
- package/lib/StuffPresenter.d.ts +0 -14
- package/lib/StuffPresenter.d.ts.map +0 -1
- package/lib/StuffPresenter.js +0 -53
- package/lib/presenter.d.ts +0 -14
- package/lib/presenter.d.ts.map +0 -1
- package/lib/presenter.js +0 -68
- package/lib/styles/FriendList.css +0 -12
- package/lib/styles/StuffCard.css +0 -23
- package/lib/styles/editProfile.css +0 -62
- package/lib/styles/profileRDFFormsEnforced.css +0 -427
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.presentSkillDetails = presentSkillDetails;
|
|
7
|
+
exports.presentSkills = presentSkills;
|
|
8
|
+
exports.skillAsText = skillAsText;
|
|
9
|
+
var _solidUi = require("solid-ui");
|
|
10
|
+
function skillAsText(store, sk) {
|
|
11
|
+
if (sk.termType === 'Literal') return '';
|
|
12
|
+
const directName = store.anyJS(sk, _solidUi.ns.schema('name'));
|
|
13
|
+
if (directName) return directName;
|
|
14
|
+
|
|
15
|
+
// Canonical shape: entry node -> solid:publicId -> schema:name.
|
|
16
|
+
const publicId = store.any(sk, _solidUi.ns.solid('publicId'));
|
|
17
|
+
if (publicId && publicId.termType === 'NamedNode') {
|
|
18
|
+
const name = store.anyJS(publicId, _solidUi.ns.schema('name'));
|
|
19
|
+
if (name) return name;
|
|
20
|
+
return _solidUi.utils.label(publicId, true);
|
|
21
|
+
}
|
|
22
|
+
return '';
|
|
23
|
+
}
|
|
24
|
+
function presentSkillDetails(subject, store) {
|
|
25
|
+
return store.each(subject, _solidUi.ns.schema('skills')).filter(sk => sk.termType !== 'Literal').map(sk => {
|
|
26
|
+
const publicId = store.any(sk, _solidUi.ns.solid('publicId'));
|
|
27
|
+
const publicIdUri = publicId ? publicId.value : '';
|
|
28
|
+
return {
|
|
29
|
+
name: skillAsText(store, sk),
|
|
30
|
+
publicId: publicIdUri,
|
|
31
|
+
entryNode: sk
|
|
32
|
+
};
|
|
33
|
+
}).filter(detail => detail.name !== '');
|
|
34
|
+
}
|
|
35
|
+
function presentSkills(subject, store) {
|
|
36
|
+
return presentSkillDetails(subject, store).map(detail => detail.name);
|
|
37
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Node } from 'rdflib';
|
|
2
|
+
import { RowStatus } from '../shared/types';
|
|
3
|
+
export interface SkillFields {
|
|
4
|
+
name: string;
|
|
5
|
+
publicId: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SkillDetails extends SkillFields {
|
|
8
|
+
entryNode: Node;
|
|
9
|
+
}
|
|
10
|
+
export interface SkillRow extends SkillFields {
|
|
11
|
+
entryNode: string;
|
|
12
|
+
status: RowStatus;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/sections/skills/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C,SAAS,EAAE,IAAI,CAAA;CAChB;AAED,MAAM,WAAW,QAAS,SAAQ,WAAW;IAC3C,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,SAAS,CAAA;CAClB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Account } from './types';
|
|
2
|
+
import '../../styles/ContactInfoEditDialog.css';
|
|
3
|
+
import '../../styles/EditDialogs.css';
|
|
4
|
+
import { LiveStore, NamedNode } from 'rdflib';
|
|
5
|
+
import { ViewerMode } from '../../types';
|
|
6
|
+
export declare function createSocialEditDialog(event: Event, store: LiveStore, subject: NamedNode, socialAccounts: Account[], viewerMode: ViewerMode, onSaved?: () => Promise<void> | void): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=SocialEditDialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SocialEditDialog.d.ts","sourceRoot":"","sources":["../../../src/sections/social/SocialEditDialog.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,SAAS,CAAA;AACjD,OAAO,wCAAwC,CAAA;AAC/C,OAAO,8BAA8B,CAAA;AACrC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAuYxC,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,SAAS,EAClB,cAAc,EAAE,OAAO,EAAE,EACzB,UAAU,EAAE,UAAU,EACtB,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,iBA6CrC"}
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createSocialEditDialog = createSocialEditDialog;
|
|
7
|
+
var _dialog = require("../../ui/dialog");
|
|
8
|
+
var _litHtml = require("lit-html");
|
|
9
|
+
require("../../styles/ContactInfoEditDialog.css");
|
|
10
|
+
require("../../styles/EditDialogs.css");
|
|
11
|
+
var _rowState = require("../shared/rowState");
|
|
12
|
+
var _textUtils = require("../../textUtils");
|
|
13
|
+
var _mutations = require("./mutations");
|
|
14
|
+
var _profileIcons = require("../../icons-svg/profileIcons");
|
|
15
|
+
var _texts = require("../../texts");
|
|
16
|
+
var _constants = require("./constants");
|
|
17
|
+
var _helpers = require("./helpers");
|
|
18
|
+
/* The code below for handling reordering were generated by AI Model: GPT-5.3-Codex. */
|
|
19
|
+
/* Prompt: can you implement on SocialEditDialog add the bentoIcon as the first item
|
|
20
|
+
on the row, you should be able to drag this button around and it should allow you
|
|
21
|
+
to change the order of the rows and that should change the order in the mutations
|
|
22
|
+
that happen for this data. */
|
|
23
|
+
|
|
24
|
+
function sanitizeSocialFieldValue(value) {
|
|
25
|
+
return (0, _textUtils.sanitizeTextValue)(value);
|
|
26
|
+
}
|
|
27
|
+
function sanitizeUrlFieldValue(value) {
|
|
28
|
+
return (0, _textUtils.sanitizeTextValue)(value).replace(/\s+/g, '');
|
|
29
|
+
}
|
|
30
|
+
function isValidProfileUrl(value) {
|
|
31
|
+
const normalized = (value || '').trim();
|
|
32
|
+
if (!normalized) return false;
|
|
33
|
+
try {
|
|
34
|
+
const parsed = new URL(normalized);
|
|
35
|
+
return parsed.protocol === 'http:' || parsed.protocol === 'https:';
|
|
36
|
+
} catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function rowHasContent(row) {
|
|
41
|
+
// A social account is considered meaningful only when a personal profile URL is set.
|
|
42
|
+
return (0, _textUtils.hasNonEmptyText)(row.homepage);
|
|
43
|
+
}
|
|
44
|
+
function toFormState(socialAccounts) {
|
|
45
|
+
const rows = (socialAccounts || []).map(account => ({
|
|
46
|
+
name: sanitizeSocialFieldValue((0, _textUtils.toText)(account.name)),
|
|
47
|
+
icon: sanitizeSocialFieldValue((0, _textUtils.toText)(account.icon)),
|
|
48
|
+
homepage: sanitizeSocialFieldValue((0, _textUtils.toText)(account.homepage)),
|
|
49
|
+
entryNode: (0, _textUtils.toText)(account.entryNode),
|
|
50
|
+
status: (0, _textUtils.toText)(account.entryNode) ? 'existing' : 'new'
|
|
51
|
+
})).filter(row => Boolean(row.name || row.icon || row.homepage || row.entryNode));
|
|
52
|
+
return {
|
|
53
|
+
socialAccounts: rows.length ? rows : [{
|
|
54
|
+
name: '',
|
|
55
|
+
icon: '',
|
|
56
|
+
homepage: '',
|
|
57
|
+
entryNode: '',
|
|
58
|
+
status: 'new'
|
|
59
|
+
}],
|
|
60
|
+
initialExistingOrder: []
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function hasOrderChanged(rows, initialExistingOrder) {
|
|
64
|
+
const currentExistingOrder = rows.filter(row => row.status !== 'deleted' && Boolean((row.entryNode || '').trim())).map(row => (row.entryNode || '').trim());
|
|
65
|
+
if (currentExistingOrder.length !== initialExistingOrder.length) return true;
|
|
66
|
+
for (let i = 0; i < currentExistingOrder.length; i++) {
|
|
67
|
+
if (currentExistingOrder[i] !== initialExistingOrder[i]) return true;
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
function validateSocialBeforeSave(rows, initialExistingOrder) {
|
|
72
|
+
const ops = (0, _rowState.summarizeRowOps)(rows, rowHasContent);
|
|
73
|
+
const hasChanges = ops.create.length > 0 || ops.update.length > 0 || ops.remove.length > 0;
|
|
74
|
+
const orderChanged = hasOrderChanged(rows, initialExistingOrder);
|
|
75
|
+
if (!hasChanges && !orderChanged) return 'No social changes detected.';
|
|
76
|
+
for (let i = 0; i < rows.length; i++) {
|
|
77
|
+
const row = rows[i];
|
|
78
|
+
if (!row || row.status === 'deleted') continue;
|
|
79
|
+
const hasAnyValue = [row.name, row.icon, row.homepage].some(_textUtils.hasNonEmptyText);
|
|
80
|
+
if (!hasAnyValue) continue;
|
|
81
|
+
if (!(0, _textUtils.hasNonEmptyText)(row.name) || !(0, _textUtils.hasNonEmptyText)(row.icon)) {
|
|
82
|
+
return `Social account ${i + 1}: please choose an account type from the dropdown.`;
|
|
83
|
+
}
|
|
84
|
+
if (!(0, _textUtils.hasNonEmptyText)(row.homepage)) {
|
|
85
|
+
return `Social account ${i + 1}: please enter your personal profile link.`;
|
|
86
|
+
}
|
|
87
|
+
if (!isValidProfileUrl(row.homepage || '')) {
|
|
88
|
+
return `Social account ${i + 1}: profile link must be a valid http(s) URL.`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
function renderSocialAccountInputSelect(row, rowIndex, options, onChange) {
|
|
94
|
+
const selected = (0, _helpers.findSocialAccountOption)(options, row?.name || '');
|
|
95
|
+
const selectedLabel = selected?.label || '';
|
|
96
|
+
return (0, _litHtml.html)`
|
|
97
|
+
<select
|
|
98
|
+
class="profile-edit-dialog__social-account-select"
|
|
99
|
+
name=${`social-account-type-${rowIndex}`}
|
|
100
|
+
data-row-index=${String(rowIndex)}
|
|
101
|
+
autocomplete="off"
|
|
102
|
+
@change=${onChange}
|
|
103
|
+
>
|
|
104
|
+
<option value="">Select</option>
|
|
105
|
+
${options.map(option => (0, _litHtml.html)`
|
|
106
|
+
<option value=${option.label} ?selected=${option.label === selectedLabel}>${option.label}</option>
|
|
107
|
+
`)}
|
|
108
|
+
</select>
|
|
109
|
+
`;
|
|
110
|
+
}
|
|
111
|
+
function renderSocialInputRow({
|
|
112
|
+
rows,
|
|
113
|
+
index,
|
|
114
|
+
displayIndex,
|
|
115
|
+
onDelete,
|
|
116
|
+
onChange,
|
|
117
|
+
options,
|
|
118
|
+
onDragStart,
|
|
119
|
+
onDragOver,
|
|
120
|
+
onDrop,
|
|
121
|
+
onDragEnd,
|
|
122
|
+
isDropTarget
|
|
123
|
+
}) {
|
|
124
|
+
const row = rows[index];
|
|
125
|
+
const nameLabel = `Social Account Name ${displayIndex + 1}`;
|
|
126
|
+
const homepageLabel = `Social Account Homepage ${displayIndex + 1}`;
|
|
127
|
+
const handleTextInput = field => event => {
|
|
128
|
+
const target = event.target;
|
|
129
|
+
const nextValue = field === 'homepage' ? sanitizeUrlFieldValue(target.value) : sanitizeSocialFieldValue(target.value);
|
|
130
|
+
if (rows[index]) {
|
|
131
|
+
(0, _rowState.applyRowFieldChange)(rows[index], field, nextValue, rowHasContent);
|
|
132
|
+
onChange();
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
const handleAccountTypeInput = event => {
|
|
136
|
+
const target = event.target;
|
|
137
|
+
const selected = (0, _helpers.findSocialAccountOption)(options, target.value);
|
|
138
|
+
if (!rows[index]) return;
|
|
139
|
+
if (!selected) {
|
|
140
|
+
(0, _rowState.applyRowFieldChange)(rows[index], 'name', '', rowHasContent);
|
|
141
|
+
(0, _rowState.applyRowFieldChange)(rows[index], 'icon', '', rowHasContent);
|
|
142
|
+
onChange();
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
(0, _rowState.applyRowFieldChange)(rows[index], 'name', selected.label, rowHasContent);
|
|
146
|
+
(0, _rowState.applyRowFieldChange)(rows[index], 'icon', selected.icon || _constants.DEFAULT_ICON_URI, rowHasContent);
|
|
147
|
+
onChange();
|
|
148
|
+
};
|
|
149
|
+
const handleDelete = event => {
|
|
150
|
+
event.preventDefault();
|
|
151
|
+
onDelete();
|
|
152
|
+
};
|
|
153
|
+
return (0, _litHtml.html)`
|
|
154
|
+
<div
|
|
155
|
+
class="profile-edit-dialog__row profile-edit-dialog__row--social ${isDropTarget ? 'profile-edit-dialog__row--drop-target' : ''}"
|
|
156
|
+
@dragover=${event => onDragOver(event)}
|
|
157
|
+
@drop=${() => onDrop(index)}
|
|
158
|
+
>
|
|
159
|
+
<button
|
|
160
|
+
type="button"
|
|
161
|
+
class="profile-edit-dialog__drag-handle"
|
|
162
|
+
aria-label=${`Reorder social account ${displayIndex + 1}`}
|
|
163
|
+
title="Drag to reorder"
|
|
164
|
+
draggable="true"
|
|
165
|
+
@dragstart=${() => onDragStart(index)}
|
|
166
|
+
@dragend=${() => onDragEnd()}
|
|
167
|
+
>
|
|
168
|
+
${_profileIcons.bentoIcon}
|
|
169
|
+
</button>
|
|
170
|
+
<img
|
|
171
|
+
class="profile-edit-dialog__social-icon"
|
|
172
|
+
src="${row?.icon || _constants.DEFAULT_ICON_URI}"
|
|
173
|
+
alt="${row?.name || 'Social'} icon"
|
|
174
|
+
width="30"
|
|
175
|
+
height="30"
|
|
176
|
+
loading="lazy"
|
|
177
|
+
/>
|
|
178
|
+
<label aria-label=${nameLabel} class="label profile-edit-dialog__field profile-edit-dialog__field--social-type">
|
|
179
|
+
${renderSocialAccountInputSelect(row, index, options, handleAccountTypeInput)}
|
|
180
|
+
</label>
|
|
181
|
+
<label aria-label=${homepageLabel} class="label profile-edit-dialog__field profile-edit-dialog__field--social-url">
|
|
182
|
+
<input
|
|
183
|
+
class="input"
|
|
184
|
+
type="url"
|
|
185
|
+
name=${`social-homepage-${index}`}
|
|
186
|
+
.value=${row?.homepage || ''}
|
|
187
|
+
data-contact-field="homepage"
|
|
188
|
+
data-entry-node=${row?.entryNode || ''}
|
|
189
|
+
data-row-status=${row?.status || 'n/a'}
|
|
190
|
+
placeholder="Profile URL"
|
|
191
|
+
autocomplete="url"
|
|
192
|
+
inputmode="url"
|
|
193
|
+
required
|
|
194
|
+
@input=${handleTextInput('homepage')}
|
|
195
|
+
/>
|
|
196
|
+
<small class="profile-edit-dialog__input-help-text">Paste your full profile URL (for example: https://example.com/username)</small>
|
|
197
|
+
</label>
|
|
198
|
+
<div class="profile-edit-dialog__actions profile-edit-dialog__actions--edge">
|
|
199
|
+
<button
|
|
200
|
+
type="button"
|
|
201
|
+
class="profile-edit-dialog__delete-button"
|
|
202
|
+
aria-label=${`Delete social account ${displayIndex + 1}`}
|
|
203
|
+
title=${_texts.deleteEntryButtonTitleText}
|
|
204
|
+
@click=${handleDelete}
|
|
205
|
+
>
|
|
206
|
+
<span class="profile-edit-dialog__delete-icon" aria-hidden="true">${_profileIcons.trashIcon}</span>
|
|
207
|
+
</button>
|
|
208
|
+
</div>
|
|
209
|
+
</div>
|
|
210
|
+
`;
|
|
211
|
+
}
|
|
212
|
+
function renderSocialSection(rows, options, onRerender) {
|
|
213
|
+
let dragSourceIndex = null;
|
|
214
|
+
let dropTargetIndex = null;
|
|
215
|
+
const reorderRows = (from, to) => {
|
|
216
|
+
if (from === to) return;
|
|
217
|
+
const row = rows[from];
|
|
218
|
+
if (!row) return;
|
|
219
|
+
rows.splice(from, 1);
|
|
220
|
+
rows.splice(to, 0, row);
|
|
221
|
+
};
|
|
222
|
+
const handleDragStart = index => {
|
|
223
|
+
dragSourceIndex = index;
|
|
224
|
+
dropTargetIndex = index;
|
|
225
|
+
};
|
|
226
|
+
const handleDragOver = event => {
|
|
227
|
+
event.preventDefault();
|
|
228
|
+
if (event.dataTransfer) {
|
|
229
|
+
event.dataTransfer.dropEffect = 'move';
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
const handleDrop = index => {
|
|
233
|
+
if (dragSourceIndex === null) return;
|
|
234
|
+
reorderRows(dragSourceIndex, index);
|
|
235
|
+
dragSourceIndex = null;
|
|
236
|
+
dropTargetIndex = null;
|
|
237
|
+
onRerender();
|
|
238
|
+
};
|
|
239
|
+
const handleDragEnd = () => {
|
|
240
|
+
dragSourceIndex = null;
|
|
241
|
+
dropTargetIndex = null;
|
|
242
|
+
};
|
|
243
|
+
const visibleRows = rows.map((row, index) => ({
|
|
244
|
+
row,
|
|
245
|
+
index
|
|
246
|
+
})).filter(({
|
|
247
|
+
row
|
|
248
|
+
}) => row.status !== 'deleted');
|
|
249
|
+
return (0, _litHtml.html)`
|
|
250
|
+
<section class="profile-edit-dialog__section" aria-label="Social Accounts">
|
|
251
|
+
<fieldset>
|
|
252
|
+
<legend class="sr-only">Social account entries</legend>
|
|
253
|
+
${visibleRows.map(({
|
|
254
|
+
index
|
|
255
|
+
}, displayIndex) => renderSocialInputRow({
|
|
256
|
+
rows,
|
|
257
|
+
index,
|
|
258
|
+
displayIndex,
|
|
259
|
+
onDelete: () => {
|
|
260
|
+
(0, _rowState.deleteRow)(rows, index);
|
|
261
|
+
onRerender();
|
|
262
|
+
},
|
|
263
|
+
onChange: onRerender,
|
|
264
|
+
options,
|
|
265
|
+
onDragStart: handleDragStart,
|
|
266
|
+
onDragOver: handleDragOver,
|
|
267
|
+
onDrop: handleDrop,
|
|
268
|
+
onDragEnd: handleDragEnd,
|
|
269
|
+
isDropTarget: dropTargetIndex === index
|
|
270
|
+
}))}
|
|
271
|
+
</fieldset>
|
|
272
|
+
</section>
|
|
273
|
+
`;
|
|
274
|
+
}
|
|
275
|
+
function focusSocialField(form, selector) {
|
|
276
|
+
const nextField = form.querySelector(selector);
|
|
277
|
+
if (!nextField || typeof nextField.focus !== 'function') return;
|
|
278
|
+
nextField.scrollIntoView({
|
|
279
|
+
block: 'start',
|
|
280
|
+
behavior: 'auto'
|
|
281
|
+
});
|
|
282
|
+
nextField.focus();
|
|
283
|
+
}
|
|
284
|
+
function renderSocialEditTemplate(form, formState, store, viewerMode, rerenderOptions = {}) {
|
|
285
|
+
const rerender = (nextOptions = {}) => renderSocialEditTemplate(form, formState, store, viewerMode, nextOptions);
|
|
286
|
+
const socialOptions = (0, _helpers.getSocialAccountOptions)(store);
|
|
287
|
+
(0, _litHtml.render)((0, _litHtml.html)`
|
|
288
|
+
${renderSocialSection(formState.socialAccounts, socialOptions, rerender)}
|
|
289
|
+
${viewerMode !== 'owner' ? (0, _litHtml.html)`<p class="profile-edit-dialog__login-message">${_texts.ownerLoginRequiredDialogMessageText}</p>` : null}
|
|
290
|
+
`, form);
|
|
291
|
+
if (rerenderOptions.focusSelector) {
|
|
292
|
+
focusSocialField(form, rerenderOptions.focusSelector);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
function createSocialEditForm(details, store, viewerMode) {
|
|
296
|
+
const form = document.createElement('form');
|
|
297
|
+
form.classList.add('profile__edit-form');
|
|
298
|
+
const formState = toFormState(details);
|
|
299
|
+
formState.initialExistingOrder = formState.socialAccounts.filter(row => Boolean((row.entryNode || '').trim())).map(row => (row.entryNode || '').trim());
|
|
300
|
+
renderSocialEditTemplate(form, formState, store, viewerMode);
|
|
301
|
+
const addRow = () => {
|
|
302
|
+
formState.socialAccounts.unshift({
|
|
303
|
+
name: '',
|
|
304
|
+
icon: '',
|
|
305
|
+
homepage: '',
|
|
306
|
+
entryNode: '',
|
|
307
|
+
status: 'new'
|
|
308
|
+
});
|
|
309
|
+
renderSocialEditTemplate(form, formState, store, viewerMode, {
|
|
310
|
+
focusSelector: '[name="social-account-type-0"]'
|
|
311
|
+
});
|
|
312
|
+
};
|
|
313
|
+
return {
|
|
314
|
+
form,
|
|
315
|
+
formState,
|
|
316
|
+
addRow
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
async function createSocialEditDialog(event, store, subject, socialAccounts, viewerMode, onSaved) {
|
|
320
|
+
const dom = event.currentTarget?.ownerDocument || document;
|
|
321
|
+
const {
|
|
322
|
+
form,
|
|
323
|
+
formState,
|
|
324
|
+
addRow
|
|
325
|
+
} = createSocialEditForm(socialAccounts, store, viewerMode);
|
|
326
|
+
const result = await (0, _dialog.openInputDialog)({
|
|
327
|
+
title: _texts.editSocialDialogTitleText,
|
|
328
|
+
dom,
|
|
329
|
+
form,
|
|
330
|
+
headerAction: {
|
|
331
|
+
type: 'button',
|
|
332
|
+
label: '+ Add More',
|
|
333
|
+
ariaLabel: 'Add another social account',
|
|
334
|
+
onClick: addRow
|
|
335
|
+
},
|
|
336
|
+
submitLabel: _texts.dialogSubmitLabelText,
|
|
337
|
+
cancelLabel: _texts.dialogCancelLabelText,
|
|
338
|
+
validate: () => {
|
|
339
|
+
if (viewerMode !== 'owner') {
|
|
340
|
+
return _texts.ownerLoginRequiredDialogMessageText;
|
|
341
|
+
}
|
|
342
|
+
return validateSocialBeforeSave(formState.socialAccounts, formState.initialExistingOrder);
|
|
343
|
+
},
|
|
344
|
+
onSave: async () => {
|
|
345
|
+
const socialOps = (0, _rowState.summarizeRowOps)(formState.socialAccounts, rowHasContent);
|
|
346
|
+
const plan = {
|
|
347
|
+
create: socialOps.create,
|
|
348
|
+
update: socialOps.update,
|
|
349
|
+
remove: socialOps.remove
|
|
350
|
+
};
|
|
351
|
+
await (0, _mutations.processSocialMutations)(store, subject, plan, formState.socialAccounts);
|
|
352
|
+
},
|
|
353
|
+
formatSaveError: error => {
|
|
354
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
355
|
+
return message.startsWith(_texts.saveSocialUpdatesFailedPrefixText) ? message : `${_texts.saveSocialUpdatesFailedPrefixText} ${message}`;
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
if (!result) return;
|
|
359
|
+
if (onSaved) {
|
|
360
|
+
await onSaved();
|
|
361
|
+
}
|
|
362
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { TemplateResult } from 'lit-html';
|
|
2
|
+
import { SocialPresentation } from './types';
|
|
3
|
+
import { ViewerMode } from '../../types';
|
|
4
|
+
import '../../styles/SocialCard.css';
|
|
5
|
+
import { LiveStore, NamedNode } from 'rdflib';
|
|
6
|
+
export declare const SocialCard: (SocialData: SocialPresentation, viewerMode: ViewerMode) => TemplateResult;
|
|
7
|
+
export declare function renderSocialAccounts(store: LiveStore, subject: NamedNode, socialData: SocialPresentation, viewerMode: ViewerMode, onSaved?: () => Promise<void> | void): TemplateResult<1> | "";
|
|
8
|
+
//# sourceMappingURL=SocialSection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SocialSection.d.ts","sourceRoot":"","sources":["../../../src/sections/social/SocialSection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,cAAc,EAAE,MAAM,UAAU,CAAA;AAC/C,OAAO,EAAW,kBAAkB,EAAE,MAAM,SAAS,CAAA;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,6BAA6B,CAAA;AAGpC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAoB7C,eAAO,MAAM,UAAU,GACrB,YAAY,kBAAkB,EAC9B,YAAY,UAAU,KACrB,cA6DF,CAAA;AAwJD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,SAAS,EAClB,UAAU,EAAE,kBAAkB,EAC9B,UAAU,EAAE,UAAU,EACtB,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,0BAYrC"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.SocialCard = void 0;
|
|
7
|
+
exports.renderSocialAccounts = renderSocialAccounts;
|
|
8
|
+
var _litHtml = require("lit-html");
|
|
9
|
+
require("../../styles/SocialCard.css");
|
|
10
|
+
var _texts = require("../../texts");
|
|
11
|
+
var _SocialEditDialog = require("./SocialEditDialog");
|
|
12
|
+
var _collapsibleSection = require("../shared/collapsibleSection");
|
|
13
|
+
var _profileIcons = require("../../icons-svg/profileIcons");
|
|
14
|
+
const MAX_VISIBLE_SOCIAL_ACCOUNTS_MOBILE = 10;
|
|
15
|
+
function isRenderableAccount(account) {
|
|
16
|
+
return Boolean(account?.homepage && account?.name && account?.icon);
|
|
17
|
+
}
|
|
18
|
+
function expandSocialAccounts(event) {
|
|
19
|
+
const button = event.currentTarget;
|
|
20
|
+
const socialCard = button?.closest('.socialCard');
|
|
21
|
+
if (!button || !socialCard) return;
|
|
22
|
+
socialCard.setAttribute('data-mobile-expanded', 'true');
|
|
23
|
+
button.setAttribute('aria-expanded', 'true');
|
|
24
|
+
button.hidden = true;
|
|
25
|
+
}
|
|
26
|
+
const SocialCard = (SocialData, viewerMode) => {
|
|
27
|
+
void viewerMode;
|
|
28
|
+
const accounts = (SocialData.accounts || []).filter(isRenderableAccount);
|
|
29
|
+
const hiddenAccountsCount = Math.max(0, accounts.length - MAX_VISIBLE_SOCIAL_ACCOUNTS_MOBILE);
|
|
30
|
+
if (accounts.length) {
|
|
31
|
+
return (0, _litHtml.html)`
|
|
32
|
+
<section
|
|
33
|
+
class="socialCard"
|
|
34
|
+
aria-label="Social media"
|
|
35
|
+
data-testid="social-media"
|
|
36
|
+
data-mobile-expanded="${hiddenAccountsCount > 0 ? 'false' : 'true'}"
|
|
37
|
+
>
|
|
38
|
+
<nav aria-label="Social media profiles">
|
|
39
|
+
<ul class="socialList list-reset" role="list">
|
|
40
|
+
${accounts.map(account => renderAccount(account))}
|
|
41
|
+
</ul>
|
|
42
|
+
</nav>
|
|
43
|
+
${hiddenAccountsCount > 0 ? (0, _litHtml.html)`
|
|
44
|
+
<button
|
|
45
|
+
type="button"
|
|
46
|
+
class="socialCard__more-button"
|
|
47
|
+
aria-controls="social-media"
|
|
48
|
+
aria-expanded="false"
|
|
49
|
+
@click=${expandSocialAccounts}
|
|
50
|
+
>
|
|
51
|
+
${hiddenAccountsCount} more
|
|
52
|
+
</button>
|
|
53
|
+
` : (0, _litHtml.html)``}
|
|
54
|
+
</section>
|
|
55
|
+
`;
|
|
56
|
+
}
|
|
57
|
+
return (0, _litHtml.html)``;
|
|
58
|
+
function renderAccount(account) {
|
|
59
|
+
return (0, _litHtml.html)`
|
|
60
|
+
<li class="socialItem" role="listitem">
|
|
61
|
+
<a
|
|
62
|
+
href="${account.homepage}"
|
|
63
|
+
target="_blank"
|
|
64
|
+
rel="noopener noreferrer"
|
|
65
|
+
aria-label="Visit ${account.name} profile (opens in new tab)"
|
|
66
|
+
>
|
|
67
|
+
<img
|
|
68
|
+
class="socialIcon"
|
|
69
|
+
src="${account.icon}"
|
|
70
|
+
alt="${account.name} icon"
|
|
71
|
+
width="40"
|
|
72
|
+
height="40"
|
|
73
|
+
loading="lazy"
|
|
74
|
+
/>
|
|
75
|
+
</a>
|
|
76
|
+
</li>
|
|
77
|
+
`;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
exports.SocialCard = SocialCard;
|
|
81
|
+
function renderSocialSectionContent(socialData, viewerMode) {
|
|
82
|
+
const hasAccounts = socialData.accounts && socialData.accounts.length > 0;
|
|
83
|
+
return (0, _litHtml.html)`
|
|
84
|
+
${hasAccounts ? SocialCard(socialData, viewerMode) : (0, _litHtml.html)`<p>No social accounts added yet.</p>`}
|
|
85
|
+
`;
|
|
86
|
+
}
|
|
87
|
+
function renderSocialSectionDefault(store, subject, socialData, viewerMode, onSaved) {
|
|
88
|
+
// const hasAccounts = socialData.accounts && socialData.accounts.length > 0
|
|
89
|
+
const showSection = true;
|
|
90
|
+
const isOwner = viewerMode === 'owner';
|
|
91
|
+
const handleEdit = event => {
|
|
92
|
+
return (0, _SocialEditDialog.createSocialEditDialog)(event, store, subject, socialData.accounts, viewerMode, onSaved);
|
|
93
|
+
};
|
|
94
|
+
return showSection ? (0, _litHtml.html)`
|
|
95
|
+
<section
|
|
96
|
+
aria-labelledby="social-heading"
|
|
97
|
+
class="profile__section border-lighter profile-section-collapsible profile-section-collapsible--inline-mobile-actions"
|
|
98
|
+
role="region"
|
|
99
|
+
tabindex="-1"
|
|
100
|
+
data-expanded="false"
|
|
101
|
+
>
|
|
102
|
+
<header class="profile__section-header profile-section-collapsible__header">
|
|
103
|
+
<h2 id="social-heading" tabindex="-1">${_texts.socialAccountsHeadingText}</h2>
|
|
104
|
+
<div class="profile-section-collapsible__actions flex-column">
|
|
105
|
+
${isOwner ? (0, _litHtml.html)`
|
|
106
|
+
<button
|
|
107
|
+
type="button"
|
|
108
|
+
class="profile__action-button profile-action-text flex-center profile-section-collapsible__edit-button"
|
|
109
|
+
aria-label="Edit social accounts"
|
|
110
|
+
@click=${handleEdit}
|
|
111
|
+
>
|
|
112
|
+
<span class="profile-section-collapsible__edit-label">${_profileIcons.editIcon} Edit</span>
|
|
113
|
+
<span class="profile-section-collapsible__edit-icon" aria-hidden="true">${_profileIcons.editIcon}</span>
|
|
114
|
+
</button>
|
|
115
|
+
` : (0, _litHtml.html)``}
|
|
116
|
+
<button
|
|
117
|
+
type="button"
|
|
118
|
+
class="inline-flex-row"
|
|
119
|
+
aria-label="Toggle social accounts section"
|
|
120
|
+
aria-controls="social-panel"
|
|
121
|
+
aria-expanded="false"
|
|
122
|
+
@click=${_collapsibleSection.toggleCollapsibleSection}
|
|
123
|
+
>
|
|
124
|
+
<span class="profile-section-collapsible__chevron" aria-hidden="true">⌄</span>
|
|
125
|
+
</button>
|
|
126
|
+
</div>
|
|
127
|
+
</header>
|
|
128
|
+
<div id="social-panel" class="profile-section-collapsible__content" aria-hidden="true">
|
|
129
|
+
${renderSocialSectionContent(socialData, viewerMode)}
|
|
130
|
+
</div>
|
|
131
|
+
</section>
|
|
132
|
+
` : (0, _litHtml.html)``;
|
|
133
|
+
}
|
|
134
|
+
function renderOwnerEmptySocialContent(_store, _subject, _socialData, _viewerMode, _onSaved) {
|
|
135
|
+
return (0, _litHtml.html)`
|
|
136
|
+
<div class="profile__empty-state-content flex-column-center" role="group" aria-label="Empty social accounts section">
|
|
137
|
+
<div class="social__empty-icon-wrapper">
|
|
138
|
+
<span class="social__empty-icon inline-flex-row">${_profileIcons.globeIcon}</span>
|
|
139
|
+
</div>
|
|
140
|
+
<p class="profile__empty-state-message social__empty-message">
|
|
141
|
+
No social media links added yet.
|
|
142
|
+
</p>
|
|
143
|
+
</div>
|
|
144
|
+
`;
|
|
145
|
+
}
|
|
146
|
+
function renderOwnerEmptySocialSection(store, subject, socialData, viewerMode, onSaved) {
|
|
147
|
+
return (0, _litHtml.html)`
|
|
148
|
+
<section
|
|
149
|
+
aria-labelledby="social-heading"
|
|
150
|
+
data-profile-section="social"
|
|
151
|
+
class="profile__section--empty border-lighter flex-column-center rounded-md gap-lg profile-section-collapsible profile-section-collapsible--inline-mobile-actions"
|
|
152
|
+
role="region"
|
|
153
|
+
tabindex="-1"
|
|
154
|
+
data-expanded="false"
|
|
155
|
+
>
|
|
156
|
+
<header class="profile__section-header profile-section-collapsible__header">
|
|
157
|
+
<h2 id="social-heading" tabindex="-1">${_texts.socialAccountsHeadingText}</h2>
|
|
158
|
+
<div class="profile-section-collapsible__actions flex-column">
|
|
159
|
+
<button
|
|
160
|
+
type="button"
|
|
161
|
+
class="profile__action-button profile-action-text flex-center profile-section-collapsible__edit-button"
|
|
162
|
+
aria-label="Add social accounts"
|
|
163
|
+
@click=${event => {
|
|
164
|
+
return (0, _SocialEditDialog.createSocialEditDialog)(event, store, subject, socialData.accounts, viewerMode, onSaved);
|
|
165
|
+
}}
|
|
166
|
+
>
|
|
167
|
+
<span class="profile-section-collapsible__edit-label profile__add-more-content inline-flex-row">
|
|
168
|
+
<span class="profile__add-more-icon inline-flex-row" aria-hidden="true">${_profileIcons.addIcon}</span>
|
|
169
|
+
Add Account
|
|
170
|
+
</span>
|
|
171
|
+
<span class="profile-section-collapsible__edit-icon" aria-hidden="true">${_profileIcons.editIcon}</span>
|
|
172
|
+
</button>
|
|
173
|
+
<button
|
|
174
|
+
type="button"
|
|
175
|
+
class="inline-flex-row"
|
|
176
|
+
aria-label="Toggle social accounts section"
|
|
177
|
+
aria-controls="social-panel"
|
|
178
|
+
aria-expanded="false"
|
|
179
|
+
@click=${_collapsibleSection.toggleCollapsibleSection}
|
|
180
|
+
>
|
|
181
|
+
<span class="profile-section-collapsible__chevron" aria-hidden="true">⌄</span>
|
|
182
|
+
</button>
|
|
183
|
+
</div>
|
|
184
|
+
</header>
|
|
185
|
+
<div id="social-panel" class="profile-section-collapsible__content" aria-hidden="true">
|
|
186
|
+
${renderOwnerEmptySocialContent(store, subject, socialData, viewerMode, onSaved)}
|
|
187
|
+
</div>
|
|
188
|
+
</section>
|
|
189
|
+
`;
|
|
190
|
+
}
|
|
191
|
+
function renderSocialAccounts(store, subject, socialData, viewerMode, onSaved) {
|
|
192
|
+
const safeSocialData = socialData || {
|
|
193
|
+
accounts: []
|
|
194
|
+
};
|
|
195
|
+
const hasAccounts = Array.isArray(safeSocialData.accounts) && safeSocialData.accounts.length > 0;
|
|
196
|
+
const showOwnerEmptyAccounts = !hasAccounts && viewerMode === 'owner';
|
|
197
|
+
const showSection = true;
|
|
198
|
+
return showSection ? (0, _litHtml.html)`
|
|
199
|
+
${showOwnerEmptyAccounts ? renderOwnerEmptySocialSection(store, subject, safeSocialData, viewerMode, onSaved) : renderSocialSectionDefault(store, subject, safeSocialData, viewerMode, onSaved)}
|
|
200
|
+
` : '';
|
|
201
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/sections/social/constants.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mBAAmB,oBAAoB,CAAA;AAIpD,eAAO,MAAM,gBAAgB,QAGzB,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.socialMediaFormName = exports.DEFAULT_ICON_URI = void 0;
|
|
7
|
+
var _solidUi = require("solid-ui");
|
|
8
|
+
var _profileIcons = require("../../icons-svg/profileIcons");
|
|
9
|
+
const socialMediaFormName = exports.socialMediaFormName = 'socialMedia.ttl'; // The name of the file to upload
|
|
10
|
+
|
|
11
|
+
const FALLBACK_ICON_URI = `${_solidUi.icons.iconBase}noun_10636_grey.svg`; // grey disc
|
|
12
|
+
|
|
13
|
+
const DEFAULT_ICON_URI = exports.DEFAULT_ICON_URI = (() => {
|
|
14
|
+
const svgMarkup = _profileIcons.starIcon?.strings?.join('') || '';
|
|
15
|
+
return svgMarkup ? `data:image/svg+xml;utf8,${encodeURIComponent(svgMarkup)}` : FALLBACK_ICON_URI;
|
|
16
|
+
})();
|