2022-12-12 14:36:56 -08:00
import { List as ImmutableList } from 'immutable' ;
import React from 'react' ;
2022-12-14 08:41:16 -08:00
import { defineMessages , FormattedMessage , useIntl } from 'react-intl' ;
2022-12-12 14:36:56 -08:00
2022-12-18 09:03:41 -08:00
import { joinGroup , leaveGroup } from 'soapbox/actions/groups' ;
2022-12-12 14:36:56 -08:00
import { openModal } from 'soapbox/actions/modals' ;
import StillImage from 'soapbox/components/still-image' ;
2022-12-15 14:51:30 -08:00
import { Avatar , Button , HStack , Icon , Stack , Text } from 'soapbox/components/ui' ;
import { useAppDispatch } from 'soapbox/hooks' ;
2022-12-12 14:36:56 -08:00
import { normalizeAttachment } from 'soapbox/normalizers' ;
2022-12-17 04:38:41 -08:00
import { isDefaultHeader } from 'soapbox/utils/accounts' ;
2022-12-12 14:36:56 -08:00
import type { Group } from 'soapbox/types/entities' ;
const messages = defineMessages ( {
header : { id : 'group.header.alt' , defaultMessage : 'Group header' } ,
2022-12-16 15:33:07 -08:00
confirmationHeading : { id : 'confirmations.leave_group.heading' , defaultMessage : 'Leave group' } ,
confirmationMessage : { id : 'confirmations.leave_group.message' , defaultMessage : 'You are about to leave the group. Do you want to continue?' } ,
confirmationConfirm : { id : 'confirmations.leave_group.confirm' , defaultMessage : 'Leave' } ,
2022-12-12 14:36:56 -08:00
} ) ;
interface IGroupHeader {
group? : Group | false | null ,
}
const GroupHeader : React.FC < IGroupHeader > = ( { group } ) = > {
const intl = useIntl ( ) ;
const dispatch = useAppDispatch ( ) ;
if ( ! group ) {
return (
< div className = '-mt-4 -mx-4' >
< div >
< div className = 'relative h-32 w-full lg:h-48 md:rounded-t-xl bg-gray-200 dark:bg-gray-900/50' / >
< / div >
< div className = 'px-4 sm:px-6' >
< HStack alignItems = 'bottom' space = { 5 } className = '-mt-12' >
< div className = 'flex relative' >
< div
className = 'h-24 w-24 bg-gray-400 rounded-full ring-4 ring-white dark:ring-gray-800'
/ >
< / div >
< / HStack >
< / div >
< / div >
) ;
}
2022-12-18 09:03:41 -08:00
const onJoinGroup = ( ) = > dispatch ( joinGroup ( group . id ) ) ;
2022-12-16 12:33:17 -08:00
2022-12-18 09:03:41 -08:00
const onLeaveGroup = ( ) = >
2022-12-16 12:33:17 -08:00
dispatch ( openModal ( 'CONFIRM' , {
2022-12-16 15:33:07 -08:00
heading : intl.formatMessage ( messages . confirmationHeading ) ,
message : intl.formatMessage ( messages . confirmationMessage ) ,
confirm : intl.formatMessage ( messages . confirmationConfirm ) ,
2022-12-18 09:03:41 -08:00
onConfirm : ( ) = > dispatch ( leaveGroup ( group . id ) ) ,
2022-12-16 12:33:17 -08:00
} ) ) ;
2022-12-12 14:36:56 -08:00
const onAvatarClick = ( ) = > {
const avatar = normalizeAttachment ( {
type : 'image' ,
url : group.avatar ,
} ) ;
dispatch ( openModal ( 'MEDIA' , { media : ImmutableList.of ( avatar ) , index : 0 } ) ) ;
} ;
const handleAvatarClick : React.MouseEventHandler = ( e ) = > {
if ( e . button === 0 && ! ( e . ctrlKey || e . metaKey ) ) {
e . preventDefault ( ) ;
onAvatarClick ( ) ;
}
} ;
const onHeaderClick = ( ) = > {
const header = normalizeAttachment ( {
type : 'image' ,
url : group.header ,
} ) ;
dispatch ( openModal ( 'MEDIA' , { media : ImmutableList.of ( header ) , index : 0 } ) ) ;
} ;
const handleHeaderClick : React.MouseEventHandler = ( e ) = > {
if ( e . button === 0 && ! ( e . ctrlKey || e . metaKey ) ) {
e . preventDefault ( ) ;
onHeaderClick ( ) ;
}
} ;
2022-12-17 04:38:41 -08:00
const renderHeader = ( ) = > {
let header : React.ReactNode ;
if ( group . header ) {
header = (
< StillImage
src = { group . header }
alt = { intl . formatMessage ( messages . header ) }
/ >
) ;
if ( ! isDefaultHeader ( group . header ) ) {
header = (
< a href = { group . header } onClick = { handleHeaderClick } target = '_blank' >
{ header }
< / a >
) ;
}
}
return header ;
} ;
2022-12-14 08:41:16 -08:00
const makeActionButton = ( ) = > {
2022-12-16 12:33:17 -08:00
if ( ! group . relationship || ! group . relationship . member ) {
return (
< Button
theme = 'primary'
onClick = { onJoinGroup }
>
2022-12-16 15:33:07 -08:00
{ group . locked ? < FormattedMessage id = 'group.request_join' defaultMessage = 'Request to join group' / > : < FormattedMessage id = 'group.join' defaultMessage = 'Join group' / > }
2022-12-16 12:33:17 -08:00
< / Button >
) ;
}
2022-12-18 09:03:41 -08:00
if ( group . relationship . requested ) {
return (
< Button
theme = 'secondary'
onClick = { onLeaveGroup }
>
< FormattedMessage id = 'group.cancel_request' defaultMessage = 'Cancel request' / >
< / Button >
) ;
}
2022-12-14 08:41:16 -08:00
if ( group . relationship ? . role === 'admin' ) {
return (
< Button
2022-12-15 14:51:30 -08:00
theme = 'secondary'
2022-12-18 09:03:41 -08:00
to = { ` /groups/ ${ group . id } /manage ` }
2022-12-14 08:41:16 -08:00
>
2022-12-18 09:03:41 -08:00
< FormattedMessage id = 'group.manage' defaultMessage = 'Manage group' / >
2022-12-14 08:41:16 -08:00
< / Button >
) ;
}
2022-12-16 12:33:17 -08:00
return (
< Button
theme = 'secondary'
onClick = { onLeaveGroup }
>
2022-12-16 15:33:07 -08:00
< FormattedMessage id = 'group.leave' defaultMessage = 'Leave group' / >
2022-12-16 12:33:17 -08:00
< / Button >
) ;
2022-12-14 08:41:16 -08:00
} ;
const actionButton = makeActionButton ( ) ;
2022-12-12 14:36:56 -08:00
return (
< div className = '-mt-4 -mx-4' >
2022-12-15 14:51:30 -08:00
< div className = 'relative' >
< div className = 'relative flex flex-col justify-center h-32 w-full lg:h-[200px] md:rounded-t-xl bg-gray-200 dark:bg-gray-900/50 overflow-hidden isolate' >
2022-12-17 04:38:41 -08:00
{ renderHeader ( ) }
2022-12-15 14:51:30 -08:00
< / div >
< div className = 'absolute left-1/2 bottom-0 -translate-x-1/2 translate-y-1/2' >
< a href = { group . avatar } onClick = { handleAvatarClick } target = '_blank' >
< Avatar className = 'ring-[3px] ring-white dark:ring-primary-900' src = { group . avatar } size = { 72 } / >
< / a >
2022-12-12 14:36:56 -08:00
< / div >
< / div >
2022-12-15 14:51:30 -08:00
< Stack className = 'p-3 pt-12' alignItems = 'center' space = { 2 } >
< Text className = 'mb-1' size = 'xl' weight = 'bold' dangerouslySetInnerHTML = { { __html : group.display_name_html } } / >
< HStack className = 'text-gray-700 dark:text-gray-600' space = { 3 } wrap >
{ group . relationship ? . role === 'admin' ? (
< HStack space = { 1 } alignItems = 'center' >
< Icon className = 'h-4 w-4' src = { require ( '@tabler/icons/users.svg' ) } / >
2022-12-17 08:57:43 -08:00
< span > < FormattedMessage id = 'group.role.admin' defaultMessage = 'Admin' / > < / span >
2022-12-15 14:51:30 -08:00
< / HStack >
) : group . relationship ? . role === 'moderator' && (
< HStack space = { 1 } alignItems = 'center' >
< Icon className = 'h-4 w-4' src = { require ( '@tabler/icons/gavel.svg' ) } / >
2022-12-16 15:33:07 -08:00
< span > < FormattedMessage id = 'group.role.moderator' defaultMessage = 'Moderator' / > < / span >
2022-12-15 14:51:30 -08:00
< / HStack >
) }
{ group . locked ? (
< HStack space = { 1 } alignItems = 'center' >
< Icon className = 'h-4 w-4' src = { require ( '@tabler/icons/lock.svg' ) } / >
2022-12-16 15:33:07 -08:00
< span > < FormattedMessage id = 'group.privacy.locked' defaultMessage = 'Private' / > < / span >
2022-12-12 14:36:56 -08:00
< / HStack >
2022-12-15 14:51:30 -08:00
) : (
< HStack space = { 1 } alignItems = 'center' >
< Icon className = 'h-4 w-4' src = { require ( '@tabler/icons/world.svg' ) } / >
2022-12-16 15:33:07 -08:00
< span > < FormattedMessage id = 'group.privacy.public' defaultMessage = 'Public' / > < / span >
2022-12-15 14:51:30 -08:00
< / HStack >
) }
2022-12-12 14:36:56 -08:00
< / HStack >
2022-12-15 14:51:30 -08:00
< Text theme = 'muted' dangerouslySetInnerHTML = { { __html : group.note_emojified } } / >
{ actionButton }
< / Stack >
2022-12-12 14:36:56 -08:00
< / div >
) ;
} ;
export default GroupHeader ;