Merge remote-tracking branch 'origin/develop' into feat/add-formating-buttons-to-wysiwyg

This commit is contained in:
Florian Duros 2022-10-13 12:42:21 +02:00
commit f85f53248b
No known key found for this signature in database
GPG key ID: 9700AA5870258A0B
128 changed files with 4303 additions and 1024 deletions

View file

@ -115,13 +115,13 @@ export default class ChangeAvatar extends React.Component<IProps, IState> {
this.setState({
phase: Phases.Uploading,
});
const httpPromise = MatrixClientPeg.get().uploadContent(file).then((url) => {
const httpPromise = MatrixClientPeg.get().uploadContent(file).then(({ content_uri: url }) => {
newUrl = url;
if (this.props.room) {
return MatrixClientPeg.get().sendStateEvent(
this.props.room.roomId,
'm.room.avatar',
{ url: url },
{ url },
'',
);
} else {

View file

@ -111,7 +111,7 @@ export default class ProfileSettings extends React.Component<{}, IState> {
logger.log(
`Uploading new avatar, ${this.state.avatarFile.name} of type ${this.state.avatarFile.type},` +
` (${this.state.avatarFile.size}) bytes`);
const uri = await client.uploadContent(this.state.avatarFile);
const { content_uri: uri } = await client.uploadContent(this.state.avatarFile);
await client.setAvatarUrl(uri);
newState.avatarUrl = mediaFromMxc(uri).getSquareThumbnailHttp(96);
newState.originalAvatarUrl = newState.avatarUrl;

View file

@ -14,17 +14,20 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import { LocalNotificationSettings } from 'matrix-js-sdk/src/@types/local_notifications';
import React, { useState } from 'react';
import { LocalNotificationSettings } from 'matrix-js-sdk/src/@types/local_notifications';
import { _t } from '../../../../languageHandler';
import Spinner from '../../elements/Spinner';
import SettingsSubsection from '../shared/SettingsSubsection';
import { SettingsSubsectionHeading } from '../shared/SettingsSubsectionHeading';
import DeviceDetails from './DeviceDetails';
import DeviceExpandDetailsButton from './DeviceExpandDetailsButton';
import DeviceTile from './DeviceTile';
import { DeviceVerificationStatusCard } from './DeviceVerificationStatusCard';
import { ExtendedDevice } from './types';
import { KebabContextMenu } from '../../context_menus/KebabContextMenu';
import { IconizedContextMenuOption } from '../../context_menus/IconizedContextMenu';
interface Props {
device?: ExtendedDevice;
@ -34,9 +37,48 @@ interface Props {
setPushNotifications?: (deviceId: string, enabled: boolean) => Promise<void> | undefined;
onVerifyCurrentDevice: () => void;
onSignOutCurrentDevice: () => void;
signOutAllOtherSessions?: () => void;
saveDeviceName: (deviceName: string) => Promise<void>;
}
type CurrentDeviceSectionHeadingProps =
Pick<Props, 'onSignOutCurrentDevice' | 'signOutAllOtherSessions'>
& { disabled?: boolean };
const CurrentDeviceSectionHeading: React.FC<CurrentDeviceSectionHeadingProps> = ({
onSignOutCurrentDevice,
signOutAllOtherSessions,
disabled,
}) => {
const menuOptions = [
<IconizedContextMenuOption
key="sign-out"
label={_t('Sign out')}
onClick={onSignOutCurrentDevice}
isDestructive
/>,
...(signOutAllOtherSessions
? [
<IconizedContextMenuOption
key="sign-out-all-others"
label={_t('Sign out all other sessions')}
onClick={signOutAllOtherSessions}
isDestructive
/>,
]
: []
),
];
return <SettingsSubsectionHeading heading={_t('Current session')}>
<KebabContextMenu
disabled={disabled}
title={_t('Options')}
options={menuOptions}
data-testid='current-session-menu'
/>
</SettingsSubsectionHeading>;
};
const CurrentDeviceSection: React.FC<Props> = ({
device,
isLoading,
@ -45,13 +87,18 @@ const CurrentDeviceSection: React.FC<Props> = ({
setPushNotifications,
onVerifyCurrentDevice,
onSignOutCurrentDevice,
signOutAllOtherSessions,
saveDeviceName,
}) => {
const [isExpanded, setIsExpanded] = useState(false);
return <SettingsSubsection
heading={_t('Current session')}
data-testid='current-session-section'
heading={<CurrentDeviceSectionHeading
onSignOutCurrentDevice={onSignOutCurrentDevice}
signOutAllOtherSessions={signOutAllOtherSessions}
disabled={isLoading || !device || isSigningOut}
/>}
>
{ /* only show big spinner on first load */ }
{ isLoading && !device && <Spinner /> }

View file

@ -16,17 +16,22 @@ limitations under the License.
import React, { HTMLAttributes } from "react";
import Heading from "../../typography/Heading";
import { SettingsSubsectionHeading } from "./SettingsSubsectionHeading";
export interface SettingsSubsectionProps extends HTMLAttributes<HTMLDivElement> {
heading: string;
heading: string | React.ReactNode;
description?: string | React.ReactNode;
children?: React.ReactNode;
}
const SettingsSubsection: React.FC<SettingsSubsectionProps> = ({ heading, description, children, ...rest }) => (
<div {...rest} className="mx_SettingsSubsection">
<Heading className="mx_SettingsSubsection_heading" size='h3'>{ heading }</Heading>
{ typeof heading === 'string'
? <SettingsSubsectionHeading heading={heading} />
: <>
{ heading }
</>
}
{ !!description && <div className="mx_SettingsSubsection_description">{ description }</div> }
<div className="mx_SettingsSubsection_content">
{ children }

View file

@ -0,0 +1,31 @@
/*
Copyright 2022 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.
*/
import React, { HTMLAttributes } from "react";
import Heading from "../../typography/Heading";
export interface SettingsSubsectionHeadingProps extends HTMLAttributes<HTMLDivElement> {
heading: string;
children?: React.ReactNode;
}
export const SettingsSubsectionHeading: React.FC<SettingsSubsectionHeadingProps> = ({ heading, children, ...rest }) => (
<div {...rest} className="mx_SettingsSubsectionHeading">
<Heading className="mx_SettingsSubsectionHeading_heading" size='h3'>{ heading }</Heading>
{ children }
</div>
);

View file

@ -80,7 +80,10 @@ export default class LabsUserSettingsTab extends React.Component<{}, IState> {
let betaSection;
if (betas.length) {
betaSection = <div className="mx_SettingsTab_section">
betaSection = <div
data-testid="labs-beta-section"
className="mx_SettingsTab_section"
>
{ betas.map(f => <BetaCard key={f} featureId={f} />) }
</div>;
}
@ -137,7 +140,11 @@ export default class LabsUserSettingsTab extends React.Component<{}, IState> {
labsSections = <>
{ sortBy(Array.from(groups.entries()), "0").map(([group, flags]) => (
<div className="mx_SettingsTab_section" key={group}>
<div
className="mx_SettingsTab_section"
key={group}
data-testid={`labs-group-${group}`}
>
<span className="mx_SettingsTab_subheading">{ _t(labGroupNames[group]) }</span>
{ flags }
</div>

View file

@ -346,19 +346,29 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
}
}
return (
<div className="mx_SettingsTab mx_SecurityUserSettingsTab">
{ warning }
const useNewSessionManager = SettingsStore.getValue("feature_new_device_manager");
const devicesSection = useNewSessionManager
? null
: <>
<div className="mx_SettingsTab_heading">{ _t("Where you're signed in") }</div>
<div className="mx_SettingsTab_section">
<div
className="mx_SettingsTab_section"
data-testid="devices-section"
>
<span className="mx_SettingsTab_subsectionText">
{ _t(
"Manage your signed-in devices below. " +
"A device's name is visible to people you communicate with.",
"A device's name is visible to people you communicate with.",
) }
</span>
<DevicesPanel />
</div>
</>;
return (
<div className="mx_SettingsTab mx_SecurityUserSettingsTab">
{ warning }
{ devicesSection }
<div className="mx_SettingsTab_heading">{ _t("Encryption") }</div>
<div className="mx_SettingsTab_section">
{ secureBackup }

View file

@ -171,6 +171,10 @@ const SessionManagerTab: React.FC = () => {
setSelectedDeviceIds([]);
}, [filter, setSelectedDeviceIds]);
const signOutAllOtherSessions = shouldShowOtherSessions ? () => {
onSignOutOtherDevices(Object.keys(otherDevices));
}: undefined;
return <SettingsTab heading={_t('Sessions')}>
<SecurityRecommendations
devices={devices}
@ -186,6 +190,7 @@ const SessionManagerTab: React.FC = () => {
saveDeviceName={(deviceName) => saveDeviceName(currentDeviceId, deviceName)}
onVerifyCurrentDevice={onVerifyCurrentDevice}
onSignOutCurrentDevice={onSignOutCurrentDevice}
signOutAllOtherSessions={signOutAllOtherSessions}
/>
{
shouldShowOtherSessions &&