solid-panes 4.4.2-5 → 4.4.2-7
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/dist/RDFXMLPane2.cjs.js +1 -1
- package/dist/RDFXMLPane2.esm.js +1 -1
- package/dist/_virtual/~icons/lucide/arrow-left.cjs.js +2 -0
- package/dist/_virtual/~icons/lucide/arrow-left.cjs.js.map +1 -0
- package/dist/_virtual/~icons/lucide/arrow-left.esm.js +11 -0
- package/dist/_virtual/~icons/lucide/arrow-left.esm.js.map +1 -0
- package/dist/_virtual/~icons/lucide/ellipsis-vertical.cjs.js +2 -0
- package/dist/_virtual/~icons/lucide/ellipsis-vertical.cjs.js.map +1 -0
- package/dist/_virtual/~icons/lucide/ellipsis-vertical.esm.js +11 -0
- package/dist/_virtual/~icons/lucide/ellipsis-vertical.esm.js.map +1 -0
- package/dist/_virtual/~icons/lucide/globe.cjs.js +2 -0
- package/dist/_virtual/~icons/lucide/globe.cjs.js.map +1 -0
- package/dist/_virtual/~icons/lucide/globe.esm.js +11 -0
- package/dist/_virtual/~icons/lucide/globe.esm.js.map +1 -0
- package/dist/_virtual/~icons/lucide/lock-keyhole.cjs.js +2 -0
- package/dist/_virtual/~icons/lucide/lock-keyhole.cjs.js.map +1 -0
- package/dist/_virtual/~icons/lucide/lock-keyhole.esm.js +11 -0
- package/dist/_virtual/~icons/lucide/lock-keyhole.esm.js.map +1 -0
- package/dist/_virtual/~icons/lucide/pencil.cjs.js +2 -0
- package/dist/_virtual/~icons/lucide/pencil.cjs.js.map +1 -0
- package/dist/_virtual/~icons/lucide/pencil.esm.js +11 -0
- package/dist/_virtual/~icons/lucide/pencil.esm.js.map +1 -0
- package/dist/_virtual/~icons/lucide/share-2.cjs.js +2 -0
- package/dist/_virtual/~icons/lucide/share-2.cjs.js.map +1 -0
- package/dist/_virtual/~icons/lucide/share-2.esm.js +11 -0
- package/dist/_virtual/~icons/lucide/share-2.esm.js.map +1 -0
- package/dist/_virtual/~icons/lucide/trash-2.cjs.js +2 -0
- package/dist/_virtual/~icons/lucide/trash-2.cjs.js.map +1 -0
- package/dist/_virtual/~icons/lucide/trash-2.esm.js +11 -0
- package/dist/_virtual/~icons/lucide/trash-2.esm.js.map +1 -0
- package/dist/audio/audioPane.cjs.js +1 -1
- package/dist/audio/audioPane.cjs.js.map +1 -1
- package/dist/audio/audioPane.esm.js +13 -10
- package/dist/audio/audioPane.esm.js.map +1 -1
- package/dist/components/file-explorer-header/FileExplorerHeader.cjs.js +14 -0
- package/dist/components/file-explorer-header/FileExplorerHeader.cjs.js.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerHeader.d.ts +19 -0
- package/dist/components/file-explorer-header/FileExplorerHeader.d.ts.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerHeader.esm.js +292 -0
- package/dist/components/file-explorer-header/FileExplorerHeader.esm.js.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerHeader.styles.cjs.js +2 -0
- package/dist/components/file-explorer-header/FileExplorerHeader.styles.cjs.js.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerHeader.styles.esm.js +7 -0
- package/dist/components/file-explorer-header/FileExplorerHeader.styles.esm.js.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderControls.cjs.js +22 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderControls.cjs.js.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderControls.d.ts +15 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderControls.d.ts.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderControls.esm.js +266 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderControls.esm.js.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderControls.styles.cjs.js +2 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderControls.styles.cjs.js.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderControls.styles.esm.js +7 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderControls.styles.esm.js.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderSummary.cjs.js +19 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderSummary.cjs.js.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderSummary.d.ts +19 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderSummary.d.ts.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderSummary.esm.js +321 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderSummary.esm.js.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderSummary.styles.cjs.js +2 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderSummary.styles.cjs.js.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderSummary.styles.esm.js +7 -0
- package/dist/components/file-explorer-header/FileExplorerHeaderSummary.styles.esm.js.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerProvider.cjs.js +13 -0
- package/dist/components/file-explorer-header/FileExplorerProvider.cjs.js.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerProvider.d.ts +36 -0
- package/dist/components/file-explorer-header/FileExplorerProvider.d.ts.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerProvider.esm.js +468 -0
- package/dist/components/file-explorer-header/FileExplorerProvider.esm.js.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerProvider.styles.cjs.js +2 -0
- package/dist/components/file-explorer-header/FileExplorerProvider.styles.cjs.js.map +1 -0
- package/dist/components/file-explorer-header/FileExplorerProvider.styles.esm.js +7 -0
- package/dist/components/file-explorer-header/FileExplorerProvider.styles.esm.js.map +1 -0
- package/dist/components/file-explorer-header/helper.cjs.js +2 -0
- package/dist/components/file-explorer-header/helper.cjs.js.map +1 -0
- package/dist/components/file-explorer-header/helper.d.ts +15 -0
- package/dist/components/file-explorer-header/helper.d.ts.map +1 -0
- package/dist/components/file-explorer-header/helper.esm.js +64 -0
- package/dist/components/file-explorer-header/helper.esm.js.map +1 -0
- package/dist/components/file-explorer-header/types.d.ts +2 -0
- package/dist/components/file-explorer-header/types.d.ts.map +1 -0
- package/dist/components/header/Header.cjs.js +1 -1
- package/dist/components/header/Header.cjs.js.map +1 -1
- package/dist/components/header/Header.esm.js +3 -3
- package/dist/components/navbar/Navbar.cjs.js +1 -1
- package/dist/components/navbar/Navbar.cjs.js.map +1 -1
- package/dist/components/navbar/Navbar.esm.js +3 -3
- package/dist/components/resource-actions-menu/DeleteResourceDialog.cjs.js +16 -0
- package/dist/components/resource-actions-menu/DeleteResourceDialog.cjs.js.map +1 -0
- package/dist/components/resource-actions-menu/DeleteResourceDialog.d.ts +8 -0
- package/dist/components/resource-actions-menu/DeleteResourceDialog.d.ts.map +1 -0
- package/dist/components/resource-actions-menu/DeleteResourceDialog.esm.js +215 -0
- package/dist/components/resource-actions-menu/DeleteResourceDialog.esm.js.map +1 -0
- package/dist/components/resource-actions-menu/ResourceActionsMenu.cjs.js +18 -0
- package/dist/components/resource-actions-menu/ResourceActionsMenu.cjs.js.map +1 -0
- package/dist/components/resource-actions-menu/ResourceActionsMenu.d.ts +16 -0
- package/dist/components/resource-actions-menu/ResourceActionsMenu.d.ts.map +1 -0
- package/dist/components/resource-actions-menu/ResourceActionsMenu.esm.js +260 -0
- package/dist/components/resource-actions-menu/ResourceActionsMenu.esm.js.map +1 -0
- package/dist/dashboard/basicPreferences.cjs.js +1 -1
- package/dist/dashboard/basicPreferences.cjs.js.map +1 -1
- package/dist/dashboard/dashboardPane.cjs.js +1 -1
- package/dist/dashboard/dashboardPane.cjs.js.map +1 -1
- package/dist/home/homePane.cjs.js +1 -1
- package/dist/home/homePane.cjs.js.map +1 -1
- package/dist/internal/internalPane2.cjs.js +1 -1
- package/dist/internal/internalPane2.cjs.js.map +1 -1
- package/dist/mainPage/header.cjs.js +1 -1
- package/dist/mainPage/header.cjs.js.map +1 -1
- package/dist/n3Pane2.cjs.js +1 -1
- package/dist/n3Pane2.esm.js +1 -1
- package/dist/outline/manager2.cjs.js +1 -2
- package/dist/outline/manager2.cjs.js.map +1 -1
- package/dist/outline/manager2.esm.js +356 -397
- package/dist/outline/manager2.esm.js.map +1 -1
- package/dist/outline/propertyViews.cjs.js +1 -1
- package/dist/outline/propertyViews.cjs.js.map +1 -1
- package/dist/outline/sourcePaneIcon.d.ts +2 -0
- package/dist/outline/sourcePaneIcon.d.ts.map +1 -0
- package/dist/outline/userInput.cjs.js +1 -1
- package/dist/outline/userInput.cjs.js.map +1 -1
- package/dist/outline/userInput.esm.js +6 -4
- package/dist/outline/userInput.esm.js.map +1 -1
- package/dist/pad/padPane2.cjs.js +1 -1
- package/dist/pad/padPane2.cjs.js.map +1 -1
- package/dist/sharing/sharingPane.cjs.js +1 -1
- package/dist/sharing/sharingPane.cjs.js.map +1 -1
- package/dist/social/editProfileDetails.cjs.js +1 -1
- package/dist/social/editProfileDetails.cjs.js.map +1 -1
- package/dist/social/editProfileDetails.esm.js +1 -1
- package/dist/social/socialPane2.cjs.js +1 -1
- package/dist/social/socialPane2.cjs.js.map +1 -1
- package/dist/social/socialSections.cjs.js +1 -1
- package/dist/social/socialSections.cjs.js.map +1 -1
- package/dist/social/socialSections.esm.js +7 -6
- package/dist/social/socialSections.esm.js.map +1 -1
- package/dist/social/triage.cjs.js +1 -1
- package/dist/social/triage.cjs.js.map +1 -1
- package/dist/tabbed/tabbedPane.cjs.js +1 -1
- package/dist/tabbed/tabbedPane.cjs.js.map +1 -1
- package/dist/trustedApplications/trustedApplications.dom.cjs.js +1 -1
- package/dist/trustedApplications/trustedApplications.dom.cjs.js.map +1 -1
- package/dist/trustedApplications/trustedApplications.utils.cjs.js +1 -1
- package/dist/trustedApplications/trustedApplications.utils.cjs.js.map +1 -1
- package/dist/trustedApplications/trustedApplications.view.cjs.js +1 -1
- package/dist/trustedApplications/trustedApplications.view.cjs.js.map +1 -1
- package/dist/utils/podUtils.cjs.js +1 -1
- package/dist/utils/podUtils.cjs.js.map +1 -1
- package/dist/utils/webIdUtils.cjs.js +1 -1
- package/dist/utils/webIdUtils.cjs.js.map +1 -1
- package/dist/versionInfo.cjs.js +1 -1
- package/dist/versionInfo.cjs.js.map +1 -1
- package/dist/versionInfo.esm.js +3 -3
- package/dist/versionInfo.esm.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socialPane2.cjs.js","names":[],"sources":["../../src/social/socialPane.ts"],"sourcesContent":["/* Social Pane\n **\n ** This outline pane provides social network functions\n ** Using for example the FOAF ontology.\n ** Goal: A *distributed* version of facebook, advogato, etc etc\n ** - Similarly easy user interface, but data storage distributed\n ** - Read and write both user-private (address book) and public data clearly\n ** -- todo: use common code to get username and load profile and set 'me'\n */\n\nimport './socialPane.css'\nimport { icons, utils, ns, log, widgets } from 'solid-ui'\nimport { authn } from 'solid-logic'\nimport { LiveStore, NamedNode, Statement } from 'rdflib'\nimport { DataBrowserContext } from 'pane-registry'\nimport { locationIcon } from './icons'\nimport {\n createAllFriendsSection,\n createHeaderSection,\n FriendRowRenderers,\n createMutualSection,\n createRequestsSection,\n HeaderControls,\n SocialHeaderElement\n} from './socialSections'\nimport type { ViewerMode } from './socialSections'\nimport { FriendshipTriage, loadFriendshipTriage, triageFriends } from './triage'\n\nfunction applyEnvironmentAttributes (\n element: HTMLElement,\n context: DataBrowserContext\n): void {\n const layout = context.environment?.layout ?? 'desktop'\n const theme = context.environment?.theme ?? 'light'\n const inputMode = context.environment?.inputMode ?? 'pointer'\n\n element.classList.add('social-pane-host')\n element.dataset.layout = layout\n element.dataset.theme = theme\n element.dataset.inputMode = inputMode\n}\n\nexport const socialPane = {\n icon: icons.originalIconBase + 'foaf/foafTiny.gif',\n\n name: 'social',\n\n label: function (subject, context) {\n const kb = context.session.store\n const types = kb.findTypeURIs(subject)\n if (\n types[ns.foaf('Person').uri] ||\n types[ns.vcard('Individual').uri]\n ) {\n return 'Friends'\n }\n return null\n },\n global: false,\n\n render: function (s, context) {\n const dom = context.dom\n const common = function (x: NamedNode[], y: NamedNode[]) {\n // Find common members of two lists\n const both: NamedNode[] = []\n for (let i = 0; i < x.length; i++) {\n for (let j = 0; j < y.length; j++) {\n if (y[j].sameTerm(x[i])) {\n both.push(y[j])\n break\n }\n }\n }\n return both\n }\n\n const uniqueNodes = function (nodes: NamedNode[]) {\n const seen = new Set<string>()\n const unique: NamedNode[] = []\n for (const node of nodes) {\n if (!node?.value || seen.has(node.value)) continue\n seen.add(node.value)\n unique.push(node)\n }\n return unique\n }\n\n const link = function (contents: Node, uri: string | null | undefined) {\n if (!uri) return contents\n const a = dom.createElement('a')\n a.setAttribute('href', uri)\n a.appendChild(contents)\n return a\n }\n\n const text = function (str: string) {\n return dom.createTextNode(str)\n }\n\n let refreshRelationshipUi = function () {}\n\n const buildCheckboxForm = function (\n lab: string | Node,\n statement: Statement,\n state: boolean,\n options: { disabled?: boolean, disabledTitle?: string } = {}\n ) {\n const f = dom.createElement('form')\n const label = dom.createElement('label')\n const input = dom.createElement('input')\n const tx = dom.createElement('span')\n tx.className = 'question'\n if (typeof lab === 'string') {\n tx.textContent = lab\n } else {\n tx.appendChild(lab)\n }\n input.setAttribute('type', 'checkbox')\n if (options.disabled) {\n input.disabled = true\n if (options.disabledTitle) {\n input.title = options.disabledTitle\n input.setAttribute('aria-label', options.disabledTitle)\n }\n }\n label.appendChild(tx)\n label.appendChild(input)\n f.appendChild(label)\n const boxHandler = function (this: HTMLInputElement, _e: Event) {\n if (this.checked) {\n try {\n outliner.UserInput.sparqler.insert_statement(statement, function (\n uri,\n success,\n errorBody\n ) {\n tx.className = 'question'\n if (!success) {\n log.alert(\n 'Error occurs while inserting ' +\n statement +\n '\\n\\n' +\n errorBody\n )\n input.checked = false // rollback UI\n return\n }\n kb.add(\n statement.subject,\n statement.predicate,\n statement.object,\n statement.why\n )\n refreshRelationshipUi()\n })\n } catch (e) {\n log.error('Data write fails:' + e)\n log.alert('Data write fails:' + e)\n input.checked = false // rollback UI\n tx.className = 'question'\n }\n } else {\n try {\n outliner.UserInput.sparqler.delete_statement(statement, function (\n uri,\n success,\n errorBody\n ) {\n tx.className = 'question'\n if (!success) {\n log.alert(\n 'Error occurs while deleting ' +\n statement +\n '\\n\\n' +\n errorBody\n )\n input.checked = true // Rollback UI\n } else {\n kb.removeMany(\n statement.subject,\n statement.predicate,\n statement.object,\n statement.why\n )\n refreshRelationshipUi()\n }\n })\n } catch (e) {\n log.alert('Delete fails:' + e)\n input.checked = true // Rollback UI\n // return\n }\n }\n }\n input.checked = state\n input.addEventListener('click', boxHandler, false)\n return f\n }\n\n // ////////// Body of render():\n\n const outliner = context.getOutliner(dom)\n const kb = context.session.store\n const socialPane = dom.createElement('div')\n socialPane.classList.add('social-pane', 'flex-column', 'gap-xxs')\n applyEnvironmentAttributes(socialPane, context)\n const foaf = ns.foaf\n const vcard = ns.vcard\n const me = authn.currentUser()\n const meUri = me ? me.uri : null\n\n const thisIsYou = me && kb.sameThings(me, s)\n\n const knows = foaf('knows')\n // var givenName = kb.sym('http://www.w3.org/2000/10/swap/pim/contact#givenName')\n const familiar =\n kb.anyValue(s, foaf('givenname')) ||\n kb.anyValue(s, foaf('firstName')) ||\n kb.anyValue(s, foaf('nick')) ||\n kb.anyValue(s, foaf('name')) ||\n kb.anyValue(s, vcard('fn'))\n const friends = kb.each(s, knows)\n const uniqueFriends = uniqueNodes(friends as NamedNode[])\n const myFriends = me ? uniqueNodes(kb.each(me, foaf('knows')) as NamedNode[]) : []\n const mutualConnections = me && !thisIsYou\n ? uniqueNodes(common(uniqueFriends, myFriends)).filter(friend => !kb.sameThings(friend, me))\n : []\n const mutualFriendCount = me && !thisIsYou ? mutualConnections.length : null\n const viewerMode = getViewerMode(s, me)\n\n // Do I have a public profile document?\n let profile: NamedNode | null = null // This could be SPARQL { ?me foaf:primaryTopic [ a foaf:PersonalProfileDocument ] }\n let editable = false\n let incoming: boolean | NamedNode[] = false\n let outgoing: boolean | NamedNode[] = false\n\n const structure = socialPane.appendChild(dom.createElement('div'))\n structure.className = 'social-layout'\n const primary = structure.appendChild(dom.createElement('div'))\n primary.className = 'social-primary'\n\n const tabs = primary.appendChild(dom.createElement('div'))\n tabs.classList.add('social-primary__tabs', 'flex-center')\n tabs.setAttribute('role', 'tablist')\n tabs.setAttribute('aria-label', 'Social sections')\n\n const allFriendsTab = tabs.appendChild(dom.createElement('button'))\n allFriendsTab.className = 'social-primary__tab'\n allFriendsTab.type = 'button'\n allFriendsTab.id = 'social-tab-all-friends'\n allFriendsTab.textContent = 'All Friends'\n allFriendsTab.setAttribute('role', 'tab')\n allFriendsTab.setAttribute('aria-controls', 'social-panel-all-friends')\n allFriendsTab.setAttribute('aria-selected', 'true')\n allFriendsTab.tabIndex = 0\n\n const mutualTab = tabs.appendChild(dom.createElement('button'))\n mutualTab.className = 'social-primary__tab'\n mutualTab.type = 'button'\n mutualTab.id = 'social-tab-mutual'\n mutualTab.textContent = 'Mutual'\n mutualTab.setAttribute('role', 'tab')\n mutualTab.setAttribute('aria-controls', 'social-panel-mutual')\n mutualTab.setAttribute('aria-selected', 'false')\n mutualTab.tabIndex = -1\n\n if (me) {\n // The definition of FOAF personal profile document is ..\n const works = kb.each(undefined, foaf('primaryTopic'), me) // having me as primary topic\n let message = ''\n for (let i = 0; i < works.length; i++) {\n if (\n kb.whether(\n works[i],\n ns.rdf('type'),\n foaf('PersonalProfileDocument')\n )\n ) {\n const doc = works[i]\n editable = outliner.UserInput.sparqler.editable(doc.uri, kb)\n if (!editable) {\n message +=\n 'Your profile <' +\n utils.escapeForXML(doc.uri) +\n '> is not remotely editable.'\n } else {\n profile = doc\n break\n }\n }\n }\n\n /*\n if (!profile) {\n say(\n message + '\\nI couldn\\'t find your editable personal profile document.'\n )\n } else {\n say('Editing your profile ' + profile + '.')\n editable = outliner.UserInput.sparqler.editable(profile.uri, kb)\n }\n */\n\n if (thisIsYou) {\n // This is about me\n // pass... @@\n } else {\n // This is about someone else\n // My relationship with this person\n\n const cme = kb.canon(me)\n incoming = kb.whether(s, knows, cme)\n outgoing = false\n const outgoingSt = kb.statementsMatching(cme, knows, s)\n if (outgoingSt.length) {\n outgoing = true\n if (!profile) profile = outgoingSt[0].why\n }\n } // About someone else\n } // me is defined\n // End of you and s\n\n const shouldShowHeaderAddFriendAction = (mode: ViewerMode) => {\n return mode === 'authenticated' && !thisIsYou && !outgoing\n }\n\n const canEditOwnedProfile = viewerMode === 'owner' && editable\n const canManageRelationship = viewerMode === 'authenticated' && !thisIsYou && editable && Boolean(profile)\n const canModifyFriendsTab = canEditOwnedProfile\n\n let headerControls: HeaderControls = {\n canEdit: canEditOwnedProfile,\n viewerMode,\n showAddFriendAction: shouldShowHeaderAddFriendAction(viewerMode)\n }\n\n const header = createHeaderSection(context, s, headerControls, {\n friendCount: uniqueFriends.length,\n mutualFriendCount,\n onSelectFriends: function () {\n setActivePanel('all-friends')\n },\n onSelectMutual: typeof mutualFriendCount === 'number'\n ? function () {\n setActivePanel('mutual')\n }\n : undefined\n }, function () {\n return selectProfileData(context, s)\n })\n header.classList.add('social-pane__header-section', 'flex-column')\n socialPane.prepend(header)\n\n // div.appendChild(dom.createTextNode(plural(friends.length, 'acquaintance') +'. '))\n\n // ///////////////////////////////////////////// Main block\n //\n // Should: Find the intersection and difference sets\n\n const friendDetailsByUri = new Map<string, FriendDetails>()\n\n const hydrateFriendDetailsCache = function (friendNodes: NamedNode[]) {\n const nextCache = new Map<string, FriendDetails>()\n\n friendNodes.forEach(friendNode => {\n if (!friendNode?.value || friendNode.value === s.value) return\n nextCache.set(friendNode.value, toFriendDetails(kb, friendNode))\n })\n\n friendDetailsByUri.clear()\n nextCache.forEach((value, key) => {\n friendDetailsByUri.set(key, value)\n })\n }\n\n hydrateFriendDetailsCache(uniqueFriends)\n\n const renderSupportingInfo: FriendRowRenderers['renderSupportingInfo'] = function (target: NamedNode, renderDom: HTMLDocument) {\n const friend = friendDetailsByUri.get(target.value) || toFriendDetails(kb, target)\n friendDetailsByUri.set(target.value, friend)\n\n const container = renderDom.createElement('div')\n const jobAndOrganization = [friend.jobTitle, friend.organization].filter(Boolean).join(' | ')\n if (jobAndOrganization) {\n const jobLine = container.appendChild(renderDom.createElement('div'))\n jobLine.className = 'social-friend-job-org'\n jobLine.textContent = jobAndOrganization\n }\n\n if (friend.location) {\n const locationLine = container.appendChild(renderDom.createElement('div'))\n locationLine.className = 'social-friend-location'\n locationLine.innerHTML = `${locationIcon} ${friend.location}`\n }\n\n if (!container.childNodes.length) return null\n\n return container\n }\n\n const renderNameSuffix: FriendRowRenderers['renderNameSuffix'] = function (target: NamedNode, renderDom: HTMLDocument) {\n const friend = friendDetailsByUri.get(target.value) || toFriendDetails(kb, target)\n friendDetailsByUri.set(target.value, friend)\n const pronouns = friend.pronouns\n if (!pronouns) return null\n\n const suffix = renderDom.createElement('span')\n suffix.className = 'social-friend-pronouns'\n suffix.textContent = `(${pronouns})`\n return suffix\n }\n\n let mutualSection = me && !thisIsYou\n ? createMutualSection({\n dom,\n subject: s,\n familiar,\n me,\n meUri,\n incoming,\n outgoing,\n editable: canManageRelationship,\n profile,\n knows,\n mutualConnections,\n link,\n text,\n buildCheckboxForm,\n renderSupportingInfo,\n renderNameSuffix\n })\n : {\n section: dom.createElement('section'),\n content: dom.createElement('div'),\n refreshMutualFriends: function () {}\n }\n\n let mutualFriends = mutualSection.section\n let mutualContent = mutualSection.content\n if (!mutualFriends.className) {\n mutualFriends.className = 'social-pane__mutual-friends social-primary__panel'\n mutualFriends.id = 'social-panel-mutual'\n mutualFriends.setAttribute('role', 'tabpanel')\n mutualFriends.setAttribute('aria-labelledby', 'social-tab-mutual')\n mutualContent.className = 'social-main social-main--mutual'\n mutualFriends.appendChild(mutualContent)\n }\n primary.appendChild(mutualFriends)\n\n const allFriendsSection = createAllFriendsSection({\n dom,\n subject: s,\n profile: canModifyFriendsTab ? profile : null,\n editable: canModifyFriendsTab,\n renderSupportingInfo,\n renderNameSuffix\n })\n\n const allFriends = allFriendsSection.section\n const friendsList = allFriendsSection.friendsList\n primary.appendChild(allFriends)\n\n let requestsTriage: FriendshipTriage = triageFriends(kb, s)\n const requestsSection = createRequestsSection({\n dom,\n triage: requestsTriage,\n renderSupportingInfo,\n renderNameSuffix\n })\n const requestsPanel = requestsSection.section\n primary.appendChild(requestsPanel)\n\n const requestsTab = tabs.appendChild(dom.createElement('button'))\n requestsTab.className = 'social-primary__tab'\n requestsTab.type = 'button'\n requestsTab.id = 'social-tab-requests'\n requestsTab.textContent = 'Requests'\n requestsTab.setAttribute('role', 'tab')\n requestsTab.setAttribute('aria-controls', 'social-panel-requests')\n requestsTab.setAttribute('aria-selected', 'false')\n requestsTab.tabIndex = -1\n\n type SocialPanel = 'mutual' | 'all-friends' | 'requests'\n let activePanel: SocialPanel = 'all-friends'\n let showRequestsTab = viewerMode === 'owner'\n\n const setActivePanel = function (panel: SocialPanel) {\n activePanel = panel\n const showMutual = panel === 'mutual'\n const showAllFriends = panel === 'all-friends'\n const showRequests = showRequestsTab && panel === 'requests'\n mutualTab.classList.toggle('social-primary__tab--active', showMutual)\n mutualTab.setAttribute('aria-selected', String(showMutual))\n mutualTab.tabIndex = showMutual ? 0 : -1\n\n allFriendsTab.classList.toggle('social-primary__tab--active', showAllFriends)\n allFriendsTab.setAttribute('aria-selected', String(showAllFriends))\n allFriendsTab.tabIndex = showAllFriends ? 0 : -1\n\n requestsTab.classList.toggle('social-primary__tab--active', showRequests)\n requestsTab.setAttribute('aria-selected', String(showRequests))\n requestsTab.tabIndex = showRequests ? 0 : -1\n\n mutualFriends.classList.toggle('social-primary__panel--active', showMutual)\n mutualFriends.setAttribute('aria-hidden', String(!showMutual))\n\n allFriends.classList.toggle('social-primary__panel--active', showAllFriends)\n allFriends.setAttribute('aria-hidden', String(!showAllFriends))\n\n requestsPanel.classList.toggle('social-primary__panel--active', showRequests)\n requestsPanel.setAttribute('aria-hidden', String(!showRequests))\n requestsPanel.hidden = !showRequestsTab || !showRequests\n }\n const rebuildMutualSection = function () {\n if (!me || thisIsYou) return\n\n const cme = kb.canon(me)\n incoming = kb.whether(s, knows, cme)\n\n const outgoingStatements = kb.statementsMatching(cme, knows, s)\n outgoing = outgoingStatements.length > 0\n\n const nextMutualSection = createMutualSection({\n dom,\n subject: s,\n familiar,\n me,\n meUri,\n incoming,\n outgoing,\n editable: canManageRelationship,\n profile,\n knows,\n mutualConnections,\n link,\n text,\n buildCheckboxForm,\n renderSupportingInfo,\n renderNameSuffix\n })\n\n mutualFriends.replaceWith(nextMutualSection.section)\n mutualSection = nextMutualSection\n mutualFriends = nextMutualSection.section\n mutualContent = nextMutualSection.content\n }\n\n refreshRelationshipUi = function () {\n rebuildMutualSection()\n headerControls = {\n ...headerControls,\n showAddFriendAction: shouldShowHeaderAddFriendAction(headerControls.viewerMode)\n }\n ;(header as SocialHeaderElement).refreshSocialHeader?.(headerControls)\n requestsTriage = triageFriends(kb, s)\n requestsSection.refreshRequests(requestsTriage)\n setActivePanel(activePanel)\n }\n\n setActivePanel('all-friends')\n\n const applyViewerMode = function (mode: ViewerMode) {\n const showMutualTab = mode === 'authenticated' && !thisIsYou\n showRequestsTab = mode === 'owner'\n mutualTab.hidden = !showMutualTab\n requestsTab.hidden = !showRequestsTab\n if (!showRequestsTab && activePanel === 'requests') {\n setActivePanel('all-friends')\n return\n }\n setActivePanel('all-friends')\n }\n\n mutualTab.addEventListener('click', function () {\n setActivePanel('mutual')\n })\n\n allFriendsTab.addEventListener('click', function () {\n setActivePanel('all-friends')\n })\n\n requestsTab.addEventListener('click', function () {\n setActivePanel('requests')\n })\n\n const refreshFriendsList = function () {\n const refresh = (friendsList as HTMLTableElement & { refresh?: () => void }).refresh\n if (typeof refresh !== 'function') return\n\n refresh.call(friendsList)\n }\n\n const refreshMutualFriends = function () {\n mutualSection.refreshMutualFriends()\n }\n\n ;(async () => {\n try {\n for await (const streamedFriends of streamFriends(context, s)) {\n friendDetailsByUri.clear()\n streamedFriends.forEach(friend => {\n friendDetailsByUri.set(friend.url, friend)\n })\n refreshFriendsList()\n refreshMutualFriends()\n }\n } catch {\n // Keep the initial snapshot if async friend loading fails.\n }\n })()\n\n ;(async () => {\n try {\n requestsTriage = await loadFriendshipTriage(context, s)\n requestsSection.refreshRequests(requestsTriage)\n refreshFriendsList()\n refreshMutualFriends()\n } catch {\n // Keep the initial requests snapshot if additional loading fails.\n }\n })()\n\n // Older triage logic is preserved below as a reusable data helper.\n\n applyViewerMode('anonymous')\n\n authn.checkUser()\n .then(webId => {\n const confirmedViewerMode = getViewerMode(s, webId)\n applyViewerMode(confirmedViewerMode)\n const confirmedCanEditOwnedProfile = confirmedViewerMode === 'owner' && editable\n headerControls = {\n ...headerControls,\n canEdit: confirmedCanEditOwnedProfile,\n viewerMode: confirmedViewerMode,\n showAddFriendAction: shouldShowHeaderAddFriendAction(confirmedViewerMode)\n }\n ;(header as SocialHeaderElement).refreshSocialHeader?.(headerControls)\n })\n .catch(() => {\n applyViewerMode('anonymous')\n headerControls = {\n ...headerControls,\n canEdit: false,\n viewerMode: 'anonymous',\n showAddFriendAction: false\n }\n ;(header as SocialHeaderElement).refreshSocialHeader?.(headerControls)\n })\n\n return socialPane\n } // render()\n} //\n// ends\n// ***************** Social Pane Selectors **********/\n/* Should move to another file, but will leave for now */\n/* Will create a social pane folder or maybe repo later */\n\nconst FRIEND_BATCH_SIZE = 3\n\nexport interface ProfileDetails {\n url: string\n imageUrl?: string\n name?: string\n nickname?: string\n jobTitle?: string\n organization?: string\n location?: string | null\n pronouns?: string\n birthdate?: string\n}\n\nexport interface FriendDetails extends ProfileDetails {\n subjectNode: NamedNode\n}\n\n/* pronounsAsText and formatLocation were copied from HeadingSection selectors */\nexport function pronounsAsText (store: LiveStore, subject: NamedNode): string {\n let pronouns = store.anyJS(subject, ns.solid('preferredSubjectPronoun')) || ''\n if (pronouns) {\n const them = store.anyJS(subject, ns.solid('preferredObjectPronoun'))\n if (them) {\n pronouns += '/' + them\n }\n }\n return pronouns || ''\n}\n\nfunction formatLocation (countryName: string | void, locality: string | void) {\n return countryName && locality\n ? `${locality}, ${countryName}`\n : countryName || locality || null\n}\n\nfunction toFriendDetails (store: any, friendNode: NamedNode): FriendDetails {\n const name =\n store.anyValue(friendNode, ns.vcard('fn')) ||\n store.anyValue(friendNode, ns.foaf('name')) ||\n null\n const nickname =\n store.anyValue(friendNode, ns.vcard('nickname')) ||\n store.anyValue(friendNode, ns.foaf('nick')) ||\n null\n const dateOfBirth = store.anyValue(friendNode, ns.vcard('bday')) || null\n const imageSrc = widgets.findImage(friendNode)\n const jobTitle = store.anyValue(friendNode, ns.vcard('role')) || null\n const orgName = store.anyValue(friendNode, ns.vcard('organization-name')) || null\n const primaryAddressEntryNode = store.any(friendNode, ns.vcard('hasAddress')) as NamedNode | null\n const address: NamedNode | null = primaryAddressEntryNode || null\n const countryName =\n address != null\n ? store.anyValue(address, ns.vcard('country-name'))\n : null\n const locality =\n address != null\n ? store.anyValue(address, ns.vcard('locality'))\n : null\n\n const location = formatLocation(countryName, locality)\n const pronouns = pronounsAsText(store, friendNode)\n\n return {\n url: friendNode.value,\n imageUrl: imageSrc,\n name,\n nickname,\n jobTitle,\n organization: orgName,\n birthdate: dateOfBirth,\n location,\n pronouns,\n subjectNode: friendNode\n }\n}\n\nexport async function * streamFriends (\n context: DataBrowserContext,\n subject: NamedNode,\n batchSize = FRIEND_BATCH_SIZE\n): AsyncGenerator<FriendDetails[], void, void> {\n const store = context.session.store\n const fetcher = (store as any)?.fetcher\n\n if (fetcher && typeof fetcher.load === 'function') {\n try {\n await fetcher.load(subject.doc())\n } catch {\n // Continue with whatever is already in the store.\n }\n }\n\n const seen = new Set<string>()\n const friendNodes = store.each(subject, ns.foaf('knows'), null, subject.doc())\n const uniqueFriendNodes: NamedNode[] = []\n\n for (const friendNode of friendNodes) {\n const key = friendNode?.value\n if (!key || seen.has(key) || subject.value === key) continue\n seen.add(key)\n uniqueFriendNodes.push(friendNode as NamedNode)\n }\n\n const friends: FriendDetails[] = []\n\n for (const friendNode of uniqueFriendNodes) {\n if (fetcher && typeof fetcher.load === 'function') {\n try {\n await fetcher.load(friendNode.doc())\n } catch {\n // Keep partial friend data when one linked document fails to load.\n }\n }\n\n friends.push(toFriendDetails(store, friendNode))\n\n if (friends.length % batchSize === 0) {\n yield [...friends]\n }\n }\n\n if (friends.length > 0 && friends.length % batchSize !== 0) {\n yield [...friends]\n }\n}\n\nexport async function extractFriends (context: DataBrowserContext, subject: NamedNode): Promise<FriendDetails[] | null> {\n let latestFriends: FriendDetails[] | null = null\n\n for await (const friends of streamFriends(context, subject)) {\n latestFriends = friends\n }\n\n return latestFriends\n}\n\nexport function selectProfileData (context: DataBrowserContext, subject: NamedNode): ProfileDetails | null {\n const store = context.session.store\n\n const name =\n store.anyValue(subject, ns.vcard('fn')) ||\n store.anyValue(subject, ns.foaf('name')) ||\n undefined\n const nickname =\n store.anyValue(subject, ns.vcard('nickname')) ||\n store.anyValue(subject, ns.foaf('nick')) ||\n undefined\n const dateOfBirth = store.anyValue(subject, ns.vcard('bday')) || undefined\n const imageSrc = widgets.findImage(subject)\n const jobTitle = store.anyValue(subject, ns.vcard('role')) || undefined\n const orgName = store.anyValue(subject, ns.vcard('organization-name')) || undefined\n const primaryAddressEntryNode = store.any(subject, ns.vcard('hasAddress')) as NamedNode | null\n const address: NamedNode | null = primaryAddressEntryNode || null\n const countryName =\n address != null\n ? store.anyValue(address, ns.vcard('country-name'))\n : undefined\n const locality =\n address != null\n ? store.anyValue(address, ns.vcard('locality'))\n : undefined\n\n const location = formatLocation(countryName, locality)\n const pronouns = pronounsAsText(store, subject)\n return {\n url: subject.value,\n imageUrl: imageSrc,\n name,\n nickname,\n jobTitle,\n organization: orgName,\n birthdate: dateOfBirth,\n location,\n pronouns\n }\n}\n\nexport type { ViewerMode } from './socialSections'\n\nfunction getViewerMode (subject: NamedNode, currentUser: unknown = authn.currentUser()): ViewerMode {\n const currentUserUri =\n typeof currentUser === 'string'\n ? currentUser\n : typeof currentUser === 'object' && currentUser !== null\n ? ((currentUser as { value?: string, uri?: string }).value ||\n (currentUser as { value?: string, uri?: string }).uri ||\n null)\n : null\n let mode: ViewerMode = 'anonymous'\n if (currentUserUri === subject.value) mode = 'owner'\n if (currentUserUri && currentUserUri !== subject.value) mode = 'authenticated'\n return mode\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"socialPane2.cjs.js","names":[],"sources":["../../src/social/socialPane.ts"],"sourcesContent":["/* Social Pane\n **\n ** This outline pane provides social network functions\n ** Using for example the FOAF ontology.\n ** Goal: A *distributed* version of facebook, advogato, etc etc\n ** - Similarly easy user interface, but data storage distributed\n ** - Read and write both user-private (address book) and public data clearly\n ** -- todo: use common code to get username and load profile and set 'me'\n */\n\nimport './socialPane.css'\nimport { icons, utils, ns, log, widgets } from 'solid-ui'\nimport { authn } from 'solid-logic'\nimport { LiveStore, NamedNode, Statement } from 'rdflib'\nimport { DataBrowserContext } from 'pane-registry'\nimport { locationIcon } from './icons'\nimport {\n createAllFriendsSection,\n createHeaderSection,\n FriendRowRenderers,\n createMutualSection,\n createRequestsSection,\n HeaderControls,\n SocialHeaderElement\n} from './socialSections'\nimport type { ViewerMode } from './socialSections'\nimport { FriendshipTriage, loadFriendshipTriage, triageFriends } from './triage'\n\nfunction applyEnvironmentAttributes (\n element: HTMLElement,\n context: DataBrowserContext\n): void {\n const layout = context.environment?.layout ?? 'desktop'\n const theme = context.environment?.theme ?? 'light'\n const inputMode = context.environment?.inputMode ?? 'pointer'\n\n element.classList.add('social-pane-host')\n element.dataset.layout = layout\n element.dataset.theme = theme\n element.dataset.inputMode = inputMode\n}\n\nexport const socialPane = {\n icon: icons.originalIconBase + 'foaf/foafTiny.gif',\n\n name: 'social',\n\n label: function (subject, context) {\n const kb = context.session.store\n const types = kb.findTypeURIs(subject)\n if (\n types[ns.foaf('Person').uri] ||\n types[ns.vcard('Individual').uri]\n ) {\n return 'Friends'\n }\n return null\n },\n global: false,\n\n render: function (s, context) {\n const dom = context.dom\n const common = function (x: NamedNode[], y: NamedNode[]) {\n // Find common members of two lists\n const both: NamedNode[] = []\n for (let i = 0; i < x.length; i++) {\n for (let j = 0; j < y.length; j++) {\n if (y[j].sameTerm(x[i])) {\n both.push(y[j])\n break\n }\n }\n }\n return both\n }\n\n const uniqueNodes = function (nodes: NamedNode[]) {\n const seen = new Set<string>()\n const unique: NamedNode[] = []\n for (const node of nodes) {\n if (!node?.value || seen.has(node.value)) continue\n seen.add(node.value)\n unique.push(node)\n }\n return unique\n }\n\n const link = function (contents: Node, uri: string | null | undefined) {\n if (!uri) return contents\n const a = dom.createElement('a')\n a.setAttribute('href', uri)\n a.appendChild(contents)\n return a\n }\n\n const text = function (str: string) {\n return dom.createTextNode(str)\n }\n\n let refreshRelationshipUi = function () {}\n\n const buildCheckboxForm = function (\n lab: string | Node,\n statement: Statement,\n state: boolean,\n options: { disabled?: boolean, disabledTitle?: string } = {}\n ) {\n const f = dom.createElement('form')\n const label = dom.createElement('label')\n const input = dom.createElement('input')\n const tx = dom.createElement('span')\n tx.className = 'question'\n if (typeof lab === 'string') {\n tx.textContent = lab\n } else {\n tx.appendChild(lab)\n }\n input.setAttribute('type', 'checkbox')\n if (options.disabled) {\n input.disabled = true\n if (options.disabledTitle) {\n input.title = options.disabledTitle\n input.setAttribute('aria-label', options.disabledTitle)\n }\n }\n label.appendChild(tx)\n label.appendChild(input)\n f.appendChild(label)\n const boxHandler = function (this: HTMLInputElement, _e: Event) {\n if (this.checked) {\n try {\n outliner.UserInput.sparqler.insert_statement(statement, function (\n uri,\n success,\n errorBody\n ) {\n tx.className = 'question'\n if (!success) {\n log.alert(\n 'Error occurs while inserting ' +\n statement +\n '\\n\\n' +\n errorBody\n )\n input.checked = false // rollback UI\n return\n }\n kb.add(\n statement.subject,\n statement.predicate,\n statement.object,\n statement.why\n )\n refreshRelationshipUi()\n })\n } catch (e) {\n log.error('Data write fails:' + e)\n log.alert('Data write fails:' + e)\n input.checked = false // rollback UI\n tx.className = 'question'\n }\n } else {\n try {\n outliner.UserInput.sparqler.delete_statement(statement, function (\n uri,\n success,\n errorBody\n ) {\n tx.className = 'question'\n if (!success) {\n log.alert(\n 'Error occurs while deleting ' +\n statement +\n '\\n\\n' +\n errorBody\n )\n input.checked = true // Rollback UI\n } else {\n kb.removeMany(\n statement.subject,\n statement.predicate,\n statement.object,\n statement.why\n )\n refreshRelationshipUi()\n }\n })\n } catch (e) {\n log.alert('Delete fails:' + e)\n input.checked = true // Rollback UI\n // return\n }\n }\n }\n input.checked = state\n input.addEventListener('click', boxHandler, false)\n return f\n }\n\n // ////////// Body of render():\n\n const outliner = context.getOutliner(dom)\n const kb = context.session.store\n const socialPane = dom.createElement('div')\n socialPane.classList.add('social-pane', 'flex-column', 'gap-xxs')\n applyEnvironmentAttributes(socialPane, context)\n const foaf = ns.foaf\n const vcard = ns.vcard\n const me = authn.currentUser()\n const meUri = me ? me.uri : null\n\n const thisIsYou = me && kb.sameThings(me, s)\n\n const knows = foaf('knows')\n // var givenName = kb.sym('http://www.w3.org/2000/10/swap/pim/contact#givenName')\n const familiar =\n kb.anyValue(s, foaf('givenname')) ||\n kb.anyValue(s, foaf('firstName')) ||\n kb.anyValue(s, foaf('nick')) ||\n kb.anyValue(s, foaf('name')) ||\n kb.anyValue(s, vcard('fn'))\n const friends = kb.each(s, knows)\n const uniqueFriends = uniqueNodes(friends as NamedNode[])\n const myFriends = me ? uniqueNodes(kb.each(me, foaf('knows')) as NamedNode[]) : []\n const mutualConnections = me && !thisIsYou\n ? uniqueNodes(common(uniqueFriends, myFriends)).filter(friend => !kb.sameThings(friend, me))\n : []\n const mutualFriendCount = me && !thisIsYou ? mutualConnections.length : null\n const viewerMode = getViewerMode(s, me)\n\n // Do I have a public profile document?\n let profile: NamedNode | null = null // This could be SPARQL { ?me foaf:primaryTopic [ a foaf:PersonalProfileDocument ] }\n let editable = false\n let incoming: boolean | NamedNode[] = false\n let outgoing: boolean | NamedNode[] = false\n\n const structure = socialPane.appendChild(dom.createElement('div'))\n structure.className = 'social-layout'\n const primary = structure.appendChild(dom.createElement('div'))\n primary.className = 'social-primary'\n\n const tabs = primary.appendChild(dom.createElement('div'))\n tabs.classList.add('social-primary__tabs', 'flex-center')\n tabs.setAttribute('role', 'tablist')\n tabs.setAttribute('aria-label', 'Social sections')\n\n const allFriendsTab = tabs.appendChild(dom.createElement('button'))\n allFriendsTab.className = 'social-primary__tab'\n allFriendsTab.type = 'button'\n allFriendsTab.id = 'social-tab-all-friends'\n allFriendsTab.textContent = 'All Friends'\n allFriendsTab.setAttribute('role', 'tab')\n allFriendsTab.setAttribute('aria-controls', 'social-panel-all-friends')\n allFriendsTab.setAttribute('aria-selected', 'true')\n allFriendsTab.tabIndex = 0\n\n const mutualTab = tabs.appendChild(dom.createElement('button'))\n mutualTab.className = 'social-primary__tab'\n mutualTab.type = 'button'\n mutualTab.id = 'social-tab-mutual'\n mutualTab.textContent = 'Mutual'\n mutualTab.setAttribute('role', 'tab')\n mutualTab.setAttribute('aria-controls', 'social-panel-mutual')\n mutualTab.setAttribute('aria-selected', 'false')\n mutualTab.tabIndex = -1\n\n if (me) {\n // The definition of FOAF personal profile document is ..\n const works = kb.each(undefined, foaf('primaryTopic'), me) // having me as primary topic\n let message = ''\n for (let i = 0; i < works.length; i++) {\n if (\n kb.whether(\n works[i],\n ns.rdf('type'),\n foaf('PersonalProfileDocument')\n )\n ) {\n const doc = works[i]\n editable = outliner.UserInput.sparqler.editable(doc.uri, kb)\n if (!editable) {\n message +=\n 'Your profile <' +\n utils.escapeForXML(doc.uri) +\n '> is not remotely editable.'\n } else {\n profile = doc\n break\n }\n }\n }\n\n /*\n if (!profile) {\n say(\n message + '\\nI couldn\\'t find your editable personal profile document.'\n )\n } else {\n say('Editing your profile ' + profile + '.')\n editable = outliner.UserInput.sparqler.editable(profile.uri, kb)\n }\n */\n\n if (thisIsYou) {\n // This is about me\n // pass... @@\n } else {\n // This is about someone else\n // My relationship with this person\n\n const cme = kb.canon(me)\n incoming = kb.whether(s, knows, cme)\n outgoing = false\n const outgoingSt = kb.statementsMatching(cme, knows, s)\n if (outgoingSt.length) {\n outgoing = true\n if (!profile) profile = outgoingSt[0].why\n }\n } // About someone else\n } // me is defined\n // End of you and s\n\n const shouldShowHeaderAddFriendAction = (mode: ViewerMode) => {\n return mode === 'authenticated' && !thisIsYou && !outgoing\n }\n\n const canEditOwnedProfile = viewerMode === 'owner' && editable\n const canManageRelationship = viewerMode === 'authenticated' && !thisIsYou && editable && Boolean(profile)\n const canModifyFriendsTab = canEditOwnedProfile\n\n let headerControls: HeaderControls = {\n canEdit: canEditOwnedProfile,\n viewerMode,\n showAddFriendAction: shouldShowHeaderAddFriendAction(viewerMode)\n }\n\n const header = createHeaderSection(context, s, headerControls, {\n friendCount: uniqueFriends.length,\n mutualFriendCount,\n onSelectFriends: function () {\n setActivePanel('all-friends')\n },\n onSelectMutual: typeof mutualFriendCount === 'number'\n ? function () {\n setActivePanel('mutual')\n }\n : undefined\n }, function () {\n return selectProfileData(context, s)\n })\n header.classList.add('social-pane__header-section', 'flex-column')\n socialPane.prepend(header)\n\n // div.appendChild(dom.createTextNode(plural(friends.length, 'acquaintance') +'. '))\n\n // ///////////////////////////////////////////// Main block\n //\n // Should: Find the intersection and difference sets\n\n const friendDetailsByUri = new Map<string, FriendDetails>()\n\n const hydrateFriendDetailsCache = function (friendNodes: NamedNode[]) {\n const nextCache = new Map<string, FriendDetails>()\n\n friendNodes.forEach(friendNode => {\n if (!friendNode?.value || friendNode.value === s.value) return\n nextCache.set(friendNode.value, toFriendDetails(kb, friendNode))\n })\n\n friendDetailsByUri.clear()\n nextCache.forEach((value, key) => {\n friendDetailsByUri.set(key, value)\n })\n }\n\n hydrateFriendDetailsCache(uniqueFriends)\n\n const renderSupportingInfo: FriendRowRenderers['renderSupportingInfo'] = function (target: NamedNode, renderDom: HTMLDocument) {\n const friend = friendDetailsByUri.get(target.value) || toFriendDetails(kb, target)\n friendDetailsByUri.set(target.value, friend)\n\n const container = renderDom.createElement('div')\n const jobAndOrganization = [friend.jobTitle, friend.organization].filter(Boolean).join(' | ')\n if (jobAndOrganization) {\n const jobLine = container.appendChild(renderDom.createElement('div'))\n jobLine.className = 'social-friend-job-org'\n jobLine.textContent = jobAndOrganization\n }\n\n if (friend.location) {\n const locationLine = container.appendChild(renderDom.createElement('div'))\n locationLine.className = 'social-friend-location'\n locationLine.innerHTML = `${locationIcon} ${friend.location}`\n }\n\n if (!container.childNodes.length) return null\n\n return container\n }\n\n const renderNameSuffix: FriendRowRenderers['renderNameSuffix'] = function (target: NamedNode, renderDom: HTMLDocument) {\n const friend = friendDetailsByUri.get(target.value) || toFriendDetails(kb, target)\n friendDetailsByUri.set(target.value, friend)\n const pronouns = friend.pronouns\n if (!pronouns) return null\n\n const suffix = renderDom.createElement('span')\n suffix.className = 'social-friend-pronouns'\n suffix.textContent = `(${pronouns})`\n return suffix\n }\n\n let mutualSection = me && !thisIsYou\n ? createMutualSection({\n dom,\n subject: s,\n familiar,\n me,\n meUri,\n incoming,\n outgoing,\n editable: canManageRelationship,\n profile,\n knows,\n mutualConnections,\n link,\n text,\n buildCheckboxForm,\n renderSupportingInfo,\n renderNameSuffix\n })\n : {\n section: dom.createElement('section'),\n content: dom.createElement('div'),\n refreshMutualFriends: function () {}\n }\n\n let mutualFriends = mutualSection.section\n let mutualContent = mutualSection.content\n if (!mutualFriends.className) {\n mutualFriends.className = 'social-pane__mutual-friends social-primary__panel'\n mutualFriends.id = 'social-panel-mutual'\n mutualFriends.setAttribute('role', 'tabpanel')\n mutualFriends.setAttribute('aria-labelledby', 'social-tab-mutual')\n mutualContent.className = 'social-main social-main--mutual'\n mutualFriends.appendChild(mutualContent)\n }\n primary.appendChild(mutualFriends)\n\n const allFriendsSection = createAllFriendsSection({\n dom,\n subject: s,\n profile: canModifyFriendsTab ? profile : null,\n editable: canModifyFriendsTab,\n renderSupportingInfo,\n renderNameSuffix\n })\n\n const allFriends = allFriendsSection.section\n const friendsList = allFriendsSection.friendsList\n primary.appendChild(allFriends)\n\n let requestsTriage: FriendshipTriage = triageFriends(kb, s)\n const requestsSection = createRequestsSection({\n dom,\n triage: requestsTriage,\n renderSupportingInfo,\n renderNameSuffix\n })\n const requestsPanel = requestsSection.section\n primary.appendChild(requestsPanel)\n\n const requestsTab = tabs.appendChild(dom.createElement('button'))\n requestsTab.className = 'social-primary__tab'\n requestsTab.type = 'button'\n requestsTab.id = 'social-tab-requests'\n requestsTab.textContent = 'Requests'\n requestsTab.setAttribute('role', 'tab')\n requestsTab.setAttribute('aria-controls', 'social-panel-requests')\n requestsTab.setAttribute('aria-selected', 'false')\n requestsTab.tabIndex = -1\n\n type SocialPanel = 'mutual' | 'all-friends' | 'requests'\n let activePanel: SocialPanel = 'all-friends'\n let showRequestsTab = viewerMode === 'owner'\n\n const setActivePanel = function (panel: SocialPanel) {\n activePanel = panel\n const showMutual = panel === 'mutual'\n const showAllFriends = panel === 'all-friends'\n const showRequests = showRequestsTab && panel === 'requests'\n mutualTab.classList.toggle('social-primary__tab--active', showMutual)\n mutualTab.setAttribute('aria-selected', String(showMutual))\n mutualTab.tabIndex = showMutual ? 0 : -1\n\n allFriendsTab.classList.toggle('social-primary__tab--active', showAllFriends)\n allFriendsTab.setAttribute('aria-selected', String(showAllFriends))\n allFriendsTab.tabIndex = showAllFriends ? 0 : -1\n\n requestsTab.classList.toggle('social-primary__tab--active', showRequests)\n requestsTab.setAttribute('aria-selected', String(showRequests))\n requestsTab.tabIndex = showRequests ? 0 : -1\n\n mutualFriends.classList.toggle('social-primary__panel--active', showMutual)\n mutualFriends.setAttribute('aria-hidden', String(!showMutual))\n\n allFriends.classList.toggle('social-primary__panel--active', showAllFriends)\n allFriends.setAttribute('aria-hidden', String(!showAllFriends))\n\n requestsPanel.classList.toggle('social-primary__panel--active', showRequests)\n requestsPanel.setAttribute('aria-hidden', String(!showRequests))\n requestsPanel.hidden = !showRequestsTab || !showRequests\n }\n const rebuildMutualSection = function () {\n if (!me || thisIsYou) return\n\n const cme = kb.canon(me)\n incoming = kb.whether(s, knows, cme)\n\n const outgoingStatements = kb.statementsMatching(cme, knows, s)\n outgoing = outgoingStatements.length > 0\n\n const nextMutualSection = createMutualSection({\n dom,\n subject: s,\n familiar,\n me,\n meUri,\n incoming,\n outgoing,\n editable: canManageRelationship,\n profile,\n knows,\n mutualConnections,\n link,\n text,\n buildCheckboxForm,\n renderSupportingInfo,\n renderNameSuffix\n })\n\n mutualFriends.replaceWith(nextMutualSection.section)\n mutualSection = nextMutualSection\n mutualFriends = nextMutualSection.section\n mutualContent = nextMutualSection.content\n }\n\n refreshRelationshipUi = function () {\n rebuildMutualSection()\n headerControls = {\n ...headerControls,\n showAddFriendAction: shouldShowHeaderAddFriendAction(headerControls.viewerMode)\n }\n ;(header as SocialHeaderElement).refreshSocialHeader?.(headerControls)\n requestsTriage = triageFriends(kb, s)\n requestsSection.refreshRequests(requestsTriage)\n setActivePanel(activePanel)\n }\n\n setActivePanel('all-friends')\n\n const applyViewerMode = function (mode: ViewerMode) {\n const showMutualTab = mode === 'authenticated' && !thisIsYou\n showRequestsTab = mode === 'owner'\n mutualTab.hidden = !showMutualTab\n requestsTab.hidden = !showRequestsTab\n if (!showRequestsTab && activePanel === 'requests') {\n setActivePanel('all-friends')\n return\n }\n setActivePanel('all-friends')\n }\n\n mutualTab.addEventListener('click', function () {\n setActivePanel('mutual')\n })\n\n allFriendsTab.addEventListener('click', function () {\n setActivePanel('all-friends')\n })\n\n requestsTab.addEventListener('click', function () {\n setActivePanel('requests')\n })\n\n const refreshFriendsList = function () {\n const refresh = (friendsList as HTMLTableElement & { refresh?: () => void }).refresh\n if (typeof refresh !== 'function') return\n\n refresh.call(friendsList)\n }\n\n const refreshMutualFriends = function () {\n mutualSection.refreshMutualFriends()\n }\n\n ;(async () => {\n try {\n for await (const streamedFriends of streamFriends(context, s)) {\n friendDetailsByUri.clear()\n streamedFriends.forEach(friend => {\n friendDetailsByUri.set(friend.url, friend)\n })\n refreshFriendsList()\n refreshMutualFriends()\n }\n } catch {\n // Keep the initial snapshot if async friend loading fails.\n }\n })()\n\n ;(async () => {\n try {\n requestsTriage = await loadFriendshipTriage(context, s)\n requestsSection.refreshRequests(requestsTriage)\n refreshFriendsList()\n refreshMutualFriends()\n } catch {\n // Keep the initial requests snapshot if additional loading fails.\n }\n })()\n\n // Older triage logic is preserved below as a reusable data helper.\n\n applyViewerMode('anonymous')\n\n authn.checkUser()\n .then(webId => {\n const confirmedViewerMode = getViewerMode(s, webId)\n applyViewerMode(confirmedViewerMode)\n const confirmedCanEditOwnedProfile = confirmedViewerMode === 'owner' && editable\n headerControls = {\n ...headerControls,\n canEdit: confirmedCanEditOwnedProfile,\n viewerMode: confirmedViewerMode,\n showAddFriendAction: shouldShowHeaderAddFriendAction(confirmedViewerMode)\n }\n ;(header as SocialHeaderElement).refreshSocialHeader?.(headerControls)\n })\n .catch(() => {\n applyViewerMode('anonymous')\n headerControls = {\n ...headerControls,\n canEdit: false,\n viewerMode: 'anonymous',\n showAddFriendAction: false\n }\n ;(header as SocialHeaderElement).refreshSocialHeader?.(headerControls)\n })\n\n return socialPane\n } // render()\n} //\n// ends\n// ***************** Social Pane Selectors **********/\n/* Should move to another file, but will leave for now */\n/* Will create a social pane folder or maybe repo later */\n\nconst FRIEND_BATCH_SIZE = 3\n\nexport interface ProfileDetails {\n url: string\n imageUrl?: string\n name?: string\n nickname?: string\n jobTitle?: string\n organization?: string\n location?: string | null\n pronouns?: string\n birthdate?: string\n}\n\nexport interface FriendDetails extends ProfileDetails {\n subjectNode: NamedNode\n}\n\n/* pronounsAsText and formatLocation were copied from HeadingSection selectors */\nexport function pronounsAsText (store: LiveStore, subject: NamedNode): string {\n let pronouns = store.anyJS(subject, ns.solid('preferredSubjectPronoun')) || ''\n if (pronouns) {\n const them = store.anyJS(subject, ns.solid('preferredObjectPronoun'))\n if (them) {\n pronouns += '/' + them\n }\n }\n return pronouns || ''\n}\n\nfunction formatLocation (countryName: string | void, locality: string | void) {\n return countryName && locality\n ? `${locality}, ${countryName}`\n : countryName || locality || null\n}\n\nfunction toFriendDetails (store: any, friendNode: NamedNode): FriendDetails {\n const name =\n store.anyValue(friendNode, ns.vcard('fn')) ||\n store.anyValue(friendNode, ns.foaf('name')) ||\n null\n const nickname =\n store.anyValue(friendNode, ns.vcard('nickname')) ||\n store.anyValue(friendNode, ns.foaf('nick')) ||\n null\n const dateOfBirth = store.anyValue(friendNode, ns.vcard('bday')) || null\n const imageSrc = widgets.findImage(friendNode)\n const jobTitle = store.anyValue(friendNode, ns.vcard('role')) || null\n const orgName = store.anyValue(friendNode, ns.vcard('organization-name')) || null\n const primaryAddressEntryNode = store.any(friendNode, ns.vcard('hasAddress')) as NamedNode | null\n const address: NamedNode | null = primaryAddressEntryNode || null\n const countryName =\n address != null\n ? store.anyValue(address, ns.vcard('country-name'))\n : null\n const locality =\n address != null\n ? store.anyValue(address, ns.vcard('locality'))\n : null\n\n const location = formatLocation(countryName, locality)\n const pronouns = pronounsAsText(store, friendNode)\n\n return {\n url: friendNode.value,\n imageUrl: imageSrc,\n name,\n nickname,\n jobTitle,\n organization: orgName,\n birthdate: dateOfBirth,\n location,\n pronouns,\n subjectNode: friendNode\n }\n}\n\nexport async function * streamFriends (\n context: DataBrowserContext,\n subject: NamedNode,\n batchSize = FRIEND_BATCH_SIZE\n): AsyncGenerator<FriendDetails[], void, void> {\n const store = context.session.store\n const fetcher = (store as any)?.fetcher\n\n if (fetcher && typeof fetcher.load === 'function') {\n try {\n await fetcher.load(subject.doc())\n } catch {\n // Continue with whatever is already in the store.\n }\n }\n\n const seen = new Set<string>()\n const friendNodes = store.each(subject, ns.foaf('knows'), null, subject.doc())\n const uniqueFriendNodes: NamedNode[] = []\n\n for (const friendNode of friendNodes) {\n const key = friendNode?.value\n if (!key || seen.has(key) || subject.value === key) continue\n seen.add(key)\n uniqueFriendNodes.push(friendNode as NamedNode)\n }\n\n const friends: FriendDetails[] = []\n\n for (const friendNode of uniqueFriendNodes) {\n if (fetcher && typeof fetcher.load === 'function') {\n try {\n await fetcher.load(friendNode.doc())\n } catch {\n // Keep partial friend data when one linked document fails to load.\n }\n }\n\n friends.push(toFriendDetails(store, friendNode))\n\n if (friends.length % batchSize === 0) {\n yield [...friends]\n }\n }\n\n if (friends.length > 0 && friends.length % batchSize !== 0) {\n yield [...friends]\n }\n}\n\nexport async function extractFriends (context: DataBrowserContext, subject: NamedNode): Promise<FriendDetails[] | null> {\n let latestFriends: FriendDetails[] | null = null\n\n for await (const friends of streamFriends(context, subject)) {\n latestFriends = friends\n }\n\n return latestFriends\n}\n\nexport function selectProfileData (context: DataBrowserContext, subject: NamedNode): ProfileDetails | null {\n const store = context.session.store\n\n const name =\n store.anyValue(subject, ns.vcard('fn')) ||\n store.anyValue(subject, ns.foaf('name')) ||\n undefined\n const nickname =\n store.anyValue(subject, ns.vcard('nickname')) ||\n store.anyValue(subject, ns.foaf('nick')) ||\n undefined\n const dateOfBirth = store.anyValue(subject, ns.vcard('bday')) || undefined\n const imageSrc = widgets.findImage(subject)\n const jobTitle = store.anyValue(subject, ns.vcard('role')) || undefined\n const orgName = store.anyValue(subject, ns.vcard('organization-name')) || undefined\n const primaryAddressEntryNode = store.any(subject, ns.vcard('hasAddress')) as NamedNode | null\n const address: NamedNode | null = primaryAddressEntryNode || null\n const countryName =\n address != null\n ? store.anyValue(address, ns.vcard('country-name'))\n : undefined\n const locality =\n address != null\n ? store.anyValue(address, ns.vcard('locality'))\n : undefined\n\n const location = formatLocation(countryName, locality)\n const pronouns = pronounsAsText(store, subject)\n return {\n url: subject.value,\n imageUrl: imageSrc,\n name,\n nickname,\n jobTitle,\n organization: orgName,\n birthdate: dateOfBirth,\n location,\n pronouns\n }\n}\n\nexport type { ViewerMode } from './socialSections'\n\nfunction getViewerMode (subject: NamedNode, currentUser: unknown = authn.currentUser()): ViewerMode {\n const currentUserUri =\n typeof currentUser === 'string'\n ? currentUser\n : typeof currentUser === 'object' && currentUser !== null\n ? ((currentUser as { value?: string, uri?: string }).value ||\n (currentUser as { value?: string, uri?: string }).uri ||\n null)\n : null\n let mode: ViewerMode = 'anonymous'\n if (currentUserUri === subject.value) mode = 'owner'\n if (currentUserUri && currentUserUri !== subject.value) mode = 'authenticated'\n return mode\n}\n"],"mappings":"sLA4BA,SAAS,EACP,EACA,EACM,CACN,IAAM,EAAS,EAAQ,aAAa,QAAU,UACxC,EAAQ,EAAQ,aAAa,OAAS,QACtC,EAAY,EAAQ,aAAa,WAAa,UAEpD,EAAQ,UAAU,IAAI,kBAAkB,EACxC,EAAQ,QAAQ,OAAS,EACzB,EAAQ,QAAQ,MAAQ,EACxB,EAAQ,QAAQ,UAAY,CAC9B,CAEA,IAAa,EAAa,CACxB,KAAM,EAAA,MAAM,iBAAmB,oBAE/B,KAAM,SAEN,MAAO,SAAU,EAAS,EAAS,CAEjC,IAAM,EADK,EAAQ,QAAQ,MACV,aAAa,CAAO,EAOrC,OALE,EAAM,EAAA,GAAG,KAAK,QAAQ,CAAC,CAAC,MACxB,EAAM,EAAA,GAAG,MAAM,YAAY,CAAC,CAAC,KAEtB,UAEF,IACT,EACA,OAAQ,GAER,OAAQ,SAAU,EAAG,EAAS,CAC5B,IAAM,EAAM,EAAQ,IACd,EAAS,SAAU,EAAgB,EAAgB,CAEvD,IAAM,EAAoB,CAAC,EAC3B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAE,OAAQ,IAC5B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAE,OAAQ,IAC5B,GAAI,EAAE,EAAE,CAAC,SAAS,EAAE,EAAE,EAAG,CACvB,EAAK,KAAK,EAAE,EAAE,EACd,KACF,CAGJ,OAAO,CACT,EAEM,EAAc,SAAU,EAAoB,CAChD,IAAM,EAAO,IAAI,IACX,EAAsB,CAAC,EAC7B,IAAK,IAAM,KAAQ,EACb,CAAC,GAAM,OAAS,EAAK,IAAI,EAAK,KAAK,IACvC,EAAK,IAAI,EAAK,KAAK,EACnB,EAAO,KAAK,CAAI,GAElB,OAAO,CACT,EAEM,EAAO,SAAU,EAAgB,EAAgC,CACrE,GAAI,CAAC,EAAK,OAAO,EACjB,IAAM,EAAI,EAAI,cAAc,GAAG,EAG/B,OAFA,EAAE,aAAa,OAAQ,CAAG,EAC1B,EAAE,YAAY,CAAQ,EACf,CACT,EAEM,GAAO,SAAU,EAAa,CAClC,OAAO,EAAI,eAAe,CAAG,CAC/B,EAEI,EAAwB,UAAY,CAAC,EAEnC,GAAoB,SACxB,EACA,EACA,EACA,EAA0D,CAAC,EAC3D,CACA,IAAM,EAAI,EAAI,cAAc,MAAM,EAC5B,EAAQ,EAAI,cAAc,OAAO,EACjC,EAAQ,EAAI,cAAc,OAAO,EACjC,EAAK,EAAI,cAAc,MAAM,EAsFnC,MArFA,GAAG,UAAY,WACX,OAAO,GAAQ,SACjB,EAAG,YAAc,EAEjB,EAAG,YAAY,CAAG,EAEpB,EAAM,aAAa,OAAQ,UAAU,EACjC,EAAQ,WACV,EAAM,SAAW,GACb,EAAQ,gBACV,EAAM,MAAQ,EAAQ,cACtB,EAAM,aAAa,aAAc,EAAQ,aAAa,IAG1D,EAAM,YAAY,CAAE,EACpB,EAAM,YAAY,CAAK,EACvB,EAAE,YAAY,CAAK,EAmEnB,EAAM,QAAU,EAChB,EAAM,iBAAiB,QAAS,SAnEqB,EAAW,CAC9D,GAAI,KAAK,QACP,GAAI,CACF,EAAS,UAAU,SAAS,iBAAiB,EAAW,SACtD,EACA,EACA,EACA,CAEA,GADA,EAAG,UAAY,WACX,CAAC,EAAS,CACZ,EAAA,IAAI,MACF,gCACE,EACA;;EACA,CACJ,EACA,EAAM,QAAU,GAChB,MACF,CACA,EAAG,IACD,EAAU,QACV,EAAU,UACV,EAAU,OACV,EAAU,GACZ,EACA,EAAsB,CACxB,CAAC,CACH,OAAS,EAAG,CACV,EAAA,IAAI,MAAM,oBAAsB,CAAC,EACjC,EAAA,IAAI,MAAM,oBAAsB,CAAC,EACjC,EAAM,QAAU,GAChB,EAAG,UAAY,UACjB,MAEA,GAAI,CACF,EAAS,UAAU,SAAS,iBAAiB,EAAW,SACtD,EACA,EACA,EACA,CACA,EAAG,UAAY,WACV,GASH,EAAG,WACD,EAAU,QACV,EAAU,UACV,EAAU,OACV,EAAU,GACZ,EACA,EAAsB,IAdtB,EAAA,IAAI,MACF,+BACE,EACA;;EACA,CACJ,EACA,EAAM,QAAU,GAUpB,CAAC,CACH,OAAS,EAAG,CACV,EAAA,IAAI,MAAM,gBAAkB,CAAC,EAC7B,EAAM,QAAU,EAElB,CAEJ,EAE4C,EAAK,EAC1C,CACT,EAIM,EAAW,EAAQ,YAAY,CAAG,EAClC,EAAK,EAAQ,QAAQ,MACrB,EAAa,EAAI,cAAc,KAAK,EAC1C,EAAW,UAAU,IAAI,cAAe,cAAe,SAAS,EAChE,EAA2B,EAAY,CAAO,EAC9C,IAAM,EAAO,EAAA,GAAG,KACV,GAAQ,EAAA,GAAG,MACX,EAAK,EAAA,MAAM,YAAY,EACvB,GAAQ,EAAK,EAAG,IAAM,KAEtB,EAAY,GAAM,EAAG,WAAW,EAAI,CAAC,EAErC,EAAQ,EAAK,OAAO,EAEpB,GACJ,EAAG,SAAS,EAAG,EAAK,WAAW,CAAC,GAChC,EAAG,SAAS,EAAG,EAAK,WAAW,CAAC,GAChC,EAAG,SAAS,EAAG,EAAK,MAAM,CAAC,GAC3B,EAAG,SAAS,EAAG,EAAK,MAAM,CAAC,GAC3B,EAAG,SAAS,EAAG,GAAM,IAAI,CAAC,EAEtB,EAAgB,EADN,EAAG,KAAK,EAAG,CACO,CAAsB,EAClD,GAAY,EAAK,EAAY,EAAG,KAAK,EAAI,EAAK,OAAO,CAAC,CAAgB,EAAI,CAAC,EAC3E,EAAoB,GAAM,CAAC,EAC7B,EAAY,EAAO,EAAe,EAAS,CAAC,CAAC,CAAC,OAAO,GAAU,CAAC,EAAG,WAAW,EAAQ,CAAE,CAAC,EACzF,CAAC,EACC,GAAoB,GAAM,CAAC,EAAY,EAAkB,OAAS,KAClE,EAAa,EAAc,EAAG,CAAE,EAGlC,EAA4B,KAC5B,EAAW,GACX,EAAkC,GAClC,EAAkC,GAEhC,GAAY,EAAW,YAAY,EAAI,cAAc,KAAK,CAAC,EACjE,GAAU,UAAY,gBACtB,IAAM,EAAU,GAAU,YAAY,EAAI,cAAc,KAAK,CAAC,EAC9D,EAAQ,UAAY,iBAEpB,IAAM,EAAO,EAAQ,YAAY,EAAI,cAAc,KAAK,CAAC,EACzD,EAAK,UAAU,IAAI,uBAAwB,aAAa,EACxD,EAAK,aAAa,OAAQ,SAAS,EACnC,EAAK,aAAa,aAAc,iBAAiB,EAEjD,IAAM,EAAgB,EAAK,YAAY,EAAI,cAAc,QAAQ,CAAC,EAClE,EAAc,UAAY,sBAC1B,EAAc,KAAO,SACrB,EAAc,GAAK,yBACnB,EAAc,YAAc,cAC5B,EAAc,aAAa,OAAQ,KAAK,EACxC,EAAc,aAAa,gBAAiB,0BAA0B,EACtE,EAAc,aAAa,gBAAiB,MAAM,EAClD,EAAc,SAAW,EAEzB,IAAM,EAAY,EAAK,YAAY,EAAI,cAAc,QAAQ,CAAC,EAU9D,GATA,EAAU,UAAY,sBACtB,EAAU,KAAO,SACjB,EAAU,GAAK,oBACf,EAAU,YAAc,SACxB,EAAU,aAAa,OAAQ,KAAK,EACpC,EAAU,aAAa,gBAAiB,qBAAqB,EAC7D,EAAU,aAAa,gBAAiB,OAAO,EAC/C,EAAU,SAAW,GAEjB,EAAI,CAEN,IAAM,EAAQ,EAAG,KAAK,IAAA,GAAW,EAAK,cAAc,EAAG,CAAE,EACrD,EAAU,GACd,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAChC,GACE,EAAG,QACD,EAAM,GACN,EAAA,GAAG,IAAI,MAAM,EACb,EAAK,yBAAyB,CAChC,EACA,CACA,IAAM,EAAM,EAAM,GAElB,GADA,EAAW,EAAS,UAAU,SAAS,SAAS,EAAI,IAAK,CAAE,EACvD,CAAC,EACH,GACE,iBACA,EAAA,MAAM,aAAa,EAAI,GAAG,EAC1B,kCACG,CACL,EAAU,EACV,KACF,CACF,CAcF,GAAI,GAGG,CAIL,IAAM,EAAM,EAAG,MAAM,CAAE,EACvB,EAAW,EAAG,QAAQ,EAAG,EAAO,CAAG,EACnC,EAAW,GACX,IAAM,EAAa,EAAG,mBAAmB,EAAK,EAAO,CAAC,EAClD,EAAW,SACb,EAAW,GACX,AAAc,IAAU,EAAW,EAAE,CAAC,IAE1C,CACF,CAGA,IAAM,EAAmC,GAChC,IAAS,iBAAmB,CAAC,GAAa,CAAC,EAG9C,EAAsB,IAAe,SAAW,EAChD,GAAwB,IAAe,iBAAmB,CAAC,GAAa,GAAY,EAAQ,EAC5F,GAAsB,EAExB,EAAiC,CACnC,QAAS,EACT,aACA,oBAAqB,EAAgC,CAAU,CACjE,EAEM,EAAS,EAAA,oBAAoB,EAAS,EAAG,EAAgB,CAC7D,YAAa,EAAc,OAC3B,qBACA,gBAAiB,UAAY,CAC3B,EAAe,aAAa,CAC9B,EACA,eAAgB,OAAO,IAAsB,SACzC,UAAY,CACZ,EAAe,QAAQ,CACzB,EACE,IAAA,EACN,EAAG,UAAY,CACb,OAAO,EAAkB,EAAS,CAAC,CACrC,CAAC,EACD,EAAO,UAAU,IAAI,8BAA+B,aAAa,EACjE,EAAW,QAAQ,CAAM,EAQzB,IAAM,EAAqB,IAAI,KAgB/B,SAd4C,EAA0B,CACpE,IAAM,EAAY,IAAI,IAEtB,EAAY,QAAQ,GAAc,CAC5B,CAAC,GAAY,OAAS,EAAW,QAAU,EAAE,OACjD,EAAU,IAAI,EAAW,MAAO,EAAgB,EAAI,CAAU,CAAC,CACjE,CAAC,EAED,EAAmB,MAAM,EACzB,EAAU,SAAS,EAAO,IAAQ,CAChC,EAAmB,IAAI,EAAK,CAAK,CACnC,CAAC,CACH,EAEA,CAA0B,CAAa,EAEvC,IAAM,EAAmE,SAAU,EAAmB,EAAyB,CAC7H,IAAM,EAAS,EAAmB,IAAI,EAAO,KAAK,GAAK,EAAgB,EAAI,CAAM,EACjF,EAAmB,IAAI,EAAO,MAAO,CAAM,EAE3C,IAAM,EAAY,EAAU,cAAc,KAAK,EACzC,EAAqB,CAAC,EAAO,SAAU,EAAO,YAAY,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,KAAK,EAC5F,GAAI,EAAoB,CACtB,IAAM,EAAU,EAAU,YAAY,EAAU,cAAc,KAAK,CAAC,EACpE,EAAQ,UAAY,wBACpB,EAAQ,YAAc,CACxB,CAEA,GAAI,EAAO,SAAU,CACnB,IAAM,EAAe,EAAU,YAAY,EAAU,cAAc,KAAK,CAAC,EACzE,EAAa,UAAY,yBACzB,EAAa,UAAY,GAAG,EAAA,aAAa,GAAG,EAAO,UACrD,CAIA,OAFK,EAAU,WAAW,OAEnB,EAFkC,IAG3C,EAEM,EAA2D,SAAU,EAAmB,EAAyB,CACrH,IAAM,EAAS,EAAmB,IAAI,EAAO,KAAK,GAAK,EAAgB,EAAI,CAAM,EACjF,EAAmB,IAAI,EAAO,MAAO,CAAM,EAC3C,IAAM,EAAW,EAAO,SACxB,GAAI,CAAC,EAAU,OAAO,KAEtB,IAAM,EAAS,EAAU,cAAc,MAAM,EAG7C,MAFA,GAAO,UAAY,yBACnB,EAAO,YAAc,IAAI,EAAS,GAC3B,CACT,EAEI,EAAgB,GAAM,CAAC,EACvB,EAAA,oBAAoB,CACpB,MACA,QAAS,EACT,YACA,KACA,SACA,WACA,WACA,SAAU,GACV,UACA,QACA,oBACA,OACA,QACA,qBACA,uBACA,kBACF,CAAC,EACC,CACE,QAAS,EAAI,cAAc,SAAS,EACpC,QAAS,EAAI,cAAc,KAAK,EAChC,qBAAsB,UAAY,CAAC,CACrC,EAEA,EAAgB,EAAc,QAC9B,EAAgB,EAAc,QAC7B,EAAc,YACjB,EAAc,UAAY,oDAC1B,EAAc,GAAK,sBACnB,EAAc,aAAa,OAAQ,UAAU,EAC7C,EAAc,aAAa,kBAAmB,mBAAmB,EACjE,EAAc,UAAY,kCAC1B,EAAc,YAAY,CAAa,GAEzC,EAAQ,YAAY,CAAa,EAEjC,IAAM,GAAoB,EAAA,wBAAwB,CAChD,MACA,QAAS,EACT,QAAS,GAAsB,EAAU,KACzC,SAAU,GACV,uBACA,kBACF,CAAC,EAEK,EAAa,GAAkB,QAC/B,GAAc,GAAkB,YACtC,EAAQ,YAAY,CAAU,EAE9B,IAAI,EAAmC,EAAA,cAAc,EAAI,CAAC,EACpD,EAAkB,EAAA,sBAAsB,CAC5C,MACA,OAAQ,EACR,uBACA,kBACF,CAAC,EACK,EAAgB,EAAgB,QACtC,EAAQ,YAAY,CAAa,EAEjC,IAAM,EAAc,EAAK,YAAY,EAAI,cAAc,QAAQ,CAAC,EAChE,EAAY,UAAY,sBACxB,EAAY,KAAO,SACnB,EAAY,GAAK,sBACjB,EAAY,YAAc,WAC1B,EAAY,aAAa,OAAQ,KAAK,EACtC,EAAY,aAAa,gBAAiB,uBAAuB,EACjE,EAAY,aAAa,gBAAiB,OAAO,EACjD,EAAY,SAAW,GAGvB,IAAI,EAA2B,cAC3B,EAAkB,IAAe,QAE/B,EAAiB,SAAU,EAAoB,CACnD,EAAc,EACd,IAAM,EAAa,IAAU,SACvB,EAAiB,IAAU,cAC3B,EAAe,GAAmB,IAAU,WAClD,EAAU,UAAU,OAAO,8BAA+B,CAAU,EACpE,EAAU,aAAa,gBAAiB,OAAO,CAAU,CAAC,EAC1D,EAAU,SAAW,EAAa,EAAI,GAEtC,EAAc,UAAU,OAAO,8BAA+B,CAAc,EAC5E,EAAc,aAAa,gBAAiB,OAAO,CAAc,CAAC,EAClE,EAAc,SAAW,EAAiB,EAAI,GAE9C,EAAY,UAAU,OAAO,8BAA+B,CAAY,EACxE,EAAY,aAAa,gBAAiB,OAAO,CAAY,CAAC,EAC9D,EAAY,SAAW,EAAe,EAAI,GAE1C,EAAc,UAAU,OAAO,gCAAiC,CAAU,EAC1E,EAAc,aAAa,cAAe,OAAO,CAAC,CAAU,CAAC,EAE7D,EAAW,UAAU,OAAO,gCAAiC,CAAc,EAC3E,EAAW,aAAa,cAAe,OAAO,CAAC,CAAc,CAAC,EAE9D,EAAc,UAAU,OAAO,gCAAiC,CAAY,EAC5E,EAAc,aAAa,cAAe,OAAO,CAAC,CAAY,CAAC,EAC/D,EAAc,OAAS,CAAC,GAAmB,CAAC,CAC9C,EACM,GAAuB,UAAY,CACvC,GAAI,CAAC,GAAM,EAAW,OAEtB,IAAM,EAAM,EAAG,MAAM,CAAE,EACvB,EAAW,EAAG,QAAQ,EAAG,EAAO,CAAG,EAGnC,EAD2B,EAAG,mBAAmB,EAAK,EAAO,CAClD,CAAA,CAAmB,OAAS,EAEvC,IAAM,EAAoB,EAAA,oBAAoB,CAC5C,MACA,QAAS,EACT,YACA,KACA,SACA,WACA,WACA,SAAU,GACV,UACA,QACA,oBACA,OACA,QACA,qBACA,uBACA,kBACF,CAAC,EAED,EAAc,YAAY,EAAkB,OAAO,EACnD,EAAgB,EAChB,EAAgB,EAAkB,QAClC,EAAgB,EAAkB,OACpC,EAEA,EAAwB,UAAY,CAClC,GAAqB,EACrB,EAAiB,CACf,GAAG,EACH,oBAAqB,EAAgC,EAAe,UAAU,CAChF,EACC,EAAgC,sBAAsB,CAAc,EACrE,EAAiB,EAAA,cAAc,EAAI,CAAC,EACpC,EAAgB,gBAAgB,CAAc,EAC9C,EAAe,CAAW,CAC5B,EAEA,EAAe,aAAa,EAE5B,IAAM,EAAkB,SAAU,EAAkB,CAClD,IAAM,EAAgB,IAAS,iBAAmB,CAAC,EAInD,GAHA,EAAkB,IAAS,QAC3B,EAAU,OAAS,CAAC,EACpB,EAAY,OAAS,CAAC,EAClB,CAAC,GAAmB,IAAgB,WAAY,CAClD,EAAe,aAAa,EAC5B,MACF,CACA,EAAe,aAAa,CAC9B,EAEA,EAAU,iBAAiB,QAAS,UAAY,CAC9C,EAAe,QAAQ,CACzB,CAAC,EAED,EAAc,iBAAiB,QAAS,UAAY,CAClD,EAAe,aAAa,CAC9B,CAAC,EAED,EAAY,iBAAiB,QAAS,UAAY,CAChD,EAAe,UAAU,CAC3B,CAAC,EAED,IAAM,GAAqB,UAAY,CACrC,IAAM,EAAW,GAA4D,QACzE,OAAO,GAAY,YAEvB,EAAQ,KAAK,EAAW,CAC1B,EAEM,GAAuB,UAAY,CACvC,EAAc,qBAAqB,CACrC,EAwDA,OAtDE,SAAY,CACZ,GAAI,CACF,UAAW,IAAM,KAAmB,EAAc,EAAS,CAAC,EAC1D,EAAmB,MAAM,EACzB,EAAgB,QAAQ,GAAU,CAChC,EAAmB,IAAI,EAAO,IAAK,CAAM,CAC3C,CAAC,EACD,GAAmB,EACnB,GAAqB,CAEzB,MAAQ,CAER,CACF,EAAA,CAAG,GAED,SAAY,CACZ,GAAI,CACF,EAAiB,MAAM,EAAA,qBAAqB,EAAS,CAAC,EACtD,EAAgB,gBAAgB,CAAc,EAC9C,GAAmB,EACnB,GAAqB,CACvB,MAAQ,CAER,CACF,EAAA,CAAG,EAIH,EAAgB,WAAW,EAE3B,EAAA,MAAM,UAAU,CAAC,CACd,KAAK,GAAS,CACb,IAAM,EAAsB,EAAc,EAAG,CAAK,EAClD,EAAgB,CAAmB,EACnC,IAAM,EAA+B,IAAwB,SAAW,EACxE,EAAiB,CACf,GAAG,EACH,QAAS,EACT,WAAY,EACZ,oBAAqB,EAAgC,CAAmB,CAC1E,EACC,EAAgC,sBAAsB,CAAc,CACvE,CAAC,CAAC,CACD,UAAY,CACX,EAAgB,WAAW,EAC3B,EAAiB,CACf,GAAG,EACH,QAAS,GACT,WAAY,YACZ,oBAAqB,EACvB,EACC,EAAgC,sBAAsB,CAAc,CACvE,CAAC,EAEI,CACT,CACF,EAMM,EAAoB,EAmB1B,SAAgB,EAAgB,EAAkB,EAA4B,CAC5E,IAAI,EAAW,EAAM,MAAM,EAAS,EAAA,GAAG,MAAM,yBAAyB,CAAC,GAAK,GAC5E,GAAI,EAAU,CACZ,IAAM,EAAO,EAAM,MAAM,EAAS,EAAA,GAAG,MAAM,wBAAwB,CAAC,EAChE,IACF,GAAY,IAAM,EAEtB,CACA,OAAO,GAAY,EACrB,CAEA,SAAS,EAAgB,EAA4B,EAAyB,CAC5E,OAAO,GAAe,EAClB,GAAG,EAAS,IAAI,IAChB,GAAe,GAAY,IACjC,CAEA,SAAS,EAAiB,EAAY,EAAsC,CAC1E,IAAM,EACJ,EAAM,SAAS,EAAY,EAAA,GAAG,MAAM,IAAI,CAAC,GACzC,EAAM,SAAS,EAAY,EAAA,GAAG,KAAK,MAAM,CAAC,GAC1C,KACI,EACJ,EAAM,SAAS,EAAY,EAAA,GAAG,MAAM,UAAU,CAAC,GAC/C,EAAM,SAAS,EAAY,EAAA,GAAG,KAAK,MAAM,CAAC,GAC1C,KACI,EAAc,EAAM,SAAS,EAAY,EAAA,GAAG,MAAM,MAAM,CAAC,GAAK,KAC9D,EAAW,EAAA,QAAQ,UAAU,CAAU,EACvC,EAAW,EAAM,SAAS,EAAY,EAAA,GAAG,MAAM,MAAM,CAAC,GAAK,KAC3D,EAAU,EAAM,SAAS,EAAY,EAAA,GAAG,MAAM,mBAAmB,CAAC,GAAK,KAEvE,EAD0B,EAAM,IAAI,EAAY,EAAA,GAAG,MAAM,YAAY,CACzC,GAA2B,KAUvD,EAAW,EARb,GAAW,KAEP,KADA,EAAM,SAAS,EAAS,EAAA,GAAG,MAAM,cAAc,CAAC,EAGtD,GAAW,KAEP,KADA,EAAM,SAAS,EAAS,EAAA,GAAG,MAAM,UAAU,CAAC,CAGG,EAC/C,EAAW,EAAe,EAAO,CAAU,EAEjD,MAAO,CACL,IAAK,EAAW,MAChB,SAAU,EACV,OACA,WACA,WACA,aAAc,EACd,UAAW,EACX,WACA,WACA,YAAa,CACf,CACF,CAEA,eAAwB,EACtB,EACA,EACA,EAAY,EACiC,CAC7C,IAAM,EAAQ,EAAQ,QAAQ,MACxB,EAAW,GAAe,QAEhC,GAAI,GAAW,OAAO,EAAQ,MAAS,WACrC,GAAI,CACF,MAAM,EAAQ,KAAK,EAAQ,IAAI,CAAC,CAClC,MAAQ,CAER,CAGF,IAAM,EAAO,IAAI,IACX,EAAc,EAAM,KAAK,EAAS,EAAA,GAAG,KAAK,OAAO,EAAG,KAAM,EAAQ,IAAI,CAAC,EACvE,EAAiC,CAAC,EAExC,IAAK,IAAM,KAAc,EAAa,CACpC,IAAM,EAAM,GAAY,MACpB,CAAC,GAAO,EAAK,IAAI,CAAG,GAAK,EAAQ,QAAU,IAC/C,EAAK,IAAI,CAAG,EACZ,EAAkB,KAAK,CAAuB,EAChD,CAEA,IAAM,EAA2B,CAAC,EAElC,IAAK,IAAM,KAAc,EAAmB,CAC1C,GAAI,GAAW,OAAO,EAAQ,MAAS,WACrC,GAAI,CACF,MAAM,EAAQ,KAAK,EAAW,IAAI,CAAC,CACrC,MAAQ,CAER,CAGF,EAAQ,KAAK,EAAgB,EAAO,CAAU,CAAC,EAE3C,EAAQ,OAAS,IAAc,IACjC,KAAM,CAAC,GAAG,CAAO,EAErB,CAEI,EAAQ,OAAS,GAAK,EAAQ,OAAS,IAAc,IACvD,KAAM,CAAC,GAAG,CAAO,EAErB,CAYA,SAAgB,EAAmB,EAA6B,EAA2C,CACzG,IAAM,EAAQ,EAAQ,QAAQ,MAExB,EACF,EAAM,SAAS,EAAS,EAAA,GAAG,MAAM,IAAI,CAAC,GACtC,EAAM,SAAS,EAAS,EAAA,GAAG,KAAK,MAAM,CAAC,GACvC,IAAA,GACE,EACF,EAAM,SAAS,EAAS,EAAA,GAAG,MAAM,UAAU,CAAC,GAC5C,EAAM,SAAS,EAAS,EAAA,GAAG,KAAK,MAAM,CAAC,GACvC,IAAA,GACE,EAAc,EAAM,SAAS,EAAS,EAAA,GAAG,MAAM,MAAM,CAAC,GAAK,IAAA,GAC3D,EAAW,EAAA,QAAQ,UAAU,CAAO,EACpC,EAAW,EAAM,SAAS,EAAS,EAAA,GAAG,MAAM,MAAM,CAAC,GAAK,IAAA,GACxD,EAAU,EAAM,SAAS,EAAS,EAAA,GAAG,MAAM,mBAAmB,CAAC,GAAK,IAAA,GAEpE,EAD0B,EAAM,IAAI,EAAS,EAAA,GAAG,MAAM,YAAY,CACtC,GAA2B,KAUvD,EAAW,EARX,GAAW,KAEP,IAAA,GADA,EAAM,SAAS,EAAS,EAAA,GAAG,MAAM,cAAc,CAAC,EAGtD,GAAW,KAEP,IAAA,GADA,EAAM,SAAS,EAAS,EAAA,GAAG,MAAM,UAAU,CAAC,CAGC,EAC/C,EAAW,EAAe,EAAO,CAAO,EAC9C,MAAO,CACL,IAAK,EAAQ,MACb,SAAU,EACV,OACA,WACA,WACA,aAAc,EACd,UAAW,EACX,WACA,UACF,CACF,CAIA,SAAS,EAAe,EAAoB,EAAuB,EAAA,MAAM,YAAY,EAAe,CAClG,IAAM,EACJ,OAAO,GAAgB,SACnB,EACA,OAAO,GAAgB,UAAY,IAC/B,EAAiD,OAChD,EAAiD,MAEpD,KACJ,EAAmB,YAGvB,OAFI,IAAmB,EAAQ,QAAO,EAAO,SACzC,GAAkB,IAAmB,EAAQ,QAAO,EAAO,iBACxD,CACT"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
const e=require("./icons.cjs.js");require("./editProfileDetails.cjs.js");let t=require("solid-ui"),n=require("rdflib"),r=require("profile-pane");function i(n,i,o,s,c){let l=n.dom;n.session.store;let u=l.createElement(`header`);u.className=`social-pane__header`;let d=o,f=function(){u.replaceChildren();let o=c(),f=l.createElement(`div`);f.className=`social-pane__header-content`;let p=l.createElement(`div`);if(p.className=`social-pane__header-actions profile__actions profile__heading-actions`,!d.canEdit&&d.viewerMode===`authenticated`&&d.showAddFriendAction){p.classList.add(`social-pane__header-actions--friend`);let e=(0,r.createAddMeToYourFriendsButton)(i,n);e.classList.add(`flex-center`),p.appendChild(e)}u.appendChild(f);let m=l.createElement(`div`);m.className=`social-pane__header-media`,f.appendChild(m),o&&m.appendChild(a(l,o.imageUrl,o.name));let h=l.createElement(`div`);h.className=`social-pane__header-details`,f.appendChild(h),p.childNodes.length>0&&f.appendChild(p);let g=l.createElement(`div`);g.classList.add(`social-pane__header-summary`,`flex-column`),h.appendChild(g);let _=o?.name||t.utils.label(i),v=l.createElement(`h1`);v.classList.add(`social-pane__header-name`),v.appendChild(l.createTextNode(_)),g.appendChild(v);let y=[o?.jobTitle,o?.organization].filter(Boolean).join(` | `);if(y){let e=l.createElement(`div`);e.className=`social-pane__header-job-org`,e.textContent=y,g.appendChild(e)}if(o?.location){let t=l.createElement(`div`);t.className=`social-pane__header-location`;let n=l.createElement(`span`);n.classList.add(`social-pane__header-location-icon`,`inline-flex-row`),n.innerHTML=e.locationIcon,t.appendChild(n),t.appendChild(l.createTextNode(o.location)),g.appendChild(t)}let b=l.createElement(`div`);b.className=`social-pane__header-stats`;let x=l.createElement(`button`);x.className=`social-pane__header-stat`,x.type=`button`;let S=l.createElement(`span`);if(S.className=`social-pane__header-stat-label`,S.textContent=`${s.friendCount} friend${s.friendCount===1?``:`s`}`,x.appendChild(S),s.onSelectFriends&&x.addEventListener(`click`,s.onSelectFriends),b.appendChild(x),typeof s.mutualFriendCount==`number`){let e=l.createElement(`button`);e.className=`social-pane__header-stat`,e.type=`button`;let t=l.createElement(`span`);t.className=`social-pane__header-stat-label`,t.textContent=`${s.mutualFriendCount} mutual friend${s.mutualFriendCount===1?``:`s`}`,e.appendChild(t),s.onSelectMutual&&e.addEventListener(`click`,s.onSelectMutual),b.appendChild(e)}g.appendChild(b)};return u.refreshSocialHeader=function(e){d=e,f()},f(),u}function a(t,n,r=``){if(n){let e=t.createElement(`img`);return e.className=`social-pane__header-hero`,e.src=n,e.alt=r,e.width=180,e.height=180,e.loading=`eager`,e}let i=t.createElement(`div`);i.className=`social-pane__header-hero-alt flex-center`,i.setAttribute(`role`,`img`),i.setAttribute(`aria-label`,r),i.tabIndex=0;let a=t.createElement(`span`);return a.classList.add(`social-pane__header-hero-icon`,`inline-flex-row`),a.innerHTML=e.personInCircleIcon,i.appendChild(a),i}function o(e){let{dom:r,subject:i,familiar:a,me:o,meUri:s,incoming:c,outgoing:l,editable:u,profile:d,knows:f,mutualConnections:p,link:m,text:h,buildCheckboxForm:g,renderSupportingInfo:_,renderNameSuffix:v}=e,y=function(){},b=r.createElement(`section`);b.className=`social-pane__mutual-friends social-primary__panel`,b.id=`social-panel-mutual`,b.setAttribute(`role`,`tabpanel`),b.setAttribute(`aria-labelledby`,`social-tab-mutual`);let x=b.appendChild(r.createElement(`div`));x.classList.add(`social-main`,`social-main--mutual`,`flex-column`);let S=r.createElement(`div`);S.classList.add(`social-mutual-summary`,`flex-column`),x.appendChild(S);let C=function(){let e=S.appendChild(r.createElement(`div`));return e.classList.add(`social-mutual-summary-line`),e},w=function(){let e=C();return e.appendChild(m(h(`You`),s)),e.appendChild(h(` and `)),e.appendChild(m(h(a),i.uri)),e};if(!c){if(!l)w().appendChild(h(` have not said you know each other.`));else{let e=C();e.appendChild(m(h(`You`),s)),e.appendChild(h(` know `)),e.appendChild(m(h(a),i.uri)),e.appendChild(h(` (unconfirmed).`))}}else if(l)w().appendChild(h(` say you know each other.`));else{S.classList.add(`social-mutual-summary--confirm`);let e=S.appendChild(r.createElement(`div`));e.classList.add(`social-mutual-summary-line`),e.appendChild(m(h(a),i.uri)),e.appendChild(h(` knows `)),e.appendChild(m(h(`you`),s)),e.appendChild(h(` (unconfirmed).`))}if(c&&!l){let e=r.createElement(`span`);e.className=`social-mutual-confirm-prompt`,e.appendChild(h(`Confirm you know `)),e.appendChild(m(h(a),i.uri));let t=g(e,new n.Statement(o,f,i,d??void 0),!!l,{disabled:!u,disabledTitle:u?void 0:`Your profile is not editable`});t.classList.add(`social-mutual-checkbox-form`),x.appendChild(t)}if(p.length){let e=x.appendChild(r.createElement(`table`));e.className=`social-main social-friends-list social-friends-grid`;let n=function(e){return t.widgets.personTR(r,t.ns.foaf(`knows`),e,{renderSupportingInfo:_,renderNameSuffix:v})};y=function(){let r=[...p].sort((e,n)=>{let r=t.utils.label(e)||e.value,i=t.utils.label(n)||n.value;return r.localeCompare(i)});t.utils.syncTableToArray(e,r,n,function(e,t){return n(t)})},y()}return{section:b,content:x,refreshMutualFriends:y}}function s(e){let{dom:n,subject:r,profile:i,editable:a,renderSupportingInfo:o,renderNameSuffix:s}=e,c=n.createElement(`section`);c.className=`social-pane__all-friends social-primary__panel`,c.id=`social-panel-all-friends`,c.setAttribute(`role`,`tabpanel`),c.setAttribute(`aria-labelledby`,`social-tab-all-friends`);let l=c.appendChild(n.createElement(`table`));l.className=`social-main`;let u=t.widgets.attachmentList(n,r,l,{doc:i,modify:!!a,predicate:t.ns.foaf(`knows`),noun:`friend`,refreshOnDocumentLoad:!1,renderSupportingInfo:o,renderNameSuffix:s});u.classList.add(`social-friends-list`),u.style.marginTop=`0`;let d=u.querySelector(`tr`),f=d?.children?.[0],p=d?.children?.[1],m=n.createElement(`div`);if(m.classList.add(`social-friends-header-actions`),f instanceof HTMLTableCellElement){f.classList.add(`social-friends-header-dropzone-cell`);let e=n.createElement(`table`);e.className=`social-friends-header-dropzone`,e.setAttribute(`role`,`presentation`),e.appendChild(n.createElement(`tbody`)).appendChild(n.createElement(`tr`)).appendChild(f),m.appendChild(e)}else if(f instanceof HTMLElement){for(;f.firstChild;)m.appendChild(f.firstChild);f.remove()}let h=m.querySelectorAll(`button`);if(a&&h.length>0){h.forEach(e=>{e.setAttribute(`title`,`Drop friend here`),e.setAttribute(`aria-label`,`Drop friend here`),e.querySelectorAll(`img`).forEach(e=>{e.setAttribute(`title`,`Drop friend here`),e.setAttribute(`alt`,`Drop friend here`)})});let e=n.createElement(`div`);e.className=`social-friends-header-actions social-friends-header-actions--standalone`,e.appendChild(m);let t=n.createElement(`span`);t.className=`social-friends-header-hint`,t.textContent=`Drag a WebId on the target to add a friend.`,e.appendChild(t),c.prepend(e)}p instanceof HTMLTableCellElement&&(p.colSpan=2);let g=u.querySelector(`td table`);return g instanceof HTMLTableElement&&g.classList.add(`social-friends-grid`),{section:c,mainTable:l,friendsList:u}}function c(e){let{dom:n,triage:r,renderSupportingInfo:i,renderNameSuffix:a}=e,o=n.createElement(`section`);o.className=`social-pane__requests social-primary__panel`,o.id=`social-panel-requests`,o.setAttribute(`role`,`tabpanel`),o.setAttribute(`aria-labelledby`,`social-tab-requests`);let s=o.appendChild(n.createElement(`div`));s.classList.add(`social-main`,`social-main--requests`,`flex-column`);let c=s.appendChild(n.createElement(`p`));c.className=`social-requests__note`,c.textContent=`Best effort preview: this view only reflects profile documents that are currently loaded. A dedicated inbox would still be needed for complete request discovery.`;let l=function(e,t,r){let i=s.appendChild(n.createElement(`section`));i.classList.add(`social-requests__group`,`flex-column`);let a=i.appendChild(n.createElement(`div`));a.className=`social-requests__group-header`;let o=a.appendChild(n.createElement(`h2`));o.className=`social-requests__group-title`,o.textContent=e;let c=a.appendChild(n.createElement(`p`));c.className=`social-requests__group-description`,c.textContent=t;let l=i.appendChild(n.createElement(`p`));l.className=`social-requests__empty`,l.textContent=r;let u=i.appendChild(n.createElement(`table`));return u.className=`social-main social-friends-list social-friends-grid social-requests__table`,{empty:l,table:u}},u=l(`Incoming requests`,`People who say they know this profile, but have not been confirmed yet.`,`No incoming requests are visible from the currently loaded data.`),d=l(`Awaiting confirmation`,`People this profile knows who have not linked back yet.`,`Nothing is waiting for confirmation right now.`),f=function(e){return t.widgets.personTR(n,t.ns.foaf(`knows`),e,{renderSupportingInfo:i,renderNameSuffix:a})},p=function(e){return[...e].sort((e,n)=>{let r=t.utils.label(e)||e.value,i=t.utils.label(n)||n.value;return r.localeCompare(i)})},m=function(e,n){let r=p(n);e.empty.hidden=r.length>0,e.table.hidden=r.length===0,t.utils.syncTableToArray(e.table,r,f,function(e,t){return f(t)})},h=function(e){m(u,e.requests),m(d,e.unconfirmed)};return h(r),{section:o,refreshRequests:h}}exports.createAllFriendsSection=s,exports.createHeaderSection=i,exports.createMutualSection=o,exports.createRequestsSection=c;
|
|
2
2
|
//# sourceMappingURL=socialSections.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socialSections.cjs.js","names":[],"sources":["../../src/social/socialSections.ts"],"sourcesContent":["import { DataBrowserContext } from 'pane-registry'\nimport { createAddMeToYourFriendsButton } from 'profile-pane'\nimport { Statement, NamedNode } from 'rdflib'\nimport { ns, utils, widgets } from 'solid-ui'\nimport { appendProfileLinks } from './editProfileDetails'\nimport { locationIcon, personInCircleIcon as personInCircleIconSvg } from './icons'\nimport { FriendshipTriage } from './triage'\n\nexport type ViewerMode = 'owner' | 'authenticated' | 'anonymous'\n\nexport type HeaderControls = {\n canEdit: boolean,\n viewerMode: ViewerMode,\n showAddFriendAction?: boolean\n}\n\nexport type SocialHeaderElement = HTMLElement & {\n refreshSocialHeader?: (controls: HeaderControls) => void\n}\n\nexport type HeaderStats = {\n friendCount: number,\n mutualFriendCount: number | null,\n onSelectFriends?: () => void,\n onSelectMutual?: () => void\n}\n\nexport type HeaderProfileData = {\n imageUrl?: string,\n name?: string,\n jobTitle?: string,\n organization?: string,\n location?: string | null\n} | null\n\nexport type FriendRowRenderers = {\n renderSupportingInfo: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null,\n renderNameSuffix: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null\n}\n\nexport function createHeaderSection (\n context: DataBrowserContext,\n subject: NamedNode,\n controls: HeaderControls,\n stats: HeaderStats,\n getProfileData: () => HeaderProfileData\n): SocialHeaderElement {\n const dom = context.dom\n const kb = context.session.store\n const header = dom.createElement('header') as SocialHeaderElement\n header.className = 'social-pane__header'\n let headerControls = controls\n\n const renderHeader = function () {\n header.replaceChildren()\n const profileData = getProfileData()\n\n const headerContent = dom.createElement('div')\n headerContent.className = 'social-pane__header-content'\n\n const headerActions = dom.createElement('div')\n headerActions.className = 'social-pane__header-actions profile__actions profile__heading-actions'\n\n if (headerControls.canEdit) {\n // Hidden for now because the social pane header edit control does not match the new design.\n // Revisit later if we decide to restore profile-link editing here.\n } else if (headerControls.viewerMode === 'authenticated' && headerControls.showAddFriendAction) {\n headerActions.classList.add('social-pane__header-actions--friend')\n const addToFriendsButton = createAddMeToYourFriendsButton(subject, context)\n addToFriendsButton.classList.add('flex-center')\n headerActions.appendChild(addToFriendsButton)\n }\n\n header.appendChild(headerContent)\n\n const headerMedia = dom.createElement('div')\n headerMedia.className = 'social-pane__header-media'\n headerContent.appendChild(headerMedia)\n\n if (profileData) {\n headerMedia.appendChild(createImage(dom, profileData.imageUrl, profileData.name))\n }\n\n const headerDetails = dom.createElement('div')\n headerDetails.className = 'social-pane__header-details'\n headerContent.appendChild(headerDetails)\n\n if (headerActions.childNodes.length > 0) {\n headerContent.appendChild(headerActions)\n }\n\n const headerSummary = dom.createElement('div')\n headerSummary.classList.add('social-pane__header-summary', 'flex-column')\n headerDetails.appendChild(headerSummary)\n\n const name = profileData?.name || utils.label(subject)\n const h1 = dom.createElement('h1')\n h1.classList.add('social-pane__header-name')\n h1.appendChild(dom.createTextNode(name))\n headerSummary.appendChild(h1)\n\n const jobAndOrganization = [profileData?.jobTitle, profileData?.organization].filter(Boolean).join(' | ')\n if (jobAndOrganization) {\n const jobLine = dom.createElement('div')\n jobLine.className = 'social-pane__header-job-org'\n jobLine.textContent = jobAndOrganization\n headerSummary.appendChild(jobLine)\n }\n\n if (profileData?.location) {\n const locationLine = dom.createElement('div')\n locationLine.className = 'social-pane__header-location'\n\n const locationIconSpan = dom.createElement('span')\n locationIconSpan.classList.add('social-pane__header-location-icon', 'inline-flex-row')\n locationIconSpan.innerHTML = locationIcon\n locationLine.appendChild(locationIconSpan)\n locationLine.appendChild(dom.createTextNode(profileData.location))\n\n headerSummary.appendChild(locationLine)\n }\n\n const statsRow = dom.createElement('div')\n statsRow.className = 'social-pane__header-stats'\n\n const friendCount = dom.createElement('button')\n friendCount.className = 'social-pane__header-stat'\n friendCount.type = 'button'\n const friendCountLabel = dom.createElement('span')\n friendCountLabel.className = 'social-pane__header-stat-label'\n friendCountLabel.textContent = `${stats.friendCount} friend${stats.friendCount === 1 ? '' : 's'}`\n friendCount.appendChild(friendCountLabel)\n if (stats.onSelectFriends) {\n friendCount.addEventListener('click', stats.onSelectFriends)\n }\n statsRow.appendChild(friendCount)\n\n if (typeof stats.mutualFriendCount === 'number') {\n const mutualCount = dom.createElement('button')\n mutualCount.className = 'social-pane__header-stat'\n mutualCount.type = 'button'\n const mutualCountLabel = dom.createElement('span')\n mutualCountLabel.className = 'social-pane__header-stat-label'\n mutualCountLabel.textContent = `${stats.mutualFriendCount} mutual friend${stats.mutualFriendCount === 1 ? '' : 's'}`\n mutualCount.appendChild(mutualCountLabel)\n if (stats.onSelectMutual) {\n mutualCount.addEventListener('click', stats.onSelectMutual)\n }\n statsRow.appendChild(mutualCount)\n }\n\n headerSummary.appendChild(statsRow)\n appendProfileLinks(headerMedia, dom, kb, subject)\n }\n\n header.refreshSocialHeader = function (nextControls: HeaderControls) {\n headerControls = nextControls\n renderHeader()\n }\n\n renderHeader()\n\n return header\n}\n\nfunction createImage (dom: HTMLDocument, src: string | null | undefined, alt = ''): HTMLElement {\n if (src) {\n const img = dom.createElement('img')\n img.className = 'social-pane__header-hero'\n img.src = src\n img.alt = alt\n img.width = 180\n img.height = 180\n img.loading = 'eager'\n return img\n }\n\n const fallback = dom.createElement('div')\n fallback.className = 'social-pane__header-hero-alt flex-center'\n fallback.setAttribute('role', 'img')\n fallback.setAttribute('aria-label', alt)\n fallback.tabIndex = 0\n\n const icon = dom.createElement('span')\n icon.classList.add('social-pane__header-hero-icon', 'inline-flex-row')\n icon.innerHTML = personInCircleIconSvg\n fallback.appendChild(icon)\n\n return fallback\n}\n\nexport function createMutualSection (options: {\n dom: HTMLDocument,\n subject: NamedNode,\n familiar: string,\n me: NamedNode,\n meUri: string | null,\n incoming: boolean | NamedNode[] | undefined,\n outgoing: boolean | NamedNode[] | undefined,\n editable: boolean,\n profile: NamedNode | null,\n knows: NamedNode,\n mutualConnections: NamedNode[],\n link: (contents: Node, uri: string | null | undefined) => Node,\n text: (value: string) => Text,\n buildCheckboxForm: (\n label: string | Node,\n statement: Statement,\n state: boolean,\n options?: { disabled?: boolean, disabledTitle?: string }\n ) => HTMLElement,\n renderSupportingInfo: FriendRowRenderers['renderSupportingInfo'],\n renderNameSuffix: FriendRowRenderers['renderNameSuffix']\n}): { section: HTMLElement, content: HTMLElement, refreshMutualFriends: () => void } {\n const {\n dom,\n subject,\n familiar,\n me,\n meUri,\n incoming,\n outgoing,\n editable,\n profile,\n knows,\n mutualConnections,\n link,\n text,\n buildCheckboxForm,\n renderSupportingInfo,\n renderNameSuffix\n } = options\n\n let refreshMutualFriends = function () {}\n\n const mutualSection = dom.createElement('section')\n mutualSection.className = 'social-pane__mutual-friends social-primary__panel'\n mutualSection.id = 'social-panel-mutual'\n mutualSection.setAttribute('role', 'tabpanel')\n mutualSection.setAttribute('aria-labelledby', 'social-tab-mutual')\n\n const mutualContent = mutualSection.appendChild(dom.createElement('div'))\n mutualContent.classList.add('social-main', 'social-main--mutual', 'flex-column')\n\n const relationshipSummary = dom.createElement('div')\n relationshipSummary.classList.add('social-mutual-summary', 'flex-column')\n mutualContent.appendChild(relationshipSummary)\n\n const createRelationshipLine = function () {\n const line = relationshipSummary.appendChild(dom.createElement('div'))\n line.classList.add('social-mutual-summary-line')\n return line\n }\n\n const youAndThem = function () {\n const line = createRelationshipLine()\n line.appendChild(link(text('You'), meUri))\n line.appendChild(text(' and '))\n line.appendChild(link(text(familiar), subject.uri))\n return line\n }\n\n if (!incoming) {\n if (!outgoing) {\n const line = youAndThem()\n line.appendChild(text(' have not said you know each other.'))\n } else {\n const line = createRelationshipLine()\n line.appendChild(link(text('You'), meUri))\n line.appendChild(text(' know '))\n line.appendChild(link(text(familiar), subject.uri))\n line.appendChild(text(' (unconfirmed).'))\n }\n } else if (!outgoing) {\n relationshipSummary.classList.add('social-mutual-summary--confirm')\n\n const incomingLine = relationshipSummary.appendChild(dom.createElement('div'))\n incomingLine.classList.add('social-mutual-summary-line')\n incomingLine.appendChild(link(text(familiar), subject.uri))\n incomingLine.appendChild(text(' knows '))\n incomingLine.appendChild(link(text('you'), meUri))\n incomingLine.appendChild(text(' (unconfirmed).'))\n } else {\n const line = youAndThem()\n line.appendChild(text(' say you know each other.'))\n }\n\n const shouldShowCheckboxPreview = Boolean(incoming) && !outgoing\n if (shouldShowCheckboxPreview) {\n const confirmLabel = dom.createElement('span')\n confirmLabel.className = 'social-mutual-confirm-prompt'\n confirmLabel.appendChild(text('Confirm you know '))\n confirmLabel.appendChild(link(text(familiar), subject.uri))\n\n const relationshipForm = buildCheckboxForm(\n confirmLabel,\n new Statement(me, knows, subject, profile ?? undefined),\n Boolean(outgoing),\n {\n disabled: !editable,\n disabledTitle: !editable ? 'Your profile is not editable' : undefined\n }\n )\n relationshipForm.classList.add('social-mutual-checkbox-form')\n\n mutualContent.appendChild(relationshipForm)\n }\n\n if (mutualConnections.length) {\n const mutualFriendsTable = mutualContent.appendChild(dom.createElement('table'))\n mutualFriendsTable.className = 'social-main social-friends-list social-friends-grid'\n\n const createMutualRow = function (target: NamedNode) {\n return widgets.personTR(dom, ns.foaf('knows'), target, {\n renderSupportingInfo,\n renderNameSuffix\n })\n }\n\n refreshMutualFriends = function () {\n const sortedMutualConnections = [...mutualConnections].sort((left, right) => {\n const leftLabel = utils.label(left) || left.value\n const rightLabel = utils.label(right) || right.value\n return leftLabel.localeCompare(rightLabel)\n })\n\n utils.syncTableToArray(\n mutualFriendsTable,\n sortedMutualConnections,\n createMutualRow,\n function (row, thing) {\n const replacement = createMutualRow(thing)\n return replacement\n }\n )\n }\n\n refreshMutualFriends()\n }\n\n return { section: mutualSection, content: mutualContent, refreshMutualFriends }\n}\n\nexport function createAllFriendsSection (options: {\n dom: HTMLDocument,\n subject: NamedNode,\n profile: NamedNode | null,\n editable: boolean,\n renderSupportingInfo: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null,\n renderNameSuffix: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null\n}): { section: HTMLElement, mainTable: HTMLTableElement, friendsList: HTMLElement } {\n const { dom, subject, profile, editable, renderSupportingInfo, renderNameSuffix } = options\n\n const allFriends = dom.createElement('section')\n allFriends.className = 'social-pane__all-friends social-primary__panel'\n allFriends.id = 'social-panel-all-friends'\n allFriends.setAttribute('role', 'tabpanel')\n allFriends.setAttribute('aria-labelledby', 'social-tab-all-friends')\n\n const mainTable = allFriends.appendChild(dom.createElement('table'))\n mainTable.className = 'social-main'\n\n const friendsList = widgets.attachmentList(dom, subject, mainTable, {\n doc: profile,\n modify: !!editable,\n predicate: ns.foaf('knows'),\n noun: 'friend',\n // Social pane already owns the async refresh cycle for friend data in\n // socialPane.ts. Leave attachmentList's generic follow-up rerender disabled\n // here or each fetched friend profile will trigger an extra whole-table refresh\n // on top of the pane's own batched updates.\n refreshOnDocumentLoad: false,\n renderSupportingInfo,\n renderNameSuffix\n })\n friendsList.classList.add('social-friends-list')\n friendsList.style.marginTop = '0'\n\n const friendsListRow = friendsList.querySelector('tr')\n const friendsListPromptCell = friendsListRow?.children?.[0]\n const friendsListRightCell = friendsListRow?.children?.[1]\n const friendsHeaderActions = dom.createElement('div')\n friendsHeaderActions.classList.add('social-friends-header-actions')\n\n if (friendsListPromptCell instanceof HTMLTableCellElement) {\n friendsListPromptCell.classList.add('social-friends-header-dropzone-cell')\n const friendsHeaderDropzone = dom.createElement('table')\n friendsHeaderDropzone.className = 'social-friends-header-dropzone'\n friendsHeaderDropzone.setAttribute('role', 'presentation')\n const friendsHeaderDropzoneBody = friendsHeaderDropzone.appendChild(dom.createElement('tbody'))\n const friendsHeaderDropzoneRow = friendsHeaderDropzoneBody.appendChild(dom.createElement('tr'))\n friendsHeaderDropzoneRow.appendChild(friendsListPromptCell)\n friendsHeaderActions.appendChild(friendsHeaderDropzone)\n } else if (friendsListPromptCell instanceof HTMLElement) {\n while (friendsListPromptCell.firstChild) {\n friendsHeaderActions.appendChild(friendsListPromptCell.firstChild)\n }\n friendsListPromptCell.remove()\n }\n\n const friendDropButtons = friendsHeaderActions.querySelectorAll('button')\n if (editable && friendDropButtons.length > 0) {\n friendDropButtons.forEach((button) => {\n button.setAttribute('title', 'Drop friend here')\n button.setAttribute('aria-label', 'Drop friend here')\n const buttonImages = button.querySelectorAll('img')\n buttonImages.forEach((image) => {\n image.setAttribute('title', 'Drop friend here')\n image.setAttribute('alt', 'Drop friend here')\n })\n })\n\n const friendsActionsRow = dom.createElement('div')\n friendsActionsRow.className = 'social-friends-header-actions social-friends-header-actions--standalone'\n friendsActionsRow.appendChild(friendsHeaderActions)\n const dropHint = dom.createElement('span')\n dropHint.className = 'social-friends-header-hint'\n dropHint.textContent = 'Drag a WebId on the target to add a friend.'\n friendsActionsRow.appendChild(dropHint)\n allFriends.prepend(friendsActionsRow)\n }\n\n if (friendsListRightCell instanceof HTMLTableCellElement) {\n friendsListRightCell.colSpan = 2\n }\n\n const friendsItemsTable = friendsList.querySelector('td table')\n if (friendsItemsTable instanceof HTMLTableElement) {\n friendsItemsTable.classList.add('social-friends-grid')\n }\n\n return { section: allFriends, mainTable, friendsList }\n}\n\nexport function createRequestsSection (options: {\n dom: HTMLDocument,\n triage: FriendshipTriage,\n renderSupportingInfo: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null,\n renderNameSuffix: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null\n}): { section: HTMLElement, refreshRequests: (triage: FriendshipTriage) => void } {\n const { dom, triage, renderSupportingInfo, renderNameSuffix } = options\n\n const requestsSection = dom.createElement('section')\n requestsSection.className = 'social-pane__requests social-primary__panel'\n requestsSection.id = 'social-panel-requests'\n requestsSection.setAttribute('role', 'tabpanel')\n requestsSection.setAttribute('aria-labelledby', 'social-tab-requests')\n\n const requestsContent = requestsSection.appendChild(dom.createElement('div'))\n requestsContent.classList.add('social-main', 'social-main--requests', 'flex-column')\n\n const note = requestsContent.appendChild(dom.createElement('p'))\n note.className = 'social-requests__note'\n note.textContent = 'Best effort preview: this view only reflects profile documents that are currently loaded. A dedicated inbox would still be needed for complete request discovery.'\n\n const createRequestGroup = function (title: string, description: string, emptyText: string) {\n const group = requestsContent.appendChild(dom.createElement('section'))\n group.classList.add('social-requests__group', 'flex-column')\n\n const header = group.appendChild(dom.createElement('div'))\n header.className = 'social-requests__group-header'\n\n const heading = header.appendChild(dom.createElement('h2'))\n heading.className = 'social-requests__group-title'\n heading.textContent = title\n\n const blurb = header.appendChild(dom.createElement('p'))\n blurb.className = 'social-requests__group-description'\n blurb.textContent = description\n\n const empty = group.appendChild(dom.createElement('p'))\n empty.className = 'social-requests__empty'\n empty.textContent = emptyText\n\n const table = group.appendChild(dom.createElement('table'))\n table.className = 'social-main social-friends-list social-friends-grid social-requests__table'\n\n return { empty, table }\n }\n\n const incomingGroup = createRequestGroup(\n 'Incoming requests',\n 'People who say they know this profile, but have not been confirmed yet.',\n 'No incoming requests are visible from the currently loaded data.'\n )\n const pendingGroup = createRequestGroup(\n 'Awaiting confirmation',\n 'People this profile knows who have not linked back yet.',\n 'Nothing is waiting for confirmation right now.'\n )\n\n const createPersonRow = function (target: NamedNode) {\n return widgets.personTR(dom, ns.foaf('knows'), target, {\n renderSupportingInfo,\n renderNameSuffix\n })\n }\n\n const sortNodes = function (nodes: NamedNode[]) {\n return [...nodes].sort((left, right) => {\n const leftLabel = utils.label(left) || left.value\n const rightLabel = utils.label(right) || right.value\n return leftLabel.localeCompare(rightLabel)\n })\n }\n\n const syncRequestGroup = function (\n group: { empty: HTMLElement, table: HTMLTableElement },\n nodes: NamedNode[]\n ) {\n const sortedNodes = sortNodes(nodes)\n group.empty.hidden = sortedNodes.length > 0\n group.table.hidden = sortedNodes.length === 0\n\n utils.syncTableToArray(\n group.table,\n sortedNodes,\n createPersonRow,\n function (_row, thing) {\n return createPersonRow(thing)\n }\n )\n }\n\n const refreshRequests = function (nextTriage: FriendshipTriage) {\n syncRequestGroup(incomingGroup, nextTriage.requests)\n syncRequestGroup(pendingGroup, nextTriage.unconfirmed)\n }\n\n refreshRequests(triage)\n\n return { section: requestsSection, refreshRequests }\n}\n"],"mappings":"iMAwCA,SAAgB,EACd,EACA,EACA,EACA,EACA,EACqB,CACrB,IAAM,EAAM,EAAQ,IACT,EAAQ,QAAQ,MAD3B,IAEM,EAAS,EAAI,cAAc,QAAQ,EACzC,EAAO,UAAY,sBACnB,IAAI,EAAiB,EAEf,EAAe,UAAY,CAC/B,EAAO,gBAAgB,EACvB,IAAM,EAAc,EAAe,EAE7B,EAAgB,EAAI,cAAc,KAAK,EAC7C,EAAc,UAAY,8BAE1B,IAAM,EAAgB,EAAI,cAAc,KAAK,EAG7C,GAFA,EAAc,UAAY,wEAEtB,GAAe,SAGR,EAAe,aAAe,iBAAmB,EAAe,oBAAqB,CAC9F,EAAc,UAAU,IAAI,qCAAqC,EACjE,IAAM,GAAA,EAAqB,EAAA,+BAAA,CAA+B,EAAS,CAAO,EAC1E,EAAmB,UAAU,IAAI,aAAa,EAC9C,EAAc,YAAY,CAAkB,CAC9C,CAEA,EAAO,YAAY,CAAa,EAEhC,IAAM,EAAc,EAAI,cAAc,KAAK,EAC3C,EAAY,UAAY,4BACxB,EAAc,YAAY,CAAW,EAEjC,GACF,EAAY,YAAY,EAAY,EAAK,EAAY,SAAU,EAAY,IAAI,CAAC,EAGlF,IAAM,EAAgB,EAAI,cAAc,KAAK,EAC7C,EAAc,UAAY,8BAC1B,EAAc,YAAY,CAAa,EAEnC,EAAc,WAAW,OAAS,GACpC,EAAc,YAAY,CAAa,EAGzC,IAAM,EAAgB,EAAI,cAAc,KAAK,EAC7C,EAAc,UAAU,IAAI,8BAA+B,aAAa,EACxE,EAAc,YAAY,CAAa,EAEvC,IAAM,EAAO,GAAa,MAAQ,EAAA,MAAM,MAAM,CAAO,EAC/C,EAAK,EAAI,cAAc,IAAI,EACjC,EAAG,UAAU,IAAI,0BAA0B,EAC3C,EAAG,YAAY,EAAI,eAAe,CAAI,CAAC,EACvC,EAAc,YAAY,CAAE,EAE5B,IAAM,EAAqB,CAAC,GAAa,SAAU,GAAa,YAAY,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,KAAK,EACxG,GAAI,EAAoB,CACtB,IAAM,EAAU,EAAI,cAAc,KAAK,EACvC,EAAQ,UAAY,8BACpB,EAAQ,YAAc,EACtB,EAAc,YAAY,CAAO,CACnC,CAEA,GAAI,GAAa,SAAU,CACzB,IAAM,EAAe,EAAI,cAAc,KAAK,EAC5C,EAAa,UAAY,+BAEzB,IAAM,EAAmB,EAAI,cAAc,MAAM,EACjD,EAAiB,UAAU,IAAI,oCAAqC,iBAAiB,EACrF,EAAiB,UAAY,EAAA,aAC7B,EAAa,YAAY,CAAgB,EACzC,EAAa,YAAY,EAAI,eAAe,EAAY,QAAQ,CAAC,EAEjE,EAAc,YAAY,CAAY,CACxC,CAEA,IAAM,EAAW,EAAI,cAAc,KAAK,EACxC,EAAS,UAAY,4BAErB,IAAM,EAAc,EAAI,cAAc,QAAQ,EAC9C,EAAY,UAAY,2BACxB,EAAY,KAAO,SACnB,IAAM,EAAmB,EAAI,cAAc,MAAM,EASjD,GARA,EAAiB,UAAY,iCAC7B,EAAiB,YAAc,GAAG,EAAM,YAAY,SAAS,EAAM,cAAgB,EAAI,GAAK,MAC5F,EAAY,YAAY,CAAgB,EACpC,EAAM,iBACR,EAAY,iBAAiB,QAAS,EAAM,eAAe,EAE7D,EAAS,YAAY,CAAW,EAE5B,OAAO,EAAM,mBAAsB,SAAU,CAC/C,IAAM,EAAc,EAAI,cAAc,QAAQ,EAC9C,EAAY,UAAY,2BACxB,EAAY,KAAO,SACnB,IAAM,EAAmB,EAAI,cAAc,MAAM,EACjD,EAAiB,UAAY,iCAC7B,EAAiB,YAAc,GAAG,EAAM,kBAAkB,gBAAgB,EAAM,oBAAsB,EAAI,GAAK,MAC/G,EAAY,YAAY,CAAgB,EACpC,EAAM,gBACR,EAAY,iBAAiB,QAAS,EAAM,cAAc,EAE5D,EAAS,YAAY,CAAW,CAClC,CAEA,EAAc,YAAY,CAAQ,CAEpC,EASA,MAPA,GAAO,oBAAsB,SAAU,EAA8B,CACnE,EAAiB,EACjB,EAAa,CACf,EAEA,EAAa,EAEN,CACT,CAEA,SAAS,EAAa,EAAmB,EAAgC,EAAM,GAAiB,CAC9F,GAAI,EAAK,CACP,IAAM,EAAM,EAAI,cAAc,KAAK,EAOnC,MANA,GAAI,UAAY,2BAChB,EAAI,IAAM,EACV,EAAI,IAAM,EACV,EAAI,MAAQ,IACZ,EAAI,OAAS,IACb,EAAI,QAAU,QACP,CACT,CAEA,IAAM,EAAW,EAAI,cAAc,KAAK,EACxC,EAAS,UAAY,2CACrB,EAAS,aAAa,OAAQ,KAAK,EACnC,EAAS,aAAa,aAAc,CAAG,EACvC,EAAS,SAAW,EAEpB,IAAM,EAAO,EAAI,cAAc,MAAM,EAKrC,OAJA,EAAK,UAAU,IAAI,gCAAiC,iBAAiB,EACrE,EAAK,UAAY,EAAA,mBACjB,EAAS,YAAY,CAAI,EAElB,CACT,CAEA,SAAgB,EAAqB,EAsBgD,CACnF,GAAM,CACJ,MACA,UACA,WACA,KACA,QACA,WACA,WACA,WACA,UACA,QACA,oBACA,OACA,OACA,oBACA,uBACA,oBACE,EAEA,EAAuB,UAAY,CAAC,EAElC,EAAgB,EAAI,cAAc,SAAS,EACjD,EAAc,UAAY,oDAC1B,EAAc,GAAK,sBACnB,EAAc,aAAa,OAAQ,UAAU,EAC7C,EAAc,aAAa,kBAAmB,mBAAmB,EAEjE,IAAM,EAAgB,EAAc,YAAY,EAAI,cAAc,KAAK,CAAC,EACxE,EAAc,UAAU,IAAI,cAAe,sBAAuB,aAAa,EAE/E,IAAM,EAAsB,EAAI,cAAc,KAAK,EACnD,EAAoB,UAAU,IAAI,wBAAyB,aAAa,EACxE,EAAc,YAAY,CAAmB,EAE7C,IAAM,EAAyB,UAAY,CACzC,IAAM,EAAO,EAAoB,YAAY,EAAI,cAAc,KAAK,CAAC,EAErE,OADA,EAAK,UAAU,IAAI,4BAA4B,EACxC,CACT,EAEM,EAAa,UAAY,CAC7B,IAAM,EAAO,EAAuB,EAIpC,OAHA,EAAK,YAAY,EAAK,EAAK,KAAK,EAAG,CAAK,CAAC,EACzC,EAAK,YAAY,EAAK,OAAO,CAAC,EAC9B,EAAK,YAAY,EAAK,EAAK,CAAQ,EAAG,EAAQ,GAAG,CAAC,EAC3C,CACT,EAEA,GAAI,CAAC,EACH,GAAI,CAAC,EAEH,EAAA,CAAA,CAAK,YAAY,EAAK,qCAAqC,CAAC,MACvD,CACL,IAAM,EAAO,EAAuB,EACpC,EAAK,YAAY,EAAK,EAAK,KAAK,EAAG,CAAK,CAAC,EACzC,EAAK,YAAY,EAAK,QAAQ,CAAC,EAC/B,EAAK,YAAY,EAAK,EAAK,CAAQ,EAAG,EAAQ,GAAG,CAAC,EAClD,EAAK,YAAY,EAAK,iBAAiB,CAAC,CAC1C,MACK,GAAK,EAWV,EAAA,CAAA,CAAK,YAAY,EAAK,2BAA2B,CAAC,MAX9B,CACpB,EAAoB,UAAU,IAAI,gCAAgC,EAElE,IAAM,EAAe,EAAoB,YAAY,EAAI,cAAc,KAAK,CAAC,EAC7E,EAAa,UAAU,IAAI,4BAA4B,EACvD,EAAa,YAAY,EAAK,EAAK,CAAQ,EAAG,EAAQ,GAAG,CAAC,EAC1D,EAAa,YAAY,EAAK,SAAS,CAAC,EACxC,EAAa,YAAY,EAAK,EAAK,KAAK,EAAG,CAAK,CAAC,EACjD,EAAa,YAAY,EAAK,iBAAiB,CAAC,CAClD,CAMA,GAD0C,GAAa,CAAC,EACzB,CAC7B,IAAM,EAAe,EAAI,cAAc,MAAM,EAC7C,EAAa,UAAY,+BACzB,EAAa,YAAY,EAAK,mBAAmB,CAAC,EAClD,EAAa,YAAY,EAAK,EAAK,CAAQ,EAAG,EAAQ,GAAG,CAAC,EAE1D,IAAM,EAAmB,EACvB,EACA,IAAI,EAAA,UAAU,EAAI,EAAO,EAAS,GAAW,IAAA,EAAS,EACtD,EAAQ,EACR,CACE,SAAU,CAAC,EACX,cAAgB,EAA4C,IAAA,GAAjC,8BAC7B,CACF,EACA,EAAiB,UAAU,IAAI,6BAA6B,EAE5D,EAAc,YAAY,CAAgB,CAC5C,CAEA,GAAI,EAAkB,OAAQ,CAC5B,IAAM,EAAqB,EAAc,YAAY,EAAI,cAAc,OAAO,CAAC,EAC/E,EAAmB,UAAY,sDAE/B,IAAM,EAAkB,SAAU,EAAmB,CACnD,OAAO,EAAA,QAAQ,SAAS,EAAK,EAAA,GAAG,KAAK,OAAO,EAAG,EAAQ,CACrD,uBACA,kBACF,CAAC,CACH,EAEA,EAAuB,UAAY,CACjC,IAAM,EAA0B,CAAC,GAAG,CAAiB,CAAC,CAAC,MAAM,EAAM,IAAU,CAC3E,IAAM,EAAY,EAAA,MAAM,MAAM,CAAI,GAAK,EAAK,MACtC,EAAa,EAAA,MAAM,MAAM,CAAK,GAAK,EAAM,MAC/C,OAAO,EAAU,cAAc,CAAU,CAC3C,CAAC,EAED,EAAA,MAAM,iBACJ,EACA,EACA,EACA,SAAU,EAAK,EAAO,CAEpB,OADoB,EAAgB,CAC7B,CACT,CACF,CACF,EAEA,EAAqB,CACvB,CAEA,MAAO,CAAE,QAAS,EAAe,QAAS,EAAe,sBAAqB,CAChF,CAEA,SAAgB,EAAyB,EAO2C,CAClF,GAAM,CAAE,MAAK,UAAS,UAAS,WAAU,uBAAsB,oBAAqB,EAE9E,EAAa,EAAI,cAAc,SAAS,EAC9C,EAAW,UAAY,iDACvB,EAAW,GAAK,2BAChB,EAAW,aAAa,OAAQ,UAAU,EAC1C,EAAW,aAAa,kBAAmB,wBAAwB,EAEnE,IAAM,EAAY,EAAW,YAAY,EAAI,cAAc,OAAO,CAAC,EACnE,EAAU,UAAY,cAEtB,IAAM,EAAc,EAAA,QAAQ,eAAe,EAAK,EAAS,EAAW,CAClE,IAAK,EACL,OAAQ,CAAC,CAAC,EACV,UAAW,EAAA,GAAG,KAAK,OAAO,EAC1B,KAAM,SAKN,sBAAuB,GACvB,uBACA,kBACF,CAAC,EACD,EAAY,UAAU,IAAI,qBAAqB,EAC/C,EAAY,MAAM,UAAY,IAE9B,IAAM,EAAiB,EAAY,cAAc,IAAI,EAC/C,EAAwB,GAAgB,WAAW,GACnD,EAAuB,GAAgB,WAAW,GAClD,EAAuB,EAAI,cAAc,KAAK,EAGpD,GAFA,EAAqB,UAAU,IAAI,+BAA+B,EAE9D,aAAiC,qBAAsB,CACzD,EAAsB,UAAU,IAAI,qCAAqC,EACzE,IAAM,EAAwB,EAAI,cAAc,OAAO,EACvD,EAAsB,UAAY,iCAClC,EAAsB,aAAa,OAAQ,cAAc,EAGzD,EAFwD,YAAY,EAAI,cAAc,OAAO,CAC5D,CAAA,CAA0B,YAAY,EAAI,cAAc,IAAI,CAC7F,CAAA,CAAyB,YAAY,CAAqB,EAC1D,EAAqB,YAAY,CAAqB,CACxD,MAAO,GAAI,aAAiC,YAAa,CACvD,KAAO,EAAsB,YAC3B,EAAqB,YAAY,EAAsB,UAAU,EAEnE,EAAsB,OAAO,CAC/B,CAEA,IAAM,EAAoB,EAAqB,iBAAiB,QAAQ,EACxE,GAAI,GAAY,EAAkB,OAAS,EAAG,CAC5C,EAAkB,QAAS,GAAW,CACpC,EAAO,aAAa,QAAS,kBAAkB,EAC/C,EAAO,aAAa,aAAc,kBAAkB,EAEpD,EAD4B,iBAAiB,KAC7C,CAAA,CAAa,QAAS,GAAU,CAC9B,EAAM,aAAa,QAAS,kBAAkB,EAC9C,EAAM,aAAa,MAAO,kBAAkB,CAC9C,CAAC,CACH,CAAC,EAED,IAAM,EAAoB,EAAI,cAAc,KAAK,EACjD,EAAkB,UAAY,0EAC9B,EAAkB,YAAY,CAAoB,EAClD,IAAM,EAAW,EAAI,cAAc,MAAM,EACzC,EAAS,UAAY,6BACrB,EAAS,YAAc,8CACvB,EAAkB,YAAY,CAAQ,EACtC,EAAW,QAAQ,CAAiB,CACtC,CAEI,aAAgC,uBAClC,EAAqB,QAAU,GAGjC,IAAM,EAAoB,EAAY,cAAc,UAAU,EAK9D,OAJI,aAA6B,kBAC/B,EAAkB,UAAU,IAAI,qBAAqB,EAGhD,CAAE,QAAS,EAAY,YAAW,aAAY,CACvD,CAEA,SAAgB,EAAuB,EAK2C,CAChF,GAAM,CAAE,MAAK,SAAQ,uBAAsB,oBAAqB,EAE1D,EAAkB,EAAI,cAAc,SAAS,EACnD,EAAgB,UAAY,8CAC5B,EAAgB,GAAK,wBACrB,EAAgB,aAAa,OAAQ,UAAU,EAC/C,EAAgB,aAAa,kBAAmB,qBAAqB,EAErE,IAAM,EAAkB,EAAgB,YAAY,EAAI,cAAc,KAAK,CAAC,EAC5E,EAAgB,UAAU,IAAI,cAAe,wBAAyB,aAAa,EAEnF,IAAM,EAAO,EAAgB,YAAY,EAAI,cAAc,GAAG,CAAC,EAC/D,EAAK,UAAY,wBACjB,EAAK,YAAc,oKAEnB,IAAM,EAAqB,SAAU,EAAe,EAAqB,EAAmB,CAC1F,IAAM,EAAQ,EAAgB,YAAY,EAAI,cAAc,SAAS,CAAC,EACtE,EAAM,UAAU,IAAI,yBAA0B,aAAa,EAE3D,IAAM,EAAS,EAAM,YAAY,EAAI,cAAc,KAAK,CAAC,EACzD,EAAO,UAAY,gCAEnB,IAAM,EAAU,EAAO,YAAY,EAAI,cAAc,IAAI,CAAC,EAC1D,EAAQ,UAAY,+BACpB,EAAQ,YAAc,EAEtB,IAAM,EAAQ,EAAO,YAAY,EAAI,cAAc,GAAG,CAAC,EACvD,EAAM,UAAY,qCAClB,EAAM,YAAc,EAEpB,IAAM,EAAQ,EAAM,YAAY,EAAI,cAAc,GAAG,CAAC,EACtD,EAAM,UAAY,yBAClB,EAAM,YAAc,EAEpB,IAAM,EAAQ,EAAM,YAAY,EAAI,cAAc,OAAO,CAAC,EAG1D,MAFA,GAAM,UAAY,6EAEX,CAAE,QAAO,OAAM,CACxB,EAEM,EAAgB,EACpB,oBACA,0EACA,kEACF,EACM,EAAe,EACnB,wBACA,0DACA,gDACF,EAEM,EAAkB,SAAU,EAAmB,CACnD,OAAO,EAAA,QAAQ,SAAS,EAAK,EAAA,GAAG,KAAK,OAAO,EAAG,EAAQ,CACrD,uBACA,kBACF,CAAC,CACH,EAEM,EAAY,SAAU,EAAoB,CAC9C,MAAO,CAAC,GAAG,CAAK,CAAC,CAAC,MAAM,EAAM,IAAU,CACtC,IAAM,EAAY,EAAA,MAAM,MAAM,CAAI,GAAK,EAAK,MACtC,EAAa,EAAA,MAAM,MAAM,CAAK,GAAK,EAAM,MAC/C,OAAO,EAAU,cAAc,CAAU,CAC3C,CAAC,CACH,EAEM,EAAmB,SACvB,EACA,EACA,CACA,IAAM,EAAc,EAAU,CAAK,EACnC,EAAM,MAAM,OAAS,EAAY,OAAS,EAC1C,EAAM,MAAM,OAAS,EAAY,SAAW,EAE5C,EAAA,MAAM,iBACJ,EAAM,MACN,EACA,EACA,SAAU,EAAM,EAAO,CACrB,OAAO,EAAgB,CAAK,CAC9B,CACF,CACF,EAEM,EAAkB,SAAU,EAA8B,CAC9D,EAAiB,EAAe,EAAW,QAAQ,EACnD,EAAiB,EAAc,EAAW,WAAW,CACvD,EAIA,OAFA,EAAgB,CAAM,EAEf,CAAE,QAAS,EAAiB,iBAAgB,CACrD"}
|
|
1
|
+
{"version":3,"file":"socialSections.cjs.js","names":[],"sources":["../../src/social/socialSections.ts"],"sourcesContent":["import { DataBrowserContext } from 'pane-registry'\nimport { createAddMeToYourFriendsButton } from 'profile-pane'\nimport { Statement, NamedNode } from 'rdflib'\nimport { ns, utils, widgets } from 'solid-ui'\nimport { appendProfileLinks } from './editProfileDetails'\nimport { locationIcon, personInCircleIcon as personInCircleIconSvg } from './icons'\nimport { FriendshipTriage } from './triage'\n\nexport type ViewerMode = 'owner' | 'authenticated' | 'anonymous'\n\nexport type HeaderControls = {\n canEdit: boolean,\n viewerMode: ViewerMode,\n showAddFriendAction?: boolean\n}\n\nexport type SocialHeaderElement = HTMLElement & {\n refreshSocialHeader?: (controls: HeaderControls) => void\n}\n\nexport type HeaderStats = {\n friendCount: number,\n mutualFriendCount: number | null,\n onSelectFriends?: () => void,\n onSelectMutual?: () => void\n}\n\nexport type HeaderProfileData = {\n imageUrl?: string,\n name?: string,\n jobTitle?: string,\n organization?: string,\n location?: string | null\n} | null\n\nexport type FriendRowRenderers = {\n renderSupportingInfo: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null,\n renderNameSuffix: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null\n}\n\nexport function createHeaderSection (\n context: DataBrowserContext,\n subject: NamedNode,\n controls: HeaderControls,\n stats: HeaderStats,\n getProfileData: () => HeaderProfileData\n): SocialHeaderElement {\n const dom = context.dom\n const kb = context.session.store\n const header = dom.createElement('header') as SocialHeaderElement\n header.className = 'social-pane__header'\n let headerControls = controls\n\n const renderHeader = function () {\n header.replaceChildren()\n const profileData = getProfileData()\n\n const headerContent = dom.createElement('div')\n headerContent.className = 'social-pane__header-content'\n\n const headerActions = dom.createElement('div')\n headerActions.className = 'social-pane__header-actions profile__actions profile__heading-actions'\n\n if (headerControls.canEdit) {\n // Hidden for now because the social pane header edit control does not match the new design.\n // Revisit later if we decide to restore profile-link editing here.\n } else if (headerControls.viewerMode === 'authenticated' && headerControls.showAddFriendAction) {\n headerActions.classList.add('social-pane__header-actions--friend')\n const addToFriendsButton = createAddMeToYourFriendsButton(subject, context)\n addToFriendsButton.classList.add('flex-center')\n headerActions.appendChild(addToFriendsButton)\n }\n\n header.appendChild(headerContent)\n\n const headerMedia = dom.createElement('div')\n headerMedia.className = 'social-pane__header-media'\n headerContent.appendChild(headerMedia)\n\n if (profileData) {\n headerMedia.appendChild(createImage(dom, profileData.imageUrl, profileData.name))\n }\n\n const headerDetails = dom.createElement('div')\n headerDetails.className = 'social-pane__header-details'\n headerContent.appendChild(headerDetails)\n\n if (headerActions.childNodes.length > 0) {\n headerContent.appendChild(headerActions)\n }\n\n const headerSummary = dom.createElement('div')\n headerSummary.classList.add('social-pane__header-summary', 'flex-column')\n headerDetails.appendChild(headerSummary)\n\n const name = profileData?.name || utils.label(subject)\n const h1 = dom.createElement('h1')\n h1.classList.add('social-pane__header-name')\n h1.appendChild(dom.createTextNode(name))\n headerSummary.appendChild(h1)\n\n const jobAndOrganization = [profileData?.jobTitle, profileData?.organization].filter(Boolean).join(' | ')\n if (jobAndOrganization) {\n const jobLine = dom.createElement('div')\n jobLine.className = 'social-pane__header-job-org'\n jobLine.textContent = jobAndOrganization\n headerSummary.appendChild(jobLine)\n }\n\n if (profileData?.location) {\n const locationLine = dom.createElement('div')\n locationLine.className = 'social-pane__header-location'\n\n const locationIconSpan = dom.createElement('span')\n locationIconSpan.classList.add('social-pane__header-location-icon', 'inline-flex-row')\n locationIconSpan.innerHTML = locationIcon\n locationLine.appendChild(locationIconSpan)\n locationLine.appendChild(dom.createTextNode(profileData.location))\n\n headerSummary.appendChild(locationLine)\n }\n\n const statsRow = dom.createElement('div')\n statsRow.className = 'social-pane__header-stats'\n\n const friendCount = dom.createElement('button')\n friendCount.className = 'social-pane__header-stat'\n friendCount.type = 'button'\n const friendCountLabel = dom.createElement('span')\n friendCountLabel.className = 'social-pane__header-stat-label'\n friendCountLabel.textContent = `${stats.friendCount} friend${stats.friendCount === 1 ? '' : 's'}`\n friendCount.appendChild(friendCountLabel)\n if (stats.onSelectFriends) {\n friendCount.addEventListener('click', stats.onSelectFriends)\n }\n statsRow.appendChild(friendCount)\n\n if (typeof stats.mutualFriendCount === 'number') {\n const mutualCount = dom.createElement('button')\n mutualCount.className = 'social-pane__header-stat'\n mutualCount.type = 'button'\n const mutualCountLabel = dom.createElement('span')\n mutualCountLabel.className = 'social-pane__header-stat-label'\n mutualCountLabel.textContent = `${stats.mutualFriendCount} mutual friend${stats.mutualFriendCount === 1 ? '' : 's'}`\n mutualCount.appendChild(mutualCountLabel)\n if (stats.onSelectMutual) {\n mutualCount.addEventListener('click', stats.onSelectMutual)\n }\n statsRow.appendChild(mutualCount)\n }\n\n headerSummary.appendChild(statsRow)\n appendProfileLinks(headerMedia, dom, kb, subject)\n }\n\n header.refreshSocialHeader = function (nextControls: HeaderControls) {\n headerControls = nextControls\n renderHeader()\n }\n\n renderHeader()\n\n return header\n}\n\nfunction createImage (dom: HTMLDocument, src: string | null | undefined, alt = ''): HTMLElement {\n if (src) {\n const img = dom.createElement('img')\n img.className = 'social-pane__header-hero'\n img.src = src\n img.alt = alt\n img.width = 180\n img.height = 180\n img.loading = 'eager'\n return img\n }\n\n const fallback = dom.createElement('div')\n fallback.className = 'social-pane__header-hero-alt flex-center'\n fallback.setAttribute('role', 'img')\n fallback.setAttribute('aria-label', alt)\n fallback.tabIndex = 0\n\n const icon = dom.createElement('span')\n icon.classList.add('social-pane__header-hero-icon', 'inline-flex-row')\n icon.innerHTML = personInCircleIconSvg\n fallback.appendChild(icon)\n\n return fallback\n}\n\nexport function createMutualSection (options: {\n dom: HTMLDocument,\n subject: NamedNode,\n familiar: string,\n me: NamedNode,\n meUri: string | null,\n incoming: boolean | NamedNode[] | undefined,\n outgoing: boolean | NamedNode[] | undefined,\n editable: boolean,\n profile: NamedNode | null,\n knows: NamedNode,\n mutualConnections: NamedNode[],\n link: (contents: Node, uri: string | null | undefined) => Node,\n text: (value: string) => Text,\n buildCheckboxForm: (\n label: string | Node,\n statement: Statement,\n state: boolean,\n options?: { disabled?: boolean, disabledTitle?: string }\n ) => HTMLElement,\n renderSupportingInfo: FriendRowRenderers['renderSupportingInfo'],\n renderNameSuffix: FriendRowRenderers['renderNameSuffix']\n}): { section: HTMLElement, content: HTMLElement, refreshMutualFriends: () => void } {\n const {\n dom,\n subject,\n familiar,\n me,\n meUri,\n incoming,\n outgoing,\n editable,\n profile,\n knows,\n mutualConnections,\n link,\n text,\n buildCheckboxForm,\n renderSupportingInfo,\n renderNameSuffix\n } = options\n\n let refreshMutualFriends = function () {}\n\n const mutualSection = dom.createElement('section')\n mutualSection.className = 'social-pane__mutual-friends social-primary__panel'\n mutualSection.id = 'social-panel-mutual'\n mutualSection.setAttribute('role', 'tabpanel')\n mutualSection.setAttribute('aria-labelledby', 'social-tab-mutual')\n\n const mutualContent = mutualSection.appendChild(dom.createElement('div'))\n mutualContent.classList.add('social-main', 'social-main--mutual', 'flex-column')\n\n const relationshipSummary = dom.createElement('div')\n relationshipSummary.classList.add('social-mutual-summary', 'flex-column')\n mutualContent.appendChild(relationshipSummary)\n\n const createRelationshipLine = function () {\n const line = relationshipSummary.appendChild(dom.createElement('div'))\n line.classList.add('social-mutual-summary-line')\n return line\n }\n\n const youAndThem = function () {\n const line = createRelationshipLine()\n line.appendChild(link(text('You'), meUri))\n line.appendChild(text(' and '))\n line.appendChild(link(text(familiar), subject.uri))\n return line\n }\n\n if (!incoming) {\n if (!outgoing) {\n const line = youAndThem()\n line.appendChild(text(' have not said you know each other.'))\n } else {\n const line = createRelationshipLine()\n line.appendChild(link(text('You'), meUri))\n line.appendChild(text(' know '))\n line.appendChild(link(text(familiar), subject.uri))\n line.appendChild(text(' (unconfirmed).'))\n }\n } else if (!outgoing) {\n relationshipSummary.classList.add('social-mutual-summary--confirm')\n\n const incomingLine = relationshipSummary.appendChild(dom.createElement('div'))\n incomingLine.classList.add('social-mutual-summary-line')\n incomingLine.appendChild(link(text(familiar), subject.uri))\n incomingLine.appendChild(text(' knows '))\n incomingLine.appendChild(link(text('you'), meUri))\n incomingLine.appendChild(text(' (unconfirmed).'))\n } else {\n const line = youAndThem()\n line.appendChild(text(' say you know each other.'))\n }\n\n const shouldShowCheckboxPreview = Boolean(incoming) && !outgoing\n if (shouldShowCheckboxPreview) {\n const confirmLabel = dom.createElement('span')\n confirmLabel.className = 'social-mutual-confirm-prompt'\n confirmLabel.appendChild(text('Confirm you know '))\n confirmLabel.appendChild(link(text(familiar), subject.uri))\n\n const relationshipForm = buildCheckboxForm(\n confirmLabel,\n new Statement(me, knows, subject, profile ?? undefined),\n Boolean(outgoing),\n {\n disabled: !editable,\n disabledTitle: !editable ? 'Your profile is not editable' : undefined\n }\n )\n relationshipForm.classList.add('social-mutual-checkbox-form')\n\n mutualContent.appendChild(relationshipForm)\n }\n\n if (mutualConnections.length) {\n const mutualFriendsTable = mutualContent.appendChild(dom.createElement('table'))\n mutualFriendsTable.className = 'social-main social-friends-list social-friends-grid'\n\n const createMutualRow = function (target: NamedNode) {\n return widgets.personTR(dom, ns.foaf('knows'), target, {\n renderSupportingInfo,\n renderNameSuffix\n })\n }\n\n refreshMutualFriends = function () {\n const sortedMutualConnections = [...mutualConnections].sort((left, right) => {\n const leftLabel = utils.label(left) || left.value\n const rightLabel = utils.label(right) || right.value\n return leftLabel.localeCompare(rightLabel)\n })\n\n utils.syncTableToArray(\n mutualFriendsTable,\n sortedMutualConnections,\n createMutualRow,\n function (row, thing) {\n const replacement = createMutualRow(thing)\n return replacement\n }\n )\n }\n\n refreshMutualFriends()\n }\n\n return { section: mutualSection, content: mutualContent, refreshMutualFriends }\n}\n\nexport function createAllFriendsSection (options: {\n dom: HTMLDocument,\n subject: NamedNode,\n profile: NamedNode | null,\n editable: boolean,\n renderSupportingInfo: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null,\n renderNameSuffix: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null\n}): { section: HTMLElement, mainTable: HTMLTableElement, friendsList: HTMLElement } {\n const { dom, subject, profile, editable, renderSupportingInfo, renderNameSuffix } = options\n\n const allFriends = dom.createElement('section')\n allFriends.className = 'social-pane__all-friends social-primary__panel'\n allFriends.id = 'social-panel-all-friends'\n allFriends.setAttribute('role', 'tabpanel')\n allFriends.setAttribute('aria-labelledby', 'social-tab-all-friends')\n\n const mainTable = allFriends.appendChild(dom.createElement('table'))\n mainTable.className = 'social-main'\n\n const friendsList = widgets.attachmentList(dom, subject, mainTable, {\n doc: profile,\n modify: !!editable,\n predicate: ns.foaf('knows'),\n noun: 'friend',\n // Social pane already owns the async refresh cycle for friend data in\n // socialPane.ts. Leave attachmentList's generic follow-up rerender disabled\n // here or each fetched friend profile will trigger an extra whole-table refresh\n // on top of the pane's own batched updates.\n refreshOnDocumentLoad: false,\n renderSupportingInfo,\n renderNameSuffix\n })\n friendsList.classList.add('social-friends-list')\n friendsList.style.marginTop = '0'\n\n const friendsListRow = friendsList.querySelector('tr')\n const friendsListPromptCell = friendsListRow?.children?.[0]\n const friendsListRightCell = friendsListRow?.children?.[1]\n const friendsHeaderActions = dom.createElement('div')\n friendsHeaderActions.classList.add('social-friends-header-actions')\n\n if (friendsListPromptCell instanceof HTMLTableCellElement) {\n friendsListPromptCell.classList.add('social-friends-header-dropzone-cell')\n const friendsHeaderDropzone = dom.createElement('table')\n friendsHeaderDropzone.className = 'social-friends-header-dropzone'\n friendsHeaderDropzone.setAttribute('role', 'presentation')\n const friendsHeaderDropzoneBody = friendsHeaderDropzone.appendChild(dom.createElement('tbody'))\n const friendsHeaderDropzoneRow = friendsHeaderDropzoneBody.appendChild(dom.createElement('tr'))\n friendsHeaderDropzoneRow.appendChild(friendsListPromptCell)\n friendsHeaderActions.appendChild(friendsHeaderDropzone)\n } else if (friendsListPromptCell instanceof HTMLElement) {\n while (friendsListPromptCell.firstChild) {\n friendsHeaderActions.appendChild(friendsListPromptCell.firstChild)\n }\n friendsListPromptCell.remove()\n }\n\n const friendDropButtons = friendsHeaderActions.querySelectorAll('button')\n if (editable && friendDropButtons.length > 0) {\n friendDropButtons.forEach((button) => {\n button.setAttribute('title', 'Drop friend here')\n button.setAttribute('aria-label', 'Drop friend here')\n const buttonImages = button.querySelectorAll('img')\n buttonImages.forEach((image) => {\n image.setAttribute('title', 'Drop friend here')\n image.setAttribute('alt', 'Drop friend here')\n })\n })\n\n const friendsActionsRow = dom.createElement('div')\n friendsActionsRow.className = 'social-friends-header-actions social-friends-header-actions--standalone'\n friendsActionsRow.appendChild(friendsHeaderActions)\n const dropHint = dom.createElement('span')\n dropHint.className = 'social-friends-header-hint'\n dropHint.textContent = 'Drag a WebId on the target to add a friend.'\n friendsActionsRow.appendChild(dropHint)\n allFriends.prepend(friendsActionsRow)\n }\n\n if (friendsListRightCell instanceof HTMLTableCellElement) {\n friendsListRightCell.colSpan = 2\n }\n\n const friendsItemsTable = friendsList.querySelector('td table')\n if (friendsItemsTable instanceof HTMLTableElement) {\n friendsItemsTable.classList.add('social-friends-grid')\n }\n\n return { section: allFriends, mainTable, friendsList }\n}\n\nexport function createRequestsSection (options: {\n dom: HTMLDocument,\n triage: FriendshipTriage,\n renderSupportingInfo: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null,\n renderNameSuffix: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null\n}): { section: HTMLElement, refreshRequests: (triage: FriendshipTriage) => void } {\n const { dom, triage, renderSupportingInfo, renderNameSuffix } = options\n\n const requestsSection = dom.createElement('section')\n requestsSection.className = 'social-pane__requests social-primary__panel'\n requestsSection.id = 'social-panel-requests'\n requestsSection.setAttribute('role', 'tabpanel')\n requestsSection.setAttribute('aria-labelledby', 'social-tab-requests')\n\n const requestsContent = requestsSection.appendChild(dom.createElement('div'))\n requestsContent.classList.add('social-main', 'social-main--requests', 'flex-column')\n\n const note = requestsContent.appendChild(dom.createElement('p'))\n note.className = 'social-requests__note'\n note.textContent = 'Best effort preview: this view only reflects profile documents that are currently loaded. A dedicated inbox would still be needed for complete request discovery.'\n\n const createRequestGroup = function (title: string, description: string, emptyText: string) {\n const group = requestsContent.appendChild(dom.createElement('section'))\n group.classList.add('social-requests__group', 'flex-column')\n\n const header = group.appendChild(dom.createElement('div'))\n header.className = 'social-requests__group-header'\n\n const heading = header.appendChild(dom.createElement('h2'))\n heading.className = 'social-requests__group-title'\n heading.textContent = title\n\n const blurb = header.appendChild(dom.createElement('p'))\n blurb.className = 'social-requests__group-description'\n blurb.textContent = description\n\n const empty = group.appendChild(dom.createElement('p'))\n empty.className = 'social-requests__empty'\n empty.textContent = emptyText\n\n const table = group.appendChild(dom.createElement('table'))\n table.className = 'social-main social-friends-list social-friends-grid social-requests__table'\n\n return { empty, table }\n }\n\n const incomingGroup = createRequestGroup(\n 'Incoming requests',\n 'People who say they know this profile, but have not been confirmed yet.',\n 'No incoming requests are visible from the currently loaded data.'\n )\n const pendingGroup = createRequestGroup(\n 'Awaiting confirmation',\n 'People this profile knows who have not linked back yet.',\n 'Nothing is waiting for confirmation right now.'\n )\n\n const createPersonRow = function (target: NamedNode) {\n return widgets.personTR(dom, ns.foaf('knows'), target, {\n renderSupportingInfo,\n renderNameSuffix\n })\n }\n\n const sortNodes = function (nodes: NamedNode[]) {\n return [...nodes].sort((left, right) => {\n const leftLabel = utils.label(left) || left.value\n const rightLabel = utils.label(right) || right.value\n return leftLabel.localeCompare(rightLabel)\n })\n }\n\n const syncRequestGroup = function (\n group: { empty: HTMLElement, table: HTMLTableElement },\n nodes: NamedNode[]\n ) {\n const sortedNodes = sortNodes(nodes)\n group.empty.hidden = sortedNodes.length > 0\n group.table.hidden = sortedNodes.length === 0\n\n utils.syncTableToArray(\n group.table,\n sortedNodes,\n createPersonRow,\n function (_row, thing) {\n return createPersonRow(thing)\n }\n )\n }\n\n const refreshRequests = function (nextTriage: FriendshipTriage) {\n syncRequestGroup(incomingGroup, nextTriage.requests)\n syncRequestGroup(pendingGroup, nextTriage.unconfirmed)\n }\n\n refreshRequests(triage)\n\n return { section: requestsSection, refreshRequests }\n}\n"],"mappings":"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"}
|
|
@@ -80,12 +80,13 @@ function l(e) {
|
|
|
80
80
|
let e = T();
|
|
81
81
|
return e.appendChild(g(_("You"), l)), e.appendChild(_(" and ")), e.appendChild(g(_(s), o.uri)), e;
|
|
82
82
|
};
|
|
83
|
-
if (!u)
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
83
|
+
if (!u) {
|
|
84
|
+
if (!d) E().appendChild(_(" have not said you know each other."));
|
|
85
|
+
else {
|
|
86
|
+
let e = T();
|
|
87
|
+
e.appendChild(g(_("You"), l)), e.appendChild(_(" know ")), e.appendChild(g(_(s), o.uri)), e.appendChild(_(" (unconfirmed)."));
|
|
88
|
+
}
|
|
89
|
+
} else if (d) E().appendChild(_(" say you know each other."));
|
|
89
90
|
else {
|
|
90
91
|
w.classList.add("social-mutual-summary--confirm");
|
|
91
92
|
let e = w.appendChild(t.createElement("div"));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socialSections.esm.js","names":[],"sources":["../../src/social/socialSections.ts"],"sourcesContent":["import { DataBrowserContext } from 'pane-registry'\nimport { createAddMeToYourFriendsButton } from 'profile-pane'\nimport { Statement, NamedNode } from 'rdflib'\nimport { ns, utils, widgets } from 'solid-ui'\nimport { appendProfileLinks } from './editProfileDetails'\nimport { locationIcon, personInCircleIcon as personInCircleIconSvg } from './icons'\nimport { FriendshipTriage } from './triage'\n\nexport type ViewerMode = 'owner' | 'authenticated' | 'anonymous'\n\nexport type HeaderControls = {\n canEdit: boolean,\n viewerMode: ViewerMode,\n showAddFriendAction?: boolean\n}\n\nexport type SocialHeaderElement = HTMLElement & {\n refreshSocialHeader?: (controls: HeaderControls) => void\n}\n\nexport type HeaderStats = {\n friendCount: number,\n mutualFriendCount: number | null,\n onSelectFriends?: () => void,\n onSelectMutual?: () => void\n}\n\nexport type HeaderProfileData = {\n imageUrl?: string,\n name?: string,\n jobTitle?: string,\n organization?: string,\n location?: string | null\n} | null\n\nexport type FriendRowRenderers = {\n renderSupportingInfo: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null,\n renderNameSuffix: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null\n}\n\nexport function createHeaderSection (\n context: DataBrowserContext,\n subject: NamedNode,\n controls: HeaderControls,\n stats: HeaderStats,\n getProfileData: () => HeaderProfileData\n): SocialHeaderElement {\n const dom = context.dom\n const kb = context.session.store\n const header = dom.createElement('header') as SocialHeaderElement\n header.className = 'social-pane__header'\n let headerControls = controls\n\n const renderHeader = function () {\n header.replaceChildren()\n const profileData = getProfileData()\n\n const headerContent = dom.createElement('div')\n headerContent.className = 'social-pane__header-content'\n\n const headerActions = dom.createElement('div')\n headerActions.className = 'social-pane__header-actions profile__actions profile__heading-actions'\n\n if (headerControls.canEdit) {\n // Hidden for now because the social pane header edit control does not match the new design.\n // Revisit later if we decide to restore profile-link editing here.\n } else if (headerControls.viewerMode === 'authenticated' && headerControls.showAddFriendAction) {\n headerActions.classList.add('social-pane__header-actions--friend')\n const addToFriendsButton = createAddMeToYourFriendsButton(subject, context)\n addToFriendsButton.classList.add('flex-center')\n headerActions.appendChild(addToFriendsButton)\n }\n\n header.appendChild(headerContent)\n\n const headerMedia = dom.createElement('div')\n headerMedia.className = 'social-pane__header-media'\n headerContent.appendChild(headerMedia)\n\n if (profileData) {\n headerMedia.appendChild(createImage(dom, profileData.imageUrl, profileData.name))\n }\n\n const headerDetails = dom.createElement('div')\n headerDetails.className = 'social-pane__header-details'\n headerContent.appendChild(headerDetails)\n\n if (headerActions.childNodes.length > 0) {\n headerContent.appendChild(headerActions)\n }\n\n const headerSummary = dom.createElement('div')\n headerSummary.classList.add('social-pane__header-summary', 'flex-column')\n headerDetails.appendChild(headerSummary)\n\n const name = profileData?.name || utils.label(subject)\n const h1 = dom.createElement('h1')\n h1.classList.add('social-pane__header-name')\n h1.appendChild(dom.createTextNode(name))\n headerSummary.appendChild(h1)\n\n const jobAndOrganization = [profileData?.jobTitle, profileData?.organization].filter(Boolean).join(' | ')\n if (jobAndOrganization) {\n const jobLine = dom.createElement('div')\n jobLine.className = 'social-pane__header-job-org'\n jobLine.textContent = jobAndOrganization\n headerSummary.appendChild(jobLine)\n }\n\n if (profileData?.location) {\n const locationLine = dom.createElement('div')\n locationLine.className = 'social-pane__header-location'\n\n const locationIconSpan = dom.createElement('span')\n locationIconSpan.classList.add('social-pane__header-location-icon', 'inline-flex-row')\n locationIconSpan.innerHTML = locationIcon\n locationLine.appendChild(locationIconSpan)\n locationLine.appendChild(dom.createTextNode(profileData.location))\n\n headerSummary.appendChild(locationLine)\n }\n\n const statsRow = dom.createElement('div')\n statsRow.className = 'social-pane__header-stats'\n\n const friendCount = dom.createElement('button')\n friendCount.className = 'social-pane__header-stat'\n friendCount.type = 'button'\n const friendCountLabel = dom.createElement('span')\n friendCountLabel.className = 'social-pane__header-stat-label'\n friendCountLabel.textContent = `${stats.friendCount} friend${stats.friendCount === 1 ? '' : 's'}`\n friendCount.appendChild(friendCountLabel)\n if (stats.onSelectFriends) {\n friendCount.addEventListener('click', stats.onSelectFriends)\n }\n statsRow.appendChild(friendCount)\n\n if (typeof stats.mutualFriendCount === 'number') {\n const mutualCount = dom.createElement('button')\n mutualCount.className = 'social-pane__header-stat'\n mutualCount.type = 'button'\n const mutualCountLabel = dom.createElement('span')\n mutualCountLabel.className = 'social-pane__header-stat-label'\n mutualCountLabel.textContent = `${stats.mutualFriendCount} mutual friend${stats.mutualFriendCount === 1 ? '' : 's'}`\n mutualCount.appendChild(mutualCountLabel)\n if (stats.onSelectMutual) {\n mutualCount.addEventListener('click', stats.onSelectMutual)\n }\n statsRow.appendChild(mutualCount)\n }\n\n headerSummary.appendChild(statsRow)\n appendProfileLinks(headerMedia, dom, kb, subject)\n }\n\n header.refreshSocialHeader = function (nextControls: HeaderControls) {\n headerControls = nextControls\n renderHeader()\n }\n\n renderHeader()\n\n return header\n}\n\nfunction createImage (dom: HTMLDocument, src: string | null | undefined, alt = ''): HTMLElement {\n if (src) {\n const img = dom.createElement('img')\n img.className = 'social-pane__header-hero'\n img.src = src\n img.alt = alt\n img.width = 180\n img.height = 180\n img.loading = 'eager'\n return img\n }\n\n const fallback = dom.createElement('div')\n fallback.className = 'social-pane__header-hero-alt flex-center'\n fallback.setAttribute('role', 'img')\n fallback.setAttribute('aria-label', alt)\n fallback.tabIndex = 0\n\n const icon = dom.createElement('span')\n icon.classList.add('social-pane__header-hero-icon', 'inline-flex-row')\n icon.innerHTML = personInCircleIconSvg\n fallback.appendChild(icon)\n\n return fallback\n}\n\nexport function createMutualSection (options: {\n dom: HTMLDocument,\n subject: NamedNode,\n familiar: string,\n me: NamedNode,\n meUri: string | null,\n incoming: boolean | NamedNode[] | undefined,\n outgoing: boolean | NamedNode[] | undefined,\n editable: boolean,\n profile: NamedNode | null,\n knows: NamedNode,\n mutualConnections: NamedNode[],\n link: (contents: Node, uri: string | null | undefined) => Node,\n text: (value: string) => Text,\n buildCheckboxForm: (\n label: string | Node,\n statement: Statement,\n state: boolean,\n options?: { disabled?: boolean, disabledTitle?: string }\n ) => HTMLElement,\n renderSupportingInfo: FriendRowRenderers['renderSupportingInfo'],\n renderNameSuffix: FriendRowRenderers['renderNameSuffix']\n}): { section: HTMLElement, content: HTMLElement, refreshMutualFriends: () => void } {\n const {\n dom,\n subject,\n familiar,\n me,\n meUri,\n incoming,\n outgoing,\n editable,\n profile,\n knows,\n mutualConnections,\n link,\n text,\n buildCheckboxForm,\n renderSupportingInfo,\n renderNameSuffix\n } = options\n\n let refreshMutualFriends = function () {}\n\n const mutualSection = dom.createElement('section')\n mutualSection.className = 'social-pane__mutual-friends social-primary__panel'\n mutualSection.id = 'social-panel-mutual'\n mutualSection.setAttribute('role', 'tabpanel')\n mutualSection.setAttribute('aria-labelledby', 'social-tab-mutual')\n\n const mutualContent = mutualSection.appendChild(dom.createElement('div'))\n mutualContent.classList.add('social-main', 'social-main--mutual', 'flex-column')\n\n const relationshipSummary = dom.createElement('div')\n relationshipSummary.classList.add('social-mutual-summary', 'flex-column')\n mutualContent.appendChild(relationshipSummary)\n\n const createRelationshipLine = function () {\n const line = relationshipSummary.appendChild(dom.createElement('div'))\n line.classList.add('social-mutual-summary-line')\n return line\n }\n\n const youAndThem = function () {\n const line = createRelationshipLine()\n line.appendChild(link(text('You'), meUri))\n line.appendChild(text(' and '))\n line.appendChild(link(text(familiar), subject.uri))\n return line\n }\n\n if (!incoming) {\n if (!outgoing) {\n const line = youAndThem()\n line.appendChild(text(' have not said you know each other.'))\n } else {\n const line = createRelationshipLine()\n line.appendChild(link(text('You'), meUri))\n line.appendChild(text(' know '))\n line.appendChild(link(text(familiar), subject.uri))\n line.appendChild(text(' (unconfirmed).'))\n }\n } else if (!outgoing) {\n relationshipSummary.classList.add('social-mutual-summary--confirm')\n\n const incomingLine = relationshipSummary.appendChild(dom.createElement('div'))\n incomingLine.classList.add('social-mutual-summary-line')\n incomingLine.appendChild(link(text(familiar), subject.uri))\n incomingLine.appendChild(text(' knows '))\n incomingLine.appendChild(link(text('you'), meUri))\n incomingLine.appendChild(text(' (unconfirmed).'))\n } else {\n const line = youAndThem()\n line.appendChild(text(' say you know each other.'))\n }\n\n const shouldShowCheckboxPreview = Boolean(incoming) && !outgoing\n if (shouldShowCheckboxPreview) {\n const confirmLabel = dom.createElement('span')\n confirmLabel.className = 'social-mutual-confirm-prompt'\n confirmLabel.appendChild(text('Confirm you know '))\n confirmLabel.appendChild(link(text(familiar), subject.uri))\n\n const relationshipForm = buildCheckboxForm(\n confirmLabel,\n new Statement(me, knows, subject, profile ?? undefined),\n Boolean(outgoing),\n {\n disabled: !editable,\n disabledTitle: !editable ? 'Your profile is not editable' : undefined\n }\n )\n relationshipForm.classList.add('social-mutual-checkbox-form')\n\n mutualContent.appendChild(relationshipForm)\n }\n\n if (mutualConnections.length) {\n const mutualFriendsTable = mutualContent.appendChild(dom.createElement('table'))\n mutualFriendsTable.className = 'social-main social-friends-list social-friends-grid'\n\n const createMutualRow = function (target: NamedNode) {\n return widgets.personTR(dom, ns.foaf('knows'), target, {\n renderSupportingInfo,\n renderNameSuffix\n })\n }\n\n refreshMutualFriends = function () {\n const sortedMutualConnections = [...mutualConnections].sort((left, right) => {\n const leftLabel = utils.label(left) || left.value\n const rightLabel = utils.label(right) || right.value\n return leftLabel.localeCompare(rightLabel)\n })\n\n utils.syncTableToArray(\n mutualFriendsTable,\n sortedMutualConnections,\n createMutualRow,\n function (row, thing) {\n const replacement = createMutualRow(thing)\n return replacement\n }\n )\n }\n\n refreshMutualFriends()\n }\n\n return { section: mutualSection, content: mutualContent, refreshMutualFriends }\n}\n\nexport function createAllFriendsSection (options: {\n dom: HTMLDocument,\n subject: NamedNode,\n profile: NamedNode | null,\n editable: boolean,\n renderSupportingInfo: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null,\n renderNameSuffix: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null\n}): { section: HTMLElement, mainTable: HTMLTableElement, friendsList: HTMLElement } {\n const { dom, subject, profile, editable, renderSupportingInfo, renderNameSuffix } = options\n\n const allFriends = dom.createElement('section')\n allFriends.className = 'social-pane__all-friends social-primary__panel'\n allFriends.id = 'social-panel-all-friends'\n allFriends.setAttribute('role', 'tabpanel')\n allFriends.setAttribute('aria-labelledby', 'social-tab-all-friends')\n\n const mainTable = allFriends.appendChild(dom.createElement('table'))\n mainTable.className = 'social-main'\n\n const friendsList = widgets.attachmentList(dom, subject, mainTable, {\n doc: profile,\n modify: !!editable,\n predicate: ns.foaf('knows'),\n noun: 'friend',\n // Social pane already owns the async refresh cycle for friend data in\n // socialPane.ts. Leave attachmentList's generic follow-up rerender disabled\n // here or each fetched friend profile will trigger an extra whole-table refresh\n // on top of the pane's own batched updates.\n refreshOnDocumentLoad: false,\n renderSupportingInfo,\n renderNameSuffix\n })\n friendsList.classList.add('social-friends-list')\n friendsList.style.marginTop = '0'\n\n const friendsListRow = friendsList.querySelector('tr')\n const friendsListPromptCell = friendsListRow?.children?.[0]\n const friendsListRightCell = friendsListRow?.children?.[1]\n const friendsHeaderActions = dom.createElement('div')\n friendsHeaderActions.classList.add('social-friends-header-actions')\n\n if (friendsListPromptCell instanceof HTMLTableCellElement) {\n friendsListPromptCell.classList.add('social-friends-header-dropzone-cell')\n const friendsHeaderDropzone = dom.createElement('table')\n friendsHeaderDropzone.className = 'social-friends-header-dropzone'\n friendsHeaderDropzone.setAttribute('role', 'presentation')\n const friendsHeaderDropzoneBody = friendsHeaderDropzone.appendChild(dom.createElement('tbody'))\n const friendsHeaderDropzoneRow = friendsHeaderDropzoneBody.appendChild(dom.createElement('tr'))\n friendsHeaderDropzoneRow.appendChild(friendsListPromptCell)\n friendsHeaderActions.appendChild(friendsHeaderDropzone)\n } else if (friendsListPromptCell instanceof HTMLElement) {\n while (friendsListPromptCell.firstChild) {\n friendsHeaderActions.appendChild(friendsListPromptCell.firstChild)\n }\n friendsListPromptCell.remove()\n }\n\n const friendDropButtons = friendsHeaderActions.querySelectorAll('button')\n if (editable && friendDropButtons.length > 0) {\n friendDropButtons.forEach((button) => {\n button.setAttribute('title', 'Drop friend here')\n button.setAttribute('aria-label', 'Drop friend here')\n const buttonImages = button.querySelectorAll('img')\n buttonImages.forEach((image) => {\n image.setAttribute('title', 'Drop friend here')\n image.setAttribute('alt', 'Drop friend here')\n })\n })\n\n const friendsActionsRow = dom.createElement('div')\n friendsActionsRow.className = 'social-friends-header-actions social-friends-header-actions--standalone'\n friendsActionsRow.appendChild(friendsHeaderActions)\n const dropHint = dom.createElement('span')\n dropHint.className = 'social-friends-header-hint'\n dropHint.textContent = 'Drag a WebId on the target to add a friend.'\n friendsActionsRow.appendChild(dropHint)\n allFriends.prepend(friendsActionsRow)\n }\n\n if (friendsListRightCell instanceof HTMLTableCellElement) {\n friendsListRightCell.colSpan = 2\n }\n\n const friendsItemsTable = friendsList.querySelector('td table')\n if (friendsItemsTable instanceof HTMLTableElement) {\n friendsItemsTable.classList.add('social-friends-grid')\n }\n\n return { section: allFriends, mainTable, friendsList }\n}\n\nexport function createRequestsSection (options: {\n dom: HTMLDocument,\n triage: FriendshipTriage,\n renderSupportingInfo: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null,\n renderNameSuffix: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null\n}): { section: HTMLElement, refreshRequests: (triage: FriendshipTriage) => void } {\n const { dom, triage, renderSupportingInfo, renderNameSuffix } = options\n\n const requestsSection = dom.createElement('section')\n requestsSection.className = 'social-pane__requests social-primary__panel'\n requestsSection.id = 'social-panel-requests'\n requestsSection.setAttribute('role', 'tabpanel')\n requestsSection.setAttribute('aria-labelledby', 'social-tab-requests')\n\n const requestsContent = requestsSection.appendChild(dom.createElement('div'))\n requestsContent.classList.add('social-main', 'social-main--requests', 'flex-column')\n\n const note = requestsContent.appendChild(dom.createElement('p'))\n note.className = 'social-requests__note'\n note.textContent = 'Best effort preview: this view only reflects profile documents that are currently loaded. A dedicated inbox would still be needed for complete request discovery.'\n\n const createRequestGroup = function (title: string, description: string, emptyText: string) {\n const group = requestsContent.appendChild(dom.createElement('section'))\n group.classList.add('social-requests__group', 'flex-column')\n\n const header = group.appendChild(dom.createElement('div'))\n header.className = 'social-requests__group-header'\n\n const heading = header.appendChild(dom.createElement('h2'))\n heading.className = 'social-requests__group-title'\n heading.textContent = title\n\n const blurb = header.appendChild(dom.createElement('p'))\n blurb.className = 'social-requests__group-description'\n blurb.textContent = description\n\n const empty = group.appendChild(dom.createElement('p'))\n empty.className = 'social-requests__empty'\n empty.textContent = emptyText\n\n const table = group.appendChild(dom.createElement('table'))\n table.className = 'social-main social-friends-list social-friends-grid social-requests__table'\n\n return { empty, table }\n }\n\n const incomingGroup = createRequestGroup(\n 'Incoming requests',\n 'People who say they know this profile, but have not been confirmed yet.',\n 'No incoming requests are visible from the currently loaded data.'\n )\n const pendingGroup = createRequestGroup(\n 'Awaiting confirmation',\n 'People this profile knows who have not linked back yet.',\n 'Nothing is waiting for confirmation right now.'\n )\n\n const createPersonRow = function (target: NamedNode) {\n return widgets.personTR(dom, ns.foaf('knows'), target, {\n renderSupportingInfo,\n renderNameSuffix\n })\n }\n\n const sortNodes = function (nodes: NamedNode[]) {\n return [...nodes].sort((left, right) => {\n const leftLabel = utils.label(left) || left.value\n const rightLabel = utils.label(right) || right.value\n return leftLabel.localeCompare(rightLabel)\n })\n }\n\n const syncRequestGroup = function (\n group: { empty: HTMLElement, table: HTMLTableElement },\n nodes: NamedNode[]\n ) {\n const sortedNodes = sortNodes(nodes)\n group.empty.hidden = sortedNodes.length > 0\n group.table.hidden = sortedNodes.length === 0\n\n utils.syncTableToArray(\n group.table,\n sortedNodes,\n createPersonRow,\n function (_row, thing) {\n return createPersonRow(thing)\n }\n )\n }\n\n const refreshRequests = function (nextTriage: FriendshipTriage) {\n syncRequestGroup(incomingGroup, nextTriage.requests)\n syncRequestGroup(pendingGroup, nextTriage.unconfirmed)\n }\n\n refreshRequests(triage)\n\n return { section: requestsSection, refreshRequests }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"socialSections.esm.js","names":[],"sources":["../../src/social/socialSections.ts"],"sourcesContent":["import { DataBrowserContext } from 'pane-registry'\nimport { createAddMeToYourFriendsButton } from 'profile-pane'\nimport { Statement, NamedNode } from 'rdflib'\nimport { ns, utils, widgets } from 'solid-ui'\nimport { appendProfileLinks } from './editProfileDetails'\nimport { locationIcon, personInCircleIcon as personInCircleIconSvg } from './icons'\nimport { FriendshipTriage } from './triage'\n\nexport type ViewerMode = 'owner' | 'authenticated' | 'anonymous'\n\nexport type HeaderControls = {\n canEdit: boolean,\n viewerMode: ViewerMode,\n showAddFriendAction?: boolean\n}\n\nexport type SocialHeaderElement = HTMLElement & {\n refreshSocialHeader?: (controls: HeaderControls) => void\n}\n\nexport type HeaderStats = {\n friendCount: number,\n mutualFriendCount: number | null,\n onSelectFriends?: () => void,\n onSelectMutual?: () => void\n}\n\nexport type HeaderProfileData = {\n imageUrl?: string,\n name?: string,\n jobTitle?: string,\n organization?: string,\n location?: string | null\n} | null\n\nexport type FriendRowRenderers = {\n renderSupportingInfo: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null,\n renderNameSuffix: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null\n}\n\nexport function createHeaderSection (\n context: DataBrowserContext,\n subject: NamedNode,\n controls: HeaderControls,\n stats: HeaderStats,\n getProfileData: () => HeaderProfileData\n): SocialHeaderElement {\n const dom = context.dom\n const kb = context.session.store\n const header = dom.createElement('header') as SocialHeaderElement\n header.className = 'social-pane__header'\n let headerControls = controls\n\n const renderHeader = function () {\n header.replaceChildren()\n const profileData = getProfileData()\n\n const headerContent = dom.createElement('div')\n headerContent.className = 'social-pane__header-content'\n\n const headerActions = dom.createElement('div')\n headerActions.className = 'social-pane__header-actions profile__actions profile__heading-actions'\n\n if (headerControls.canEdit) {\n // Hidden for now because the social pane header edit control does not match the new design.\n // Revisit later if we decide to restore profile-link editing here.\n } else if (headerControls.viewerMode === 'authenticated' && headerControls.showAddFriendAction) {\n headerActions.classList.add('social-pane__header-actions--friend')\n const addToFriendsButton = createAddMeToYourFriendsButton(subject, context)\n addToFriendsButton.classList.add('flex-center')\n headerActions.appendChild(addToFriendsButton)\n }\n\n header.appendChild(headerContent)\n\n const headerMedia = dom.createElement('div')\n headerMedia.className = 'social-pane__header-media'\n headerContent.appendChild(headerMedia)\n\n if (profileData) {\n headerMedia.appendChild(createImage(dom, profileData.imageUrl, profileData.name))\n }\n\n const headerDetails = dom.createElement('div')\n headerDetails.className = 'social-pane__header-details'\n headerContent.appendChild(headerDetails)\n\n if (headerActions.childNodes.length > 0) {\n headerContent.appendChild(headerActions)\n }\n\n const headerSummary = dom.createElement('div')\n headerSummary.classList.add('social-pane__header-summary', 'flex-column')\n headerDetails.appendChild(headerSummary)\n\n const name = profileData?.name || utils.label(subject)\n const h1 = dom.createElement('h1')\n h1.classList.add('social-pane__header-name')\n h1.appendChild(dom.createTextNode(name))\n headerSummary.appendChild(h1)\n\n const jobAndOrganization = [profileData?.jobTitle, profileData?.organization].filter(Boolean).join(' | ')\n if (jobAndOrganization) {\n const jobLine = dom.createElement('div')\n jobLine.className = 'social-pane__header-job-org'\n jobLine.textContent = jobAndOrganization\n headerSummary.appendChild(jobLine)\n }\n\n if (profileData?.location) {\n const locationLine = dom.createElement('div')\n locationLine.className = 'social-pane__header-location'\n\n const locationIconSpan = dom.createElement('span')\n locationIconSpan.classList.add('social-pane__header-location-icon', 'inline-flex-row')\n locationIconSpan.innerHTML = locationIcon\n locationLine.appendChild(locationIconSpan)\n locationLine.appendChild(dom.createTextNode(profileData.location))\n\n headerSummary.appendChild(locationLine)\n }\n\n const statsRow = dom.createElement('div')\n statsRow.className = 'social-pane__header-stats'\n\n const friendCount = dom.createElement('button')\n friendCount.className = 'social-pane__header-stat'\n friendCount.type = 'button'\n const friendCountLabel = dom.createElement('span')\n friendCountLabel.className = 'social-pane__header-stat-label'\n friendCountLabel.textContent = `${stats.friendCount} friend${stats.friendCount === 1 ? '' : 's'}`\n friendCount.appendChild(friendCountLabel)\n if (stats.onSelectFriends) {\n friendCount.addEventListener('click', stats.onSelectFriends)\n }\n statsRow.appendChild(friendCount)\n\n if (typeof stats.mutualFriendCount === 'number') {\n const mutualCount = dom.createElement('button')\n mutualCount.className = 'social-pane__header-stat'\n mutualCount.type = 'button'\n const mutualCountLabel = dom.createElement('span')\n mutualCountLabel.className = 'social-pane__header-stat-label'\n mutualCountLabel.textContent = `${stats.mutualFriendCount} mutual friend${stats.mutualFriendCount === 1 ? '' : 's'}`\n mutualCount.appendChild(mutualCountLabel)\n if (stats.onSelectMutual) {\n mutualCount.addEventListener('click', stats.onSelectMutual)\n }\n statsRow.appendChild(mutualCount)\n }\n\n headerSummary.appendChild(statsRow)\n appendProfileLinks(headerMedia, dom, kb, subject)\n }\n\n header.refreshSocialHeader = function (nextControls: HeaderControls) {\n headerControls = nextControls\n renderHeader()\n }\n\n renderHeader()\n\n return header\n}\n\nfunction createImage (dom: HTMLDocument, src: string | null | undefined, alt = ''): HTMLElement {\n if (src) {\n const img = dom.createElement('img')\n img.className = 'social-pane__header-hero'\n img.src = src\n img.alt = alt\n img.width = 180\n img.height = 180\n img.loading = 'eager'\n return img\n }\n\n const fallback = dom.createElement('div')\n fallback.className = 'social-pane__header-hero-alt flex-center'\n fallback.setAttribute('role', 'img')\n fallback.setAttribute('aria-label', alt)\n fallback.tabIndex = 0\n\n const icon = dom.createElement('span')\n icon.classList.add('social-pane__header-hero-icon', 'inline-flex-row')\n icon.innerHTML = personInCircleIconSvg\n fallback.appendChild(icon)\n\n return fallback\n}\n\nexport function createMutualSection (options: {\n dom: HTMLDocument,\n subject: NamedNode,\n familiar: string,\n me: NamedNode,\n meUri: string | null,\n incoming: boolean | NamedNode[] | undefined,\n outgoing: boolean | NamedNode[] | undefined,\n editable: boolean,\n profile: NamedNode | null,\n knows: NamedNode,\n mutualConnections: NamedNode[],\n link: (contents: Node, uri: string | null | undefined) => Node,\n text: (value: string) => Text,\n buildCheckboxForm: (\n label: string | Node,\n statement: Statement,\n state: boolean,\n options?: { disabled?: boolean, disabledTitle?: string }\n ) => HTMLElement,\n renderSupportingInfo: FriendRowRenderers['renderSupportingInfo'],\n renderNameSuffix: FriendRowRenderers['renderNameSuffix']\n}): { section: HTMLElement, content: HTMLElement, refreshMutualFriends: () => void } {\n const {\n dom,\n subject,\n familiar,\n me,\n meUri,\n incoming,\n outgoing,\n editable,\n profile,\n knows,\n mutualConnections,\n link,\n text,\n buildCheckboxForm,\n renderSupportingInfo,\n renderNameSuffix\n } = options\n\n let refreshMutualFriends = function () {}\n\n const mutualSection = dom.createElement('section')\n mutualSection.className = 'social-pane__mutual-friends social-primary__panel'\n mutualSection.id = 'social-panel-mutual'\n mutualSection.setAttribute('role', 'tabpanel')\n mutualSection.setAttribute('aria-labelledby', 'social-tab-mutual')\n\n const mutualContent = mutualSection.appendChild(dom.createElement('div'))\n mutualContent.classList.add('social-main', 'social-main--mutual', 'flex-column')\n\n const relationshipSummary = dom.createElement('div')\n relationshipSummary.classList.add('social-mutual-summary', 'flex-column')\n mutualContent.appendChild(relationshipSummary)\n\n const createRelationshipLine = function () {\n const line = relationshipSummary.appendChild(dom.createElement('div'))\n line.classList.add('social-mutual-summary-line')\n return line\n }\n\n const youAndThem = function () {\n const line = createRelationshipLine()\n line.appendChild(link(text('You'), meUri))\n line.appendChild(text(' and '))\n line.appendChild(link(text(familiar), subject.uri))\n return line\n }\n\n if (!incoming) {\n if (!outgoing) {\n const line = youAndThem()\n line.appendChild(text(' have not said you know each other.'))\n } else {\n const line = createRelationshipLine()\n line.appendChild(link(text('You'), meUri))\n line.appendChild(text(' know '))\n line.appendChild(link(text(familiar), subject.uri))\n line.appendChild(text(' (unconfirmed).'))\n }\n } else if (!outgoing) {\n relationshipSummary.classList.add('social-mutual-summary--confirm')\n\n const incomingLine = relationshipSummary.appendChild(dom.createElement('div'))\n incomingLine.classList.add('social-mutual-summary-line')\n incomingLine.appendChild(link(text(familiar), subject.uri))\n incomingLine.appendChild(text(' knows '))\n incomingLine.appendChild(link(text('you'), meUri))\n incomingLine.appendChild(text(' (unconfirmed).'))\n } else {\n const line = youAndThem()\n line.appendChild(text(' say you know each other.'))\n }\n\n const shouldShowCheckboxPreview = Boolean(incoming) && !outgoing\n if (shouldShowCheckboxPreview) {\n const confirmLabel = dom.createElement('span')\n confirmLabel.className = 'social-mutual-confirm-prompt'\n confirmLabel.appendChild(text('Confirm you know '))\n confirmLabel.appendChild(link(text(familiar), subject.uri))\n\n const relationshipForm = buildCheckboxForm(\n confirmLabel,\n new Statement(me, knows, subject, profile ?? undefined),\n Boolean(outgoing),\n {\n disabled: !editable,\n disabledTitle: !editable ? 'Your profile is not editable' : undefined\n }\n )\n relationshipForm.classList.add('social-mutual-checkbox-form')\n\n mutualContent.appendChild(relationshipForm)\n }\n\n if (mutualConnections.length) {\n const mutualFriendsTable = mutualContent.appendChild(dom.createElement('table'))\n mutualFriendsTable.className = 'social-main social-friends-list social-friends-grid'\n\n const createMutualRow = function (target: NamedNode) {\n return widgets.personTR(dom, ns.foaf('knows'), target, {\n renderSupportingInfo,\n renderNameSuffix\n })\n }\n\n refreshMutualFriends = function () {\n const sortedMutualConnections = [...mutualConnections].sort((left, right) => {\n const leftLabel = utils.label(left) || left.value\n const rightLabel = utils.label(right) || right.value\n return leftLabel.localeCompare(rightLabel)\n })\n\n utils.syncTableToArray(\n mutualFriendsTable,\n sortedMutualConnections,\n createMutualRow,\n function (row, thing) {\n const replacement = createMutualRow(thing)\n return replacement\n }\n )\n }\n\n refreshMutualFriends()\n }\n\n return { section: mutualSection, content: mutualContent, refreshMutualFriends }\n}\n\nexport function createAllFriendsSection (options: {\n dom: HTMLDocument,\n subject: NamedNode,\n profile: NamedNode | null,\n editable: boolean,\n renderSupportingInfo: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null,\n renderNameSuffix: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null\n}): { section: HTMLElement, mainTable: HTMLTableElement, friendsList: HTMLElement } {\n const { dom, subject, profile, editable, renderSupportingInfo, renderNameSuffix } = options\n\n const allFriends = dom.createElement('section')\n allFriends.className = 'social-pane__all-friends social-primary__panel'\n allFriends.id = 'social-panel-all-friends'\n allFriends.setAttribute('role', 'tabpanel')\n allFriends.setAttribute('aria-labelledby', 'social-tab-all-friends')\n\n const mainTable = allFriends.appendChild(dom.createElement('table'))\n mainTable.className = 'social-main'\n\n const friendsList = widgets.attachmentList(dom, subject, mainTable, {\n doc: profile,\n modify: !!editable,\n predicate: ns.foaf('knows'),\n noun: 'friend',\n // Social pane already owns the async refresh cycle for friend data in\n // socialPane.ts. Leave attachmentList's generic follow-up rerender disabled\n // here or each fetched friend profile will trigger an extra whole-table refresh\n // on top of the pane's own batched updates.\n refreshOnDocumentLoad: false,\n renderSupportingInfo,\n renderNameSuffix\n })\n friendsList.classList.add('social-friends-list')\n friendsList.style.marginTop = '0'\n\n const friendsListRow = friendsList.querySelector('tr')\n const friendsListPromptCell = friendsListRow?.children?.[0]\n const friendsListRightCell = friendsListRow?.children?.[1]\n const friendsHeaderActions = dom.createElement('div')\n friendsHeaderActions.classList.add('social-friends-header-actions')\n\n if (friendsListPromptCell instanceof HTMLTableCellElement) {\n friendsListPromptCell.classList.add('social-friends-header-dropzone-cell')\n const friendsHeaderDropzone = dom.createElement('table')\n friendsHeaderDropzone.className = 'social-friends-header-dropzone'\n friendsHeaderDropzone.setAttribute('role', 'presentation')\n const friendsHeaderDropzoneBody = friendsHeaderDropzone.appendChild(dom.createElement('tbody'))\n const friendsHeaderDropzoneRow = friendsHeaderDropzoneBody.appendChild(dom.createElement('tr'))\n friendsHeaderDropzoneRow.appendChild(friendsListPromptCell)\n friendsHeaderActions.appendChild(friendsHeaderDropzone)\n } else if (friendsListPromptCell instanceof HTMLElement) {\n while (friendsListPromptCell.firstChild) {\n friendsHeaderActions.appendChild(friendsListPromptCell.firstChild)\n }\n friendsListPromptCell.remove()\n }\n\n const friendDropButtons = friendsHeaderActions.querySelectorAll('button')\n if (editable && friendDropButtons.length > 0) {\n friendDropButtons.forEach((button) => {\n button.setAttribute('title', 'Drop friend here')\n button.setAttribute('aria-label', 'Drop friend here')\n const buttonImages = button.querySelectorAll('img')\n buttonImages.forEach((image) => {\n image.setAttribute('title', 'Drop friend here')\n image.setAttribute('alt', 'Drop friend here')\n })\n })\n\n const friendsActionsRow = dom.createElement('div')\n friendsActionsRow.className = 'social-friends-header-actions social-friends-header-actions--standalone'\n friendsActionsRow.appendChild(friendsHeaderActions)\n const dropHint = dom.createElement('span')\n dropHint.className = 'social-friends-header-hint'\n dropHint.textContent = 'Drag a WebId on the target to add a friend.'\n friendsActionsRow.appendChild(dropHint)\n allFriends.prepend(friendsActionsRow)\n }\n\n if (friendsListRightCell instanceof HTMLTableCellElement) {\n friendsListRightCell.colSpan = 2\n }\n\n const friendsItemsTable = friendsList.querySelector('td table')\n if (friendsItemsTable instanceof HTMLTableElement) {\n friendsItemsTable.classList.add('social-friends-grid')\n }\n\n return { section: allFriends, mainTable, friendsList }\n}\n\nexport function createRequestsSection (options: {\n dom: HTMLDocument,\n triage: FriendshipTriage,\n renderSupportingInfo: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null,\n renderNameSuffix: (target: NamedNode, renderDom: HTMLDocument) => HTMLElement | null\n}): { section: HTMLElement, refreshRequests: (triage: FriendshipTriage) => void } {\n const { dom, triage, renderSupportingInfo, renderNameSuffix } = options\n\n const requestsSection = dom.createElement('section')\n requestsSection.className = 'social-pane__requests social-primary__panel'\n requestsSection.id = 'social-panel-requests'\n requestsSection.setAttribute('role', 'tabpanel')\n requestsSection.setAttribute('aria-labelledby', 'social-tab-requests')\n\n const requestsContent = requestsSection.appendChild(dom.createElement('div'))\n requestsContent.classList.add('social-main', 'social-main--requests', 'flex-column')\n\n const note = requestsContent.appendChild(dom.createElement('p'))\n note.className = 'social-requests__note'\n note.textContent = 'Best effort preview: this view only reflects profile documents that are currently loaded. A dedicated inbox would still be needed for complete request discovery.'\n\n const createRequestGroup = function (title: string, description: string, emptyText: string) {\n const group = requestsContent.appendChild(dom.createElement('section'))\n group.classList.add('social-requests__group', 'flex-column')\n\n const header = group.appendChild(dom.createElement('div'))\n header.className = 'social-requests__group-header'\n\n const heading = header.appendChild(dom.createElement('h2'))\n heading.className = 'social-requests__group-title'\n heading.textContent = title\n\n const blurb = header.appendChild(dom.createElement('p'))\n blurb.className = 'social-requests__group-description'\n blurb.textContent = description\n\n const empty = group.appendChild(dom.createElement('p'))\n empty.className = 'social-requests__empty'\n empty.textContent = emptyText\n\n const table = group.appendChild(dom.createElement('table'))\n table.className = 'social-main social-friends-list social-friends-grid social-requests__table'\n\n return { empty, table }\n }\n\n const incomingGroup = createRequestGroup(\n 'Incoming requests',\n 'People who say they know this profile, but have not been confirmed yet.',\n 'No incoming requests are visible from the currently loaded data.'\n )\n const pendingGroup = createRequestGroup(\n 'Awaiting confirmation',\n 'People this profile knows who have not linked back yet.',\n 'Nothing is waiting for confirmation right now.'\n )\n\n const createPersonRow = function (target: NamedNode) {\n return widgets.personTR(dom, ns.foaf('knows'), target, {\n renderSupportingInfo,\n renderNameSuffix\n })\n }\n\n const sortNodes = function (nodes: NamedNode[]) {\n return [...nodes].sort((left, right) => {\n const leftLabel = utils.label(left) || left.value\n const rightLabel = utils.label(right) || right.value\n return leftLabel.localeCompare(rightLabel)\n })\n }\n\n const syncRequestGroup = function (\n group: { empty: HTMLElement, table: HTMLTableElement },\n nodes: NamedNode[]\n ) {\n const sortedNodes = sortNodes(nodes)\n group.empty.hidden = sortedNodes.length > 0\n group.table.hidden = sortedNodes.length === 0\n\n utils.syncTableToArray(\n group.table,\n sortedNodes,\n createPersonRow,\n function (_row, thing) {\n return createPersonRow(thing)\n }\n )\n }\n\n const refreshRequests = function (nextTriage: FriendshipTriage) {\n syncRequestGroup(incomingGroup, nextTriage.requests)\n syncRequestGroup(pendingGroup, nextTriage.unconfirmed)\n }\n\n refreshRequests(triage)\n\n return { section: requestsSection, refreshRequests }\n}\n"],"mappings":";;;;;;AAwCA,SAAgB,EACd,GACA,GACA,GACA,GACA,GACqB;CACrB,IAAM,IAAM,EAAQ;CACT,EAAQ,QAAQ;CAD3B,IAEM,IAAS,EAAI,cAAc,QAAQ;CACzC,EAAO,YAAY;CACnB,IAAI,IAAiB,GAEf,IAAe,WAAY;EAC/B,EAAO,gBAAgB;EACvB,IAAM,IAAc,EAAe,GAE7B,IAAgB,EAAI,cAAc,KAAK;EAC7C,EAAc,YAAY;EAE1B,IAAM,IAAgB,EAAI,cAAc,KAAK;EAG7C,IAFA,EAAc,YAAY,yEAEtB,GAAe,WAGR,EAAe,eAAe,mBAAmB,EAAe,qBAAqB;GAC9F,EAAc,UAAU,IAAI,qCAAqC;GACjE,IAAM,IAAqB,EAA+B,GAAS,CAAO;GAE1E,AADA,EAAmB,UAAU,IAAI,aAAa,GAC9C,EAAc,YAAY,CAAkB;EAC9C;EAEA,EAAO,YAAY,CAAa;EAEhC,IAAM,IAAc,EAAI,cAAc,KAAK;EAI3C,AAHA,EAAY,YAAY,6BACxB,EAAc,YAAY,CAAW,GAEjC,KACF,EAAY,YAAY,EAAY,GAAK,EAAY,UAAU,EAAY,IAAI,CAAC;EAGlF,IAAM,IAAgB,EAAI,cAAc,KAAK;EAI7C,AAHA,EAAc,YAAY,+BAC1B,EAAc,YAAY,CAAa,GAEnC,EAAc,WAAW,SAAS,KACpC,EAAc,YAAY,CAAa;EAGzC,IAAM,IAAgB,EAAI,cAAc,KAAK;EAE7C,AADA,EAAc,UAAU,IAAI,+BAA+B,aAAa,GACxE,EAAc,YAAY,CAAa;EAEvC,IAAM,IAAO,GAAa,QAAQ,EAAM,MAAM,CAAO,GAC/C,IAAK,EAAI,cAAc,IAAI;EAGjC,AAFA,EAAG,UAAU,IAAI,0BAA0B,GAC3C,EAAG,YAAY,EAAI,eAAe,CAAI,CAAC,GACvC,EAAc,YAAY,CAAE;EAE5B,IAAM,IAAqB,CAAC,GAAa,UAAU,GAAa,YAAY,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,KAAK;EACxG,IAAI,GAAoB;GACtB,IAAM,IAAU,EAAI,cAAc,KAAK;GAGvC,AAFA,EAAQ,YAAY,+BACpB,EAAQ,cAAc,GACtB,EAAc,YAAY,CAAO;EACnC;EAEA,IAAI,GAAa,UAAU;GACzB,IAAM,IAAe,EAAI,cAAc,KAAK;GAC5C,EAAa,YAAY;GAEzB,IAAM,IAAmB,EAAI,cAAc,MAAM;GAMjD,AALA,EAAiB,UAAU,IAAI,qCAAqC,iBAAiB,GACrF,EAAiB,YAAY,GAC7B,EAAa,YAAY,CAAgB,GACzC,EAAa,YAAY,EAAI,eAAe,EAAY,QAAQ,CAAC,GAEjE,EAAc,YAAY,CAAY;EACxC;EAEA,IAAM,IAAW,EAAI,cAAc,KAAK;EACxC,EAAS,YAAY;EAErB,IAAM,IAAc,EAAI,cAAc,QAAQ;EAE9C,AADA,EAAY,YAAY,4BACxB,EAAY,OAAO;EACnB,IAAM,IAAmB,EAAI,cAAc,MAAM;EASjD,IARA,EAAiB,YAAY,kCAC7B,EAAiB,cAAc,GAAG,EAAM,YAAY,SAAS,EAAM,gBAAgB,IAAI,KAAK,OAC5F,EAAY,YAAY,CAAgB,GACpC,EAAM,mBACR,EAAY,iBAAiB,SAAS,EAAM,eAAe,GAE7D,EAAS,YAAY,CAAW,GAE5B,OAAO,EAAM,qBAAsB,UAAU;GAC/C,IAAM,IAAc,EAAI,cAAc,QAAQ;GAE9C,AADA,EAAY,YAAY,4BACxB,EAAY,OAAO;GACnB,IAAM,IAAmB,EAAI,cAAc,MAAM;GAOjD,AANA,EAAiB,YAAY,kCAC7B,EAAiB,cAAc,GAAG,EAAM,kBAAkB,gBAAgB,EAAM,sBAAsB,IAAI,KAAK,OAC/G,EAAY,YAAY,CAAgB,GACpC,EAAM,kBACR,EAAY,iBAAiB,SAAS,EAAM,cAAc,GAE5D,EAAS,YAAY,CAAW;EAClC;EAEA,EAAc,YAAY,CAAQ;CAEpC;CASA,OAPA,EAAO,sBAAsB,SAAU,GAA8B;EAEnE,AADA,IAAiB,GACjB,EAAa;CACf,GAEA,EAAa,GAEN;AACT;AAEA,SAAS,EAAa,GAAmB,GAAgC,IAAM,IAAiB;CAC9F,IAAI,GAAK;EACP,IAAM,IAAM,EAAI,cAAc,KAAK;EAOnC,OANA,EAAI,YAAY,4BAChB,EAAI,MAAM,GACV,EAAI,MAAM,GACV,EAAI,QAAQ,KACZ,EAAI,SAAS,KACb,EAAI,UAAU,SACP;CACT;CAEA,IAAM,IAAW,EAAI,cAAc,KAAK;CAIxC,AAHA,EAAS,YAAY,4CACrB,EAAS,aAAa,QAAQ,KAAK,GACnC,EAAS,aAAa,cAAc,CAAG,GACvC,EAAS,WAAW;CAEpB,IAAM,IAAO,EAAI,cAAc,MAAM;CAKrC,OAJA,EAAK,UAAU,IAAI,iCAAiC,iBAAiB,GACrE,EAAK,YAAY,GACjB,EAAS,YAAY,CAAI,GAElB;AACT;AAEA,SAAgB,EAAqB,GAsBgD;CACnF,IAAM,EACJ,QACA,YACA,aACA,OACA,UACA,aACA,aACA,aACA,YACA,UACA,sBACA,SACA,SACA,sBACA,yBACA,wBACE,GAEA,IAAuB,WAAY,CAAC,GAElC,IAAgB,EAAI,cAAc,SAAS;CAIjD,AAHA,EAAc,YAAY,qDAC1B,EAAc,KAAK,uBACnB,EAAc,aAAa,QAAQ,UAAU,GAC7C,EAAc,aAAa,mBAAmB,mBAAmB;CAEjE,IAAM,IAAgB,EAAc,YAAY,EAAI,cAAc,KAAK,CAAC;CACxE,EAAc,UAAU,IAAI,eAAe,uBAAuB,aAAa;CAE/E,IAAM,IAAsB,EAAI,cAAc,KAAK;CAEnD,AADA,EAAoB,UAAU,IAAI,yBAAyB,aAAa,GACxE,EAAc,YAAY,CAAmB;CAE7C,IAAM,IAAyB,WAAY;EACzC,IAAM,IAAO,EAAoB,YAAY,EAAI,cAAc,KAAK,CAAC;EAErE,OADA,EAAK,UAAU,IAAI,4BAA4B,GACxC;CACT,GAEM,IAAa,WAAY;EAC7B,IAAM,IAAO,EAAuB;EAIpC,OAHA,EAAK,YAAY,EAAK,EAAK,KAAK,GAAG,CAAK,CAAC,GACzC,EAAK,YAAY,EAAK,OAAO,CAAC,GAC9B,EAAK,YAAY,EAAK,EAAK,CAAQ,GAAG,EAAQ,GAAG,CAAC,GAC3C;CACT;CAEA,IAAI,CAAC,GAAU;EACb,IAAI,CAAC,GAEH,EAAA,CAAA,CAAK,YAAY,EAAK,qCAAqC,CAAC;OACvD;GACL,IAAM,IAAO,EAAuB;GAIpC,AAHA,EAAK,YAAY,EAAK,EAAK,KAAK,GAAG,CAAK,CAAC,GACzC,EAAK,YAAY,EAAK,QAAQ,CAAC,GAC/B,EAAK,YAAY,EAAK,EAAK,CAAQ,GAAG,EAAQ,GAAG,CAAC,GAClD,EAAK,YAAY,EAAK,iBAAiB,CAAC;EAC1C;CACF,OAAO,IAAK,GAWV,EAAA,CAAA,CAAK,YAAY,EAAK,2BAA2B,CAAC;MAX9B;EACpB,EAAoB,UAAU,IAAI,gCAAgC;EAElE,IAAM,IAAe,EAAoB,YAAY,EAAI,cAAc,KAAK,CAAC;EAK7E,AAJA,EAAa,UAAU,IAAI,4BAA4B,GACvD,EAAa,YAAY,EAAK,EAAK,CAAQ,GAAG,EAAQ,GAAG,CAAC,GAC1D,EAAa,YAAY,EAAK,SAAS,CAAC,GACxC,EAAa,YAAY,EAAK,EAAK,KAAK,GAAG,CAAK,CAAC,GACjD,EAAa,YAAY,EAAK,iBAAiB,CAAC;CAClD;CAMA,IAD0C,KAAa,CAAC,GACzB;EAC7B,IAAM,IAAe,EAAI,cAAc,MAAM;EAG7C,AAFA,EAAa,YAAY,gCACzB,EAAa,YAAY,EAAK,mBAAmB,CAAC,GAClD,EAAa,YAAY,EAAK,EAAK,CAAQ,GAAG,EAAQ,GAAG,CAAC;EAE1D,IAAM,IAAmB,EACvB,GACA,IAAI,EAAU,GAAI,GAAO,GAAS,KAAW,KAAA,CAAS,GACtD,EAAQ,GACR;GACE,UAAU,CAAC;GACX,eAAgB,IAA4C,KAAA,IAAjC;EAC7B,CACF;EAGA,AAFA,EAAiB,UAAU,IAAI,6BAA6B,GAE5D,EAAc,YAAY,CAAgB;CAC5C;CAEA,IAAI,EAAkB,QAAQ;EAC5B,IAAM,IAAqB,EAAc,YAAY,EAAI,cAAc,OAAO,CAAC;EAC/E,EAAmB,YAAY;EAE/B,IAAM,IAAkB,SAAU,GAAmB;GACnD,OAAO,EAAQ,SAAS,GAAK,EAAG,KAAK,OAAO,GAAG,GAAQ;IACrD;IACA;GACF,CAAC;EACH;EAoBA,AAlBA,IAAuB,WAAY;GACjC,IAAM,IAA0B,CAAC,GAAG,CAAiB,CAAC,CAAC,MAAM,GAAM,MAAU;IAC3E,IAAM,IAAY,EAAM,MAAM,CAAI,KAAK,EAAK,OACtC,IAAa,EAAM,MAAM,CAAK,KAAK,EAAM;IAC/C,OAAO,EAAU,cAAc,CAAU;GAC3C,CAAC;GAED,EAAM,iBACJ,GACA,GACA,GACA,SAAU,GAAK,GAAO;IAEpB,OADoB,EAAgB,CAC7B;GACT,CACF;EACF,GAEA,EAAqB;CACvB;CAEA,OAAO;EAAE,SAAS;EAAe,SAAS;EAAe;CAAqB;AAChF;AAEA,SAAgB,EAAyB,GAO2C;CAClF,IAAM,EAAE,QAAK,YAAS,YAAS,aAAU,yBAAsB,wBAAqB,GAE9E,IAAa,EAAI,cAAc,SAAS;CAI9C,AAHA,EAAW,YAAY,kDACvB,EAAW,KAAK,4BAChB,EAAW,aAAa,QAAQ,UAAU,GAC1C,EAAW,aAAa,mBAAmB,wBAAwB;CAEnE,IAAM,IAAY,EAAW,YAAY,EAAI,cAAc,OAAO,CAAC;CACnE,EAAU,YAAY;CAEtB,IAAM,IAAc,EAAQ,eAAe,GAAK,GAAS,GAAW;EAClE,KAAK;EACL,QAAQ,CAAC,CAAC;EACV,WAAW,EAAG,KAAK,OAAO;EAC1B,MAAM;EAKN,uBAAuB;EACvB;EACA;CACF,CAAC;CAED,AADA,EAAY,UAAU,IAAI,qBAAqB,GAC/C,EAAY,MAAM,YAAY;CAE9B,IAAM,IAAiB,EAAY,cAAc,IAAI,GAC/C,IAAwB,GAAgB,WAAW,IACnD,IAAuB,GAAgB,WAAW,IAClD,IAAuB,EAAI,cAAc,KAAK;CAGpD,IAFA,EAAqB,UAAU,IAAI,+BAA+B,GAE9D,aAAiC,sBAAsB;EACzD,EAAsB,UAAU,IAAI,qCAAqC;EACzE,IAAM,IAAwB,EAAI,cAAc,OAAO;EAMvD,AALA,EAAsB,YAAY,kCAClC,EAAsB,aAAa,QAAQ,cAAc,GAGzD,EAFwD,YAAY,EAAI,cAAc,OAAO,CAC5D,CAAA,CAA0B,YAAY,EAAI,cAAc,IAAI,CAC7F,CAAA,CAAyB,YAAY,CAAqB,GAC1D,EAAqB,YAAY,CAAqB;CACxD,OAAO,IAAI,aAAiC,aAAa;EACvD,OAAO,EAAsB,aAC3B,EAAqB,YAAY,EAAsB,UAAU;EAEnE,EAAsB,OAAO;CAC/B;CAEA,IAAM,IAAoB,EAAqB,iBAAiB,QAAQ;CACxE,IAAI,KAAY,EAAkB,SAAS,GAAG;EAC5C,EAAkB,SAAS,MAAW;GAIpC,AAHA,EAAO,aAAa,SAAS,kBAAkB,GAC/C,EAAO,aAAa,cAAc,kBAAkB,GAEpD,EAD4B,iBAAiB,KAC7C,CAAA,CAAa,SAAS,MAAU;IAE9B,AADA,EAAM,aAAa,SAAS,kBAAkB,GAC9C,EAAM,aAAa,OAAO,kBAAkB;GAC9C,CAAC;EACH,CAAC;EAED,IAAM,IAAoB,EAAI,cAAc,KAAK;EAEjD,AADA,EAAkB,YAAY,2EAC9B,EAAkB,YAAY,CAAoB;EAClD,IAAM,IAAW,EAAI,cAAc,MAAM;EAIzC,AAHA,EAAS,YAAY,8BACrB,EAAS,cAAc,+CACvB,EAAkB,YAAY,CAAQ,GACtC,EAAW,QAAQ,CAAiB;CACtC;CAEA,AAAI,aAAgC,yBAClC,EAAqB,UAAU;CAGjC,IAAM,IAAoB,EAAY,cAAc,UAAU;CAK9D,OAJI,aAA6B,oBAC/B,EAAkB,UAAU,IAAI,qBAAqB,GAGhD;EAAE,SAAS;EAAY;EAAW;CAAY;AACvD;AAEA,SAAgB,EAAuB,GAK2C;CAChF,IAAM,EAAE,QAAK,WAAQ,yBAAsB,wBAAqB,GAE1D,IAAkB,EAAI,cAAc,SAAS;CAInD,AAHA,EAAgB,YAAY,+CAC5B,EAAgB,KAAK,yBACrB,EAAgB,aAAa,QAAQ,UAAU,GAC/C,EAAgB,aAAa,mBAAmB,qBAAqB;CAErE,IAAM,IAAkB,EAAgB,YAAY,EAAI,cAAc,KAAK,CAAC;CAC5E,EAAgB,UAAU,IAAI,eAAe,yBAAyB,aAAa;CAEnF,IAAM,IAAO,EAAgB,YAAY,EAAI,cAAc,GAAG,CAAC;CAE/D,AADA,EAAK,YAAY,yBACjB,EAAK,cAAc;CAEnB,IAAM,IAAqB,SAAU,GAAe,GAAqB,GAAmB;EAC1F,IAAM,IAAQ,EAAgB,YAAY,EAAI,cAAc,SAAS,CAAC;EACtE,EAAM,UAAU,IAAI,0BAA0B,aAAa;EAE3D,IAAM,IAAS,EAAM,YAAY,EAAI,cAAc,KAAK,CAAC;EACzD,EAAO,YAAY;EAEnB,IAAM,IAAU,EAAO,YAAY,EAAI,cAAc,IAAI,CAAC;EAE1D,AADA,EAAQ,YAAY,gCACpB,EAAQ,cAAc;EAEtB,IAAM,IAAQ,EAAO,YAAY,EAAI,cAAc,GAAG,CAAC;EAEvD,AADA,EAAM,YAAY,sCAClB,EAAM,cAAc;EAEpB,IAAM,IAAQ,EAAM,YAAY,EAAI,cAAc,GAAG,CAAC;EAEtD,AADA,EAAM,YAAY,0BAClB,EAAM,cAAc;EAEpB,IAAM,IAAQ,EAAM,YAAY,EAAI,cAAc,OAAO,CAAC;EAG1D,OAFA,EAAM,YAAY,8EAEX;GAAE;GAAO;EAAM;CACxB,GAEM,IAAgB,EACpB,qBACA,2EACA,kEACF,GACM,IAAe,EACnB,yBACA,2DACA,gDACF,GAEM,IAAkB,SAAU,GAAmB;EACnD,OAAO,EAAQ,SAAS,GAAK,EAAG,KAAK,OAAO,GAAG,GAAQ;GACrD;GACA;EACF,CAAC;CACH,GAEM,IAAY,SAAU,GAAoB;EAC9C,OAAO,CAAC,GAAG,CAAK,CAAC,CAAC,MAAM,GAAM,MAAU;GACtC,IAAM,IAAY,EAAM,MAAM,CAAI,KAAK,EAAK,OACtC,IAAa,EAAM,MAAM,CAAK,KAAK,EAAM;GAC/C,OAAO,EAAU,cAAc,CAAU;EAC3C,CAAC;CACH,GAEM,IAAmB,SACvB,GACA,GACA;EACA,IAAM,IAAc,EAAU,CAAK;EAInC,AAHA,EAAM,MAAM,SAAS,EAAY,SAAS,GAC1C,EAAM,MAAM,SAAS,EAAY,WAAW,GAE5C,EAAM,iBACJ,EAAM,OACN,GACA,GACA,SAAU,GAAM,GAAO;GACrB,OAAO,EAAgB,CAAK;EAC9B,CACF;CACF,GAEM,IAAkB,SAAU,GAA8B;EAE9D,AADA,EAAiB,GAAe,EAAW,QAAQ,GACnD,EAAiB,GAAc,EAAW,WAAW;CACvD;CAIA,OAFA,EAAgB,CAAM,GAEf;EAAE,SAAS;EAAiB;CAAgB;AACrD"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
let e=require("solid-ui");function t(e){let t=new Set,n=[];for(let r of e){let e=r?.value;!e||t.has(e)||(t.add(e),n.push(r))}return n}function n(n,r){let i=t(n.each(r,e.ns.foaf(`knows`))),a=t(n.each(void 0,e.ns.foaf(`knows`),r)),o=[],s=[],c=[];for(let e of i)a.some(t=>t.sameTerm(e))?o.push(e):s.push(e);for(let e of a)i.some(t=>t.sameTerm(e))||c.push(e);return{acquaintances:i,confirmed:o,unconfirmed:s,requests:c}}async function r(t,r){let i=t.session.store,a=i.fetcher;if(!a||typeof a.load!=`function`)return n(i,r);try{await a.load(r.doc())}catch{}let o=n(i,r),s=new Map;s.set(r.doc().value,r.doc());for(let e of[...o.acquaintances,...o.requests])s.set(e.doc().value,e.doc());let c=i.statementsMatching(void 0,e.ns.foaf(`knows`),r);for(let e of c){let t=e.why;t?.value&&s.set(t.value,t)}for(let e of s.values())try{await a.load(e)}catch{}return n(i,r)}exports.loadFriendshipTriage=r,exports.triageFriends=n;
|
|
2
2
|
//# sourceMappingURL=triage.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"triage.cjs.js","names":[],"sources":["../../src/social/triage.ts"],"sourcesContent":["import { DataBrowserContext } from 'pane-registry'\nimport { IndexedFormula, NamedNode } from 'rdflib'\nimport { ns } from 'solid-ui'\n\ntype FriendshipStore = IndexedFormula & {\n fetcher?: {\n load?: (target: NamedNode | string) => Promise<unknown>\n }\n}\n\nexport interface FriendshipTriage {\n acquaintances: NamedNode[]\n confirmed: NamedNode[]\n unconfirmed: NamedNode[]\n requests: NamedNode[]\n}\n\nfunction uniqueNamedNodes (nodes: NamedNode[]): NamedNode[] {\n const seen = new Set<string>()\n const unique: NamedNode[] = []\n\n for (const node of nodes) {\n const key = node?.value\n if (!key || seen.has(key)) continue\n seen.add(key)\n unique.push(node)\n }\n\n return unique\n}\n\nexport function triageFriends (store: FriendshipStore, subject: NamedNode): FriendshipTriage {\n const outgoingFriends = uniqueNamedNodes(store.each(subject, ns.foaf('knows')) as NamedNode[])\n const incomingFriends = uniqueNamedNodes(\n store.each(undefined, ns.foaf('knows'), subject) as NamedNode[]\n )\n const confirmed: NamedNode[] = []\n const unconfirmed: NamedNode[] = []\n const requests: NamedNode[] = []\n\n for (const friend of outgoingFriends) {\n const isConfirmed = incomingFriends.some(incomingFriend => incomingFriend.sameTerm(friend))\n if (isConfirmed) {\n confirmed.push(friend)\n } else {\n unconfirmed.push(friend)\n }\n }\n\n for (const friend of incomingFriends) {\n const isAlreadyOutgoing = outgoingFriends.some(outgoingFriend => outgoingFriend.sameTerm(friend))\n if (!isAlreadyOutgoing) {\n requests.push(friend)\n }\n }\n\n return {\n acquaintances: outgoingFriends,\n confirmed,\n unconfirmed,\n requests\n }\n}\n\nexport async function loadFriendshipTriage (\n context: DataBrowserContext,\n subject: NamedNode\n): Promise<FriendshipTriage> {\n const store = context.session.store as FriendshipStore\n const fetcher = store.fetcher\n\n if (!fetcher || typeof fetcher.load !== 'function') {\n return triageFriends(store, subject)\n }\n\n try {\n await fetcher.load(subject.doc())\n } catch {\n // Continue with the store snapshot we already have.\n }\n\n const initialTriage = triageFriends(store, subject)\n const documentsToLoad = new Map<string, NamedNode | string>()\n\n documentsToLoad.set(subject.doc().value, subject.doc())\n\n for (const friend of [...initialTriage.acquaintances, ...initialTriage.requests]) {\n documentsToLoad.set(friend.doc().value, friend.doc())\n }\n\n const incomingStatements = store.statementsMatching(undefined, ns.foaf('knows'), subject)\n for (const statement of incomingStatements) {\n const why = statement.why as NamedNode | undefined\n if (why?.value) {\n documentsToLoad.set(why.value, why)\n }\n }\n\n for (const target of documentsToLoad.values()) {\n try {\n await fetcher.load(target)\n } catch {\n // Keep partial results when one profile document fails to load.\n }\n }\n\n return triageFriends(store, subject)\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"triage.cjs.js","names":[],"sources":["../../src/social/triage.ts"],"sourcesContent":["import { DataBrowserContext } from 'pane-registry'\nimport { IndexedFormula, NamedNode } from 'rdflib'\nimport { ns } from 'solid-ui'\n\ntype FriendshipStore = IndexedFormula & {\n fetcher?: {\n load?: (target: NamedNode | string) => Promise<unknown>\n }\n}\n\nexport interface FriendshipTriage {\n acquaintances: NamedNode[]\n confirmed: NamedNode[]\n unconfirmed: NamedNode[]\n requests: NamedNode[]\n}\n\nfunction uniqueNamedNodes (nodes: NamedNode[]): NamedNode[] {\n const seen = new Set<string>()\n const unique: NamedNode[] = []\n\n for (const node of nodes) {\n const key = node?.value\n if (!key || seen.has(key)) continue\n seen.add(key)\n unique.push(node)\n }\n\n return unique\n}\n\nexport function triageFriends (store: FriendshipStore, subject: NamedNode): FriendshipTriage {\n const outgoingFriends = uniqueNamedNodes(store.each(subject, ns.foaf('knows')) as NamedNode[])\n const incomingFriends = uniqueNamedNodes(\n store.each(undefined, ns.foaf('knows'), subject) as NamedNode[]\n )\n const confirmed: NamedNode[] = []\n const unconfirmed: NamedNode[] = []\n const requests: NamedNode[] = []\n\n for (const friend of outgoingFriends) {\n const isConfirmed = incomingFriends.some(incomingFriend => incomingFriend.sameTerm(friend))\n if (isConfirmed) {\n confirmed.push(friend)\n } else {\n unconfirmed.push(friend)\n }\n }\n\n for (const friend of incomingFriends) {\n const isAlreadyOutgoing = outgoingFriends.some(outgoingFriend => outgoingFriend.sameTerm(friend))\n if (!isAlreadyOutgoing) {\n requests.push(friend)\n }\n }\n\n return {\n acquaintances: outgoingFriends,\n confirmed,\n unconfirmed,\n requests\n }\n}\n\nexport async function loadFriendshipTriage (\n context: DataBrowserContext,\n subject: NamedNode\n): Promise<FriendshipTriage> {\n const store = context.session.store as FriendshipStore\n const fetcher = store.fetcher\n\n if (!fetcher || typeof fetcher.load !== 'function') {\n return triageFriends(store, subject)\n }\n\n try {\n await fetcher.load(subject.doc())\n } catch {\n // Continue with the store snapshot we already have.\n }\n\n const initialTriage = triageFriends(store, subject)\n const documentsToLoad = new Map<string, NamedNode | string>()\n\n documentsToLoad.set(subject.doc().value, subject.doc())\n\n for (const friend of [...initialTriage.acquaintances, ...initialTriage.requests]) {\n documentsToLoad.set(friend.doc().value, friend.doc())\n }\n\n const incomingStatements = store.statementsMatching(undefined, ns.foaf('knows'), subject)\n for (const statement of incomingStatements) {\n const why = statement.why as NamedNode | undefined\n if (why?.value) {\n documentsToLoad.set(why.value, why)\n }\n }\n\n for (const target of documentsToLoad.values()) {\n try {\n await fetcher.load(target)\n } catch {\n // Keep partial results when one profile document fails to load.\n }\n }\n\n return triageFriends(store, subject)\n}\n"],"mappings":"0BAiBA,SAAS,EAAkB,EAAiC,CAC1D,IAAM,EAAO,IAAI,IACX,EAAsB,CAAC,EAE7B,IAAK,IAAM,KAAQ,EAAO,CACxB,IAAM,EAAM,GAAM,MACd,CAAC,GAAO,EAAK,IAAI,CAAG,IACxB,EAAK,IAAI,CAAG,EACZ,EAAO,KAAK,CAAI,EAClB,CAEA,OAAO,CACT,CAEA,SAAgB,EAAe,EAAwB,EAAsC,CAC3F,IAAM,EAAkB,EAAiB,EAAM,KAAK,EAAS,EAAA,GAAG,KAAK,OAAO,CAAC,CAAgB,EACvF,EAAkB,EACtB,EAAM,KAAK,IAAA,GAAW,EAAA,GAAG,KAAK,OAAO,EAAG,CAAO,CACjD,EACM,EAAyB,CAAC,EAC1B,EAA2B,CAAC,EAC5B,EAAwB,CAAC,EAE/B,IAAK,IAAM,KAAU,EACC,EAAgB,KAAK,GAAkB,EAAe,SAAS,CAAM,CACrF,EACF,EAAU,KAAK,CAAM,EAErB,EAAY,KAAK,CAAM,EAI3B,IAAK,IAAM,KAAU,EACO,EAAgB,KAAK,GAAkB,EAAe,SAAS,CAAM,CAC1F,GACH,EAAS,KAAK,CAAM,EAIxB,MAAO,CACL,cAAe,EACf,YACA,cACA,UACF,CACF,CAEA,eAAsB,EACpB,EACA,EAC2B,CAC3B,IAAM,EAAQ,EAAQ,QAAQ,MACxB,EAAU,EAAM,QAEtB,GAAI,CAAC,GAAW,OAAO,EAAQ,MAAS,WACtC,OAAO,EAAc,EAAO,CAAO,EAGrC,GAAI,CACF,MAAM,EAAQ,KAAK,EAAQ,IAAI,CAAC,CAClC,MAAQ,CAER,CAEA,IAAM,EAAgB,EAAc,EAAO,CAAO,EAC5C,EAAkB,IAAI,IAE5B,EAAgB,IAAI,EAAQ,IAAI,CAAC,CAAC,MAAO,EAAQ,IAAI,CAAC,EAEtD,IAAK,IAAM,IAAU,CAAC,GAAG,EAAc,cAAe,GAAG,EAAc,QAAQ,EAC7E,EAAgB,IAAI,EAAO,IAAI,CAAC,CAAC,MAAO,EAAO,IAAI,CAAC,EAGtD,IAAM,EAAqB,EAAM,mBAAmB,IAAA,GAAW,EAAA,GAAG,KAAK,OAAO,EAAG,CAAO,EACxF,IAAK,IAAM,KAAa,EAAoB,CAC1C,IAAM,EAAM,EAAU,IAClB,GAAK,OACP,EAAgB,IAAI,EAAI,MAAO,CAAG,CAEtC,CAEA,IAAK,IAAM,KAAU,EAAgB,OAAO,EAC1C,GAAI,CACF,MAAM,EAAQ,KAAK,CAAM,CAC3B,MAAQ,CAER,CAGF,OAAO,EAAc,EAAO,CAAO,CACrC"}
|