import type EventEmitter from 'events'; import { AcceptedUploadFileType } from '@growi/core'; import type { ColorScheme, IUserHasId } from '@growi/core'; import { useSWRStatic } from '@growi/core/dist/swr'; import type { SWRResponse } from 'swr'; import useSWR from 'swr'; import useSWRImmutable from 'swr/immutable'; import type { SupportedActionType } from '~/interfaces/activity'; import type { RendererConfig } from '~/interfaces/services/renderer'; import { useContextSWR } from './use-context-swr'; declare global { // eslint-disable-next-line vars-on-top, no-var var globalEmitter: EventEmitter; } type Nullable = T | null; export const useCsrfToken = (initialData?: string): SWRResponse => { return useContextSWR('csrfToken', initialData); }; export const useAppTitle = (initialData?: string): SWRResponse => { return useContextSWR('appTitle', initialData); }; export const useSiteUrl = (initialData?: string): SWRResponse => { return useContextSWR('siteUrl', initialData); }; export const useConfidential = (initialData?: string): SWRResponse => { return useContextSWR('confidential', initialData); }; export const useCurrentUser = (initialData?: Nullable): SWRResponse, Error> => { return useContextSWR('currentUser', initialData); }; export const useCurrentPathname = (initialData?: string): SWRResponse => { return useContextSWR('currentPathname', initialData); }; export const useIsIdenticalPath = (initialData?: boolean): SWRResponse => { return useContextSWR('isIdenticalPath', initialData, { fallbackData: false }); }; export const useIsForbidden = (initialData?: boolean): SWRResponse => { return useContextSWR('isForbidden', initialData, { fallbackData: false }); }; export const useIsNotCreatable = (initialData?: boolean): SWRResponse => { return useContextSWR('isNotCreatable', initialData, { fallbackData: false }); }; export const useIsSharedUser = (initialData?: boolean): SWRResponse => { return useContextSWR('isSharedUser', initialData); }; export const useShareLinkId = (initialData?: string): SWRResponse => { return useContextSWR('shareLinkId', initialData); }; export const useDisableLinkSharing = (initialData?: Nullable): SWRResponse, Error> => { return useContextSWR, Error>('disableLinkSharing', initialData); }; export const useRegistrationWhitelist = (initialData?: Nullable): SWRResponse, Error> => { return useContextSWR, Error>('registrationWhitelist', initialData); }; export const useIsSearchPage = (initialData?: Nullable) : SWRResponse, Error> => { return useContextSWR, Error>('isSearchPage', initialData); }; export const useIsAclEnabled = (initialData?: boolean) : SWRResponse => { return useContextSWR('isAclEnabled', initialData); }; export const useIsSearchServiceConfigured = (initialData?: boolean) : SWRResponse => { return useContextSWR('isSearchServiceConfigured', initialData); }; export const useIsSearchServiceReachable = (initialData?: boolean) : SWRResponse => { return useContextSWR('isSearchServiceReachable', initialData); }; export const useElasticsearchMaxBodyLengthToIndex = (initialData?: number) : SWRResponse => { return useContextSWR('elasticsearchMaxBodyLengthToIndex', initialData); }; export const useIsMailerSetup = (initialData?: boolean): SWRResponse => { return useContextSWR('isMailerSetup', initialData); }; export const useIsSearchScopeChildrenAsDefault = (initialData?: boolean) : SWRResponse => { return useContextSWR('isSearchScopeChildrenAsDefault', initialData, { fallbackData: false }); }; export const useShowPageSideAuthors = (initialData?: boolean): SWRResponse => { return useContextSWR('showPageSideAuthors', initialData, { fallbackData: false }); }; export const useIsEnabledMarp = (initialData?: boolean) : SWRResponse => { return useContextSWR('isEnabledMarp', initialData, { fallbackData: false }); }; export const useIsSlackConfigured = (initialData?: boolean) : SWRResponse => { return useContextSWR('isSlackConfigured', initialData); }; export const useIsEnabledAttachTitleHeader = (initialData?: boolean) : SWRResponse => { return useContextSWR('isEnabledAttachTitleHeader', initialData); }; export const useIsIndentSizeForced = (initialData?: boolean) : SWRResponse => { return useContextSWR('isIndentSizeForced', initialData, { fallbackData: false }); }; export const useDefaultIndentSize = (initialData?: number) : SWRResponse => { return useContextSWR('defaultIndentSize', initialData, { fallbackData: 4 }); }; export const useAuditLogEnabled = (initialData?: boolean): SWRResponse => { return useContextSWR('auditLogEnabled', initialData, { fallbackData: false }); }; export const useActivityExpirationSeconds = (initialData?: number) : SWRResponse => { return useContextSWR('activityExpirationSeconds', initialData); }; export const useAuditLogAvailableActions = (initialData?: Array) : SWRResponse, Error> => { return useContextSWR, Error>('auditLogAvailableActions', initialData); }; export const useGrowiVersion = (initialData?: string): SWRResponse => { return useContextSWR('growiVersion', initialData); }; export const useIsEnabledStaleNotification = (initialData?: boolean): SWRResponse => { return useContextSWR('isEnabledStaleNotification', initialData); }; export const useRendererConfig = (initialData?: RendererConfig): SWRResponse => { return useContextSWR('growiRendererConfig', initialData); }; export const useIsAllReplyShown = (initialData?: boolean): SWRResponse => { return useContextSWR('isAllReplyShown', initialData); }; export const useIsBlinkedHeaderAtBoot = (initialData?: boolean): SWRResponse => { return useContextSWR('isBlinkedAtBoot', initialData, { fallbackData: false }); }; export const useIsUploadEnabled = (initialData?: boolean): SWRResponse => { return useContextSWR('isUploadEnabled', initialData); }; export const useIsUploadAllFileAllowed = (initialData?: boolean): SWRResponse => { return useContextSWR('isUploadAllFileAllowed', initialData); }; export const useIsBulkExportPagesEnabled = (initialData?: boolean): SWRResponse => { return useContextSWR('isBulkExportPagesEnabled', initialData); }; export const useIsPdfBulkExportEnabled = (initialData?: boolean): SWRResponse => { return useContextSWR('isPdfBulkExportEnabled', initialData); }; export const useShowPageLimitationL = (initialData?: number): SWRResponse => { return useContextSWR('showPageLimitationL', initialData); }; export const useShowPageLimitationXL = (initialData?: number): SWRResponse => { return useContextSWR('showPageLimitationXL', initialData); }; export const useCustomizeTitle = (initialData?: string): SWRResponse => { return useContextSWR('CustomizeTitle', initialData); }; export const useIsDefaultLogo = (initialData?: boolean): SWRResponse => { return useContextSWR('isDefaultLogo', initialData); }; export const useIsCustomizedLogoUploaded = (initialData?: boolean): SWRResponse => { return useSWRStatic('isCustomizedLogoUploaded', initialData); }; export const useForcedColorScheme = (initialData?: ColorScheme): SWRResponse => { return useContextSWR('forcedColorScheme', initialData); }; export const useGrowiCloudUri = (initialData?: string): SWRResponse => { return useContextSWR('growiCloudUri', initialData); }; export const useGrowiAppIdForGrowiCloud = (initialData?: number): SWRResponse => { return useContextSWR('growiAppIdForGrowiCloud', initialData); }; export const useIsContainerFluid = (initialData?: boolean): SWRResponse => { return useContextSWR('isContainerFluid', initialData); }; export const useIsLocalAccountRegistrationEnabled = (initialData?: boolean): SWRResponse => { return useContextSWR('isLocalAccountRegistrationEnabled', initialData); }; export const useIsRomUserAllowedToComment = (initialData?: boolean): SWRResponse => { return useContextSWR('isRomUserAllowedToComment', initialData); }; export const useIsAiEnabled = (initialData?: boolean): SWRResponse => { return useContextSWR('isAiEnabled', initialData); }; export const useLimitLearnablePageCountPerAssistant = (initialData?: number): SWRResponse => { return useContextSWR('limitLearnablePageCountPerAssistant', initialData); }; export const useIsUsersHomepageDeletionEnabled = (initialData?: boolean): SWRResponse => { return useContextSWR('isUsersHomepageDeletionEnabled', initialData); export const useIsEnableUnifiedMergeView = (initialData?: boolean): SWRResponse => { return useSWRStatic('isEnableUnifiedMergeView', initialData, { fallbackData: false }); }; /** ********************************************************** * Computed contexts *********************************************************** */ export const useIsGuestUser = (): SWRResponse => { const { data: currentUser, isLoading } = useCurrentUser(); return useSWRImmutable( isLoading ? null : ['isGuestUser', currentUser?._id], ([, currentUserId]) => currentUserId == null, { fallbackData: currentUser?._id == null }, ); }; export const useIsReadOnlyUser = (): SWRResponse => { const { data: currentUser, isLoading: isCurrentUserLoading } = useCurrentUser(); const { data: isGuestUser, isLoading: isGuestUserLoding } = useIsGuestUser(); const isLoading = isCurrentUserLoading || isGuestUserLoding; const isReadOnlyUser = !isGuestUser && !!currentUser?.readOnly; return useSWRImmutable( isLoading ? null : ['isReadOnlyUser', isReadOnlyUser, currentUser?._id], () => isReadOnlyUser, { fallbackData: isReadOnlyUser }, ); }; export const useIsAdmin = (): SWRResponse => { const { data: currentUser, isLoading } = useCurrentUser(); return useSWR( isLoading ? null : ['isAdminUser', currentUser?._id, currentUser?.admin], ([, , isAdmin]) => isAdmin ?? false, { fallbackData: currentUser?.admin ?? false, keepPreviousData: true, // disable all revalidation but revalidateIfStale revalidateOnMount: false, revalidateOnFocus: false, revalidateOnReconnect: false, }, ); }; export const useIsEditable = (): SWRResponse => { const { data: isGuestUser } = useIsGuestUser(); const { data: isReadOnlyUser } = useIsReadOnlyUser(); const { data: isForbidden } = useIsForbidden(); const { data: isNotCreatable } = useIsNotCreatable(); const { data: isIdenticalPath } = useIsIdenticalPath(); return useSWRImmutable( ['isEditable', isGuestUser, isReadOnlyUser, isForbidden, isNotCreatable, isIdenticalPath], ([, isGuestUser, isReadOnlyUser, isForbidden, isNotCreatable, isIdenticalPath]) => { return (!isForbidden && !isIdenticalPath && !isNotCreatable && !isGuestUser && !isReadOnlyUser); }, ); }; export const useAcceptedUploadFileType = (): SWRResponse => { const { data: isUploadEnabled } = useIsUploadEnabled(); const { data: isUploadAllFileAllowed } = useIsUploadAllFileAllowed(); return useSWRImmutable( ['acceptedUploadFileType', isUploadEnabled, isUploadAllFileAllowed], ([, isUploadEnabled, isUploadAllFileAllowed]) => { if (!isUploadEnabled) { return AcceptedUploadFileType.NONE; } if (isUploadAllFileAllowed) { return AcceptedUploadFileType.ALL; } return AcceptedUploadFileType.IMAGE; }, ); }; // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export const useGrowiDocumentationUrl = () => { const { data: growiCloudUri } = useGrowiCloudUri(); return useSWR( ['documentationUrl', growiCloudUri], ([, growiCloudUri]) => { const url = growiCloudUri != null ? new URL('/help', growiCloudUri) : new URL('https://docs.growi.org'); return url.toString(); }, { fallbackData: 'https://docs.growi.org', revalidateOnFocus: false, revalidateOnReconnect: false, }, ); };