Skip to content

Commit

Permalink
Merge branch 'develop' into renovate/testcontainers-node-monorepo
Browse files Browse the repository at this point in the history
  • Loading branch information
t3chguy authored Jan 22, 2025
2 parents f17987c + 68c03db commit 28f6760
Show file tree
Hide file tree
Showing 34 changed files with 508 additions and 254 deletions.
2 changes: 1 addition & 1 deletion playwright/e2e/right-panel/memberlist.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ test.describe("Memberlist", () => {
await app.viewRoomByName(ROOM_NAME);
const memberlist = await app.toggleMemberlistPanel();
await expect(memberlist.locator(".mx_MemberTileView")).toHaveCount(4);
await expect(memberlist.getByText("(Invited)")).toHaveCount(1);
await expect(memberlist.getByText("Invited")).toHaveCount(1);
await expect(page.locator(".mx_MemberListView")).toMatchScreenshot("with-four-members.png");
});
});
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions res/css/views/elements/_Pill.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ Please see LICENSE files in the repository root for full details.
}

&.mx_UserPill_me,
&.mx_AtRoomPill {
&.mx_AtRoomPill,
&.mx_KeywordPill {
background-color: var(--cpd-color-bg-critical-primary) !important; /* To override .markdown-body */
}

Expand All @@ -45,7 +46,8 @@ Please see LICENSE files in the repository root for full details.
}

/* We don't want to indicate clickability */
&.mx_AtRoomPill:hover {
&.mx_AtRoomPill:hover,
&.mx_KeywordPill:hover {
background-color: var(--cpd-color-bg-critical-primary) !important; /* To override .markdown-body */
cursor: unset;
}
Expand Down
2 changes: 2 additions & 0 deletions res/css/views/messages/_DisambiguatedProfile.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ Please see LICENSE files in the repository root for full details.
.mx_DisambiguatedProfile_mxid {
margin-inline-start: 0;
font: var(--cpd-font-body-sm-regular);
text-overflow: ellipsis;
overflow: hidden;
}

span:not(.mx_DisambiguatedProfile_mxid) {
Expand Down
6 changes: 0 additions & 6 deletions res/css/views/rooms/_EventTile.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,6 @@ $left-gutter: 64px;
}
}

&.mx_EventTile_highlight,
&.mx_EventTile_highlight .markdown-body,
&.mx_EventTile_highlight .mx_EventTile_edited {
color: $alert;
}

&.mx_EventTile_bubbleContainer {
display: grid;
grid-template-columns: 1fr 100px;
Expand Down
1 change: 1 addition & 0 deletions res/css/views/rooms/_MemberTileView.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Please see LICENSE files in the repository root for full details.
font: var(--cpd-font-body-sm-regular);
font-size: 13px;
color: var(--cpd-color-text-secondary);
margin-left: var(--cpd-space-4x);
}

.mx_MemberTileView_avatar {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export function useMemberTileViewModel(props: MemberTileViewModelProps): MemberT
userLabel = _t(PowerLabel[powerStatus]);
}
if (props.member.isInvite) {
userLabel = `(${_t("member_list|invited_label")})`;
userLabel = _t("member_list|invited_label");
}

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function useThreePidTileViewModel(props: ThreePidTileViewModelProps): Thr
});
};

const userLabel = `(${_t("member_list|invited_label")})`;
const userLabel = _t("member_list|invited_label");

