UNPKG

solid-panes

Version:

Solid-compatible Panes: applets and views for the mashlib and databrowser

317 lines (312 loc) • 12.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createAllFriendsSection = createAllFriendsSection; exports.createHeaderSection = createHeaderSection; exports.createMutualSection = createMutualSection; var _profilePane = require("profile-pane"); var _solidUi = require("solid-ui"); var _editProfileDetails = require("./editProfileDetails"); var _icons = require("./icons"); function createHeaderSection(context, subject, controls, stats, getProfileData) { const dom = context.dom; const kb = context.session.store; const header = document.createElement('header'); header.className = 'social-pane__header'; let headerControls = controls; const renderHeader = function () { header.replaceChildren(); const profileData = getProfileData(); const headerContent = dom.createElement('div'); headerContent.className = 'social-pane__header-content'; if (headerControls.canEdit) { header.appendChild((0, _editProfileDetails.createEditProfileDetailsButton)({ dom, store: kb, subject, header, onSaved: renderHeader })); } else if (headerControls.viewerMode === 'authenticated') { const addToFriendsButton = (0, _profilePane.createAddMeToYourFriendsButton)(subject, context); addToFriendsButton.classList.add('social-pane__friend-action', 'profile__action-button', 'profile__btn-friends', 'flex-center'); // header.appendChild(addToFriendsButton) headerContent.appendChild(addToFriendsButton); } header.appendChild(headerContent); const headerMedia = dom.createElement('div'); headerMedia.className = 'social-pane__header-media'; headerContent.appendChild(headerMedia); if (profileData) { headerMedia.appendChild(createImage(profileData.imageUrl, profileData.name)); } const headerDetails = dom.createElement('div'); headerDetails.className = 'social-pane__header-details'; headerContent.appendChild(headerDetails); const headerSummary = dom.createElement('div'); headerSummary.classList.add('social-pane__header-summary', 'flex-column'); headerDetails.appendChild(headerSummary); const name = profileData?.name || '???'; const h1 = dom.createElement('h1'); h1.classList.add('social-pane__header-name'); h1.appendChild(dom.createTextNode(name)); headerSummary.appendChild(h1); const jobAndOrganization = [profileData?.jobTitle, profileData?.organization].filter(Boolean).join(' | '); if (jobAndOrganization) { const jobLine = dom.createElement('div'); jobLine.className = 'social-pane__header-job-org'; jobLine.textContent = jobAndOrganization; headerSummary.appendChild(jobLine); } if (profileData?.location) { const locationLine = dom.createElement('div'); locationLine.className = 'social-pane__header-location'; const locationIconSpan = dom.createElement('span'); locationIconSpan.classList.add('social-pane__header-location-icon', 'inline-flex-row'); locationIconSpan.innerHTML = _icons.locationIcon; locationLine.appendChild(locationIconSpan); locationLine.appendChild(dom.createTextNode(profileData.location)); headerSummary.appendChild(locationLine); } const statsRow = dom.createElement('div'); statsRow.className = 'social-pane__header-stats'; const friendCount = dom.createElement('button'); friendCount.className = 'social-pane__header-stat'; friendCount.type = 'button'; const friendCountLabel = dom.createElement('span'); friendCountLabel.className = 'social-pane__header-stat-label'; friendCountLabel.textContent = `${stats.friendCount} friend${stats.friendCount === 1 ? '' : 's'}`; friendCount.appendChild(friendCountLabel); if (stats.onSelectFriends) { friendCount.addEventListener('click', stats.onSelectFriends); } statsRow.appendChild(friendCount); if (typeof stats.mutualFriendCount === 'number') { const mutualCount = dom.createElement('button'); mutualCount.className = 'social-pane__header-stat'; mutualCount.type = 'button'; const mutualCountLabel = dom.createElement('span'); mutualCountLabel.className = 'social-pane__header-stat-label'; mutualCountLabel.textContent = `${stats.mutualFriendCount} mutual friend${stats.mutualFriendCount === 1 ? '' : 's'}`; mutualCount.appendChild(mutualCountLabel); if (stats.onSelectMutual) { mutualCount.addEventListener('click', stats.onSelectMutual); } statsRow.appendChild(mutualCount); } headerSummary.appendChild(statsRow); (0, _editProfileDetails.appendProfileLinks)(headerMedia, dom, kb, subject); }; header.refreshSocialHeader = function (nextControls) { headerControls = nextControls; renderHeader(); }; renderHeader(); return header; } function createImage(src, alt = '') { if (src) { const img = document.createElement('img'); img.className = 'social-pane__header-hero'; img.src = src; img.alt = alt; img.width = 180; img.height = 180; img.loading = 'eager'; return img; } const fallback = document.createElement('div'); fallback.className = 'social-pane__header-hero-alt flex-center'; fallback.setAttribute('role', 'img'); fallback.setAttribute('aria-label', alt); fallback.tabIndex = 0; const icon = document.createElement('span'); icon.classList.add('social-pane__header-hero-icon', 'inline-flex-row'); icon.innerHTML = _icons.personInCircleIcon; fallback.appendChild(icon); return fallback; } function createMutualSection(options) { const { dom, subject, familiar, meUri, incoming, outgoing, mutualConnections, link, text, renderSupportingInfo, renderNameSuffix } = options; // Mutual confirm UI is intentionally hidden for now. // The related options remain in the function contract so that block can be // restored later without reshaping callers. let refreshMutualFriends = function () {}; const mutualSection = dom.createElement('section'); mutualSection.className = 'social-pane__mutual-friends social-primary__panel'; mutualSection.id = 'social-panel-mutual'; mutualSection.setAttribute('role', 'tabpanel'); mutualSection.setAttribute('aria-labelledby', 'social-tab-mutual'); const mutualContent = mutualSection.appendChild(dom.createElement('div')); mutualContent.classList.add('social-main', 'social-main--mutual', 'flex-column'); const relationshipSummary = dom.createElement('div'); relationshipSummary.classList.add('social-mutual-summary', 'flex-column'); mutualContent.appendChild(relationshipSummary); const createRelationshipLine = function () { const line = relationshipSummary.appendChild(dom.createElement('div')); line.classList.add('social-mutual-summary-line'); return line; }; const youAndThem = function () { const line = createRelationshipLine(); line.appendChild(link(text('You'), meUri)); line.appendChild(text(' and ')); line.appendChild(link(text(familiar), subject.uri)); return line; }; if (!incoming) { if (!outgoing) { const line = youAndThem(); line.appendChild(text(' have not said you know each other.')); /* NOTE: hiding the outgoing-only unconfirmed message for now. } else { relationshipSummary.appendChild(link(text('You'), meUri)) relationshipSummary.appendChild(text(' know ')) relationshipSummary.appendChild(link(text(familiar), subject.uri)) relationshipSummary.appendChild(text(' (unconfirmed)')) */ } /* NOTE: hiding the incoming-only unconfirmed message for now. } else if (!outgoing) { relationshipSummary.classList.add('social-mutual-summary--confirm') const incomingLine = relationshipSummary.appendChild(dom.createElement('div')) incomingLine.classList.add('social-mutual-summary-line') incomingLine.appendChild(link(text(familiar), subject.uri)) incomingLine.appendChild(text(' knows ')) incomingLine.appendChild(link(text('you'), meUri)) incomingLine.appendChild(text(' (unconfirmed).')) */ } else { const line = youAndThem(); line.appendChild(text(' say you know each other.')); } /* NOTE: hiding the confirm-friend checkbox for now. const shouldShowCheckboxPreview = editable || (Boolean(incoming) && !outgoing) if (shouldShowCheckboxPreview) { const confirmLabel = dom.createElement('span') confirmLabel.appendChild(text('Confirm you know ')) confirmLabel.appendChild(link(text(familiar), subject.uri)) const relationshipForm = buildCheckboxForm( confirmLabel, new Statement(me, knows, subject, profile ?? undefined), Boolean(outgoing), { disabled: !editable, disabledTitle: !editable ? 'Your profile is not editable' : undefined } ) relationshipForm.classList.add('social-mutual-checkbox-form') mutualContent.appendChild(relationshipForm) } */ if (mutualConnections.length) { const mutualFriendsTable = mutualContent.appendChild(dom.createElement('table')); mutualFriendsTable.className = 'social-main social-friends-list social-friends-grid'; const createMutualRow = function (target) { return _solidUi.widgets.personTR(dom, _solidUi.ns.foaf('knows'), target, { renderSupportingInfo, renderNameSuffix }); }; refreshMutualFriends = function () { const sortedMutualConnections = [...mutualConnections].sort((left, right) => { const leftLabel = _solidUi.utils.label(left) || left.value; const rightLabel = _solidUi.utils.label(right) || right.value; return leftLabel.localeCompare(rightLabel); }); _solidUi.utils.syncTableToArray(mutualFriendsTable, sortedMutualConnections, createMutualRow, function (row, thing) { const replacement = createMutualRow(thing); return replacement; }); }; refreshMutualFriends(); } return { section: mutualSection, content: mutualContent, refreshMutualFriends }; } function createAllFriendsSection(options) { const { dom, subject, profile, editable, renderSupportingInfo, renderNameSuffix } = options; const allFriends = dom.createElement('section'); allFriends.className = 'social-pane__all-friends social-primary__panel'; allFriends.id = 'social-panel-all-friends'; allFriends.setAttribute('role', 'tabpanel'); allFriends.setAttribute('aria-labelledby', 'social-tab-all-friends'); const mainTable = allFriends.appendChild(dom.createElement('table')); mainTable.className = 'social-main'; const friendsList = _solidUi.widgets.attachmentList(dom, subject, mainTable, { doc: profile, modify: !!editable, predicate: _solidUi.ns.foaf('knows'), noun: 'friend', renderSupportingInfo, renderNameSuffix }); friendsList.classList.add('social-friends-list'); friendsList.style.marginTop = '0'; const friendsListRow = friendsList.querySelector('tr'); const friendsListPromptCell = friendsListRow?.children?.[0]; const friendsListRightCell = friendsListRow?.children?.[1]; const friendsHeaderActions = dom.createElement('div'); friendsHeaderActions.classList.add('social-friends-header-actions'); if (friendsListPromptCell instanceof HTMLElement) { while (friendsListPromptCell.firstChild) { friendsHeaderActions.appendChild(friendsListPromptCell.firstChild); } friendsListPromptCell.remove(); } if (friendsHeaderActions.childNodes.length > 0) { const friendDropButtons = friendsHeaderActions.querySelectorAll('button'); friendDropButtons.forEach(button => { button.setAttribute('title', 'Drop friend here'); button.setAttribute('aria-label', 'Drop friend here'); const buttonImages = button.querySelectorAll('img'); buttonImages.forEach(image => { image.setAttribute('title', 'Drop friend here'); image.setAttribute('alt', 'Drop friend here'); }); }); const friendsActionsRow = dom.createElement('div'); friendsActionsRow.className = 'social-friends-header-actions social-friends-header-actions--standalone'; friendsActionsRow.appendChild(friendsHeaderActions); const dropHint = dom.createElement('span'); dropHint.className = 'social-friends-header-hint'; dropHint.textContent = 'Drag a WebId on the target to add a friend.'; friendsActionsRow.appendChild(dropHint); allFriends.prepend(friendsActionsRow); } if (friendsListRightCell instanceof HTMLTableCellElement) { friendsListRightCell.colSpan = 2; } const friendsItemsTable = friendsList.querySelector('td table'); if (friendsItemsTable instanceof HTMLTableElement) { friendsItemsTable.classList.add('social-friends-grid'); } return { section: allFriends, mainTable, friendsList }; }