allow interaction only if account is member

This commit is contained in:
Pavel Prichodko 2022-10-09 17:47:34 -05:00
parent 79b09cf005
commit e958b1df01
No known key found for this signature in database
GPG Key ID: 8E4C82D464215E83
5 changed files with 44 additions and 21 deletions

View File

@ -9,7 +9,7 @@ export const useAccount = () => {
account, account,
createAccount: () => client.createAccount(), createAccount: () => client.createAccount(),
deleteAccount: () => client.deleteAccount(), deleteAccount: () => client.deleteAccount(),
isMember: account ? client.community.isMember(account.chatKey) : false, isMember: account?.membership === 'approved',
} as const } as const
} }

View File

@ -1,6 +1,7 @@
import React, { useEffect, useRef, useState } from 'react' import React, { useEffect, useRef, useState } from 'react'
import { useChatContext } from '../../../../contexts/chat-context' import { useChatContext } from '../../../../contexts/chat-context'
import { useAccount } from '../../../../protocol'
// import { EmojiIcon } from '../../../../icons/emoji-icon' // import { EmojiIcon } from '../../../../icons/emoji-icon'
// import { GifIcon } from '../../../../icons/gif-icon' // import { GifIcon } from '../../../../icons/gif-icon'
// import { ImageIcon } from '../../../../icons/image-icon' // import { ImageIcon } from '../../../../icons/image-icon'
@ -19,6 +20,8 @@ interface Props {
export const ChatInput = (props: Props) => { export const ChatInput = (props: Props) => {
const { value, editing, onSubmit } = props const { value, editing, onSubmit } = props
const { isMember } = useAccount()
const [inputValue, setInputValue] = useState(value ?? '') const [inputValue, setInputValue] = useState(value ?? '')
const { state, dispatch } = useChatContext() const { state, dispatch } = useChatContext()
@ -56,10 +59,15 @@ export const ChatInput = (props: Props) => {
<InputWrapper> <InputWrapper>
<Input <Input
ref={inputRef} ref={inputRef}
placeholder="Message" placeholder={
isMember
? 'Message'
: 'You need to join this community to send messages'
}
value={inputValue} value={inputValue}
onChange={handleChange} onChange={handleChange}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
disabled={!isMember}
/> />
{/* <Flex> {/* <Flex>
<IconButton label="Pick emoji"> <IconButton label="Pick emoji">
@ -109,4 +117,13 @@ const Input = styled('input', {
background: 'none', background: 'none',
alignItems: 'center', alignItems: 'center',
width: '100%', width: '100%',
fontSize: '15px',
'&:disabled': {
cursor: 'not-allowed',
},
'&::placeholder': {
color: '$accent-5',
},
}) })

View File

@ -6,7 +6,7 @@ import { useMatch } from 'react-router-dom'
import { useChatContext } from '../../../../contexts/chat-context' import { useChatContext } from '../../../../contexts/chat-context'
// import { BellIcon } from '../../../../icons/bell-icon' // import { BellIcon } from '../../../../icons/bell-icon'
// import { PinIcon } from '../../../../icons/pin-icon' // import { PinIcon } from '../../../../icons/pin-icon'
import { useProtocol } from '../../../../protocol' import { useAccount, useProtocol } from '../../../../protocol'
import { keyframes, styled } from '../../../../styles/config' import { keyframes, styled } from '../../../../styles/config'
import { import {
Avatar, Avatar,
@ -60,6 +60,7 @@ export const ChatMessage = (props: Props) => {
const { message, collapse, highlight } = props const { message, collapse, highlight } = props
const { client, account } = useProtocol() const { client, account } = useProtocol()
const { isMember } = useAccount()
const { params } = useMatch(':id')! const { params } = useMatch(':id')!
const chatId = params.id! const chatId = params.id!
@ -237,7 +238,7 @@ export const ChatMessage = (props: Props) => {
{response && <MessageReply message={response} />} {response && <MessageReply message={response} />}
{renderMessage()} {renderMessage()}
{account && ( {isMember && (
<Actions <Actions
owner={owner} owner={owner}
pinned={pinned} pinned={pinned}
@ -268,8 +269,8 @@ const backgroundAnimation = keyframes({
// TODO: Use compound variants https://stitches.dev/docs/variants#compound-variants // TODO: Use compound variants https://stitches.dev/docs/variants#compound-variants
const Wrapper = styled('div', { const Wrapper = styled('div', {
position: 'relative', position: 'relative',
padding: '2px 16px', padding: '8px 16px',
marginTop: 14, marginTop: 2,
gap: '$2', gap: '$2',
transitionProperty: 'background-color, border-color, color, fill, stroke', transitionProperty: 'background-color, border-color, color, fill, stroke',

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react' import React, { useMemo, useState } from 'react'
import { import {
emojis, emojis,
@ -19,9 +19,13 @@ interface Props {
export const MessageReactions = (props: Props) => { export const MessageReactions = (props: Props) => {
const { reactions, onClick } = props const { reactions, onClick } = props
const { isMember } = useAccount()
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const hasReaction = Object.values(reactions).some(value => value.size > 0) const hasReaction = useMemo(() => {
return Object.values(reactions).some(value => value.size > 0)
}, [reactions])
if (hasReaction === false) { if (hasReaction === false) {
return null return null
@ -43,16 +47,18 @@ export const MessageReactions = (props: Props) => {
/> />
))} ))}
<ReactionPopover {isMember && (
open={open} <ReactionPopover
onOpenChange={setOpen} open={open}
reactions={reactions} onOpenChange={setOpen}
onClick={handlePopoverClick} reactions={reactions}
> onClick={handlePopoverClick}
<AddReactionButton aria-label="Add Reaction"> >
<ReactionIcon width={16} height={16} /> <AddReactionButton aria-label="Add Reaction">
</AddReactionButton> <ReactionIcon width={16} height={16} />
</ReactionPopover> </AddReactionButton>
</ReactionPopover>
)}
</Flex> </Flex>
) )
} }

View File

@ -6,7 +6,7 @@ import { useLocation, useMatch } from 'react-router-dom'
import { MemberSidebar } from '../../components/member-sidebar' import { MemberSidebar } from '../../components/member-sidebar'
import { useAppState } from '../../contexts/app-context' import { useAppState } from '../../contexts/app-context'
import { ChatProvider, useChatContext } from '../../contexts/chat-context' import { ChatProvider, useChatContext } from '../../contexts/chat-context'
import { useAccount, useChat, useMessages, useProtocol } from '../../protocol' import { useChat, useMessages, useProtocol } from '../../protocol'
import { styled } from '../../styles/config' import { styled } from '../../styles/config'
import { Avatar, Flex, Heading, Text } from '../../system' import { Avatar, Flex, Heading, Text } from '../../system'
import { ChatInput } from './components/chat-input' import { ChatInput } from './components/chat-input'
@ -44,7 +44,6 @@ const ChatStart = (props: ChatStartProps) => {
const Body = () => { const Body = () => {
const { client } = useProtocol() const { client } = useProtocol()
const { state } = useChatContext() const { state } = useChatContext()
const { account } = useAccount()
const { params } = useMatch(':id')! // eslint-disable-line @typescript-eslint/no-non-null-assertion const { params } = useMatch(':id')! // eslint-disable-line @typescript-eslint/no-non-null-assertion
const chatId = params.id! const chatId = params.id!
@ -125,7 +124,7 @@ const Body = () => {
return ( return (
<> <>
<ContentWrapper ref={contentRef}>{renderContent()}</ContentWrapper> <ContentWrapper ref={contentRef}>{renderContent()}</ContentWrapper>
{account && <ChatInput onSubmit={handleMessageSubmit} />} <ChatInput onSubmit={handleMessageSubmit} />
</> </>
) )
} }