Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Room #52

Merged
merged 40 commits into from
Apr 25, 2022
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
0f96828
Co-authored-by: Estelle Comment <estellecomment@users.noreply.github.…
odelcroi Apr 15, 2022
2613081
WIP : draft that half-works, rooms are not configured yet
estellecomment Apr 15, 2022
68a627e
Move the dropdown to a separate file
estellecomment Apr 15, 2022
8a9ba15
Add translations
estellecomment Apr 15, 2022
aa211e0
add room creation opts
odelcroi Apr 15, 2022
8198eb1
Move the TchapRoomType enum to a separate file
estellecomment Apr 15, 2022
1c7468c
merge
odelcroi Apr 15, 2022
42b0156
Merge branch 'feat/46_create_room' of https://github.com/tchapgouv/tc…
odelcroi Apr 15, 2022
fa08ac3
Use radio buttons instead of dropdown
estellecomment Apr 15, 2022
79310cc
Rename file, and stop replacing JoinRuleDropdown, since it is a not n…
estellecomment Apr 15, 2022
d9289d9
Add scss. It does not work.
estellecomment Apr 15, 2022
91e12eb
fix component loaded before skin
odelcroi Apr 19, 2022
0a5455b
Somewhat less broken css, probably
estellecomment Apr 19, 2022
3de6b58
Remove scss file from customisations.json, for some reason
estellecomment Apr 19, 2022
c26e698
add federate switch on forum
odelcroi Apr 20, 2022
1fa0d46
Merge branch 'feat/46_create_room' of https://github.com/tchapgouv/tc…
odelcroi Apr 20, 2022
0a068ef
Clean up css.
estellecomment Apr 20, 2022
d9f69c5
Better css
estellecomment Apr 20, 2022
42b9a9e
Add icons
estellecomment Apr 20, 2022
19a3f02
Merge branch 'feat/46_create_room' of https://github.com/tchapgouv/tc…
odelcroi Apr 20, 2022
471f66f
merge
odelcroi Apr 20, 2022
c0d9afa
Use theme colors, specified in config
estellecomment Apr 20, 2022
73a0e0b
always show federate button
odelcroi Apr 21, 2022
40b22ce
add logs to active theme
odelcroi Apr 21, 2022
37c9d03
externalize createTchapRoom + UT
odelcroi Apr 21, 2022
7d3b224
Add the missing CSS var to our custom theme
estellecomment Apr 22, 2022
29734e6
fix transformIgnorePatterns to new format
odelcroi Apr 22, 2022
ca8bff1
Only show federation toggle for intradef
estellecomment Apr 22, 2022
24487da
Move the federation options to TchapUtils
estellecomment Apr 22, 2022
e4d3273
Add type to function
estellecomment Apr 22, 2022
aabd5b5
Invert the toggle switch to avoid double negations for humans
estellecomment Apr 22, 2022
02f72c0
Sort out the css
estellecomment Apr 22, 2022
f250a28
Document types
estellecomment Apr 25, 2022
01920b6
Standardize imports
estellecomment Apr 25, 2022
abbc298
Use TS syntax for funct argument default
estellecomment Apr 25, 2022
e195626
Type function return
estellecomment Apr 25, 2022
65b669d
Refactor test, much pretty, wow
estellecomment Apr 25, 2022
e4860b2
Remove references to spaces. We do not support them. We have not deci…
estellecomment Apr 25, 2022
dc96457
Remove todos
estellecomment Apr 25, 2022
dc19b62
Remove a console.log
estellecomment Apr 25, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion config.preprod.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@
"accent": "#162d58",
"primary-color": "#368bd6",
"warning-color": "#ff4b55",
"private-color": "#eb5757",
"external-color": "#f07a12",
"forum-color": "#27ae60",
"sidebar-color": "#27303a",
"roomlist-background-color": "#f3f8fd",
"roomlist-text-color": "#2e2f32",
Expand All @@ -76,7 +79,8 @@
"timeline-background-color": "#ffffff",
"timeline-text-color": "#2e2f32",
"timeline-text-secondary-color": "#61708b",
"timeline-highlights-color": "#f3f8fd"
"timeline-highlights-color": "#f3f8fd",
"togglesw-off-color": "#c1c9d6"
}
}
]
Expand Down
6 changes: 5 additions & 1 deletion config.prod.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@
"accent": "#162d58",
"primary-color": "#368bd6",
"warning-color": "#ff4b55",
"private-color": "#eb5757",
"external-color": "#f07a12",
"forum-color": "#27ae60",
"sidebar-color": "#27303a",
"roomlist-background-color": "#f3f8fd",
"roomlist-text-color": "#2e2f32",
Expand All @@ -160,7 +163,8 @@
"timeline-background-color": "#ffffff",
"timeline-text-color": "#2e2f32",
"timeline-text-secondary-color": "#61708b",
"timeline-highlights-color": "#f3f8fd"
"timeline-highlights-color": "#f3f8fd",
"togglesw-off-color": "#c1c9d6"
}
}
]
Expand Down
5 changes: 5 additions & 0 deletions customisations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"src/@types/tchap.ts": "src/@types/tchap.ts",
"src/components/views/dialogs/CreateRoomDialog.tsx": "src/components/views/dialogs/TchapCreateRoomDialog.tsx",
"src/components/views/elements/TchapRoomTypeSelector.tsx": "src/components/views/elements/TchapRoomTypeSelector.tsx"
}
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,7 @@
"RecorderWorklet": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/empty.js"
},
"transformIgnorePatterns": [
"/node_modules/(?!matrix-js-sdk).+$",
"/node_modules/(?!matrix-react-sdk).+$"
"/node_modules/(?!matrix-js-sdk|matrix-react-sdk).+$"
]
}
}
96 changes: 96 additions & 0 deletions res/css/views/elements/_TchapRoomTypeSelector.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
.tc_TchapRoomTypeSelector {
display: flex;
flex-direction: column;
gap: 24px;

>.tc_TchapRoomTypeSelector_RadioButton {
flex-grow: 0;
flex-shrink: 1;
display: flex;
flex-direction: column;
padding: 10px;

border-width: 3px;
border-style: solid;
border-color: transparent;
border-radius: 10px;

.tc_TchapRoomTypeSelector_RadioButton_title {
font-weight: bold;
}
}

.tc_TchapRoomTypeSelector_private {
.tc_TchapRoomTypeSelector_RadioButton_title {
color: var(--private-color);
&::before {
width: 12px;
height: 16px;
content: "";
display: inline-block;
vertical-align: sub;
background-image: url("../../../img/tchap/padlock-private.svg");
background-repeat: no-repeat;
background-size: 100%;
margin-right: 4px;
}
}

&.tc_TchapRoomTypeSelector_RadioButton_selected {
border-color: var(--private-color);
}
}

.tc_TchapRoomTypeSelector_external {
.tc_TchapRoomTypeSelector_RadioButton_title {
color: var(--external-color);
&::before {
width: 12px;
height: 16px;
content: "";
display: inline-block;
vertical-align: sub;
background-image: url("../../../img/tchap/padlock-external.svg");
background-repeat: no-repeat;
background-size: 100%;
margin-right: 4px;
}
}

&.tc_TchapRoomTypeSelector_RadioButton_selected {
border-color: var(--external-color);
}

}

.tc_TchapRoomTypeSelector_forum {
.tc_TchapRoomTypeSelector_RadioButton_title {
color: var(--forum-color);
&::before {
width: 12px;
height: 16px;
content: "";
display: inline-block;
vertical-align: sub;
background-image: url("../../../img/tchap/padlock-forum.svg");
background-repeat: no-repeat;
background-size: 100%;
margin-right: 4px;
}
}

&.tc_TchapRoomTypeSelector_RadioButton_selected {
border-color: var(--forum-color);
}

.mx_SettingsFlag {
flex-direction: row;
display: flex;
align-items: center;
margin-top: 10px;
.mx_SettingsFlag_label {
padding-top: 0px;
}
}
}
}
4 changes: 4 additions & 0 deletions res/img/tchap/padlock-external.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions res/img/tchap/padlock-forum.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions res/img/tchap/padlock-private.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions src/@types/tchap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export enum TchapRoomType {
Direct = "direct",
Private = "private",
External = "external",
Forum = "forum",
}


