@@ -13,7 +13,8 @@ import {
1313 EventType ,
1414 HttpApiEvent ,
1515 type MatrixClient ,
16- type MatrixEvent ,
16+ MatrixEvent ,
17+ MsgType ,
1718 type RoomType ,
1819 SyncState ,
1920 type SyncStateData ,
@@ -24,9 +25,9 @@ import { logger } from "matrix-js-sdk/src/logger";
2425import { throttle } from "lodash" ;
2526import { CryptoEvent , type KeyBackupInfo } from "matrix-js-sdk/src/crypto-api" ;
2627import { TooltipProvider } from "@vector-im/compound-web" ;
27-
2828// what-input helps improve keyboard accessibility
2929import "what-input" ;
30+ import sanitizeHtml from "sanitize-html" ;
3031
3132import PosthogTrackers from "../../PosthogTrackers" ;
3233import { DecryptionFailureTracker } from "../../DecryptionFailureTracker" ;
@@ -50,6 +51,7 @@ import ThemeController from "../../settings/controllers/ThemeController";
5051import { startAnyRegistrationFlow } from "../../Registration" ;
5152import ResizeNotifier from "../../utils/ResizeNotifier" ;
5253import AutoDiscoveryUtils from "../../utils/AutoDiscoveryUtils" ;
54+ import { makeRoomPermalink } from "../../utils/permalinks/Permalinks" ;
5355import ThemeWatcher , { ThemeWatcherEvent } from "../../settings/watchers/ThemeWatcher" ;
5456import { FontWatcher } from "../../settings/watchers/FontWatcher" ;
5557import { storeRoomAliasInCache } from "../../RoomAliasCache" ;
@@ -94,7 +96,6 @@ import VerificationRequestToast from "../views/toasts/VerificationRequestToast";
9496import PerformanceMonitor , { PerformanceEntryNames } from "../../performance" ;
9597import UIStore , { UI_EVENTS } from "../../stores/UIStore" ;
9698import SoftLogout from "./auth/SoftLogout" ;
97- import { makeRoomPermalink } from "../../utils/permalinks/Permalinks" ;
9899import { copyPlaintext } from "../../utils/strings" ;
99100import { PosthogAnalytics } from "../../PosthogAnalytics" ;
100101import { initSentry } from "../../sentry" ;
@@ -124,7 +125,7 @@ import { viewUserDeviceSettings } from "../../actions/handlers/viewUserDeviceSet
124125import GenericToast from "../views/toasts/GenericToast" ;
125126import RovingSpotlightDialog from "../views/dialogs/spotlight/SpotlightDialog" ;
126127import { findDMForUser } from "../../utils/dm/findDMForUser" ;
127- import { Linkify } from "../../HtmlUtils" ;
128+ import { getHtmlText , Linkify } from "../../HtmlUtils" ;
128129import { NotificationLevel } from "../../stores/notifications/NotificationLevel" ;
129130import { type UserTab } from "../views/dialogs/UserTab" ;
130131import { shouldSkipSetupEncryption } from "../../utils/crypto/shouldSkipSetupEncryption" ;
@@ -136,6 +137,10 @@ import { LoginSplashView } from "./auth/LoginSplashView";
136137import { cleanUpDraftsIfRequired } from "../../DraftCleaner" ;
137138import { InitialCryptoSetupStore } from "../../stores/InitialCryptoSetupStore" ;
138139import { setTheme } from "../../theme" ;
140+ import { type OpenForwardDialogPayload } from "../../dispatcher/payloads/OpenForwardDialogPayload" ;
141+ import { ShareFormat , type SharePayload } from "../../dispatcher/payloads/SharePayload" ;
142+ import Markdown from "../../Markdown" ;
143+ import { sanitizeHtmlParams } from "../../Linkify" ;
139144
140145// legacy export
141146export { default as Views } from "../../Views" ;
@@ -780,6 +785,9 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
780785 case Action . ViewHomePage :
781786 this . viewHome ( payload . justRegistered ) ;
782787 break ;
788+ case Action . Share :
789+ this . viewShare ( payload . format , payload . msg ) ;
790+ break ;
783791 case Action . ViewStartChatOrReuse :
784792 this . chatCreateOrReuse ( payload . user_id ) ;
785793 break ;
@@ -1115,6 +1123,58 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
11151123 } ) ;
11161124 }
11171125
1126+ private viewShare ( format : ShareFormat , msg : string ) : void {
1127+ // Wait for the first sync so we can present possible rooms to share into
1128+ this . firstSyncPromise . promise . then ( ( ) => {
1129+ this . notifyNewScreen ( "share" ) ;
1130+ let rawEvent ;
1131+ switch ( format ) {
1132+ case ShareFormat . Html : {
1133+ rawEvent = {
1134+ type : "m.room.message" ,
1135+ content : {
1136+ msgtype : MsgType . Text ,
1137+ body : getHtmlText ( msg ) ,
1138+ format : "org.matrix.custom.html" ,
1139+ formatted_body : sanitizeHtml ( msg , sanitizeHtmlParams ) ,
1140+ } ,
1141+ origin_server_ts : Date . now ( ) ,
1142+ } ;
1143+ break ;
1144+ }
1145+ case ShareFormat . Markdown : {
1146+ const html = new Markdown ( msg ) . toHTML ( { externalLinks : true } ) ;
1147+ rawEvent = {
1148+ type : "m.room.message" ,
1149+ content : {
1150+ msgtype : MsgType . Text ,
1151+ body : msg ,
1152+ format : "org.matrix.custom.html" ,
1153+ formatted_body : html ,
1154+ } ,
1155+ origin_server_ts : Date . now ( ) ,
1156+ } ;
1157+ break ;
1158+ }
1159+ default :
1160+ rawEvent = {
1161+ type : "m.room.message" ,
1162+ content : {
1163+ msgtype : MsgType . Text ,
1164+ body : msg ,
1165+ } ,
1166+ origin_server_ts : Date . now ( ) ,
1167+ } ;
1168+ }
1169+ const event = new MatrixEvent ( rawEvent ) ;
1170+ dis . dispatch < OpenForwardDialogPayload > ( {
1171+ action : Action . OpenForwardDialog ,
1172+ event : event ,
1173+ permalinkCreator : null ,
1174+ } ) ;
1175+ } ) ;
1176+ }
1177+
11181178 private async createRoom ( defaultPublic = false , defaultName ?: string , type ?: RoomType ) : Promise < void > {
11191179 const modal = Modal . createDialog ( CreateRoomDialog , {
11201180 type,
@@ -1742,6 +1802,20 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
17421802 dis . dispatch ( {
17431803 action : Action . CreateChat ,
17441804 } ) ;
1805+ } else if ( screen === "share" ) {
1806+ if ( params && params [ "msg" ] !== undefined ) {
1807+ dis . dispatch < SharePayload > ( {
1808+ action : Action . Share ,
1809+ msg : params [ "msg" ] ,
1810+ format : params [ "format" ] ,
1811+ } ) ;
1812+ }
1813+ // if we weren't already coming at this from an existing screen
1814+ // and we're logged in, then explicitly default to home.
1815+ // if we're not logged in, then the login flow will do the right thing.
1816+ if ( ! this . state . currentRoomId && ! this . state . currentUserId ) {
1817+ this . viewHome ( ) ;
1818+ }
17451819 } else if ( screen === "settings" ) {
17461820 dis . fire ( Action . ViewUserSettings ) ;
17471821 } else if ( screen === "welcome" ) {
0 commit comments