Skip to content

Commit

Permalink
feat: add custom dialog (#230)
Browse files Browse the repository at this point in the history
* feat: add confirmation dialog (#209)

* chore: add dialog component

* chore: update logout and chat close dialog popup

* fix mobile view

* update dialog component to be more reliable

* update dialog usage
  • Loading branch information
Dun-sin authored Oct 26, 2022
1 parent a0ac990 commit 45107de
Show file tree
Hide file tree
Showing 9 changed files with 452 additions and 303 deletions.
1 change: 1 addition & 0 deletions client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<div id="portal"></div>
<script type="module" src="/src/index.jsx"></script>
<!--
This HTML file is a template.
Expand Down
257 changes: 132 additions & 125 deletions client/src/components/Anonymous.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,154 +13,161 @@ import { BiArrowBack, BiDotsVerticalRounded } from 'react-icons/bi';
import { SocketContext } from 'src/context/Context';
import { useChat } from 'src/context/ChatContext';
import { useApp } from 'src/context/AppContext';
import { useDialog } from 'src/context/DialogContext';

// Components
import Chat from 'components/Chat';
import { createClassesFromArray } from 'src/lib/utils';


const centerItems = `flex items-center justify-center`;

const Anonymous = ({ onChatClosed }) => {
const { app, endSearch } = useApp();
const { currentChatId } = app;
const currentChatIdRef = useRef(currentChatId);
const [isTyping, setIsTyping] = useState(false);
const [autoSearchAfterClose, setAutoSearchAfterClose] = useState(false);
const autoSearchRef = useRef();
autoSearchRef.current = autoSearchAfterClose;

const navigate = useNavigate();
const socket = useContext(SocketContext);
const { closeChat } = useChat();

socket.on('display', ({ isTyping, chatId }) => {
// eslint-disable-next-line curly
if (chatId !== currentChatId) return;
isTyping ? setIsTyping(true) : setIsTyping(false);
});

const handleClose = (autoSearch = false) => {
if (!confirm('Are you sure you want to close this chat?')) {
return;
const { app, endSearch } = useApp();
const { currentChatId } = app;
const currentChatIdRef = useRef(currentChatId);
const [isTyping, setIsTyping] = useState(false);
const [autoSearchAfterClose, setAutoSearchAfterClose] = useState(false);
const autoSearchRef = useRef();
autoSearchRef.current = autoSearchAfterClose;

const navigate = useNavigate();
const socket = useContext(SocketContext);
const { closeChat } = useChat();
const { setDialog } = useDialog();

socket.on('display', ({ isTyping, chatId }) => {
// eslint-disable-next-line curly
if (chatId !== currentChatId) return;
isTyping ? setIsTyping(true) : setIsTyping(false);
});

const closeChatHandler = (autoSearch = false) => {
const currentChatId = currentChatIdRef.current;

if (!currentChatId) {
navigate('/');
return;
}

setAutoSearchAfterClose(autoSearch);

socket
.timeout(30000)
.emit('close', currentChatId, (err, chatClosed) => {
if (err) {
alert('An error occured whiles closing chat.');
console.log(err);

setAutoSearchAfterClose(false);
return;
}

const currentChatId = currentChatIdRef.current;

if (!currentChatId) {
navigate('/');
return;
if (chatClosed) {
closeChat(currentChatId);
}

setAutoSearchAfterClose(autoSearch);
endSearch()

socket
.timeout(30000)
.emit('close', currentChatId, (err, chatClosed) => {
if (err) {
alert('An error occured whiles closing chat.');
console.log(err);
if (chatClosed && autoSearchRef.current) {
if (onChatClosed) {
onChatClosed();
}

setAutoSearchAfterClose(false);
return;
}

if (chatClosed) {
closeChat(currentChatId);
}

endSearch()
setAutoSearchAfterClose(false);
} else {
navigate('/');
}
});
};

if (chatClosed && autoSearchRef.current) {
if (onChatClosed) {
onChatClosed();
}
const MenuToggle = (props, ref) => {
return (
<IconButton
{...props}
ref={ref}
icon={<Icon as={BiDotsVerticalRounded} />}
appearance="subtle"
circle
/>
);
};

setAutoSearchAfterClose(false);
} else {
navigate('/');
}
});
};
const handleClose = (autoSearch = false) => {
setDialog({
isOpen: true,
text: 'Are you sure you want to close this chat?',
handler: () => closeChatHandler(autoSearch),
});

const MenuToggle = (props, ref) => {
return (
}
return (
<div
className={createClassesFromArray([
centerItems,
'bg-primary',
'md:min-w-[calc(100%-108px)]',
'min-w-full',
'flex-col',
'h-screen',
'text-white',
])}
>
<div className="flex items-center justify-between border-b-[2px] px-5 border-secondary h-[100px] w-[100%]">
<div className="md:hidden">
<Whisper
placement="auto"
controlId="control-id-hover"
trigger="hover"
speaker={<Tooltip>Home</Tooltip>}
>
<IconButton
{...props}
ref={ref}
icon={<Icon as={BiDotsVerticalRounded} />}
appearance="subtle"
circle
onClick={() => navigate('/')}
appearance="subtle"
className="bg-primary "
icon={<Icon as={BiArrowBack} />}
circle
/>
);
};
</Whisper>
</div>
<div>
<h2 className="text-[1em] font-semibold">Anonymous User</h2>
{isTyping && <p className="mt-[-15px]">Typing</p>}
</div>

return (
<div
className={createClassesFromArray([
centerItems,
'bg-primary',
'md:min-w-[calc(100%-108px)]',
'min-w-full',
'flex-col',
'h-screen',
'text-white',
])}
<Dropdown
placement="leftStart"
style={{ zIndex: 3 }}
renderToggle={MenuToggle}
noCaret
>
<div className="flex items-center justify-between border-b-[2px] px-5 border-secondary h-[100px] w-[100%]">
<div className="md:hidden">
<Whisper
placement="auto"
controlId="control-id-hover"
trigger="hover"
speaker={<Tooltip>Home</Tooltip>}
>
<IconButton
onClick={() => navigate('/')}
appearance="subtle"
className="bg-primary "
icon={<Icon as={BiArrowBack} />}
circle
/>
</Whisper>
</div>
<div>
<h2 className="text-[1em] font-semibold">Anonymous User</h2>
{isTyping && <p className="mt-[-15px]">Typing</p>}
</div>

<Dropdown
placement="leftStart"
style={{ zIndex: 3 }}
renderToggle={MenuToggle}
noCaret
>
<Dropdown.Item onClick={() => handleClose()}>
Close Chat
</Dropdown.Item>

{/* TODO: Use a checkbox in modal dialog instead */}
<Dropdown.Item onClick={() => handleClose(true)}>
Find a new buddy
</Dropdown.Item>
</Dropdown>
</div>
<div
className={createClassesFromArray([
centerItems,
'flex-col',
'w-[90%]',
'h-[calc(100%-100px)]',
'mt-auto',
])}
>
<Chat />
</div>
</div>
);
<Dropdown.Item onClick={() => handleClose()}>
Close Chat
</Dropdown.Item>

{/* TODO: Use a checkbox in modal dialog instead */}
<Dropdown.Item onClick={() => handleClose(true)}>
Find a new buddy
</Dropdown.Item>
</Dropdown>
</div>
<div
className={createClassesFromArray([
centerItems,
'flex-col',
'w-[90%]',
'h-[calc(100%-100px)]',
'mt-auto',
])}
>
<Chat />
</div>
</div>
);
};

export default Anonymous;

Anonymous.propTypes = {
onChatClosed: PropTypes.func,
};
onChatClosed: PropTypes.func,
};
Loading

1 comment on commit 45107de

@vercel
Copy link

@vercel vercel bot commented on 45107de Oct 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.