Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Merge branch 'develop' into florianduros/settings-appearance-message-…
Browse files Browse the repository at this point in the history
…layout
  • Loading branch information
florianduros authored Jul 4, 2024
2 parents a094d9c + de12d69 commit cca481c
Show file tree
Hide file tree
Showing 17 changed files with 118 additions and 155 deletions.
9 changes: 5 additions & 4 deletions .github/workflows/end-to-end-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ jobs:
- uses: actions/setup-node@v4
with:
cache: "yarn"
node-version: "lts/*"

- name: Fetch layered build
id: layered_build
Expand Down Expand Up @@ -121,6 +122,7 @@ jobs:
with:
cache: "yarn"
cache-dependency-path: matrix-react-sdk/yarn.lock
node-version: "lts/*"

- name: Install dependencies
working-directory: matrix-react-sdk
Expand All @@ -145,10 +147,8 @@ jobs:
run: yarn playwright install --with-deps

- name: Run Playwright tests
uses: coactions/setup-xvfb@6b00cf1889f4e1d5a48635647013c0508128ee1a
with:
run: yarn playwright test --shard ${{ matrix.runner }}/${{ strategy.job-total }}
working-directory: matrix-react-sdk
run: yarn playwright test --shard ${{ matrix.runner }}/${{ strategy.job-total }}
working-directory: matrix-react-sdk

- name: Upload blob report to GitHub Actions Artifacts
if: always()
Expand All @@ -174,6 +174,7 @@ jobs:
if: inputs.skip != true
with:
cache: "yarn"
node-version: "lts/*"

- name: Install dependencies
if: inputs.skip != true
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/static_analysis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ jobs:
- uses: actions/setup-node@v4
with:
cache: "yarn"
node-version: "lts/*"

- name: Install Deps
run: "./scripts/ci/install-deps.sh"
Expand Down Expand Up @@ -83,6 +84,7 @@ jobs:
- uses: actions/setup-node@v4
with:
cache: "yarn"
node-version: "lts/*"

# Does not need branch matching as only analyses this layer
- name: Install Deps
Expand All @@ -100,6 +102,7 @@ jobs:
- uses: actions/setup-node@v4
with:
cache: "yarn"
node-version: "lts/*"

# Does not need branch matching as only analyses this layer
- name: Install Deps
Expand All @@ -117,6 +120,7 @@ jobs:
- uses: actions/setup-node@v4
with:
cache: "yarn"
node-version: "lts/*"

# Does not need branch matching as only analyses this layer
- name: Install Deps
Expand All @@ -134,6 +138,7 @@ jobs:
- uses: actions/setup-node@v4
with:
cache: "yarn"
node-version: "lts/*"

- name: Install Deps
run: "scripts/ci/layered.sh"
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ jobs:
- name: Yarn cache
uses: actions/setup-node@v4
with:
node-version: "lts/*"
cache: "yarn"

- name: Install Deps
Expand Down Expand Up @@ -115,6 +116,7 @@ jobs:
- uses: actions/setup-node@v4
with:
cache: "yarn"
node-version: "lts/*"

