You've already forked matrix-react-sdk
							
							
				mirror of
				https://github.com/matrix-org/matrix-react-sdk.git
				synced 2025-10-29 14:29:29 +03:00 
			
		
		
		
	use ExternalLink components for external links (#10758)
* use ExternalLink components for external links * test * strict
This commit is contained in:
		| @@ -30,6 +30,7 @@ import AccessibleButton from "../views/elements/AccessibleButton"; | |||||||
| import InlineSpinner from "../views/elements/InlineSpinner"; | import InlineSpinner from "../views/elements/InlineSpinner"; | ||||||
| import MatrixClientContext from "../../contexts/MatrixClientContext"; | import MatrixClientContext from "../../contexts/MatrixClientContext"; | ||||||
| import { RoomStatusBarUnsentMessages } from "./RoomStatusBarUnsentMessages"; | import { RoomStatusBarUnsentMessages } from "./RoomStatusBarUnsentMessages"; | ||||||
|  | import ExternalLink from "../views/elements/ExternalLink"; | ||||||
|  |  | ||||||
| const STATUS_BAR_HIDDEN = 0; | const STATUS_BAR_HIDDEN = 0; | ||||||
| const STATUS_BAR_EXPANDED = 1; | const STATUS_BAR_EXPANDED = 1; | ||||||
| @@ -213,9 +214,9 @@ export default class RoomStatusBar extends React.PureComponent<IProps, IState> { | |||||||
|                 {}, |                 {}, | ||||||
|                 { |                 { | ||||||
|                     consentLink: (sub) => ( |                     consentLink: (sub) => ( | ||||||
|                         <a href={consentError!.data?.consent_uri} target="_blank" rel="noreferrer noopener"> |                         <ExternalLink href={consentError!.data?.consent_uri} target="_blank" rel="noreferrer noopener"> | ||||||
|                             {sub} |                             {sub} | ||||||
|                         </a> |                         </ExternalLink> | ||||||
|                     ), |                     ), | ||||||
|                 }, |                 }, | ||||||
|             ); |             ); | ||||||
|   | |||||||
| @@ -77,6 +77,7 @@ import MainSplit from "./MainSplit"; | |||||||
| import RightPanel from "./RightPanel"; | import RightPanel from "./RightPanel"; | ||||||
| import SpaceHierarchy, { showRoom } from "./SpaceHierarchy"; | import SpaceHierarchy, { showRoom } from "./SpaceHierarchy"; | ||||||
| import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks"; | import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks"; | ||||||
|  | import ExternalLink from "../views/elements/ExternalLink"; | ||||||
|  |  | ||||||
| interface IProps { | interface IProps { | ||||||
|     space: Room; |     space: Room; | ||||||
| @@ -593,9 +594,9 @@ const SpaceSetupPrivateInvite: React.FC<{ | |||||||
|                     { |                     { | ||||||
|                         b: (sub) => <b>{sub}</b>, |                         b: (sub) => <b>{sub}</b>, | ||||||
|                         link: () => ( |                         link: () => ( | ||||||
|                             <a href="https://app.element.io/" rel="noreferrer noopener" target="_blank"> |                             <ExternalLink href="https://app.element.io/" rel="noreferrer noopener" target="_blank"> | ||||||
|                                 app.element.io |                                 app.element.io | ||||||
|                             </a> |                             </ExternalLink> | ||||||
|                         ), |                         ), | ||||||
|                     }, |                     }, | ||||||
|                 )} |                 )} | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ import DialogButtons from "../elements/DialogButtons"; | |||||||
| import Modal, { ComponentProps } from "../../../Modal"; | import Modal, { ComponentProps } from "../../../Modal"; | ||||||
| import SdkConfig from "../../../SdkConfig"; | import SdkConfig from "../../../SdkConfig"; | ||||||
| import { getPolicyUrl } from "../../../toasts/AnalyticsToast"; | import { getPolicyUrl } from "../../../toasts/AnalyticsToast"; | ||||||
|  | import ExternalLink from "../elements/ExternalLink"; | ||||||
|  |  | ||||||
| export enum ButtonClicked { | export enum ButtonClicked { | ||||||
|     Primary, |     Primary, | ||||||
| @@ -55,10 +56,10 @@ export const AnalyticsLearnMoreDialog: React.FC<IProps> = ({ | |||||||
|                 { |                 { | ||||||
|                     PrivacyPolicyUrl: (sub) => { |                     PrivacyPolicyUrl: (sub) => { | ||||||
|                         return ( |                         return ( | ||||||
|                             <a href={privacyPolicyUrl} rel="norefferer noopener" target="_blank"> |                             <ExternalLink href={privacyPolicyUrl} rel="norefferer noopener" target="_blank"> | ||||||
|                                 {sub} |                                 {sub} | ||||||
|                                 <span className="mx_AnalyticsPolicyLink" /> |                                 <span className="mx_AnalyticsPolicyLink" /> | ||||||
|                             </a> |                             </ExternalLink> | ||||||
|                         ); |                         ); | ||||||
|                     }, |                     }, | ||||||
|                 }, |                 }, | ||||||
|   | |||||||
| @@ -27,6 +27,7 @@ import InfoDialog from "./InfoDialog"; | |||||||
| import { submitFeedback } from "../../../rageshake/submit-rageshake"; | import { submitFeedback } from "../../../rageshake/submit-rageshake"; | ||||||
| import { useStateToggle } from "../../../hooks/useStateToggle"; | import { useStateToggle } from "../../../hooks/useStateToggle"; | ||||||
| import StyledCheckbox from "../elements/StyledCheckbox"; | import StyledCheckbox from "../elements/StyledCheckbox"; | ||||||
|  | import ExternalLink from "../elements/ExternalLink"; | ||||||
|  |  | ||||||
| interface IProps { | interface IProps { | ||||||
|     feature?: string; |     feature?: string; | ||||||
| @@ -130,16 +131,20 @@ const FeedbackDialog: React.FC<IProps> = (props: IProps) => { | |||||||
|                                 { |                                 { | ||||||
|                                     existingIssuesLink: (sub) => { |                                     existingIssuesLink: (sub) => { | ||||||
|                                         return ( |                                         return ( | ||||||
|                                             <a target="_blank" rel="noreferrer noopener" href={existingIssuesUrl}> |                                             <ExternalLink | ||||||
|  |                                                 target="_blank" | ||||||
|  |                                                 rel="noreferrer noopener" | ||||||
|  |                                                 href={existingIssuesUrl} | ||||||
|  |                                             > | ||||||
|                                                 {sub} |                                                 {sub} | ||||||
|                                             </a> |                                             </ExternalLink> | ||||||
|                                         ); |                                         ); | ||||||
|                                     }, |                                     }, | ||||||
|                                     newIssueLink: (sub) => { |                                     newIssueLink: (sub) => { | ||||||
|                                         return ( |                                         return ( | ||||||
|                                             <a target="_blank" rel="noreferrer noopener" href={newIssueUrl}> |                                             <ExternalLink target="_blank" rel="noreferrer noopener" href={newIssueUrl}> | ||||||
|                                                 {sub} |                                                 {sub} | ||||||
|                                             </a> |                                             </ExternalLink> | ||||||
|                                         ); |                                         ); | ||||||
|                                     }, |                                     }, | ||||||
|                                 }, |                                 }, | ||||||
|   | |||||||
| @@ -28,6 +28,7 @@ import StyledRadioButton from "../elements/StyledRadioButton"; | |||||||
| import TextWithTooltip from "../elements/TextWithTooltip"; | import TextWithTooltip from "../elements/TextWithTooltip"; | ||||||
| import withValidation, { IFieldState, IValidationResult } from "../elements/Validation"; | import withValidation, { IFieldState, IValidationResult } from "../elements/Validation"; | ||||||
| import { ValidatedServerConfig } from "../../../utils/ValidatedServerConfig"; | import { ValidatedServerConfig } from "../../../utils/ValidatedServerConfig"; | ||||||
|  | import ExternalLink from "../elements/ExternalLink"; | ||||||
|  |  | ||||||
| interface IProps { | interface IProps { | ||||||
|     title?: string; |     title?: string; | ||||||
| @@ -236,9 +237,13 @@ export default class ServerPickerDialog extends React.PureComponent<IProps, ISta | |||||||
|                     </AccessibleButton> |                     </AccessibleButton> | ||||||
|  |  | ||||||
|                     <h2>{_t("Learn more")}</h2> |                     <h2>{_t("Learn more")}</h2> | ||||||
|                     <a href="https://matrix.org/faq/#what-is-a-homeserver%3F" target="_blank" rel="noreferrer noopener"> |                     <ExternalLink | ||||||
|  |                         href="https://matrix.org/faq/#what-is-a-homeserver%3F" | ||||||
|  |                         target="_blank" | ||||||
|  |                         rel="noreferrer noopener" | ||||||
|  |                     > | ||||||
|                         {_t("About homeservers")} |                         {_t("About homeservers")} | ||||||
|                     </a> |                     </ExternalLink> | ||||||
|                 </form> |                 </form> | ||||||
|             </BaseDialog> |             </BaseDialog> | ||||||
|         ); |         ); | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ import { _t, pickBestLanguage } from "../../../languageHandler"; | |||||||
| import DialogButtons from "../elements/DialogButtons"; | import DialogButtons from "../elements/DialogButtons"; | ||||||
| import BaseDialog from "./BaseDialog"; | import BaseDialog from "./BaseDialog"; | ||||||
| import { ServicePolicyPair } from "../../../Terms"; | import { ServicePolicyPair } from "../../../Terms"; | ||||||
|  | import ExternalLink from "../elements/ExternalLink"; | ||||||
|  |  | ||||||
| interface ITermsCheckboxProps { | interface ITermsCheckboxProps { | ||||||
|     onChange: (url: string, checked: boolean) => void; |     onChange: (url: string, checked: boolean) => void; | ||||||
| @@ -148,9 +149,9 @@ export default class TermsDialog extends React.PureComponent<ITermsDialogProps, | |||||||
|                         <td className="mx_TermsDialog_summary">{summary}</td> |                         <td className="mx_TermsDialog_summary">{summary}</td> | ||||||
|                         <td> |                         <td> | ||||||
|                             {termDoc[termsLang].name} |                             {termDoc[termsLang].name} | ||||||
|                             <a rel="noreferrer noopener" target="_blank" href={termDoc[termsLang].url}> |                             <ExternalLink rel="noreferrer noopener" target="_blank" href={termDoc[termsLang].url}> | ||||||
|                                 <span className="mx_TermsDialog_link" /> |                                 <span className="mx_TermsDialog_link" /> | ||||||
|                             </a> |                             </ExternalLink> | ||||||
|                         </td> |                         </td> | ||||||
|                         <td> |                         <td> | ||||||
|                             <TermsCheckbox |                             <TermsCheckbox | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ import EventIndexPeg from "../../../indexing/EventIndexPeg"; | |||||||
| import { SettingLevel } from "../../../settings/SettingLevel"; | import { SettingLevel } from "../../../settings/SettingLevel"; | ||||||
| import SeshatResetDialog from "../dialogs/SeshatResetDialog"; | import SeshatResetDialog from "../dialogs/SeshatResetDialog"; | ||||||
| import InlineSpinner from "../elements/InlineSpinner"; | import InlineSpinner from "../elements/InlineSpinner"; | ||||||
|  | import ExternalLink from "../elements/ExternalLink"; | ||||||
|  |  | ||||||
| interface IState { | interface IState { | ||||||
|     enabling: boolean; |     enabling: boolean; | ||||||
| @@ -197,9 +198,9 @@ export default class EventIndexPanel extends React.Component<{}, IState> { | |||||||
|                         }, |                         }, | ||||||
|                         { |                         { | ||||||
|                             nativeLink: (sub) => ( |                             nativeLink: (sub) => ( | ||||||
|                                 <a href={nativeLink} target="_blank" rel="noreferrer noopener"> |                                 <ExternalLink href={nativeLink} target="_blank" rel="noreferrer noopener"> | ||||||
|                                     {sub} |                                     {sub} | ||||||
|                                 </a> |                                 </ExternalLink> | ||||||
|                             ), |                             ), | ||||||
|                         }, |                         }, | ||||||
|                     )} |                     )} | ||||||
| @@ -217,9 +218,13 @@ export default class EventIndexPanel extends React.Component<{}, IState> { | |||||||
|                         }, |                         }, | ||||||
|                         { |                         { | ||||||
|                             desktopLink: (sub) => ( |                             desktopLink: (sub) => ( | ||||||
|                                 <a href="https://element.io/get-started" target="_blank" rel="noreferrer noopener"> |                                 <ExternalLink | ||||||
|  |                                     href="https://element.io/get-started" | ||||||
|  |                                     target="_blank" | ||||||
|  |                                     rel="noreferrer noopener" | ||||||
|  |                                 > | ||||||
|                                     {sub} |                                     {sub} | ||||||
|                                 </a> |                                 </ExternalLink> | ||||||
|                             ), |                             ), | ||||||
|                         }, |                         }, | ||||||
|                     )} |                     )} | ||||||
|   | |||||||
| @@ -31,6 +31,7 @@ import { Action } from "../../../../../dispatcher/actions"; | |||||||
| import { UserTab } from "../../../dialogs/UserTab"; | import { UserTab } from "../../../dialogs/UserTab"; | ||||||
| import dis from "../../../../../dispatcher/dispatcher"; | import dis from "../../../../../dispatcher/dispatcher"; | ||||||
| import CopyableText from "../../../elements/CopyableText"; | import CopyableText from "../../../elements/CopyableText"; | ||||||
|  | import ExternalLink from "../../../elements/ExternalLink"; | ||||||
|  |  | ||||||
| interface IProps { | interface IProps { | ||||||
|     closeSettingsFn: () => void; |     closeSettingsFn: () => void; | ||||||
| @@ -114,9 +115,9 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState> | |||||||
|         for (const tocEntry of tocLinks) { |         for (const tocEntry of tocLinks) { | ||||||
|             legalLinks.push( |             legalLinks.push( | ||||||
|                 <div key={tocEntry.url}> |                 <div key={tocEntry.url}> | ||||||
|                     <a href={tocEntry.url} rel="noreferrer noopener" target="_blank"> |                     <ExternalLink href={tocEntry.url} rel="noreferrer noopener" target="_blank"> | ||||||
|                         {tocEntry.text} |                         {tocEntry.text} | ||||||
|                     </a> |                     </ExternalLink> | ||||||
|                 </div>, |                 </div>, | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
| @@ -143,27 +144,31 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState> | |||||||
|                             {}, |                             {}, | ||||||
|                             { |                             { | ||||||
|                                 photo: (sub) => ( |                                 photo: (sub) => ( | ||||||
|                                     <a |                                     <ExternalLink | ||||||
|                                         href="themes/element/img/backgrounds/lake.jpg" |                                         href="themes/element/img/backgrounds/lake.jpg" | ||||||
|                                         rel="noreferrer noopener" |                                         rel="noreferrer noopener" | ||||||
|                                         target="_blank" |                                         target="_blank" | ||||||
|                                     > |                                     > | ||||||
|                                         {sub} |                                         {sub} | ||||||
|                                     </a> |                                     </ExternalLink> | ||||||
|                                 ), |                                 ), | ||||||
|                                 author: (sub) => ( |                                 author: (sub) => ( | ||||||
|                                     <a href="https://www.flickr.com/golan" rel="noreferrer noopener" target="_blank"> |                                     <ExternalLink | ||||||
|  |                                         href="https://www.flickr.com/golan" | ||||||
|  |                                         rel="noreferrer noopener" | ||||||
|  |                                         target="_blank" | ||||||
|  |                                     > | ||||||
|                                         {sub} |                                         {sub} | ||||||
|                                     </a> |                                     </ExternalLink> | ||||||
|                                 ), |                                 ), | ||||||
|                                 terms: (sub) => ( |                                 terms: (sub) => ( | ||||||
|                                     <a |                                     <ExternalLink | ||||||
|                                         href="https://creativecommons.org/licenses/by-sa/4.0/" |                                         href="https://creativecommons.org/licenses/by-sa/4.0/" | ||||||
|                                         rel="noreferrer noopener" |                                         rel="noreferrer noopener" | ||||||
|                                         target="_blank" |                                         target="_blank" | ||||||
|                                     > |                                     > | ||||||
|                                         {sub} |                                         {sub} | ||||||
|                                     </a> |                                     </ExternalLink> | ||||||
|                                 ), |                                 ), | ||||||
|                             }, |                             }, | ||||||
|                         )} |                         )} | ||||||
| @@ -175,27 +180,27 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState> | |||||||
|                             {}, |                             {}, | ||||||
|                             { |                             { | ||||||
|                                 colr: (sub) => ( |                                 colr: (sub) => ( | ||||||
|                                     <a |                                     <ExternalLink | ||||||
|                                         href="https://github.com/matrix-org/twemoji-colr" |                                         href="https://github.com/matrix-org/twemoji-colr" | ||||||
|                                         rel="noreferrer noopener" |                                         rel="noreferrer noopener" | ||||||
|                                         target="_blank" |                                         target="_blank" | ||||||
|                                     > |                                     > | ||||||
|                                         {sub} |                                         {sub} | ||||||
|                                     </a> |                                     </ExternalLink> | ||||||
|                                 ), |                                 ), | ||||||
|                                 author: (sub) => ( |                                 author: (sub) => ( | ||||||
|                                     <a href="https://mozilla.org" rel="noreferrer noopener" target="_blank"> |                                     <ExternalLink href="https://mozilla.org" rel="noreferrer noopener" target="_blank"> | ||||||
|                                         {sub} |                                         {sub} | ||||||
|                                     </a> |                                     </ExternalLink> | ||||||
|                                 ), |                                 ), | ||||||
|                                 terms: (sub) => ( |                                 terms: (sub) => ( | ||||||
|                                     <a |                                     <ExternalLink | ||||||
|                                         href="https://www.apache.org/licenses/LICENSE-2.0" |                                         href="https://www.apache.org/licenses/LICENSE-2.0" | ||||||
|                                         rel="noreferrer noopener" |                                         rel="noreferrer noopener" | ||||||
|                                         target="_blank" |                                         target="_blank" | ||||||
|                                     > |                                     > | ||||||
|                                         {sub} |                                         {sub} | ||||||
|                                     </a> |                                     </ExternalLink> | ||||||
|                                 ), |                                 ), | ||||||
|                             }, |                             }, | ||||||
|                         )} |                         )} | ||||||
| @@ -208,23 +213,31 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState> | |||||||
|                             {}, |                             {}, | ||||||
|                             { |                             { | ||||||
|                                 twemoji: (sub) => ( |                                 twemoji: (sub) => ( | ||||||
|                                     <a href="https://twemoji.twitter.com/" rel="noreferrer noopener" target="_blank"> |                                     <ExternalLink | ||||||
|  |                                         href="https://twemoji.twitter.com/" | ||||||
|  |                                         rel="noreferrer noopener" | ||||||
|  |                                         target="_blank" | ||||||
|  |                                     > | ||||||
|                                         {sub} |                                         {sub} | ||||||
|                                     </a> |                                     </ExternalLink> | ||||||
|                                 ), |                                 ), | ||||||
|                                 author: (sub) => ( |                                 author: (sub) => ( | ||||||
|                                     <a href="https://twemoji.twitter.com/" rel="noreferrer noopener" target="_blank"> |                                     <ExternalLink | ||||||
|  |                                         href="https://twemoji.twitter.com/" | ||||||
|  |                                         rel="noreferrer noopener" | ||||||
|  |                                         target="_blank" | ||||||
|  |                                     > | ||||||
|                                         {sub} |                                         {sub} | ||||||
|                                     </a> |                                     </ExternalLink> | ||||||
|                                 ), |                                 ), | ||||||
|                                 terms: (sub) => ( |                                 terms: (sub) => ( | ||||||
|                                     <a |                                     <ExternalLink | ||||||
|                                         href="https://creativecommons.org/licenses/by/4.0/" |                                         href="https://creativecommons.org/licenses/by/4.0/" | ||||||
|                                         rel="noreferrer noopener" |                                         rel="noreferrer noopener" | ||||||
|                                         target="_blank" |                                         target="_blank" | ||||||
|                                     > |                                     > | ||||||
|                                         {sub} |                                         {sub} | ||||||
|                                     </a> |                                     </ExternalLink> | ||||||
|                                 ), |                                 ), | ||||||
|                             }, |                             }, | ||||||
|                         )} |                         )} | ||||||
| @@ -256,9 +269,9 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState> | |||||||
|             }, |             }, | ||||||
|             { |             { | ||||||
|                 a: (sub) => ( |                 a: (sub) => ( | ||||||
|                     <a href="https://element.io/help" rel="noreferrer noopener" target="_blank"> |                     <ExternalLink href="https://element.io/help" rel="noreferrer noopener" target="_blank"> | ||||||
|                         {sub} |                         {sub} | ||||||
|                     </a> |                     </ExternalLink> | ||||||
|                 ), |                 ), | ||||||
|             }, |             }, | ||||||
|         ); |         ); | ||||||
| @@ -273,9 +286,9 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState> | |||||||
|                         }, |                         }, | ||||||
|                         { |                         { | ||||||
|                             a: (sub) => ( |                             a: (sub) => ( | ||||||
|                                 <a href="https://element.io/help" rel="noreferrer noopener" target="_blank"> |                                 <ExternalLink href="https://element.io/help" rel="noreferrer noopener" target="_blank"> | ||||||
|                                     {sub} |                                     {sub} | ||||||
|                                 </a> |                                 </ExternalLink> | ||||||
|                             ), |                             ), | ||||||
|                         }, |                         }, | ||||||
|                     )} |                     )} | ||||||
| @@ -321,13 +334,13 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState> | |||||||
|                             {}, |                             {}, | ||||||
|                             { |                             { | ||||||
|                                 a: (sub) => ( |                                 a: (sub) => ( | ||||||
|                                     <a |                                     <ExternalLink | ||||||
|                                         href="https://matrix.org/security-disclosure-policy/" |                                         href="https://matrix.org/security-disclosure-policy/" | ||||||
|                                         rel="noreferrer noopener" |                                         rel="noreferrer noopener" | ||||||
|                                         target="_blank" |                                         target="_blank" | ||||||
|                                     > |                                     > | ||||||
|                                         {sub} |                                         {sub} | ||||||
|                                     </a> |                                     </ExternalLink> | ||||||
|                                 ), |                                 ), | ||||||
|                             }, |                             }, | ||||||
|                         )} |                         )} | ||||||
|   | |||||||
| @@ -20,6 +20,7 @@ import { MatrixError, ConnectionError } from "matrix-js-sdk/src/http-api"; | |||||||
| import { _t, _td, Tags, TranslatedString } from "../languageHandler"; | import { _t, _td, Tags, TranslatedString } from "../languageHandler"; | ||||||
| import SdkConfig from "../SdkConfig"; | import SdkConfig from "../SdkConfig"; | ||||||
| import { ValidatedServerConfig } from "./ValidatedServerConfig"; | import { ValidatedServerConfig } from "./ValidatedServerConfig"; | ||||||
|  | import ExternalLink from "../components/views/elements/ExternalLink"; | ||||||
|  |  | ||||||
| export const resourceLimitStrings = { | export const resourceLimitStrings = { | ||||||
|     "monthly_active_user": _td("This homeserver has hit its Monthly Active User limit."), |     "monthly_active_user": _td("This homeserver has hit its Monthly Active User limit."), | ||||||
| @@ -183,9 +184,9 @@ export function messageForConnectionError( | |||||||
|                     {}, |                     {}, | ||||||
|                     { |                     { | ||||||
|                         a: (sub) => ( |                         a: (sub) => ( | ||||||
|                             <a target="_blank" rel="noreferrer noopener" href={serverConfig.hsUrl}> |                             <ExternalLink target="_blank" rel="noreferrer noopener" href={serverConfig.hsUrl}> | ||||||
|                                 {sub} |                                 {sub} | ||||||
|                             </a> |                             </ExternalLink> | ||||||
|                         ), |                         ), | ||||||
|                     }, |                     }, | ||||||
|                 )} |                 )} | ||||||
|   | |||||||
| @@ -14,11 +14,15 @@ See the License for the specific language governing permissions and | |||||||
| limitations under the License. | limitations under the License. | ||||||
| */ | */ | ||||||
|  |  | ||||||
|  | import React from "react"; | ||||||
|  | import { render } from "@testing-library/react"; | ||||||
| import { MatrixClient, PendingEventOrdering } from "matrix-js-sdk/src/client"; | import { MatrixClient, PendingEventOrdering } from "matrix-js-sdk/src/client"; | ||||||
| import { EventStatus, MatrixEvent } from "matrix-js-sdk/src/models/event"; | import { EventStatus, MatrixEvent } from "matrix-js-sdk/src/models/event"; | ||||||
| import { Room } from "matrix-js-sdk/src/models/room"; | import { Room } from "matrix-js-sdk/src/models/room"; | ||||||
|  | import { MatrixError } from "matrix-js-sdk/src/http-api"; | ||||||
|  |  | ||||||
| import { getUnsentMessages } from "../../../src/components/structures/RoomStatusBar"; | import RoomStatusBar, { getUnsentMessages } from "../../../src/components/structures/RoomStatusBar"; | ||||||
|  | import MatrixClientContext from "../../../src/contexts/MatrixClientContext"; | ||||||
| import { MatrixClientPeg } from "../../../src/MatrixClientPeg"; | import { MatrixClientPeg } from "../../../src/MatrixClientPeg"; | ||||||
| import { mkEvent, stubClient } from "../../test-utils/test-utils"; | import { mkEvent, stubClient } from "../../test-utils/test-utils"; | ||||||
| import { mkThread } from "../../test-utils/threads"; | import { mkThread } from "../../test-utils/threads"; | ||||||
| @@ -34,6 +38,7 @@ describe("RoomStatusBar", () => { | |||||||
|  |  | ||||||
|         stubClient(); |         stubClient(); | ||||||
|         client = MatrixClientPeg.get(); |         client = MatrixClientPeg.get(); | ||||||
|  |         client.getSyncStateData = jest.fn().mockReturnValue({}); | ||||||
|         room = new Room(ROOM_ID, client, client.getUserId()!, { |         room = new Room(ROOM_ID, client, client.getUserId()!, { | ||||||
|             pendingEventOrdering: PendingEventOrdering.Detached, |             pendingEventOrdering: PendingEventOrdering.Detached, | ||||||
|         }); |         }); | ||||||
| @@ -47,6 +52,13 @@ describe("RoomStatusBar", () => { | |||||||
|         event.status = EventStatus.NOT_SENT; |         event.status = EventStatus.NOT_SENT; | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|  |     const getComponent = () => | ||||||
|  |         render(<RoomStatusBar room={room} />, { | ||||||
|  |             wrapper: ({ children }) => ( | ||||||
|  |                 <MatrixClientContext.Provider value={client}>{children}</MatrixClientContext.Provider> | ||||||
|  |             ), | ||||||
|  |         }); | ||||||
|  |  | ||||||
|     describe("getUnsentMessages", () => { |     describe("getUnsentMessages", () => { | ||||||
|         it("returns no unsent messages", () => { |         it("returns no unsent messages", () => { | ||||||
|             expect(getUnsentMessages(room)).toHaveLength(0); |             expect(getUnsentMessages(room)).toHaveLength(0); | ||||||
| @@ -88,4 +100,55 @@ describe("RoomStatusBar", () => { | |||||||
|             expect(pendingEvents.every((ev) => ev.getId() !== event.getId())).toBe(true); |             expect(pendingEvents.every((ev) => ev.getId() !== event.getId())).toBe(true); | ||||||
|         }); |         }); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|  |     describe("<RoomStatusBar />", () => { | ||||||
|  |         it("should render nothing when room has no error or unsent messages", () => { | ||||||
|  |             const { container } = getComponent(); | ||||||
|  |             expect(container.firstChild).toBe(null); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         describe("unsent messages", () => { | ||||||
|  |             it("should render warning when messages are unsent due to consent", () => { | ||||||
|  |                 const unsentMessage = mkEvent({ | ||||||
|  |                     event: true, | ||||||
|  |                     type: "m.room.message", | ||||||
|  |                     user: "@user1:server", | ||||||
|  |                     room: "!room1:server", | ||||||
|  |                     content: {}, | ||||||
|  |                 }); | ||||||
|  |                 unsentMessage.status = EventStatus.NOT_SENT; | ||||||
|  |                 unsentMessage.error = new MatrixError({ | ||||||
|  |                     errcode: "M_CONSENT_NOT_GIVEN", | ||||||
|  |                     data: { consent_uri: "terms.com" }, | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |                 room.addPendingEvent(unsentMessage, "123"); | ||||||
|  |  | ||||||
|  |                 const { container } = getComponent(); | ||||||
|  |  | ||||||
|  |                 expect(container).toMatchSnapshot(); | ||||||
|  |             }); | ||||||
|  |  | ||||||
|  |             it("should render warning when messages are unsent due to resource limit", () => { | ||||||
|  |                 const unsentMessage = mkEvent({ | ||||||
|  |                     event: true, | ||||||
|  |                     type: "m.room.message", | ||||||
|  |                     user: "@user1:server", | ||||||
|  |                     room: "!room1:server", | ||||||
|  |                     content: {}, | ||||||
|  |                 }); | ||||||
|  |                 unsentMessage.status = EventStatus.NOT_SENT; | ||||||
|  |                 unsentMessage.error = new MatrixError({ | ||||||
|  |                     errcode: "M_RESOURCE_LIMIT_EXCEEDED", | ||||||
|  |                     data: { limit_type: "monthly_active_user" }, | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |                 room.addPendingEvent(unsentMessage, "123"); | ||||||
|  |  | ||||||
|  |                 const { container } = getComponent(); | ||||||
|  |  | ||||||
|  |                 expect(container).toMatchSnapshot(); | ||||||
|  |             }); | ||||||
|  |         }); | ||||||
|  |     }); | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -0,0 +1,126 @@ | |||||||
|  | // Jest Snapshot v1, https://goo.gl/fbAQLP | ||||||
|  |  | ||||||
|  | exports[`RoomStatusBar <RoomStatusBar /> unsent messages should render warning when messages are unsent due to consent 1`] = ` | ||||||
|  | <div> | ||||||
|  |   <div | ||||||
|  |     class="mx_RoomStatusBar mx_RoomStatusBar_unsentMessages" | ||||||
|  |   > | ||||||
|  |     <div | ||||||
|  |       role="alert" | ||||||
|  |     > | ||||||
|  |       <div | ||||||
|  |         class="mx_RoomStatusBar_unsentBadge" | ||||||
|  |       > | ||||||
|  |         <div | ||||||
|  |           class="mx_NotificationBadge mx_NotificationBadge_visible mx_NotificationBadge_highlighted mx_NotificationBadge_2char" | ||||||
|  |         > | ||||||
|  |           <span | ||||||
|  |             class="mx_NotificationBadge_count" | ||||||
|  |           > | ||||||
|  |             ! | ||||||
|  |           </span> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <div> | ||||||
|  |         <div | ||||||
|  |           class="mx_RoomStatusBar_unsentTitle" | ||||||
|  |         > | ||||||
|  |           <span> | ||||||
|  |             You can't send any messages until you review and agree to  | ||||||
|  |             <a | ||||||
|  |               class="mx_ExternalLink" | ||||||
|  |               rel="noreferrer noopener" | ||||||
|  |               target="_blank" | ||||||
|  |             > | ||||||
|  |               our terms and conditions | ||||||
|  |               <i | ||||||
|  |                 class="mx_ExternalLink_icon" | ||||||
|  |               /> | ||||||
|  |             </a> | ||||||
|  |             . | ||||||
|  |           </span> | ||||||
|  |         </div> | ||||||
|  |         <div | ||||||
|  |           class="mx_RoomStatusBar_unsentDescription" | ||||||
|  |         > | ||||||
|  |           You can select all or individual messages to retry or delete | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <div | ||||||
|  |         class="mx_RoomStatusBar_unsentButtonBar" | ||||||
|  |       > | ||||||
|  |         <div | ||||||
|  |           class="mx_AccessibleButton mx_RoomStatusBar_unsentCancelAllBtn" | ||||||
|  |           role="button" | ||||||
|  |           tabindex="0" | ||||||
|  |         > | ||||||
|  |           Delete all | ||||||
|  |         </div> | ||||||
|  |         <div | ||||||
|  |           class="mx_AccessibleButton mx_RoomStatusBar_unsentRetry" | ||||||
|  |           role="button" | ||||||
|  |           tabindex="0" | ||||||
|  |         > | ||||||
|  |           Retry all | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
|  | `; | ||||||
|  |  | ||||||
|  | exports[`RoomStatusBar <RoomStatusBar /> unsent messages should render warning when messages are unsent due to resource limit 1`] = ` | ||||||
|  | <div> | ||||||
|  |   <div | ||||||
|  |     class="mx_RoomStatusBar mx_RoomStatusBar_unsentMessages" | ||||||
|  |   > | ||||||
|  |     <div | ||||||
|  |       role="alert" | ||||||
|  |     > | ||||||
|  |       <div | ||||||
|  |         class="mx_RoomStatusBar_unsentBadge" | ||||||
|  |       > | ||||||
|  |         <div | ||||||
|  |           class="mx_NotificationBadge mx_NotificationBadge_visible mx_NotificationBadge_highlighted mx_NotificationBadge_2char" | ||||||
|  |         > | ||||||
|  |           <span | ||||||
|  |             class="mx_NotificationBadge_count" | ||||||
|  |           > | ||||||
|  |             ! | ||||||
|  |           </span> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <div> | ||||||
|  |         <div | ||||||
|  |           class="mx_RoomStatusBar_unsentTitle" | ||||||
|  |         > | ||||||
|  |           Your message wasn't sent because this homeserver has exceeded a resource limit. Please contact your service administrator to continue using the service. | ||||||
|  |         </div> | ||||||
|  |         <div | ||||||
|  |           class="mx_RoomStatusBar_unsentDescription" | ||||||
|  |         > | ||||||
|  |           You can select all or individual messages to retry or delete | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <div | ||||||
|  |         class="mx_RoomStatusBar_unsentButtonBar" | ||||||
|  |       > | ||||||
|  |         <div | ||||||
|  |           class="mx_AccessibleButton mx_RoomStatusBar_unsentCancelAllBtn" | ||||||
|  |           role="button" | ||||||
|  |           tabindex="0" | ||||||
|  |         > | ||||||
|  |           Delete all | ||||||
|  |         </div> | ||||||
|  |         <div | ||||||
|  |           class="mx_AccessibleButton mx_RoomStatusBar_unsentRetry" | ||||||
|  |           role="button" | ||||||
|  |           tabindex="0" | ||||||
|  |         > | ||||||
|  |           Retry all | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
|  | `; | ||||||
| @@ -38,19 +38,27 @@ exports[`FeedbackDialog should respect feedback config 1`] = ` | |||||||
|           <span> |           <span> | ||||||
|             Please view  |             Please view  | ||||||
|             <a |             <a | ||||||
|  |               class="mx_ExternalLink" | ||||||
|               href="http://existing?foo=bar" |               href="http://existing?foo=bar" | ||||||
|               rel="noreferrer noopener" |               rel="noreferrer noopener" | ||||||
|               target="_blank" |               target="_blank" | ||||||
|             > |             > | ||||||
|               existing bugs on Github |               existing bugs on Github | ||||||
|  |               <i | ||||||
|  |                 class="mx_ExternalLink_icon" | ||||||
|  |               /> | ||||||
|             </a> |             </a> | ||||||
|              first. No match?  |              first. No match?  | ||||||
|             <a |             <a | ||||||
|  |               class="mx_ExternalLink" | ||||||
|               href="https://new.issue.url?foo=bar" |               href="https://new.issue.url?foo=bar" | ||||||
|               rel="noreferrer noopener" |               rel="noreferrer noopener" | ||||||
|               target="_blank" |               target="_blank" | ||||||
|             > |             > | ||||||
|               Start a new one |               Start a new one | ||||||
|  |               <i | ||||||
|  |                 class="mx_ExternalLink_icon" | ||||||
|  |               /> | ||||||
|             </a> |             </a> | ||||||
|             . |             . | ||||||
|           </span> |           </span> | ||||||
|   | |||||||
| @@ -6,11 +6,15 @@ exports[`messageForConnectionError should match snapshot for ConnectionError 1`] | |||||||
|     <span> |     <span> | ||||||
|       Can't connect to homeserver - please check your connectivity, ensure your  |       Can't connect to homeserver - please check your connectivity, ensure your  | ||||||
|       <a |       <a | ||||||
|  |         class="mx_ExternalLink" | ||||||
|         href="hsUrl" |         href="hsUrl" | ||||||
|         rel="noreferrer noopener" |         rel="noreferrer noopener" | ||||||
|         target="_blank" |         target="_blank" | ||||||
|       > |       > | ||||||
|         homeserver's SSL certificate |         homeserver's SSL certificate | ||||||
|  |         <i | ||||||
|  |           class="mx_ExternalLink_icon" | ||||||
|  |         /> | ||||||
|       </a> |       </a> | ||||||
|        is trusted, and that a browser extension is not blocking requests. |        is trusted, and that a browser extension is not blocking requests. | ||||||
|     </span> |     </span> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user