Skip to content

Commit

Permalink
1898 New Ui-features (Accountdata) (element-hq#32)
Browse files Browse the repository at this point in the history
* 1898 New Ui-features (Accountdata)
1899 New Ui-features (div1)

* 1898 New Ui-features (Accountdata)
1899 New Ui-features (div1)

* 1898 New Ui-features (Accountdata)
1899 New Ui-features (div1)

* 1898 New Ui-features (Accountdata)
1899 New Ui-features (div1)
  • Loading branch information
eiksta authored Apr 25, 2024
1 parent c4e7c33 commit 944db89
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 36 deletions.
41 changes: 24 additions & 17 deletions src/components/structures/auth/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -546,23 +546,30 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
}

return (
<AuthPage>
<AuthHeader disableLanguageSelector={this.props.isSyncing || this.state.busyLoggingIn} />
<AuthBody>
<h1>
{_t("action|sign_in")}
{loader}
</h1>
{errorTextSection}
{serverDeadSection}
<ServerPicker
serverConfig={this.props.serverConfig}
onServerConfigChange={this.props.onServerConfigChange}
/>
{this.renderLoginComponentForFlows()}
{footer}
</AuthBody>
</AuthPage>
<div>
{SettingsStore.getValue(UIFeature.EnableLoginPage) && (
<>
<AuthPage>
<AuthHeader disableLanguageSelector={this.props.isSyncing || this.state.busyLoggingIn} />
<AuthBody>
<h1>
{_t("action|sign_in")}
{loader}
</h1>
{errorTextSection}
{serverDeadSection}
<ServerPicker
serverConfig={this.props.serverConfig}
onServerConfigChange={this.props.onServerConfigChange}
/>
{this.renderLoginComponentForFlows()}
{footer}
</AuthBody>
</AuthPage>
</>
)}
;
</div>
);
}
}
6 changes: 5 additions & 1 deletion src/components/structures/grouper/CreationGrouper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import DateSeparator from "../../views/messages/DateSeparator";
import NewRoomIntro from "../../views/rooms/NewRoomIntro";
import GenericEventListSummary from "../../views/elements/GenericEventListSummary";
import { SeparatorKind } from "../../views/messages/TimelineSeparator";
import SettingsStore from "../../../settings/SettingsStore";
import { UIFeature } from "../../../settings/UIFeature";

// Wrap initial room creation events into a GenericEventListSummary
// Grouping only events sent by the same user that sent the `m.room.create` and only until
Expand Down Expand Up @@ -141,7 +143,9 @@ export class CreationGrouper extends BaseGrouper {
summaryText = _t("timeline|creation_summary_room", { creator });
}

ret.push(<NewRoomIntro key="newroomintro" />);
{
SettingsStore.getValue(UIFeature.EnableNewRoomIntro) && ret.push(<NewRoomIntro key="newroomintro" />);
}