export enum TchapRoomAccessRule {
Unrestricted = "unrestricted", // todo not used in this file, we haven't implemented DMs yet
Restricted = "restricted"
}
200 changes: 200 additions & 0 deletions src/components/views/dialogs/TchapCreateRoomDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/*
Copyright 2017 Michael Telatynski <7t3chguy@gmail.com>
Copyright 2020, 2021 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/*
Note on imports : because this file will be copied to a different directory by the customisations
mechanism, imports must use absolute paths.
Except when importing from other customisation files. Then imports must use relative paths.
*/
import React, { ChangeEvent, createRef, KeyboardEvent } from "react";
import { Room } from "matrix-js-sdk/src/models/room";
import withValidation, { IFieldState } from 'matrix-react-sdk/src/components/views/elements/Validation';
import { _t } from 'matrix-react-sdk/src/languageHandler';
import { IOpts } from "matrix-react-sdk/src/createRoom";
import { getKeyBindingsManager } from "matrix-react-sdk/src/KeyBindingsManager";
import { KeyBindingAction } from "matrix-react-sdk/src/accessibility/KeyboardShortcuts";
import * as sdk from 'matrix-react-sdk/src/index';
import Field from "matrix-react-sdk/src/components/views/elements/Field";

import TchapUtils from '../../../util/TchapUtils';
import TchapRoomTypeSelector from "./../elements/TchapRoomTypeSelector";
import { TchapRoomType } from "../../../@types/tchap";
import roomCreateOptions from "../../../lib/createTchapRoom";