- name: Run tests
run: "./scripts/ci/app-tests.sh"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@
"pako": "^2.0.3",
"png-chunks-extract": "^1.0.0",
"posthog-js": "1.141.3",
"proposal-temporal": "^0.9.0",
"qrcode": "1.5.3",
"re-resizable": "^6.9.0",
"react": "17.0.2",
Expand All @@ -133,6 +132,7 @@
"sanitize-filename": "^1.6.3",
"sanitize-html": "2.13.0",
"tar-js": "^0.3.0",
"temporal-polyfill": "^0.2.5",
"ua-parser-js": "^1.0.2",
"uuid": "^10.0.0",
"what-input": "^5.2.10"
Expand Down
11 changes: 10 additions & 1 deletion playwright/flaky-reporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,23 @@ class FlakyReporter implements Reporter {

const headers = { Authorization: `Bearer ${GITHUB_TOKEN}` };
// Fetch all existing issues with the flaky-test label.
const issuesRequest = await fetch(`${GITHUB_API_URL}/repos/${REPO}/issues?labels=${LABEL}`, { headers });
const issuesRequest = await fetch(
`${GITHUB_API_URL}/repos/${REPO}/issues?labels=${LABEL}&state=all&per_page=100&sort=created`,
{ headers },
);
const issues = await issuesRequest.json();
for (const flake of this.flakes) {
const title = ISSUE_TITLE_PREFIX + "`" + flake + "`";
const existingIssue = issues.find((issue) => issue.title === title);

if (existingIssue) {
console.log(`Found issue ${existingIssue.number} for ${flake}, adding comment...`);
// Ensure that the test is open
await fetch(existingIssue.url, {
method: "PATCH",
headers,
body: JSON.stringify({ state: "open" }),
});
await fetch(`${existingIssue.url}/comments`, {
method: "POST",
headers,
Expand Down
2 changes: 1 addition & 1 deletion playwright/plugins/homeserver/synapse/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { randB64Bytes } from "../../utils/rand";
// Docker tag to use for `matrixdotorg/synapse` image.
// We target a specific digest as every now and then a Synapse update will break our CI.
// This digest is updated by the playwright-image-updates.yaml workflow periodically.
const DOCKER_TAG = "develop@sha256:951af3d5ec16542bab93fe8a54681055cef3fad6162bc0dbb9e0277b6bd4b20f";
const DOCKER_TAG = "develop@sha256:b4a545afb085414852e515fa24fba2b92ac26f5f1a00b338041ff5b2ea80dc28";

async function cfgDirFromTemplate(opts: StartHomeserverOpts): Promise<Omit<HomeserverConfig, "dockerUrl">> {
const templateDir = path.join(__dirname, "templates", opts.template);
Expand Down
9 changes: 9 additions & 0 deletions res/css/views/settings/_UserProfileSettings.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ limitations under the License.
font-size: 15px;
font-weight: 500;
}

.mx_UserProfileSettings_profile_buttons {
margin-top: var(--cpd-space-8x);
margin-bottom: var(--cpd-space-8x);
}

.mx_UserProfileSettings_accountmanageIcon {
margin-right: var(--cpd-space-2x);
}
}

@media (max-width: 768px) {
Expand Down
4 changes: 1 addition & 3 deletions src/components/structures/LoggedInView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -458,9 +458,7 @@ class LoggedInView extends React.Component<IProps, IState> {
handled = true;
break;
case KeyBindingAction.SearchInRoom:
dis.dispatch({
action: "focus_search",
});
dis.fire(Action.FocusMessageSearch);
handled = true;
break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/structures/RoomView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1196,7 +1196,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
);
}
break;
case "focus_search":
case Action.FocusMessageSearch:
this.onSearchClick();
break;

Expand Down
7 changes: 4 additions & 3 deletions src/components/views/audio_messages/Clock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ limitations under the License.
*/

import React, { HTMLProps } from "react";
import { Temporal } from "proposal-temporal";
import { Temporal } from "temporal-polyfill";

import { formatSeconds } from "../../../DateUtils";

Expand Down Expand Up @@ -45,8 +45,9 @@ export default class Clock extends React.Component<Props> {
return currentFloor !== nextFloor;
}

private calculateDuration(seconds: number): string {
return new Temporal.Duration(0, 0, 0, 0, 0, 0, seconds)
private calculateDuration(seconds: number): string | undefined {
if (isNaN(seconds)) return undefined;
return new Temporal.Duration(0, 0, 0, 0, 0, 0, Math.round(seconds))
.round({ smallestUnit: "seconds", largestUnit: "hours" })
.toString();
}
Expand Down
34 changes: 33 additions & 1 deletion src/components/views/settings/UserProfileSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
import React, { ChangeEvent, useCallback, useEffect, useMemo, useState } from "react";
import { logger } from "matrix-js-sdk/src/logger";
import { EditInPlace, Alert, ErrorMessage } from "@vector-im/compound-web";
import { Icon as PopOutIcon } from "@vector-im/compound-design-tokens/icons/pop-out.svg";

import { _t } from "../../../languageHandler";
import { OwnProfileStore } from "../../../stores/OwnProfileStore";
Expand All @@ -29,6 +30,7 @@ import UserIdentifierCustomisations from "../../../customisations/UserIdentifier
import { useId } from "../../../utils/useId";
import CopyableText from "../elements/CopyableText";
import { useMatrixClientContext } from "../../../contexts/MatrixClientContext";
import AccessibleButton from "../elements/AccessibleButton";

const SpinnerToast: React.FC = ({ children }) => (
<>
Expand All @@ -55,7 +57,28 @@ const UsernameBox: React.FC<UsernameBoxProps> = ({ username }) => {
);
};

interface ManageAccountButtonProps {
externalAccountManagementUrl: string;
}

const ManageAccountButton: React.FC<ManageAccountButtonProps> = ({ externalAccountManagementUrl }) => (
<AccessibleButton
onClick={null}
element="a"
kind="primary"
target="_blank"
rel="noreferrer noopener"
href={externalAccountManagementUrl}
data-testid="external-account-management-link"
>
<PopOutIcon className="mx_UserProfileSettings_accountmanageIcon" width="24" height="24" />
{_t("settings|general|oidc_manage_button")}
</AccessibleButton>
);

interface UserProfileSettingsProps {
// The URL to redirect the user to in order to manage their account.
externalAccountManagementUrl?: string;
// Whether the homeserver allows the user to set their display name.
canSetDisplayName: boolean;
// Whether the homeserver allows the user to set their avatar.
Expand All @@ -65,7 +88,11 @@ interface UserProfileSettingsProps {
/**
* A group of settings views to allow the user to set their profile information.
*/
const UserProfileSettings: React.FC<UserProfileSettingsProps> = ({ canSetDisplayName, canSetAvatar }) => {
const UserProfileSettings: React.FC<UserProfileSettingsProps> = ({
externalAccountManagementUrl,
canSetDisplayName,
canSetAvatar,
}) => {
const [avatarURL, setAvatarURL] = useState(OwnProfileStore.instance.avatarMxc);
const [displayName, setDisplayName] = useState(OwnProfileStore.instance.displayName ?? "");
const [avatarError, setAvatarError] = useState<boolean>(false);
Expand Down Expand Up @@ -192,6 +219,11 @@ const UserProfileSettings: React.FC<UserProfileSettingsProps> = ({ canSetDisplay
</Alert>
)}
{userIdentifier && <UsernameBox username={userIdentifier} />}
{externalAccountManagementUrl && (
<div className="mx_UserProfileSettings_profile_buttons">
<ManageAccountButton externalAccountManagementUrl={externalAccountManagementUrl} />
</div>
)}
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,41 +215,13 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
);
}

let externalAccountManagement: JSX.Element | undefined;
if (this.state.externalAccountManagementUrl) {
const { hostname } = new URL(this.state.externalAccountManagementUrl);

externalAccountManagement = (
<>
<SettingsSubsectionText data-testid="external-account-management-outer">
{_t(
"settings|general|external_account_management",
{ hostname },
{ code: (sub) => <code>{sub}</code> },
)}
</SettingsSubsectionText>
<AccessibleButton
onClick={null}
element="a"
kind="primary"
target="_blank"
rel="noreferrer noopener"
href={this.state.externalAccountManagementUrl}
data-testid="external-account-management-link"
>
{_t("settings|general|oidc_manage_button")}
</AccessibleButton>
</>
);
}
return (
<>
<SettingsSubsection
heading={_t("settings|general|account_section")}
stretchContent
data-testid="accountSection"
>
{externalAccountManagement}
{passwordChangeSection}
</SettingsSubsection>
</>
Expand Down Expand Up @@ -324,6 +296,7 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
<SettingsTab data-testid="mx_GeneralUserSettingsTab">
<SettingsSection>
<UserProfileSettings
externalAccountManagementUrl={this.state.externalAccountManagementUrl}
canSetDisplayName={this.state.canSetDisplayName}
canSetAvatar={this.state.canSetAvatar}
/>
Expand Down
5 changes: 5 additions & 0 deletions src/dispatcher/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,4 +388,9 @@ export enum Action {
* Opens right panel with 3pid invite information
*/
View3pidInvite = "view_3pid_invite",

/**
* Opens right panel room summary and focuses the search input
*/
FocusMessageSearch = "focus_search",
}
3 changes: 1 addition & 2 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1955,7 +1955,7 @@
"video_call_ec_layout_spotlight": "Spotlight",
"video_room_view_chat_button": "View chat timeline"
},
"header_face_pile_tooltip": "Toggle member list",
"header_face_pile_tooltip": "People",
"header_untrusted_label": "Untrusted",
"inaccessible": "This room or space is not accessible at this time.",
"inaccessible_name": "%(roomName)s is not accessible at this time.",
Expand Down Expand Up @@ -2513,7 +2513,6 @@
"error_revoke_msisdn_discovery": "Unable to revoke sharing for phone number",
"error_share_email_discovery": "Unable to share email address",
"error_share_msisdn_discovery": "Unable to share phone number",
"external_account_management": "Your account details are managed separately at <code>%(hostname)s</code>.",
"identity_server_no_token": "No identity access token found",
"identity_server_not_set": "Identity server not set",
"incorrect_msisdn_verification": "Incorrect verification code",
Expand Down
14 changes: 14 additions & 0 deletions test/components/structures/LoggedInView-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,18 @@ import { render, RenderResult } from "@testing-library/react";
import { ConditionKind, EventType, IPushRule, MatrixEvent, ClientEvent, PushRuleKind } from "matrix-js-sdk/src/matrix";
import { MediaHandler } from "matrix-js-sdk/src/webrtc/mediaHandler";
import { logger } from "matrix-js-sdk/src/logger";
import userEvent from "@testing-library/user-event";

import LoggedInView from "../../../src/components/structures/LoggedInView";
import { SDKContext } from "../../../src/contexts/SDKContext";
import { StandardActions } from "../../../src/notifications/StandardActions";
import ResizeNotifier from "../../../src/utils/ResizeNotifier";
import { flushPromises, getMockClientWithEventEmitter, mockClientMethodsUser } from "../../test-utils";
import { TestSdkContext } from "../../TestSdkContext";
import defaultDispatcher from "../../../src/dispatcher/dispatcher";
import SettingsStore from "../../../src/settings/SettingsStore";
import { SettingLevel } from "../../../src/settings/SettingLevel";
import { Action } from "../../../src/dispatcher/actions";

describe("<LoggedInView />", () => {
const userId = "@alice:domain.org";
Expand Down Expand Up @@ -384,4 +389,13 @@ describe("<LoggedInView />", () => {
});
});
});

it("should fire FocusMessageSearch on Ctrl+F when enabled", async () => {
jest.spyOn(defaultDispatcher, "fire");
await SettingsStore.setValue("ctrlFForSearch", null, SettingLevel.DEVICE, true);

getComponent();
await userEvent.keyboard("{Control>}f{/Control}");
expect(defaultDispatcher.fire).toHaveBeenCalledWith(Action.FocusMessageSearch);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,10 @@ describe("<GeneralUserSettingsTab />", () => {
} as unknown as OidcClientStore;
jest.spyOn(stores, "oidcClientStore", "get").mockReturnValue(mockOidcClientStore);

const { getByTestId } = render(getComponent());
render(getComponent());

// wait for well-known call to settle
await flushPromises();

expect(getByTestId("external-account-management-outer").textContent).toMatch(/.*id\.server\.org/);
expect(getByTestId("external-account-management-link").getAttribute("href")).toMatch(accountManagementLink);
const manageAccountLink = await screen.findByRole("button", { name: "Manage account" });
expect(manageAccountLink.getAttribute("href")).toMatch(accountManagementLink);
});

describe("Manage integrations", () => {
Expand Down
Loading

0 comments on commit cca481c

Please sign in to comment.