From 1c266f035fa5c37c667f05a5fb3e3cbaa8e4fb66 Mon Sep 17 00:00:00 2001 From: Sharon Stratsianis Date: Fri, 24 Apr 2026 21:30:38 +1000 Subject: [PATCH 001/238] write literals for addresses --- src/sections/contactInfo/mutations.ts | 12 ++++++------ src/sections/heading/mutations.ts | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/sections/contactInfo/mutations.ts b/src/sections/contactInfo/mutations.ts index 1fe932dd..ca87fd2f 100644 --- a/src/sections/contactInfo/mutations.ts +++ b/src/sections/contactInfo/mutations.ts @@ -1,4 +1,4 @@ -import { LiveStore, NamedNode, Node, st, sym } from 'rdflib' +import { LiveStore, NamedNode, Node, literal, st, sym } from 'rdflib' import { ns } from 'solid-ui' import { ContactAddressRow, ContactMutationPlan, ContactPointRow } from './types' import { MutationOps } from '../shared/types' @@ -40,11 +40,11 @@ function buildAddressStatements(subject: NamedNode, doc: NamedNode, node: Node, const inserts = [st(subject, ns.vcard('hasAddress'), node as any, doc)] if (address.type) inserts.push(st(node as any, ns.rdf('type'), ns.vcard(address.type), doc)) - if (address.streetAddress) inserts.push(st(node as any, ns.vcard('street-address'), address.streetAddress as any, doc)) - if (address.locality) inserts.push(st(node as any, ns.vcard('locality'), address.locality as any, doc)) - if (address.region) inserts.push(st(node as any, ns.vcard('region'), address.region as any, doc)) - if (address.postalCode) inserts.push(st(node as any, ns.vcard('postal-code'), address.postalCode as any, doc)) - if (address.countryName) inserts.push(st(node as any, ns.vcard('country-name'), address.countryName as any, doc)) + if (address.streetAddress) inserts.push(st(node as any, ns.vcard('street-address'), literal(address.streetAddress), doc)) + if (address.locality) inserts.push(st(node as any, ns.vcard('locality'), literal(address.locality), doc)) + if (address.region) inserts.push(st(node as any, ns.vcard('region'), literal(address.region), doc)) + if (address.postalCode) inserts.push(st(node as any, ns.vcard('postal-code'), literal(address.postalCode), doc)) + if (address.countryName) inserts.push(st(node as any, ns.vcard('country-name'), literal(address.countryName), doc)) return inserts } diff --git a/src/sections/heading/mutations.ts b/src/sections/heading/mutations.ts index 8217cbac..62c1da07 100644 --- a/src/sections/heading/mutations.ts +++ b/src/sections/heading/mutations.ts @@ -41,11 +41,11 @@ function buildAddressStatements(subject: NamedNode, doc: NamedNode, node: Node, const inserts = [st(subject, ns.vcard('hasAddress'), node as any, doc)] if (address.type) inserts.push(st(node as any, ns.rdf('type'), ns.vcard(address.type), doc)) - if (address.streetAddress) inserts.push(st(node as any, ns.vcard('street-address'), address.streetAddress as any, doc)) - if (address.locality) inserts.push(st(node as any, ns.vcard('locality'), address.locality as any, doc)) - if (address.region) inserts.push(st(node as any, ns.vcard('region'), address.region as any, doc)) - if (address.postalCode) inserts.push(st(node as any, ns.vcard('postal-code'), address.postalCode as any, doc)) - if (address.countryName) inserts.push(st(node as any, ns.vcard('country-name'), address.countryName as any, doc)) + if (address.streetAddress) inserts.push(st(node as any, ns.vcard('street-address'), literal(address.streetAddress), doc)) + if (address.locality) inserts.push(st(node as any, ns.vcard('locality'), literal(address.locality), doc)) + if (address.region) inserts.push(st(node as any, ns.vcard('region'), literal(address.region), doc)) + if (address.postalCode) inserts.push(st(node as any, ns.vcard('postal-code'), literal(address.postalCode), doc)) + if (address.countryName) inserts.push(st(node as any, ns.vcard('country-name'), literal(address.countryName), doc)) return inserts } From 868b65d4f85540106dd6d5e80d50bd0ca2b8dd64 Mon Sep 17 00:00:00 2001 From: Sharon Stratsianis Date: Fri, 24 Apr 2026 21:37:12 +1000 Subject: [PATCH 002/238] flatten knows language --- src/sections/languages/selectors.ts | 5 +--- .../languages.selectors-mutations.test.ts | 27 ++++++++++++++++++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/sections/languages/selectors.ts b/src/sections/languages/selectors.ts index a77604ee..ab0ce9ff 100644 --- a/src/sections/languages/selectors.ts +++ b/src/sections/languages/selectors.ts @@ -151,11 +151,8 @@ export function presentLanguages(subject: NamedNode, store: LiveStore): Language .filter((node) => isRdfListNode(store, node)) .map((node) => expandRdfList(store, node)) - const longestList = expandedLists - .sort((a, b) => b.length - a.length)[0] || [] - const standaloneNodes = languageObjects.filter((node) => !isRdfListNode(store, node)) - const languageNodes = [...longestList, ...standaloneNodes] + const languageNodes = [...expandedLists.flat(), ...standaloneNodes] const details: LanguageDetails[] = languageNodes .map((lan) => ({ diff --git a/test/sections/languages.selectors-mutations.test.ts b/test/sections/languages.selectors-mutations.test.ts index b8894df4..68c42bd3 100644 --- a/test/sections/languages.selectors-mutations.test.ts +++ b/test/sections/languages.selectors-mutations.test.ts @@ -87,7 +87,7 @@ describe('Languages selectors and mutations', () => { expect(languages.map((item) => item.publicId)).toEqual(['fr', 'de']) }) - it('reads cumulative legacy list snapshots and keeps longest ordered list', () => { + it('reads cumulative legacy list snapshots and keeps merged ordered languages', () => { const store = graph() as any const subject = sym('https://example.com/profile/card#me') const doc = subject.doc() @@ -112,6 +112,31 @@ describe('Languages selectors and mutations', () => { ]) }) + it('merges fragmented knowsLanguage rdf lists before deduping', () => { + const store = graph() as any + const subject = sym('https://example.com/profile/card#me') + const doc = subject.doc() + const id1 = sym('https://example.com/profile/card#id1') + const id2 = sym('https://example.com/profile/card#id2') + const id3 = sym('https://example.com/profile/card#id3') + + store.add(subject, ns.schema('knowsLanguage'), new Collection([id1, id2]), doc) + store.add(subject, ns.schema('knowsLanguage'), new Collection([id2, id3]), doc) + + store.add(id1, ns.solid('publicId'), sym('https://www.w3.org/ns/iana/language-code/en'), doc) + store.add(id2, ns.solid('publicId'), sym('https://www.w3.org/ns/iana/language-code/fr'), doc) + store.add(id3, ns.solid('publicId'), sym('https://www.w3.org/ns/iana/language-code/de'), doc) + + const languages = presentLanguages(subject, store) + + expect(languages).toHaveLength(3) + expect(languages.map((item) => item.publicId)).toEqual([ + 'https://www.w3.org/ns/iana/language-code/en', + 'https://www.w3.org/ns/iana/language-code/fr', + 'https://www.w3.org/ns/iana/language-code/de' + ]) + }) + it('writes canonical id-node rdf:list model and removes legacy entry-node model statements', async () => { const store = graph() as any const subject = sym('https://example.com/profile/card#me') From d7119fdc9e225ff2f3519ee9c34f44e17401e6bc Mon Sep 17 00:00:00 2001 From: Sharon Stratsianis Date: Fri, 24 Apr 2026 21:40:11 +1000 Subject: [PATCH 003/238] test refresh add friend --- test/add-me-to-your-friends-functions.test.ts | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/test/add-me-to-your-friends-functions.test.ts b/test/add-me-to-your-friends-functions.test.ts index ae43a403..10d04b30 100644 --- a/test/add-me-to-your-friends-functions.test.ts +++ b/test/add-me-to-your-friends-functions.test.ts @@ -1,7 +1,34 @@ +import { afterEach, beforeEach, describe, expect, it, jest } from '@jest/globals' +import { fireEvent, waitFor } from '@testing-library/dom' +import { authn } from 'solid-logic' +import { sym } from 'rdflib' import { context, subject } from './setup' import { addMeToYourFriendsDiv, checkIfThingExists, createAddMeToYourFriendsButton, saveNewThing } from '../src/addMeToYourFriends' +import { + addMeToYourFriendsButtonText, + friendExistsAlreadyButtonText, + logInAddMeToYourFriendsButtonText +} from '../src/texts' describe('add-me-to-your-friends functions', () => { + const baseStore = context.session.store as any + const me = sym('https://example.com/profile/card#me') + + beforeEach(() => { + jest.restoreAllMocks() + baseStore.fetcher = { + load: jest.fn().mockResolvedValue(undefined) + } + baseStore.updater = { + update: jest.fn().mockResolvedValue(undefined) + } + baseStore.whether = jest.fn().mockReturnValue(0) + }) + + afterEach(() => { + jest.restoreAllMocks() + }) + describe('addMeToYourFriendsDiv', () => { it('exists', () => { expect(addMeToYourFriendsDiv).toBeInstanceOf(Function) @@ -20,6 +47,38 @@ describe('add-me-to-your-friends functions', () => { it('runs', () => { expect(createAddMeToYourFriendsButton(subject, context)).toBeTruthy() }) + + it('disables the action and shows the logged-out label for anonymous users', () => { + jest.spyOn(authn, 'currentUser').mockReturnValue(null as any) + + const button = createAddMeToYourFriendsButton(subject, context) + + expect(button.disabled).toBe(true) + expect(button.textContent).toBe(logInAddMeToYourFriendsButtonText) + }) + + it('refreshes after a successful add and updates the label to already friends', async () => { + jest.spyOn(authn, 'currentUser').mockReturnValue(me as any) + const whetherMock = jest.fn() + .mockReturnValueOnce(0) + .mockReturnValueOnce(0) + .mockReturnValueOnce(1) + baseStore.whether = whetherMock + + const button = createAddMeToYourFriendsButton(subject, context) + + await waitFor(() => { + expect(button.textContent).toBe(addMeToYourFriendsButtonText) + }) + + fireEvent.click(button) + + await waitFor(() => { + expect(button.textContent).toBe(friendExistsAlreadyButtonText) + }) + + expect(baseStore.updater.update).toHaveBeenCalledTimes(1) + }) }) describe('saveNewThing', () => { From 0707c09293eb0b9b96f034143b3223fab032b6b6 Mon Sep 17 00:00:00 2001 From: Sharon Stratsianis Date: Fri, 24 Apr 2026 21:44:49 +1000 Subject: [PATCH 004/238] comment in forms helper file --- src/rdfFormsHelper.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rdfFormsHelper.ts b/src/rdfFormsHelper.ts index 8be173e3..cebb37ae 100644 --- a/src/rdfFormsHelper.ts +++ b/src/rdfFormsHelper.ts @@ -1,4 +1,5 @@ -/** Project-local: currently unused component. Keep temporarily; do not add new usage. */ +/** Project-local: currently unused component. */ +/* will bring forms back so keeping the file */ import { NamedNode, Store, Namespace, sym, parse } from 'rdflib' import { widgets } from 'solid-ui' From 1a813de25fbb82fb2332b2f57dd56a71bd0dfce6 Mon Sep 17 00:00:00 2001 From: Sharon Stratsianis Date: Fri, 24 Apr 2026 22:40:34 +1000 Subject: [PATCH 005/238] clean up --- src/ChatWithMe.ts | 107 ------------------------------ src/sections/bio/BioEditDialog.ts | 3 +- src/styles/ChatWithMe.css | 6 -- src/texts.ts | 10 +-- 4 files changed, 3 insertions(+), 123 deletions(-) delete mode 100644 src/ChatWithMe.ts delete mode 100644 src/styles/ChatWithMe.css diff --git a/src/ChatWithMe.ts b/src/ChatWithMe.ts deleted file mode 100644 index 84a6e4e2..00000000 --- a/src/ChatWithMe.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { html, TemplateResult } from 'lit-html' -import { DataBrowserContext } from 'pane-registry' -import { NamedNode } from 'rdflib' -import { widgets } from 'solid-ui' -import { authn } from 'solid-logic' -import { asyncReplace } from 'lit-html/directives/async-replace.js' -import { chatWithMeButtonText, logInToChatWithMeButtonText, loadingMessage } from './texts' -import { checkIfAnyUserLoggedIn, complain } from './buttonsHelper' -import { ViewerMode } from './types' -import './styles/ChatWithMe.css' - - -export const ChatWithMe = ( - subject: NamedNode, - context: DataBrowserContext, - viewerMode: ViewerMode -): TemplateResult => { - const logic = context.session.logic - const longChatPane = context.session.paneRegistry.byName('long chat') - - async function* chatContainer() { - const chatContainer = context.dom.createElement('section') as HTMLDivElement - chatContainer.setAttribute('class', 'chatSection section-centered') - chatContainer.setAttribute('aria-labelledby', 'chat-section-title') - chatContainer.setAttribute('role', 'region') - chatContainer.setAttribute('data-testid', 'chat') - - // Add hidden title for screen readers - const title = context.dom.createElement('h3') - title.id = 'chat-section-title' - title.className = 'sr-only' - title.textContent = 'Communication' - chatContainer.appendChild(title) - - let exists - try { - yield html` -
-
- ${loadingMessage.toUpperCase()} -
-
- ` - exists = await logic.chat.getChat(subject, false) - } catch (e) { - exists = false - } - - if (exists) { - const chatArea = context.dom.createElement('div') - chatArea.setAttribute('role', 'log') - chatArea.setAttribute('aria-label', 'Chat conversation') - chatArea.appendChild(longChatPane.render(exists, context, {})) - chatContainer.appendChild(chatArea) - yield chatContainer - } else { - const me = authn.currentUser() - let label = checkIfAnyUserLoggedIn(me) ? chatWithMeButtonText.toUpperCase() : logInToChatWithMeButtonText.toUpperCase() - const button = widgets.button( - context.dom, - undefined, - label, - setButtonHandler, - { needsBorder: true } - ) - - async function setButtonHandler(event) { - event.preventDefault() - try { - const chat: NamedNode = await logic.chat.getChat(subject, true) - chatContainer.innerHTML = '' - chatContainer.appendChild(longChatPane.render(chat, context, {})) - } catch (error) { - complain(chatContainer, context, error) - } - } - - button.refresh = refreshButton() - - function refreshButton() { - const me = authn.currentUser() - - if (checkIfAnyUserLoggedIn(me)) { - button.innerHTML = chatWithMeButtonText.toUpperCase() - } else { - //not logged in - button.innerHTML = logInToChatWithMeButtonText.toUpperCase() - } - } - - button.setAttribute('type', 'button') - button.setAttribute('aria-describedby', 'chat-button-description') - - const description = context.dom.createElement('span') - description.id = 'chat-button-description' - description.className = 'sr-only' - description.textContent = 'Start a new conversation or sign in to continue existing chat' - - button.classList.add('profile__action-button', 'btn-primary', 'action-button-focus') - chatContainer.appendChild(button) - chatContainer.appendChild(description) - yield chatContainer - } - } - - return html` ${asyncReplace(chatContainer())} ` -} \ No newline at end of file diff --git a/src/sections/bio/BioEditDialog.ts b/src/sections/bio/BioEditDialog.ts index 7fdb9bbe..bf56c955 100644 --- a/src/sections/bio/BioEditDialog.ts +++ b/src/sections/bio/BioEditDialog.ts @@ -10,6 +10,7 @@ import { hasNonEmptyText, sanitizeTextValue, toText } from '../../textUtils' import { dialogCancelLabelText, dialogSubmitLabelText, + editBioDialogTitleText, ownerLoginRequiredDialogMessageText, saveBioUpdatesFailedPrefixText } from '../../texts' @@ -107,7 +108,7 @@ export async function createBioEditDialog( const { form, formState } = createBioEditForm(bioData, viewerMode) const result = await openInputDialog({ - title: 'Edit Bio', + title: editBioDialogTitleText, dom, form, headerAction: { type: 'none' }, diff --git a/src/styles/ChatWithMe.css b/src/styles/ChatWithMe.css deleted file mode 100644 index 3cf237f0..00000000 --- a/src/styles/ChatWithMe.css +++ /dev/null @@ -1,6 +0,0 @@ -/* ChatWithMe.css */ -/* Uses utilities: .section-centered, .loading-text, .btn-primary, .btn-transparent */ - -.chatSection { - overflow-x: auto; -} diff --git a/src/texts.ts b/src/texts.ts index 2557cce3..7598f648 100644 --- a/src/texts.ts +++ b/src/texts.ts @@ -3,7 +3,6 @@ export const scanQrToConnectText = 'Link to Profile' //ERRORS & SUCCESS //Same 'not logged in' error message like on 'Chat with me' button export const userNotLoggedInErrorMessage = 'Current user not found! Not logged in?' -export const internalErrorMessage = 'An internal error occured!' export const friendWasAddedSuccesMessage = 'Friend was added!' //OTHER @@ -15,7 +14,6 @@ export const addMeToYourFriendsButtonText = 'Add as friend' export const logInAddMeToYourFriendsButtonText = 'Log in to add as friend' export const logInToChatWithMeButtonText = 'Login to chat with me' export const friendExistsAlreadyButtonText = 'Already part of friends' -export const chatWithMeButtonText = 'Chat with me' // Profile & Edit profile texts export const yourContactInformationHeading = 'Your profile' @@ -43,8 +41,6 @@ export const dialogCancelLabelText = 'Cancel' export const pasteEntryButtonTitleText = 'Paste' export const deleteEntryButtonTitleText = 'Delete entry' export const ownerLoginRequiredDialogMessageText = 'You need to log in as the profile owner to save contact updates.' -export const loginRequiredDialogTitleText = 'Login Required' -export const saveFailedDialogTitleText = 'Save Failed' export const saveContactUpdatesFailedPrefixText = 'Could not save contact updates.' export const saveHeadingUpdatesFailedPrefixText = 'Could not save heading updates.' export const saveLanguageUpdatesFailedPrefixText = 'Could not save language updates.' @@ -58,12 +54,8 @@ export const mutationSaveLanguagesFailedPrefixText = 'Failed to save languages:' export const mutationSaveSkillsFailedPrefixText = 'Failed to save skills:' export const mutationSaveResumeFailedPrefixText = 'Failed to save resume:' export const mutationEducationFailedPrefixText = 'Failed to save education:' -export const mutationBioFailedPrefixText = 'Failed to save bio:' export const resumeUpdateEntryNotFoundErrorMessageText = 'Could not find existing resume entry for update. Please reload profile data and try again.' -export const bioUpdateEntryNotFoundErrorMessageText = 'Could not find existing bio entry for update. Please reload profile data and try again.' export const updaterUnsupportedStoreErrorMessageText = 'Store does not support updates' export const fallbackSaveUpdatesErrorMessageText = 'Failed to save updates' export const socialAccountsHeadingText = 'Follow me on' -export const sharedItemsHeadingText = 'Shared items' -export const friendsHeadingText = 'Friends' -export const contactHeadingText = 'Contact' \ No newline at end of file +export const friendsHeadingText = 'Friends' \ No newline at end of file From 27bbd50e1f5e9b3b4b95c073f1e5c44aafe587ce Mon Sep 17 00:00:00 2001 From: Sharon Stratsianis Date: Fri, 24 Apr 2026 22:44:55 +1000 Subject: [PATCH 006/238] more cleanup --- src/ProfileView.ts | 2 +- src/index.ts | 2 +- src/{ => sections/qrcode}/QRCodeCard.ts | 0 src/{ => specialButtons}/addMeToYourFriends.ts | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename src/{ => sections/qrcode}/QRCodeCard.ts (100%) rename src/{ => specialButtons}/addMeToYourFriends.ts (100%) diff --git a/src/ProfileView.ts b/src/ProfileView.ts index d7a38cc5..291b3b5c 100644 --- a/src/ProfileView.ts +++ b/src/ProfileView.ts @@ -3,7 +3,7 @@ import { DataBrowserContext } from 'pane-registry' import { NamedNode, LiveStore } from 'rdflib' import { authn } from 'solid-logic' import './styles/ProfileView.css' -import { QRCodeCard } from './QRCodeCard' +import { QRCodeCard } from './sections/qrcode/QRCodeCard' import { ViewerMode } from './types' import { presentProfileViewModel } from './ProfileViewModelPresenter' import { renderContactInfoSection } from './sections/contactInfo/ContactInfoSection' diff --git a/src/index.ts b/src/index.ts index 307f9eaf..822a8a59 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,7 +16,7 @@ export { createAddMeToYourFriendsButton, saveNewThing, checkIfThingExists -} from './addMeToYourFriends' +} from './specialButtons/addMeToYourFriends' async function loadExtendedProfile(store: LiveStore, subject: NamedNode) { const otherProfiles = store.each( diff --git a/src/QRCodeCard.ts b/src/sections/qrcode/QRCodeCard.ts similarity index 100% rename from src/QRCodeCard.ts rename to src/sections/qrcode/QRCodeCard.ts diff --git a/src/addMeToYourFriends.ts b/src/specialButtons/addMeToYourFriends.ts similarity index 100% rename from src/addMeToYourFriends.ts rename to src/specialButtons/addMeToYourFriends.ts From 7495e3b79b1a0eec9aa3acafe6cad5fba17f3ff3 Mon Sep 17 00:00:00 2001 From: Sharon Stratsianis Date: Fri, 24 Apr 2026 22:48:20 +1000 Subject: [PATCH 007/238] move qrcode section --- src/ProfileView.ts | 13 +------------ src/sections/qrcode/QRCodeSection.ts | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 12 deletions(-) create mode 100644 src/sections/qrcode/QRCodeSection.ts diff --git a/src/ProfileView.ts b/src/ProfileView.ts index 291b3b5c..fec708fb 100644 --- a/src/ProfileView.ts +++ b/src/ProfileView.ts @@ -3,7 +3,6 @@ import { DataBrowserContext } from 'pane-registry' import { NamedNode, LiveStore } from 'rdflib' import { authn } from 'solid-logic' import './styles/ProfileView.css' -import { QRCodeCard } from './sections/qrcode/QRCodeCard' import { ViewerMode } from './types' import { presentProfileViewModel } from './ProfileViewModelPresenter' import { renderContactInfoSection } from './sections/contactInfo/ContactInfoSection' @@ -17,6 +16,7 @@ import { renderProjectSection } from './sections/projects/ProjectSection' import { renderHeadingSection } from './sections/heading/HeadingSection' import { renderBioSection } from './sections/bio/BioSection' import { renderSocialAccounts } from './sections/social/SocialSection' +import { renderQRCode } from './sections/qrcode/QRCodeSection' type ProfileViewModelData = Awaited> type SocialAccounts = ProfileViewModelData['social'] @@ -55,17 +55,6 @@ function renderSidebar( ` } -function renderQRCode(subject: NamedNode, store: LiveStore) { - return html` -
-

QR code

-
- ${QRCodeCard(subject, store)} -
-
- ` -} - export async function ProfileView ( subject: NamedNode, context: DataBrowserContext, diff --git a/src/sections/qrcode/QRCodeSection.ts b/src/sections/qrcode/QRCodeSection.ts new file mode 100644 index 00000000..44c76151 --- /dev/null +++ b/src/sections/qrcode/QRCodeSection.ts @@ -0,0 +1,14 @@ +import { html } from "lit-html"; +import { QRCodeCard } from "./QRCodeCard"; +import { LiveStore, NamedNode } from "rdflib"; + +export function renderQRCode(subject: NamedNode, store: LiveStore) { + return html` +
+

QR code

+
+ ${QRCodeCard(subject, store)} +
+
+ ` +} From d79df1aa4a542f9bae453269920bd859e64502ce Mon Sep 17 00:00:00 2001 From: Sharon Stratsianis Date: Fri, 24 Apr 2026 22:50:30 +1000 Subject: [PATCH 008/238] remove unnecessary types --- src/ProfileView.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ProfileView.ts b/src/ProfileView.ts index fec708fb..0af3bcb1 100644 --- a/src/ProfileView.ts +++ b/src/ProfileView.ts @@ -16,11 +16,9 @@ import { renderProjectSection } from './sections/projects/ProjectSection' import { renderHeadingSection } from './sections/heading/HeadingSection' import { renderBioSection } from './sections/bio/BioSection' import { renderSocialAccounts } from './sections/social/SocialSection' +import { SocialPresentation } from './sections/social/types' import { renderQRCode } from './sections/qrcode/QRCodeSection' -type ProfileViewModelData = Awaited> -type SocialAccounts = ProfileViewModelData['social'] - function getViewerMode(subject: NamedNode): ViewerMode { let mode: ViewerMode = 'anonymous' if (authn.currentUser() && authn.currentUser().sameTerm(subject)) mode = 'owner' @@ -31,7 +29,7 @@ function getViewerMode(subject: NamedNode): ViewerMode { function renderSidebar( store: LiveStore, subject: NamedNode, - accounts: SocialAccounts, + accounts: SocialPresentation, skills: SkillDetails[], languages: LanguageDetails[], contactInfo: ContactInfo, From fcf0f35dde257f0fdeaf48a3e1d1cef2299f2602 Mon Sep 17 00:00:00 2001 From: Sharon Stratsianis Date: Fri, 24 Apr 2026 23:03:34 +1000 Subject: [PATCH 009/238] a11y --- .../contactInfo/ContactInfoSection.ts | 4 +- src/sections/education/EducationSection.ts | 2 +- src/sections/projects/ProjectSection.ts | 4 +- src/sections/qrcode/QRCodeCard.ts | 6 +- src/sections/shared/collapsibleSection.ts | 1 + src/sections/skills/SkillsSection.ts | 3 +- src/sections/social/SocialSection.ts | 5 +- src/specialButtons/addMeToYourFriends.ts | 8 +-- ...d-me-to-your-friends.accessibility.test.ts | 49 +++++++++++++ test/dialog.accessibility.test.ts | 33 +++++++++ test/qrcode-card.accessibility.test.ts | 14 ++-- test/sections/accessibility-variants.test.ts | 68 +++++++++++++++++++ test/sections/bio.section.test.ts | 18 +++++ test/sections/contact-info.section.test.ts | 41 +++++++++++ test/sections/education.section.test.ts | 24 +++++++ test/sections/languages.section.test.ts | 18 +++++ test/sections/projects.section.test.ts | 24 +++++++ test/sections/resume.section.test.ts | 25 +++++++ test/sections/skills.section.test.ts | 26 +++++++ 19 files changed, 349 insertions(+), 24 deletions(-) create mode 100644 test/add-me-to-your-friends.accessibility.test.ts create mode 100644 test/dialog.accessibility.test.ts create mode 100644 test/sections/accessibility-variants.test.ts diff --git a/src/sections/contactInfo/ContactInfoSection.ts b/src/sections/contactInfo/ContactInfoSection.ts index 5b890037..0e6e625b 100644 --- a/src/sections/contactInfo/ContactInfoSection.ts +++ b/src/sections/contactInfo/ContactInfoSection.ts @@ -174,7 +174,7 @@ function renderContactInfoSectionDefault( -