2020-06-15 17:23:53 +02:00
import React , { useState , useEffect } from 'react' ;
2020-08-25 15:18:10 +02:00
import { api , ShareWith , ShareType , RoomShare , Room , Permission , ShareWithOption } from './Api' ;
2020-06-15 17:23:53 +02:00
import './ShareWith.scss' ;
type Props = {
2020-06-16 16:54:50 +02:00
room : Room ;
permission : Permission.User | Permission . Moderator ;
shares : RoomShare [ ] | undefined ;
setShares : ( shares : RoomShare [ ] ) = > void ;
2020-06-15 17:23:53 +02:00
}
2020-06-16 16:54:50 +02:00
const ShareWith : React.FC < Props > = ( { room , permission , shares : allShares , setShares } ) = > {
2020-06-15 17:23:53 +02:00
const [ search , setSearch ] = useState < string > ( '' ) ;
const [ hasFocus , setFocus ] = useState < boolean > ( false ) ;
2020-08-25 15:18:10 +02:00
const [ showSearchResults , setShowSearchResults ] = useState < boolean > ( false ) ;
2020-06-15 17:23:53 +02:00
const [ recommendations , setRecommendations ] = useState < ShareWith > ( ) ;
const [ searchResults , setSearchResults ] = useState < ShareWith > ( ) ;
2020-06-17 10:56:28 +02:00
const isOwner = room . userId === OC . currentUser ;
2020-06-16 16:54:50 +02:00
const shares = ( allShares && permission === Permission . Moderator ) ?
allShares . filter ( share = > share . permission !== Permission . User ) : allShares ;
2020-06-15 17:23:53 +02:00
2020-06-16 16:54:50 +02:00
const sharedUserIds = shares ? shares . filter ( share = > share . shareType === ShareType . User ) . map ( share = > share . shareWith ) : [ ] ;
const sharedGroupIds = shares ? shares . filter ( share = > share . shareType === ShareType . Group ) . map ( share = > share . shareWith ) : [ ] ;
2020-06-15 17:23:53 +02:00
useEffect ( ( ) = > {
2020-08-25 15:18:10 +02:00
setSearchResults ( undefined ) ;
const searchQuery = search ;
api . searchShareWith ( searchQuery ) . then ( result = > {
if ( searchQuery === search ) {
setSearchResults ( result ) ;
}
2020-06-15 17:23:53 +02:00
} ) ;
} , [ search ] ) ;
useEffect ( ( ) = > {
api . getRecommendedShareWith ( ) . then ( result = > setRecommendations ( result ) ) ;
} , [ ] ) ;
2020-08-25 15:18:10 +02:00
useEffect ( ( ) = > {
setTimeout ( ( ) = > setShowSearchResults ( hasFocus ) , 100 ) ;
} , [ hasFocus ] ) ;
2020-06-17 10:56:28 +02:00
async function addRoomShare ( shareWith : string , shareType : number , displayName : string , permission : Permission ) {
2020-06-16 16:54:50 +02:00
const roomShare = await api . createRoomShare ( room . id , shareType , shareWith , permission ) ;
2020-06-15 17:23:53 +02:00
roomShare . shareWithDisplayName = displayName ;
2020-06-16 16:54:50 +02:00
console . log ( 'addRoomShare' , allShares , roomShare ) ;
const newShares = allShares ? [ . . . allShares ] : [ ] ;
const index = newShares . findIndex ( share = > share . id === roomShare . id ) ;
if ( index > - 1 ) {
newShares [ index ] = roomShare ;
} else {
newShares . push ( roomShare ) ;
}
console . log ( 'newroomshares' , newShares ) ;
setShares ( newShares ) ;
2020-06-15 17:23:53 +02:00
}
async function deleteRoomShare ( id : number ) {
2020-06-16 16:54:50 +02:00
console . log ( 'deleteRoomShare' , id ) ;
2020-06-15 17:23:53 +02:00
await api . deleteRoomShare ( id ) ;
2020-06-16 16:54:50 +02:00
setShares ( ( allShares ? [ . . . allShares ] : [ ] ) . filter ( share = > share . id !== id ) ) ;
2020-06-15 17:23:53 +02:00
}
2020-06-17 10:56:28 +02:00
async function toggleAdminShare ( share : RoomShare ) {
const newPermission = share . permission === Permission . Admin ? Permission.Moderator : Permission.Admin ;
return addRoomShare ( share . shareWith , share . shareType , share . shareWithDisplayName || share . shareWith , newPermission ) ;
}
2020-08-25 15:18:10 +02:00
function renderSearchResults ( options : ShareWith | undefined ) {
const results = options ? [
. . . options . users . filter ( user = > ! sharedUserIds . includes ( user . value . shareWith ) ) ,
. . . options . groups . filter ( group = > ! sharedGroupIds . includes ( group . value . shareWith ) ) ,
] : [ ] ;
const renderOption = ( option : ShareWithOption ) = > {
return ( < li key = { option . value . shareWith } className = "suggestion" onClick = { ( ) = > addRoomShare ( option . value . shareWith , option . value . shareType , option . label , permission ) } >
{ option . label } { option . value . shareType === ShareType . Group ? ` ( ${ t ( 'bbb' , 'Group' ) } ) ` : '' }
< / li > ) ;
} ;
2020-06-15 17:23:53 +02:00
return (
< ul className = "bbb-selection" >
2020-08-25 15:18:10 +02:00
{ ! options ?
< li > < span className = "icon icon-loading-small icon-visible" > < / span > { t ( 'bbb' , 'Searching' ) } < / li > :
(
( results . length === 0 && search ) ? < li > { t ( 'bbb' , 'No matches' ) } < / li > : results . map ( renderOption )
) }
2020-06-15 17:23:53 +02:00
< / ul >
) ;
}
function renderShares ( shares : RoomShare [ ] ) {
const currentUser = OC . getCurrentUser ( ) ;
const ownShare = {
id : - 1 ,
roomId : room.id ,
shareType : ShareType.User ,
shareWith : currentUser.uid ,
shareWithDisplayName : currentUser.displayName ,
permission : Permission.Admin ,
} ;
return (
< ul className = "bbb-shareWith" >
{ [ ownShare , . . . shares ] . map ( share = > {
const avatarUrl = share . shareType === ShareType . User ? OC . generateUrl ( '/avatar/' + encodeURIComponent ( share . shareWith ) + '/' + 32 , {
user : share.shareWith ,
size : 32 ,
requesttoken : OC.requestToken ,
} ) : undefined ;
const displayName = share . shareWithDisplayName || share . shareWith ;
return (
< li key = { share . id } className = "bbb-shareWith__item" >
< div className = "avatardiv" >
{ avatarUrl && < img src = { avatarUrl } alt = { ` Avatar from ${ displayName } ` } / > }
2020-06-16 16:54:50 +02:00
{ share . shareType === ShareType . Group && < span className = "icon-group-white" > < / span > }
2020-06-15 17:23:53 +02:00
< / div >
< div className = "bbb-shareWith__item__label" >
2020-06-17 10:56:28 +02:00
< h5 > { displayName }
{ ( share . permission === Permission . Moderator && permission === Permission . User ) && ` ( ${ t ( 'bbb' , 'moderator' ) } ) ` }
{ ( share . permission === Permission . Admin ) && ` ( ${ t ( 'bbb' , 'admin' ) } ) ` } < / h5 >
2020-06-15 17:23:53 +02:00
< / div >
2020-06-17 10:56:28 +02:00
{ ( share . id > - 1 && permission === Permission . Moderator && isOwner ) && < div className = "bbb-shareWith__item__action" >
< a className = { ` icon icon-shared icon-visible ${ share . permission === Permission . Admin ? 'bbb-icon-selected' : 'bbb-icon-unselected' } ` }
onClick = { ev = > { ev . preventDefault ( ) ; toggleAdminShare ( share ) ; } }
title = { t ( 'bbb' , 'Share' ) } / >
< / div > }
{ ( share . id > - 1 && isOwner ) && < div className = "bbb-shareWith__item__action" >
2020-06-15 17:23:53 +02:00
< a className = "icon icon-delete icon-visible"
onClick = { ev = > { ev . preventDefault ( ) ; deleteRoomShare ( share . id ) ; } }
title = { t ( 'bbb' , 'Delete' ) } / >
< / div > }
< / li >
) ;
} ) }
< / ul >
) ;
}
const loading = < > < span className = "icon icon-loading-small icon-visible" > < / span > { t ( 'bbb' , 'Loading' ) } < / > ;
return (
< >
{ shares ? renderShares ( shares ) : loading }
< div className = "bbb-selection-container" >
2020-06-17 10:56:28 +02:00
{ isOwner ? < input
2020-06-15 17:23:53 +02:00
type = "text"
value = { search }
onChange = { ev = > setSearch ( ev . currentTarget . value ) }
onFocus = { ( ) = > setFocus ( true ) }
2020-08-25 15:18:10 +02:00
onBlur = { ( ) = > setFocus ( false ) }
2020-06-17 10:56:28 +02:00
placeholder = { t ( 'bbb' , 'Name, group, ...' ) } / > :
< em > < span className = "icon icon-details icon-visible" > < / span > { t ( 'bbb' , 'You are not allowed to change this option, because this room is shared with you.' ) } < / em > }
2020-08-25 15:18:10 +02:00
{ showSearchResults && renderSearchResults ( ( search && searchResults ) ? searchResults : ( ( recommendations && ! search ) ? recommendations : undefined ) ) }
2020-06-15 17:23:53 +02:00
< / div >
< / >
) ;
} ;
2020-06-16 16:54:50 +02:00
export default ShareWith ;