return {
name,
Expand Down
26 changes: 24 additions & 2 deletions src/components/views/elements/Pill.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export enum PillType {
AtRoomMention = "TYPE_AT_ROOM_MENTION", // '@room' mention
EventInSameRoom = "TYPE_EVENT_IN_SAME_ROOM",
EventInOtherRoom = "TYPE_EVENT_IN_OTHER_ROOM",
Keyword = "TYPE_KEYWORD", // Used to highlight keywords that triggered a notification rule
}

export const pillRoomNotifPos = (text: string | null): number => {
Expand Down Expand Up @@ -76,14 +77,32 @@ export interface PillProps {
room?: Room;
// Whether to include an avatar in the pill
shouldShowPillAvatar?: boolean;
// Explicitly-provided text to display in the pill
text?: string;
}

export const Pill: React.FC<PillProps> = ({ type: propType, url, inMessage, room, shouldShowPillAvatar = true }) => {
const { event, member, onClick, resourceId, targetRoom, text, type } = usePermalink({
export const Pill: React.FC<PillProps> = ({
type: propType,
url,
inMessage,
room,
shouldShowPillAvatar = true,
text: customPillText,
}) => {
const {
event,
member,
onClick,
resourceId,
targetRoom,
text: linkText,
type,
} = usePermalink({
room,
type: propType,
url,
});
const text = customPillText ?? linkText;

if (!type || !text) {
return null;
Expand All @@ -96,6 +115,7 @@ export const Pill: React.FC<PillProps> = ({ type: propType, url, inMessage, room
mx_UserPill: type === PillType.UserMention,
mx_UserPill_me: resourceId === MatrixClientPeg.safeGet().getUserId(),
mx_EventPill: type === PillType.EventInOtherRoom || type === PillType.EventInSameRoom,
mx_KeywordPill: type === PillType.Keyword,
});

let avatar: ReactElement | null = null;
Expand Down Expand Up @@ -131,6 +151,8 @@ export const Pill: React.FC<PillProps> = ({ type: propType, url, inMessage, room
case PillType.UserMention:
avatar = <PillMemberAvatar shouldShowPillAvatar={shouldShowPillAvatar} member={member} />;
break;
case PillType.Keyword:
break;
default:
return null;
}
Expand Down
63 changes: 62 additions & 1 deletion src/components/views/messages/TextualBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ Please see LICENSE files in the repository root for full details.
*/

import React, { createRef, SyntheticEvent, MouseEvent, StrictMode } from "react";
import { MsgType } from "matrix-js-sdk/src/matrix";
import { MsgType, PushRuleKind } from "matrix-js-sdk/src/matrix";
import { TooltipProvider } from "@vector-im/compound-web";
import { globToRegexp } from "matrix-js-sdk/src/utils";

import * as HtmlUtils from "../../../HtmlUtils";
import { formatDate } from "../../../DateUtils";
Expand All @@ -35,6 +36,7 @@ import { EditWysiwygComposer } from "../rooms/wysiwyg_composer";
import { IEventTileOps } from "../rooms/EventTile";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import CodeBlock from "./CodeBlock";
import { Pill, PillType } from "../elements/Pill";
import { ReactRootManager } from "../../../utils/react";

interface IState {
Expand Down Expand Up @@ -100,6 +102,16 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
}
}
}

// Highlight notification keywords using pills
const pushDetails = this.props.mxEvent.getPushDetails();
if (
pushDetails.rule?.enabled &&
pushDetails.rule.kind === PushRuleKind.ContentSpecific &&
pushDetails.rule.pattern
) {
this.pillifyNotificationKeywords([content], this.regExpForKeywordPattern(pushDetails.rule.pattern));
}
}

private addCodeElement(pre: HTMLPreElement): void {
Expand Down Expand Up @@ -210,6 +222,55 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
}
}

/**
* Marks the text that activated a push-notification keyword pattern.
*/
private pillifyNotificationKeywords(nodes: ArrayLike<Element>, exp: RegExp): void {
let node: Node | null = nodes[0];
while (node) {
if (node.nodeType === Node.TEXT_NODE) {
const text = node.nodeValue;
if (!text) {
node = node.nextSibling;
continue;
}
const match = text.match(exp);
if (!match || match.length < 3) {
node = node.nextSibling;
continue;
}
const keywordText = match[2];
const idx = match.index! + match[1].length;
const before = text.substring(0, idx);
const after = text.substring(idx + keywordText.length);

const container = document.createElement("span");
const newContent = (
<>
{before}
<TooltipProvider>
<Pill text={keywordText} type={PillType.Keyword} />
</TooltipProvider>
{after}
</>
);
this.reactRoots.render(newContent, container, node);

node.parentNode?.replaceChild(container, node);
} else if (node.childNodes && node.childNodes.length) {
this.pillifyNotificationKeywords(node.childNodes as NodeListOf<Element>, exp);
}

node = node.nextSibling;
}
}

private regExpForKeywordPattern(pattern: string): RegExp {
// Reflects the push notification pattern-matching implementation at
// https://github.com/matrix-org/matrix-js-sdk/blob/dbd7d26968b94700827bac525c39afff2c198e61/src/pushprocessor.ts#L570
return new RegExp("(^|\\W)(" + globToRegexp(pattern) + ")(\\W|$)", "i");
}

private findLinks(nodes: ArrayLike<Element>): string[] {
let links: string[] = [];

Expand Down
3 changes: 1 addition & 2 deletions src/components/views/settings/devices/LoginWithQRSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ export function shouldShowQr(
): boolean {
const msc4108Supported = !!versions?.unstable_features?.["org.matrix.msc4108"];

const deviceAuthorizationGrantSupported =
oidcClientConfig?.metadata?.grant_types_supported.includes(DEVICE_CODE_SCOPE);
const deviceAuthorizationGrantSupported = oidcClientConfig?.grant_types_supported.includes(DEVICE_CODE_SCOPE);

return (
!!deviceAuthorizationGrantSupported &&
Expand Down
7 changes: 2 additions & 5 deletions src/components/views/settings/tabs/user/SessionManagerTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
*/

import React, { lazy, Suspense, useCallback, useContext, useEffect, useRef, useState } from "react";
import { discoverAndValidateOIDCIssuerWellKnown, MatrixClient } from "matrix-js-sdk/src/matrix";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { logger } from "matrix-js-sdk/src/logger";
import { defer } from "matrix-js-sdk/src/utils";

Expand Down Expand Up @@ -163,10 +163,7 @@ const SessionManagerTab: React.FC<{
const clientVersions = useAsyncMemo(() => matrixClient.getVersions(), [matrixClient]);
const oidcClientConfig = useAsyncMemo(async () => {
try {
const authIssuer = await matrixClient?.getAuthIssuer();
if (authIssuer) {
return discoverAndValidateOIDCIssuerWellKnown(authIssuer.issuer);
}
return await matrixClient?.getAuthMetadata();
} catch (e) {
logger.error("Failed to discover OIDC metadata", e);
}
Expand Down
18 changes: 6 additions & 12 deletions src/stores/oidc/OidcClientStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,8 @@ export class OidcClientStore {
} else {
// We are not in OIDC Native mode, as we have no locally stored issuer. Check if the server delegates auth to OIDC.
try {
const authIssuer = await this.matrixClient.getAuthIssuer();
const { accountManagementEndpoint, metadata } = await discoverAndValidateOIDCIssuerWellKnown(
authIssuer.issuer,
);
this.setAccountManagementEndpoint(accountManagementEndpoint, metadata.issuer);
const authMetadata = await this.matrixClient.getAuthMetadata();
this.setAccountManagementEndpoint(authMetadata.account_management_uri, authMetadata.issuer);
} catch (e) {
console.log("Auth issuer not found", e);
}
Expand Down Expand Up @@ -153,14 +150,11 @@ export class OidcClientStore {

try {
const clientId = getStoredOidcClientId();
const { accountManagementEndpoint, metadata, signingKeys } = await discoverAndValidateOIDCIssuerWellKnown(
this.authenticatedIssuer,
);
this.setAccountManagementEndpoint(accountManagementEndpoint, metadata.issuer);
const authMetadata = await discoverAndValidateOIDCIssuerWellKnown(this.authenticatedIssuer);
this.setAccountManagementEndpoint(authMetadata.account_management_uri, authMetadata.issuer);
this.oidcClient = new OidcClient({
...metadata,
authority: metadata.issuer,
signingKeys,
authority: authMetadata.issuer,
signingKeys: authMetadata.signingKeys ?? undefined,
redirect_uri: PlatformPeg.get()!.getOidcCallbackUrl().href,
client_id: clientId,
});
Expand Down
Loading

0 comments on commit 28f6760

Please sign in to comment.