Fix history for the 100th time. Fix role resolution in the invitation screen

This commit is contained in:
2026-05-04 11:36:09 +00:00
parent 2f2e515d72
commit dedfb69dff
4 changed files with 663 additions and 680 deletions

View File

@@ -21,7 +21,7 @@ import { useSatoshisConversion } from '../../hooks/useSatoshisConversion.js';
import { colors, logoSmall, formatSatoshis } from '../../theme.js';
import { copyToClipboard } from '../../utils/clipboard.js';
import type { Invitation } from '../../../services/invitation.js';
import type { XOTemplate } from '@xo-cash/types';
import type { XOInvitationCommit, XOTemplate } from '@xo-cash/types';
import {
getInvitationState,
@@ -29,7 +29,6 @@ import {
getInvitationInputs,
getInvitationOutputs,
getInvitationVariables,
getUserRole,
formatInvitationListItem,
formatInvitationId,
} from '../../../utils/invitation-utils.js';
@@ -80,6 +79,29 @@ const invitationListGroups: ListGroup[] = [
{ id: 'invitations', separator: true },
];
type OwnInvitationContext = {
entityIdentifier: string | null;
roleIdentifier: string | null;
};
function getRoleIdentifierFromCommits(commits: XOInvitationCommit[]): string | null {
for (const commit of commits) {
for (const input of commit.data.inputs ?? []) {
if (input.roleIdentifier) return input.roleIdentifier;
}
for (const output of commit.data.outputs ?? []) {
if (output.roleIdentifier) return output.roleIdentifier;
}
for (const variable of commit.data.variables ?? []) {
if (variable.roleIdentifier) return variable.roleIdentifier;
}
}
return null;
}
/**
* Invitation Screen Component.
*/
@@ -107,6 +129,10 @@ export function InvitationScreen(): React.ReactElement {
// ── Template cache ───────────────────────────────────────────────────────
const [templateCache, setTemplateCache] = useState<Map<string, XOTemplate>>(new Map());
const [selectedTemplate, setSelectedTemplate] = useState<XOTemplate | null>(null);
const [ownInvitationContext, setOwnInvitationContext] = useState<OwnInvitationContext>({
entityIdentifier: null,
roleIdentifier: null,
});
// Check if we should open import dialog on mount
const initialMode = navData.mode as string | undefined;
@@ -180,6 +206,43 @@ export function InvitationScreen(): React.ReactElement {
.then(template => setSelectedTemplate(template ?? null));
}, [selectedInvitation, appService]);
/**
* Load the current engine entity's commits for the selected invitation.
*/
useEffect(() => {
if (!selectedInvitation || !appService) {
setOwnInvitationContext({
entityIdentifier: null,
roleIdentifier: null,
});
return;
}
let isCurrent = true;
appService.engine.getOwnCommits(selectedInvitation.data)
.then((ownCommits) => {
if (!isCurrent) return;
setOwnInvitationContext({
entityIdentifier: ownCommits[0]?.entityIdentifier ?? null,
roleIdentifier: getRoleIdentifierFromCommits(ownCommits),
});
})
.catch(() => {
if (!isCurrent) return;
setOwnInvitationContext({
entityIdentifier: null,
roleIdentifier: null,
});
});
return () => {
isCurrent = false;
};
}, [selectedInvitation, appService]);
// ── Import flow callbacks ──────────────────────────────────────────────
/**
@@ -512,9 +575,8 @@ export function InvitationScreen(): React.ReactElement {
const inputs = getInvitationInputs(selectedInvitation);
const outputs = getInvitationOutputs(selectedInvitation);
const variables = getInvitationVariables(selectedInvitation);
const userEntityId = selectedInvitation.data.commits?.[0]?.entityIdentifier ?? null;
const userRole = getUserRole(selectedInvitation, userEntityId);
const userEntityId = ownInvitationContext.entityIdentifier;
const userRole = ownInvitationContext.roleIdentifier;
const roleInfoRaw = userRole && selectedTemplate?.roles?.[userRole];
const roleInfo = roleInfoRaw && typeof roleInfoRaw === 'object' ? roleInfoRaw : null;