interface IProps {
defaultPublic?: boolean;
defaultName?: string;
parentSpace?: Room;
defaultEncrypted?: boolean;
onFinished(proceed: boolean, opts?: IOpts): void;
}

interface IState {
name: string;
nameIsValid: boolean;
tchapRoomType: TchapRoomType;
isFederated: boolean;
showFederateSwitch: boolean;
}

export default class TchapCreateRoomDialog extends React.Component<IProps, IState> {
private nameField = createRef<Field>();

constructor(props) {
super(props);

const federationOptions = TchapUtils.getRoomFederationOptions();

this.state = {
name: this.props.defaultName || "",
nameIsValid: false,
tchapRoomType: TchapRoomType.Private,
isFederated: federationOptions.roomFederationDefault,
showFederateSwitch: federationOptions.showRoomFederationOption,
};
}

componentDidMount() {
// move focus to first field when showing dialog
this.nameField.current.focus();
}

componentWillUnmount() {
}

private onCancel = () => {
this.props.onFinished(false);
};

private onFederatedChange = (isFederated: boolean) => {
this.setState({ isFederated: isFederated });
};

private onTchapRoomTypeChange = (tchapRoomType: TchapRoomType) => {
this.setState({ tchapRoomType: tchapRoomType });
};

private onNameChange = (ev: ChangeEvent<HTMLInputElement>) => {
this.setState({ name: ev.target.value });
};

private onNameValidate = async (fieldState: IFieldState) => {
const result = await TchapCreateRoomDialog.validateRoomName(fieldState);
this.setState({ nameIsValid: result.valid });
return result;
};

private static validateRoomName = withValidation({
rules: [
{
key: "required",
test: async ({ value }) => !!value,
invalid: () => _t("Please enter a name for the room"),
},
],
});

private onKeyDown = (event: KeyboardEvent) => {
const action = getKeyBindingsManager().getAccessibilityAction(event);
switch (action) {
case KeyBindingAction.Enter:
this.onOk();
event.preventDefault();
event.stopPropagation();
break;
}
};

private onOk = async () => {
const activeElement = document.activeElement as HTMLElement;
if (activeElement) {
activeElement.blur();
}
await this.nameField.current.validate({ allowEmpty: false });
// Validation and state updates are async, so we need to wait for them to complete
// first. Queue a `setState` callback and wait for it to resolve.
await new Promise<void>(resolve => this.setState({}, resolve));
if (this.state.nameIsValid) {
this.props.onFinished(true, roomCreateOptions(
this.state.name,
this.state.tchapRoomType,
this.state.isFederated));
} else {
let field;
if (!this.state.nameIsValid) {
field = this.nameField.current;
}
if (field) {
field.focus();
field.validate({ allowEmpty: false, focused: true });
}
}
};

render() {
const Field = sdk.getComponent("elements.Field");
const DialogButtons = sdk.getComponent("elements.DialogButtons");
const BaseDialog = sdk.getComponent("dialogs.BaseDialog");

const shortDomain: string = TchapUtils.getShortDomain();

const title = _t("Create a room");
/* todo do we need this ?
if (CommunityPrototypeStore.instance.getSelectedCommunityId()) {
const name = CommunityPrototypeStore.instance.getSelectedCommunityName();
title = _t("Create a room in %(communityName)s", { communityName: name });
} else if (!this.props.parentSpace) {
title = this.state.joinRule === JoinRule.Public ? _t('Create a public room') : _t('Create a private room');
}
*/

return (
<BaseDialog
className="tc_TchapCreateRoomDialog"
onFinished={this.props.onFinished}
title={title}
screenName="CreateRoom"
>
<form onSubmit={this.onOk} onKeyDown={this.onKeyDown}>
<div className="mx_Dialog_content">
<Field
ref={this.nameField}
label={_t('Name')}
onChange={this.onNameChange}
onValidate={this.onNameValidate}
value={this.state.name}
/>

<TchapRoomTypeSelector
onChange={this.onTchapRoomTypeChange}
value={this.state.tchapRoomType}
label={_t("Type of room")}
showFederateSwitch={this.state.showFederateSwitch}
shortDomain={shortDomain}
isFederated={this.state.isFederated}
onFederatedChange={this.onFederatedChange}
/>

</div>
</form>
<DialogButtons primaryButton={_t('Create Room')}
onPrimaryButtonClick={this.onOk}
onCancel={this.onCancel} />
</BaseDialog>
);
}
}
Loading