ret.push(
<GenericEventListSummary
Expand Down
3 changes: 2 additions & 1 deletion src/components/views/context_menus/WidgetContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { Container, WidgetLayoutStore } from "../../../stores/widgets/WidgetLayo
import { getConfigLivestreamUrl, startJitsiAudioLivestream } from "../../../Livestream";
import { ModuleRunner } from "../../../modules/ModuleRunner";
import { ElementWidget } from "../../../stores/widgets/StopGapWidget";
import { UIFeature } from "../../../settings/UIFeature";

interface IProps extends Omit<ComponentProps<typeof IconizedContextMenu>, "children"> {
app: IWidget;
Expand Down Expand Up @@ -272,7 +273,7 @@ export const WidgetContextMenu: React.FC<IProps> = ({
{streamAudioStreamButton}
{editButton}
{revokeButton}
{deleteButton}
{SettingsStore.getValue(UIFeature.WidgetContextDeleteButton) && deleteButton}
{snapshotButton}
{moveLeftButton}
{moveRightButton}
Expand Down
24 changes: 16 additions & 8 deletions src/components/views/dialogs/DevtoolsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import ServerInfo from "./devtools/ServerInfo";
import { Features } from "../../../settings/Settings";
import CopyableText from "../elements/CopyableText";
import RoomNotifications from "./devtools/RoomNotifications";
import SettingsStore from "../../../../src/settings/SettingsStore";
import { UIFeature } from "../../../../src/settings/UIFeature";

enum Category {
Room,
Expand Down Expand Up @@ -94,14 +96,20 @@ const DevtoolsDialog: React.FC<IProps> = ({ roomId, threadRootId, onFinished })
<div key={category}>
<h3>{_t(categoryLabels[category as unknown as Category])}</h3>
{tools.map(([label, tool]) => {
const onClick = (): void => {
setTool([label, tool]);
};
return (
<button className="mx_DevTools_button" key={label} onClick={onClick}>
{_t(label)}
</button>
);
if (
(tool != VerificationExplorer && tool != TimelineEventEditor) ||
((tool === VerificationExplorer || tool === TimelineEventEditor) &&
SettingsStore.getValue(UIFeature.EnableRoomDevTools))
) {
const onClick = (): void => {
setTool([label, tool]);
};
return (
<button className="mx_DevTools_button" key={label} onClick={onClick}>
{_t(label)}
</button>
);
}
})}
</div>
))}
Expand Down
16 changes: 12 additions & 4 deletions src/components/views/dialogs/devtools/AccountData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import MatrixClientContext from "../../../../contexts/MatrixClientContext";
import { EventEditor, EventViewer, eventTypeField, IEditorProps, stringify } from "./Event";
import FilteredList from "./FilteredList";
import { _td, TranslationKey } from "../../../../languageHandler";
import SettingsStore from "../../../../settings/SettingsStore";
import { UIFeature } from "../../../../settings/UIFeature";

export const AccountDataEventEditor: React.FC<IEditorProps> = ({ mxEvent, onBack }) => {
const cli = useContext(MatrixClientContext);
Expand Down Expand Up @@ -98,9 +100,12 @@ export const AccountDataExplorer: React.FC<IDevtoolsProps> = ({ onBack, setTool
<BaseAccountDataExplorer
events={cli.store.accountData}
Editor={AccountDataEventEditor}
actionLabel={_td("devtools|send_custom_account_data_event")}
actionLabel={
SettingsStore.getValue(UIFeature.AccountSendAccountEvent) &&
_td("devtools|send_custom_account_data_event")
}
onBack={onBack}
setTool={setTool}
setTool={SettingsStore.getValue(UIFeature.AccountSendAccountEvent) && setTool}
/>
);
};
Expand All @@ -112,9 +117,12 @@ export const RoomAccountDataExplorer: React.FC<IDevtoolsProps> = ({ onBack, setT
<BaseAccountDataExplorer
events={context.room.accountData}
Editor={RoomAccountDataEventEditor}
actionLabel={_td("devtools|send_custom_room_account_data_event")}
actionLabel={
SettingsStore.getValue(UIFeature.AccountSendRoomEvent) &&
_td("devtools|send_custom_room_account_data_event")
}
onBack={onBack}
setTool={setTool}
setTool={SettingsStore.getValue(UIFeature.AccountSendRoomEvent) && setTool}
/>
);
};
24 changes: 24 additions & 0 deletions src/settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1311,6 +1311,30 @@ export const SETTINGS: { [setting: string]: ISetting } = {
supportedLevels: LEVELS_UI_FEATURE,
default: true,
},
[UIFeature.AccountSendAccountEvent]: {
supportedLevels: LEVELS_UI_FEATURE,
default: true,
},
[UIFeature.AccountSendRoomEvent]: {
supportedLevels: LEVELS_UI_FEATURE,
default: true,
},
[UIFeature.EnableLoginPage]: {
supportedLevels: LEVELS_UI_FEATURE,
default: true,
},
[UIFeature.EnableNewRoomIntro]: {
supportedLevels: LEVELS_UI_FEATURE,
default: true,
},
[UIFeature.EnableRoomDevTools]: {
supportedLevels: LEVELS_UI_FEATURE,
default: true,
},
[UIFeature.WidgetContextDeleteButton]: {
supportedLevels: LEVELS_UI_FEATURE,
default: true,
},

// Electron-specific settings, they are stored by Electron and set/read over an IPC.
// We store them over there are they are necessary to know before the renderer process launches.
Expand Down
6 changes: 6 additions & 0 deletions src/settings/UIFeature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ export const enum UIFeature {
UserSettingsDeleteBackup = "UIFeature.userSettingsDeleteBackup",
UserSettingsResetBackup = "UIFeature.userSettingsResetBackup",
SetupEncryptionResetButton = "UIFeature.setupEncryptionResetButton",
AccountSendAccountEvent = "UIFeature.accountSendAccountEvent",
AccountSendRoomEvent = "UIFeature.accountSendRoomEvent",
EnableLoginPage = "UIFeature.enableLoginPage",
EnableNewRoomIntro = "UIFeature.enableNewRoomIntro",
EnableRoomDevTools = "UIFeature.enableRoomDevTools",
WidgetContextDeleteButton = "UIFeature.WidgetContextDeleteButton",
}

export enum UIComponent {
Expand Down
54 changes: 54 additions & 0 deletions test/components/structures/MessagePanel-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
import ResizeNotifier from "../../../src/utils/ResizeNotifier";
import { IRoomState } from "../../../src/components/structures/RoomView";
import { MatrixClientPeg } from "../../../src/MatrixClientPeg";
import { UIFeature } from "../../../src/settings/UIFeature";

jest.mock("../../../src/utils/beacon", () => ({
useBeacon: jest.fn(),
Expand Down Expand Up @@ -110,6 +111,7 @@ describe("MessagePanel", function () {
jest.clearAllMocks();
// HACK: We assume all settings want to be disabled
jest.spyOn(SettingsStore, "getValue").mockImplementation((arg) => {
if (arg == UIFeature.EnableNewRoomIntro) return true;
return arg === "showDisplaynameChanges";
});

Expand Down Expand Up @@ -517,7 +519,59 @@ describe("MessagePanel", function () {
// read marker should be hidden given props and at the last event
expect(isReadMarkerVisible(rm)).toBeFalsy();
});
it("should show NewRoomIntro if featrue is on", function () {
const events = mkCreationEvents();
const createEvent = events.find((event) => event.getType() === "m.room.create");
client.getRoom.mockImplementation((id) => (id === createEvent!.getRoomId() ? room : null));
TestUtilsMatrix.upsertRoomStateEvents(room, events);

jest.spyOn(SettingsStore, "getValue").mockImplementation((name: string) => {
if (name == UIFeature.EnableNewRoomIntro) return true;
return true;
});

const { container } = render(
getComponent({
events,
readMarkerEventId: events[5].getId(),
readMarkerVisible: true,
}),
);

// find the <li> which wraps the read marker
const [rm] = container.getElementsByClassName("mx_MessagePanel_myReadMarker");

const [messageList] = container.getElementsByClassName("mx_RoomView_MessageList");
const rows = messageList.children;
expect(rows.length).toEqual(7); // 6 events + the NewRoomIntro
expect(rm.previousSibling).toEqual(rows[5]);

// read marker should be hidden given props and at the last event
expect(isReadMarkerVisible(rm)).toBeFalsy();
});
it("should not show NewRoomIntro if featrue is off", function () {
const events = mkCreationEvents();
const createEvent = events.find((event) => event.getType() === "m.room.create");
client.getRoom.mockImplementation((id) => (id === createEvent!.getRoomId() ? room : null));
TestUtilsMatrix.upsertRoomStateEvents(room, events);

jest.spyOn(SettingsStore, "getValue").mockImplementation((name: string) => {
if (name == UIFeature.EnableNewRoomIntro) return false;
return true;
});

const { container } = render(
getComponent({
events,
readMarkerEventId: events[5].getId(),
readMarkerVisible: true,
}),
);

const [messageList] = container.getElementsByClassName("mx_RoomView_MessageList");
const rows = messageList.children;
expect(rows.length).toEqual(6); // 6 events without the NewRoomIntro
});
it("should render Date separators for the events", function () {
const events = mkOneDayEvents();
const { queryAllByRole } = render(getComponent({ events }));
Expand Down
19 changes: 14 additions & 5 deletions test/components/structures/auth/Login-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import SettingsStore from "../../../../src/settings/SettingsStore";
import { Features } from "../../../../src/settings/Settings";
import * as registerClientUtils from "../../../../src/utils/oidc/registerClient";
import { makeDelegatedAuthConfig } from "../../../test-utils/oidc";
import { UIFeature } from "../../../../src/settings/UIFeature";

jest.useRealTimers();

Expand Down Expand Up @@ -380,17 +381,21 @@ describe("Login", function () {
const delegatedAuth = makeDelegatedAuthConfig(issuer);
beforeEach(() => {
jest.spyOn(logger, "error");
jest.spyOn(SettingsStore, "getValue").mockImplementation(
(settingName) => settingName === Features.OidcNativeFlow,
);
jest.spyOn(SettingsStore, "getValue").mockImplementation((name: string) => {
if (name == UIFeature.EnableLoginPage) return true;
return name === Features.OidcNativeFlow;
});
});

afterEach(() => {
jest.spyOn(logger, "error").mockRestore();
});

it("should not attempt registration when oidc native flow setting is disabled", async () => {
jest.spyOn(SettingsStore, "getValue").mockReturnValue(false);
jest.spyOn(SettingsStore, "getValue").mockImplementation((name: string) => {
if (name == UIFeature.EnableLoginPage) return true;
return false;
});

getComponent(hsUrl, isUrl, delegatedAuth);

Expand Down Expand Up @@ -450,7 +455,11 @@ describe("Login", function () {
* Oidc-aware flows still work while the oidc-native feature flag is disabled
*/
it("should show oidc-aware flow for oidc-enabled homeserver when oidc native flow setting is disabled", async () => {
jest.spyOn(SettingsStore, "getValue").mockReturnValue(false);
// jest.spyOn(SettingsStore, "getValue").mockReturnValue(false);
jest.spyOn(SettingsStore, "getValue").mockImplementation((name: string) => {
if (name == UIFeature.UserSettingsResetBackup) return false;
return true;
});
mockClient.loginFlows.mockResolvedValue({
flows: [
{
Expand Down

0 comments on commit 944db89

Please sign in to comment.