import React, { useState, useEffect, FC, useCallback, } from 'react'; import { useTranslation } from 'react-i18next'; import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem, } from 'reactstrap'; import SocketIoContainer from '~/client/services/SocketIoContainer'; import { toastError } from '~/client/util/apiNotification'; import { apiv3Post } from '~/client/util/apiv3-client'; import { useSWRxInAppNotifications, useSWRxInAppNotificationStatus } from '~/stores/in-app-notification'; import loggerFactory from '~/utils/logger'; import { withUnstatedContainers } from '../UnstatedUtils'; import InAppNotificationList from './InAppNotificationList'; const logger = loggerFactory('growi:InAppNotificationDropdown'); type Props = { socketIoContainer: SocketIoContainer, }; const InAppNotificationDropdown: FC = (props: Props) => { const { t } = useTranslation(); const [isOpen, setIsOpen] = useState(false); const limit = 6; const { data: inAppNotificationData, mutate: mutateInAppNotificationData } = useSWRxInAppNotifications(limit); const { data: inAppNotificationUnreadStatusCount, mutate: mutateInAppNotificationUnreadStatusCount } = useSWRxInAppNotificationStatus(); const initializeSocket = useCallback((props) => { const socket = props.socketIoContainer.getSocket(); socket.on('notificationUpdated', () => { mutateInAppNotificationUnreadStatusCount(); }); }, [mutateInAppNotificationUnreadStatusCount]); const updateNotificationStatus = async() => { try { await apiv3Post('/in-app-notification/read'); } catch (err) { toastError(err); logger.error(err); } }; useEffect(() => { initializeSocket(props); }, [initializeSocket, props]); const toggleDropdownHandler = async() => { if (!isOpen && inAppNotificationUnreadStatusCount != null && inAppNotificationUnreadStatusCount > 0) { await updateNotificationStatus(); mutateInAppNotificationUnreadStatusCount(); } const newIsOpenState = !isOpen; if (newIsOpenState) { mutateInAppNotificationData(); } setIsOpen(newIsOpenState); }; let badge; if (inAppNotificationUnreadStatusCount != null && inAppNotificationUnreadStatusCount > 0) { badge = {inAppNotificationUnreadStatusCount}; } else { badge = ''; } return ( {badge} { inAppNotificationData != null && inAppNotificationData.docs.length === 0 // no items ? {t('in_app_notification.mark_all_as_read')} // render DropdownItem : } { t('in_app_notification.see_all') } ); }; /** * Wrapper component for using unstated */ const InAppNotificationDropdownWrapper = withUnstatedContainers(InAppNotificationDropdown, [SocketIoContainer]); export default InAppNotificationDropdownWrapper;