feat(links): Copy Lotus Link permalinks, in-app recognition, /home redirect for joined rooms, via= alias, OIDC deep-link redirect (#130)
CI / Build & Quality Checks (push) Successful in 2m4s
CI / Docker image build & smoke test (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 6s
CI / Trigger Desktop Build (push) Successful in 5s
CI / Playwright smoke (e2e) (push) Successful in 2m11s
CI / Build & Quality Checks (push) Successful in 2m4s
CI / Docker image build & smoke test (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 6s
CI / Trigger Desktop Build (push) Successful in 5s
CI / Playwright smoke (e2e) (push) Successful in 2m11s
matrix.to cannot target this deployment (Cinny adapter hard-codes app.cinny.in; web-instance[] is Element-only, allowlisted), so add a "Copy Lotus Link" next to every Copy Link (message menu, space header menu, sidebar space tab) producing https://<this origin>/home/<room>/<event> ?viaServers=… via plugins/lotus-permalink.ts. Lotus links in messages are rewritten to their matrix.to form inside the HTML parser so they render as room/event mentions and navigate in place. /home/<room> for a joined room that belongs to a space or Direct now redirects to its own route (was a preview card with a View button; also the form matrix.to → Cinny links use). ?via= is accepted as an alias of ?viaServers= (what the matrix.to Cinny adapter emits). A deep link visited while logged out is now honoured after an OIDC login: the OIDC callback reloads at the app root, which discarded the stored path — the index loader consumes it via the shared takeAfterLoginPath(). Verified end-to-end with Playwright on a local Synapse: logged-out cold link → login → lands on the event under the space route; menu copies the expected link; a pasted Lotus link renders as a mention and jumps in place; both space menus copy the space link. Closes #130 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
@@ -23,6 +23,7 @@ import Linkify from 'linkify-react';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import { ChildNode } from 'domhandler';
|
||||
import { stripTrackingParams } from '../utils/urlTracking';
|
||||
import { lotusPermalinkToMatrixTo } from './lotus-permalink';
|
||||
import * as css from '../styles/CustomHtml.css';
|
||||
import {
|
||||
getMxIdLocalPart,
|
||||
@@ -118,6 +119,22 @@ export const setStripTrackingOnRender = (enabled: boolean): void => {
|
||||
const cleanHref = (href: string): string =>
|
||||
stripTrackingOnRender ? stripTrackingParams(href) : href;
|
||||
|
||||
// [Gitea #130] Links to THIS deployment's room routes render and click like
|
||||
// matrix.to links. The base is set once from the client config
|
||||
// (ClientNonUIFeatures) because this module has no access to hooks.
|
||||
let lotusPermalinkBase: string | undefined;
|
||||
export const setLotusPermalinkBase = (baseUrl: string | undefined): void => {
|
||||
lotusPermalinkBase = baseUrl;
|
||||
};
|
||||
/**
|
||||
* The matrix.to form of `href` when it is a matrix.to link or a Lotus
|
||||
* permalink; undefined for every other link.
|
||||
*/
|
||||
export const toMatrixToHref = (href: string): string | undefined => {
|
||||
if (testMatrixTo(href)) return href;
|
||||
return lotusPermalinkBase ? lotusPermalinkToMatrixTo(lotusPermalinkBase, href) : undefined;
|
||||
};
|
||||
|
||||
export const LINKIFY_OPTS: LinkifyOpts = {
|
||||
attributes: {
|
||||
target: '_blank',
|
||||
@@ -235,8 +252,10 @@ export const factoryRenderLinkifyWithMention = (
|
||||
attributes,
|
||||
content,
|
||||
}) => {
|
||||
if (tagName === 'a' && testMatrixTo(tryDecodeURIComponent(attributes.href))) {
|
||||
const mention = mentionRender(tryDecodeURIComponent(attributes.href));
|
||||
const matrixHref =
|
||||
tagName === 'a' ? toMatrixToHref(tryDecodeURIComponent(attributes.href)) : undefined;
|
||||
if (matrixHref) {
|
||||
const mention = mentionRender(matrixHref);
|
||||
if (mention) return mention;
|
||||
}
|
||||
|
||||
@@ -559,7 +578,9 @@ export const getReactCustomHtmlParser = (
|
||||
}
|
||||
}
|
||||
|
||||
if (name === 'a' && testMatrixTo(tryDecodeURIComponent(String(props.href)))) {
|
||||
const matrixHref =
|
||||
name === 'a' ? toMatrixToHref(tryDecodeURIComponent(String(props.href))) : undefined;
|
||||
if (matrixHref) {
|
||||
const content = children.find((child) => !(child instanceof DOMText))
|
||||
? undefined
|
||||
: children.map((c) => (c instanceof DOMText ? c.data : '')).join();
|
||||
@@ -567,7 +588,7 @@ export const getReactCustomHtmlParser = (
|
||||
const mention = renderMatrixMention(
|
||||
mx,
|
||||
roomId,
|
||||
tryDecodeURIComponent(String(props.href)),
|
||||
matrixHref,
|
||||
makeMentionCustomProps(params.handleMentionClick, content),
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user