@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414limitations under the License.
1515*/
1616
17- import React , { useMemo , useState } from "react" ;
17+ import React , { ReactNode , useMemo , useState } from "react" ;
1818import { Room } from "matrix-js-sdk/src/models/room" ;
1919import { MatrixClient } from "matrix-js-sdk/src/client" ;
2020import { EventType , RoomType } from "matrix-js-sdk/src/@types/event" ;
@@ -24,7 +24,7 @@ import {sortBy} from "lodash";
2424import { MatrixClientPeg } from "../../MatrixClientPeg" ;
2525import dis from "../../dispatcher/dispatcher" ;
2626import { _t } from "../../languageHandler" ;
27- import AccessibleButton from "../views/elements/AccessibleButton" ;
27+ import AccessibleButton , { ButtonEvent } from "../views/elements/AccessibleButton" ;
2828import BaseDialog from "../views/dialogs/BaseDialog" ;
2929import Spinner from "../views/elements/Spinner" ;
3030import SearchBox from "./SearchBox" ;
@@ -40,11 +40,13 @@ import InfoTooltip from "../views/elements/InfoTooltip";
4040import TextWithTooltip from "../views/elements/TextWithTooltip" ;
4141import { useStateToggle } from "../../hooks/useStateToggle" ;
4242import { getOrder } from "../../stores/SpaceStore" ;
43+ import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton" ;
4344
4445interface IHierarchyProps {
4546 space : Room ;
4647 initialText ?: string ;
4748 refreshToken ?: any ;
49+ additionalButtons ?: ReactNode ;
4850 showRoom ( room : ISpaceSummaryRoom , viaServers ?: string [ ] , autoJoin ?: boolean ) : void ;
4951}
5052
@@ -107,8 +109,16 @@ const Tile: React.FC<ITileProps> = ({
107109 const cliRoom = cli . getRoom ( room . room_id ) ;
108110 const myMembership = cliRoom ?. getMyMembership ( ) ;
109111
110- const onPreviewClick = ( ) => onViewRoomClick ( false ) ;
111- const onJoinClick = ( ) => onViewRoomClick ( true ) ;
112+ const onPreviewClick = ( ev : ButtonEvent ) => {
113+ ev . preventDefault ( ) ;
114+ ev . stopPropagation ( ) ;
115+ onViewRoomClick ( false ) ;
116+ }
117+ const onJoinClick = ( ev : ButtonEvent ) => {
118+ ev . preventDefault ( ) ;
119+ ev . stopPropagation ( ) ;
120+ onViewRoomClick ( true ) ;
121+ }
112122
113123 let button ;
114124 if ( myMembership === "join" ) {
@@ -355,6 +365,7 @@ export const SpaceHierarchy: React.FC<IHierarchyProps> = ({
355365 initialText = "" ,
356366 showRoom,
357367 refreshToken,
368+ additionalButtons,
358369 children,
359370} ) => {
360371 const cli = MatrixClientPeg . get ( ) ;
@@ -420,78 +431,83 @@ export const SpaceHierarchy: React.FC<IHierarchyProps> = ({
420431 countsStr = _t ( "%(count)s rooms" , { count : numRooms , numSpaces } ) ;
421432 }
422433
423- let editSection ;
434+ let manageButtons ;
424435 if ( space . getMyMembership ( ) === "join" && space . currentState . maySendStateEvent ( EventType . SpaceChild , userId ) ) {
425436 const selectedRelations = Array . from ( selected . keys ( ) ) . flatMap ( parentId => {
426437 return [ ...selected . get ( parentId ) . values ( ) ] . map ( childId => [ parentId , childId ] ) as [ string , string ] [ ] ;
427438 } ) ;
428439
429- let buttons ;
430- if ( selectedRelations . length ) {
431- const selectionAllSuggested = selectedRelations . every ( ( [ parentId , childId ] ) => {
432- return parentChildMap . get ( parentId ) ?. get ( childId ) ?. content . suggested ;
433- } ) ;
440+ const selectionAllSuggested = selectedRelations . every ( ( [ parentId , childId ] ) => {
441+ return parentChildMap . get ( parentId ) ?. get ( childId ) ?. content . suggested ;
442+ } ) ;
434443
435- const disabled = removing || saving ;
444+ const disabled = ! selectedRelations . length || removing || saving ;
436445
437- buttons = < >
438- < AccessibleButton
439- onClick = { async ( ) => {
440- setRemoving ( true ) ;
441- try {
442- for ( const [ parentId , childId ] of selectedRelations ) {
443- await cli . sendStateEvent ( parentId , EventType . SpaceChild , { } , childId ) ;
444- parentChildMap . get ( parentId ) . get ( childId ) . content = { } ;
445- parentChildMap . set ( parentId , new Map ( parentChildMap . get ( parentId ) ) ) ;
446- }
447- } catch ( e ) {
448- setError ( _t ( "Failed to remove some rooms. Try again later" ) ) ;
446+ let Button : React . ComponentType < React . ComponentProps < typeof AccessibleButton > > = AccessibleButton ;
447+ let props = { } ;
448+ if ( ! selectedRelations . length ) {
449+ Button = AccessibleTooltipButton ;
450+ props = {
451+ tooltip : _t ( "Select a room below first" ) ,
452+ yOffset : - 40 ,
453+ } ;
454+ }
455+
456+ manageButtons = < >
457+ < Button
458+ { ...props }
459+ onClick = { async ( ) => {
460+ setRemoving ( true ) ;
461+ try {
462+ for ( const [ parentId , childId ] of selectedRelations ) {
463+ await cli . sendStateEvent ( parentId , EventType . SpaceChild , { } , childId ) ;
464+ parentChildMap . get ( parentId ) . get ( childId ) . content = { } ;
465+ parentChildMap . set ( parentId , new Map ( parentChildMap . get ( parentId ) ) ) ;
449466 }
450- setRemoving ( false ) ;
451- } }
452- kind = "danger_outline"
453- disabled = { disabled }
454- >
455- { removing ? _t ( "Removing..." ) : _t ( "Remove" ) }
456- </ AccessibleButton >
457- < AccessibleButton
458- onClick = { async ( ) => {
459- setSaving ( true ) ;
460- try {
461- for ( const [ parentId , childId ] of selectedRelations ) {
462- const suggested = ! selectionAllSuggested ;
463- const existingContent = parentChildMap . get ( parentId ) ?. get ( childId ) ?. content ;
464- if ( ! existingContent || existingContent . suggested === suggested ) continue ;
465-
466- const content = {
467- ...existingContent ,
468- suggested : ! selectionAllSuggested ,
469- } ;
470-
471- await cli . sendStateEvent ( parentId , EventType . SpaceChild , content , childId ) ;
472-
473- parentChildMap . get ( parentId ) . get ( childId ) . content = content ;
474- parentChildMap . set ( parentId , new Map ( parentChildMap . get ( parentId ) ) ) ;
475- }
476- } catch ( e ) {
477- setError ( "Failed to update some suggestions. Try again later" ) ;
467+ } catch ( e ) {
468+ setError ( _t ( "Failed to remove some rooms. Try again later" ) ) ;
469+ }
470+ setRemoving ( false ) ;
471+ } }
472+ kind = "danger_outline"
473+ disabled = { disabled }
474+ >
475+ { removing ? _t ( "Removing..." ) : _t ( "Remove" ) }
476+ </ Button >
477+ < Button
478+ { ...props }
479+ onClick = { async ( ) => {
480+ setSaving ( true ) ;
481+ try {
482+ for ( const [ parentId , childId ] of selectedRelations ) {
483+ const suggested = ! selectionAllSuggested ;
484+ const existingContent = parentChildMap . get ( parentId ) ?. get ( childId ) ?. content ;
485+ if ( ! existingContent || existingContent . suggested === suggested ) continue ;
486+
487+ const content = {
488+ ...existingContent ,
489+ suggested : ! selectionAllSuggested ,
490+ } ;
491+
492+ await cli . sendStateEvent ( parentId , EventType . SpaceChild , content , childId ) ;
493+
494+ parentChildMap . get ( parentId ) . get ( childId ) . content = content ;
495+ parentChildMap . set ( parentId , new Map ( parentChildMap . get ( parentId ) ) ) ;
478496 }
479- setSaving ( false ) ;
480- } }
481- kind = "primary_outline"
482- disabled = { disabled }
483- >
484- { saving
485- ? _t ( "Saving..." )
486- : ( selectionAllSuggested ? _t ( "Mark as not suggested" ) : _t ( "Mark as suggested" ) )
497+ } catch ( e ) {
498+ setError ( "Failed to update some suggestions. Try again later" ) ;
487499 }
488- </ AccessibleButton >
489- </ > ;
490- }
491-
492- editSection = < span >
493- { buttons }
494- </ span > ;
500+ setSaving ( false ) ;
501+ } }
502+ kind = "primary_outline"
503+ disabled = { disabled }
504+ >
505+ { saving
506+ ? _t ( "Saving..." )
507+ : ( selectionAllSuggested ? _t ( "Mark as not suggested" ) : _t ( "Mark as suggested" ) )
508+ }
509+ </ Button >
510+ </ > ;
495511 }
496512
497513 let results ;
@@ -537,7 +553,10 @@ export const SpaceHierarchy: React.FC<IHierarchyProps> = ({
537553 content = < >
538554 < div className = "mx_SpaceRoomDirectory_listHeader" >
539555 { countsStr }
540- { editSection }
556+ < span >
557+ { additionalButtons }
558+ { manageButtons }
559+ </ span >
541560 </ div >
542561 { error && < div className = "mx_SpaceRoomDirectory_error" >
543562 { error }
0 commit comments