move GuildSubscriptions to just function exports

This commit is contained in:
Michael Peters 2021-12-30 21:33:15 -06:00
parent 6fe1016047
commit 1e437c33ae
11 changed files with 653 additions and 643 deletions

View File

@ -13,8 +13,8 @@ import { Duration } from 'moment';
import moment from 'moment'; import moment from 'moment';
import DropdownInput from '../components/input-dropdown'; import DropdownInput from '../components/input-dropdown';
import Button, { ButtonColorType } from '../components/button'; import Button, { ButtonColorType } from '../components/button';
import GuildSubscriptions from '../require/guild-subscriptions';
import BaseElements from '../require/base-elements'; import BaseElements from '../require/base-elements';
import { useTokensSubscription, useGuildMetadataSubscription, useSoftImageSrcResourceSubscription } from '../require/guild-subscriptions';
export interface GuildInvitesDisplayProps { export interface GuildInvitesDisplayProps {
@ -25,14 +25,14 @@ const GuildInvitesDisplay: FC<GuildInvitesDisplayProps> = (props: GuildInvitesDi
const url = 'https://localhost:3030'; // TODO: this will likely be a dropdown list at some point const url = 'https://localhost:3030'; // TODO: this will likely be a dropdown list at some point
const [ fetchRetryCallable, tokens, tokensError ] = GuildSubscriptions.useTokensSubscription(guild); const [ fetchRetryCallable, tokens, tokensError ] = useTokensSubscription(guild);
const [ guildMeta, guildMetaError ] = GuildSubscriptions.useGuildMetadataSubscription(guild); const [ guildMeta, guildMetaError ] = useGuildMetadataSubscription(guild);
const [ expiresFromNow, setExpiresFromNow ] = useState<Duration | null>(moment.duration(1, 'day')); const [ expiresFromNow, setExpiresFromNow ] = useState<Duration | null>(moment.duration(1, 'day'));
const [ expiresFromNowText, setExpiresFromNowText ] = useState<string>('1 day'); const [ expiresFromNowText, setExpiresFromNowText ] = useState<string>('1 day');
const [ iconSrc ] = GuildSubscriptions.useSoftImageSrcResourceSubscription(guild, guildMeta?.iconResourceId ?? null); const [ iconSrc ] = useSoftImageSrcResourceSubscription(guild, guildMeta?.iconResourceId ?? null);
useEffect(() => { useEffect(() => {
if (expiresFromNowText === 'never') { if (expiresFromNowText === 'never') {

View File

@ -10,7 +10,7 @@ import CombinedGuild from '../../guild-combined';
import Display from '../components/display'; import Display from '../components/display';
import TextInput from '../components/input-text'; import TextInput from '../components/input-text';
import ImageEditInput from '../components/input-image-edit'; import ImageEditInput from '../components/input-image-edit';
import GuildSubscriptions from '../require/guild-subscriptions'; import { useGuildMetadataSubscription, useResourceSubscription } from '../require/guild-subscriptions';
export interface GuildOverviewDisplayProps { export interface GuildOverviewDisplayProps {
guild: CombinedGuild; guild: CombinedGuild;
@ -18,8 +18,8 @@ export interface GuildOverviewDisplayProps {
const GuildOverviewDisplay: FC<GuildOverviewDisplayProps> = (props: GuildOverviewDisplayProps) => { const GuildOverviewDisplay: FC<GuildOverviewDisplayProps> = (props: GuildOverviewDisplayProps) => {
const { guild } = props; const { guild } = props;
const [ guildMeta, guildMetaError ] = GuildSubscriptions.useGuildMetadataSubscription(guild); const [ guildMeta, guildMetaError ] = useGuildMetadataSubscription(guild);
const [ iconResource, iconResourceError ] = GuildSubscriptions.useResourceSubscription(guild, guildMeta?.iconResourceId ?? null); const [ iconResource, iconResourceError ] = useResourceSubscription(guild, guildMeta?.iconResourceId ?? null);
const [ savedName, setSavedName ] = useState<string | null>(null); const [ savedName, setSavedName ] = useState<string | null>(null);
const [ savedIconBuff, setSavedIconBuff ] = useState<Buffer | null>(null); const [ savedIconBuff, setSavedIconBuff ] = useState<Buffer | null>(null);

View File

@ -5,7 +5,7 @@ import ContextMenu from '../../contexts/components/context-menu';
import BasicHover, { BasicHoverSide } from '../../contexts/context-hover-basic'; import BasicHover, { BasicHoverSide } from '../../contexts/context-hover-basic';
import BaseElements from '../../require/base-elements'; import BaseElements from '../../require/base-elements';
import { IAlignment } from '../../require/elements-util'; import { IAlignment } from '../../require/elements-util';
import GuildSubscriptions from '../../require/guild-subscriptions'; import { useGuildMetadataSubscription, useSelfMemberSubscription, useSoftImageSrcResourceSubscription } from '../../require/guild-subscriptions';
import { useContextClickContextMenu, useContextHover } from '../../require/react-helper'; import { useContextClickContextMenu, useContextHover } from '../../require/react-helper';
export interface GuildListElementProps { export interface GuildListElementProps {
@ -22,9 +22,9 @@ const GuildListElement: FC<GuildListElementProps> = (props: GuildListElementProp
// TODO: state higher up // TODO: state higher up
// TODO: handle metadata error // TODO: handle metadata error
const [ guildMeta, guildMetaError ] = GuildSubscriptions.useGuildMetadataSubscription(guild); const [ guildMeta, guildMetaError ] = useGuildMetadataSubscription(guild);
const [ selfMember ] = GuildSubscriptions.useSelfMemberSubscription(guild); const [ selfMember ] = useSelfMemberSubscription(guild);
const [ iconSrc ] = GuildSubscriptions.useSoftImageSrcResourceSubscription(guild, guildMeta?.iconResourceId ?? null); const [ iconSrc ] = useSoftImageSrcResourceSubscription(guild, guildMeta?.iconResourceId ?? null);
const [ contextHover, mouseEnterCallable, mouseLeaveCallable ] = useContextHover(() => { const [ contextHover, mouseEnterCallable, mouseLeaveCallable ] = useContextHover(() => {
if (!guildMeta) return null; if (!guildMeta) return null;

View File

@ -1,7 +1,7 @@
import React, { FC, useMemo } from 'react'; import React, { FC, useMemo } from 'react';
import { Member } from '../../../data-types'; import { Member } from '../../../data-types';
import CombinedGuild from '../../../guild-combined'; import CombinedGuild from '../../../guild-combined';
import GuildSubscriptions from '../../require/guild-subscriptions'; import { useSoftImageSrcResourceSubscription } from '../../require/guild-subscriptions';
export interface DummyMember { export interface DummyMember {
id: 'dummy'; id: 'dummy';
@ -19,7 +19,7 @@ export interface MemberProps {
const MemberElement: FC<MemberProps> = (props: MemberProps) => { const MemberElement: FC<MemberProps> = (props: MemberProps) => {
const { guild, member } = props; const { guild, member } = props;
const [ avatarSrc ] = GuildSubscriptions.useSoftImageSrcResourceSubscription(guild, member.avatarResourceId); const [ avatarSrc ] = useSoftImageSrcResourceSubscription(guild, member.avatarResourceId);
const nameStyle = useMemo(() => member.roleColor ? { color: member.roleColor } : {}, [ member.roleColor ]); const nameStyle = useMemo(() => member.roleColor ? { color: member.roleColor } : {}, [ member.roleColor ]);

View File

@ -5,7 +5,7 @@ import CombinedGuild from '../../../guild-combined';
import ImageContextMenu from '../../contexts/context-menu-image'; import ImageContextMenu from '../../contexts/context-menu-image';
import ImageOverlay from '../../overlays/overlay-image'; import ImageOverlay from '../../overlays/overlay-image';
import ElementsUtil, { IAlignment } from '../../require/elements-util'; import ElementsUtil, { IAlignment } from '../../require/elements-util';
import GuildSubscriptions from '../../require/guild-subscriptions'; import { useSoftImageSrcResourceSubscription } from '../../require/guild-subscriptions';
import { useContextClickContextMenu, useDownloadButton, useOneTimeAsyncAction } from '../../require/react-helper'; import { useContextClickContextMenu, useDownloadButton, useOneTimeAsyncAction } from '../../require/react-helper';
interface ResourceElementProps { interface ResourceElementProps {
@ -53,7 +53,7 @@ const PreviewImageElement: FC<PreviewImageElementProps> = (props: PreviewImageEl
const { guild, previewWidth, previewHeight, resourcePreviewId, resourceId, resourceName, setOverlay } = props; const { guild, previewWidth, previewHeight, resourcePreviewId, resourceId, resourceName, setOverlay } = props;
// TODO: Handle resourceError // TODO: Handle resourceError
const [ previewImgSrc, previewResource, previewResourceError ] = GuildSubscriptions.useSoftImageSrcResourceSubscription(guild, resourcePreviewId); const [ previewImgSrc, previewResource, previewResourceError ] = useSoftImageSrcResourceSubscription(guild, resourcePreviewId);
const [ contextMenu, onContextMenu ] = useContextClickContextMenu((alignment: IAlignment, relativeToPos: { x: number, y: number }, close: () => void) => { const [ contextMenu, onContextMenu ] = useContextClickContextMenu((alignment: IAlignment, relativeToPos: { x: number, y: number }, close: () => void) => {
if (!previewResource) return null; if (!previewResource) return null;

View File

@ -7,8 +7,8 @@ import React, { Dispatch, FC, ReactNode, SetStateAction, useMemo } from 'react';
import { Channel, Message } from '../../data-types'; import { Channel, Message } from '../../data-types';
import CombinedGuild from '../../guild-combined'; import CombinedGuild from '../../guild-combined';
import MessageElement from './components/message-element'; import MessageElement from './components/message-element';
import GuildSubscriptions from '../require/guild-subscriptions';
import InfiniteScroll from '../components/infinite-scroll'; import InfiniteScroll from '../components/infinite-scroll';
import { useMessagesScrollingSubscription } from '../require/guild-subscriptions';
interface MessageListProps { interface MessageListProps {
guild: CombinedGuild; guild: CombinedGuild;
@ -29,7 +29,7 @@ const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
messagesFetchError, messagesFetchError,
messagesFetchAboveError, messagesFetchAboveError,
messagesFetchBelowError messagesFetchBelowError
] = GuildSubscriptions.useMessagesScrollingSubscription(guild, channel); ] = useMessagesScrollingSubscription(guild, channel);
const messageElements = useMemo(() => { const messageElements = useMemo(() => {
const result = []; const result = [];

View File

@ -8,9 +8,9 @@ import CombinedGuild from '../../guild-combined';
import ElementsUtil, { IAlignment } from '../require/elements-util'; import ElementsUtil, { IAlignment } from '../require/elements-util';
import DownloadButton from '../components/button-download'; import DownloadButton from '../components/button-download';
import { useContextClickContextMenu } from '../require/react-helper'; import { useContextClickContextMenu } from '../require/react-helper';
import GuildSubscriptions from '../require/guild-subscriptions';
import ImageContextMenu from '../contexts/context-menu-image'; import ImageContextMenu from '../contexts/context-menu-image';
import Overlay from '../components/overlay'; import Overlay from '../components/overlay';
import { useSoftImageSrcResourceSubscription } from '../require/guild-subscriptions';
export interface ImageOverlayProps { export interface ImageOverlayProps {
guild: CombinedGuild guild: CombinedGuild
@ -24,7 +24,7 @@ const ImageOverlay: FC<ImageOverlayProps> = (props: ImageOverlayProps) => {
const rootRef = useRef<HTMLDivElement>(null); const rootRef = useRef<HTMLDivElement>(null);
const [ imgSrc, resource, resourceError ] = GuildSubscriptions.useSoftImageSrcResourceSubscription(guild, resourceId); const [ imgSrc, resource, resourceError ] = useSoftImageSrcResourceSubscription(guild, resourceId);
const [ contextMenu, onContextMenu ] = useContextClickContextMenu((alignment: IAlignment, relativeToPos: { x: number, y: number }, close: () => void) => { const [ contextMenu, onContextMenu ] = useContextClickContextMenu((alignment: IAlignment, relativeToPos: { x: number, y: number }, close: () => void) => {
if (!resource) return null; if (!resource) return null;

View File

@ -10,10 +10,10 @@ import CombinedGuild from '../../guild-combined';
import ImageEditInput from '../components/input-image-edit'; import ImageEditInput from '../components/input-image-edit';
import TextInput from '../components/input-text'; import TextInput from '../components/input-text';
import SubmitOverlayLower from '../components/submit-overlay-lower'; import SubmitOverlayLower from '../components/submit-overlay-lower';
import GuildSubscriptions from '../require/guild-subscriptions';
import { useAsyncSubmitButton } from '../require/react-helper'; import { useAsyncSubmitButton } from '../require/react-helper';
import Button from '../components/button'; import Button from '../components/button';
import Overlay from '../components/overlay'; import Overlay from '../components/overlay';
import { useResourceSubscription } from '../require/guild-subscriptions';
export interface PersonalizeOverlayProps { export interface PersonalizeOverlayProps {
document: Document; document: Document;
@ -26,7 +26,7 @@ const PersonalizeOverlay: FC<PersonalizeOverlayProps> = (props: PersonalizeOverl
const rootRef = useRef<HTMLDivElement>(null); const rootRef = useRef<HTMLDivElement>(null);
const [ avatarResource, avatarResourceError ] = GuildSubscriptions.useResourceSubscription(guild, selfMember.avatarResourceId) const [ avatarResource, avatarResourceError ] = useResourceSubscription(guild, selfMember.avatarResourceId)
const displayNameInputRef = createRef<HTMLInputElement>(); const displayNameInputRef = createRef<HTMLInputElement>();

View File

@ -81,7 +81,7 @@ export default class ElementsUtil {
} }
} }
// Avoid this function. Use GuildSubscriptions.useSoftImgSrcResourceSubscription instead // Avoid this function. Use useSoftImgSrcResourceSubscription instead
static async getImageSrcFromResourceFailSoftly(guild: CombinedGuild, resourceId: string | null): Promise<string> { static async getImageSrcFromResourceFailSoftly(guild: CombinedGuild, resourceId: string | null): Promise<string> {
if (resourceId === null) { if (resourceId === null) {
return './img/loading.svg'; return './img/loading.svg';

View File

@ -70,10 +70,21 @@ interface MultipleEventMappingParams<
} }
export default class GuildSubscriptions { export default class GuildSubscriptions {
private static useGuildSubscriptionEffect<T>(
}
function useGuildSubscriptionEffect<T>(
subscriptionParams: EffectParams<T>, subscriptionParams: EffectParams<T>,
fetchFunc: (() => Promise<T>) | (() => Promise<T | null>) fetchFunc: (() => Promise<T>) | (() => Promise<T | null>)
): [ fetchRetryCallable: () => Promise<void> ] { ): [ fetchRetryCallable: () => Promise<void> ] {
const { guild, onFetch, onFetchError, bindEventsFunc, unbindEventsFunc } = subscriptionParams; const { guild, onFetch, onFetchError, bindEventsFunc, unbindEventsFunc } = subscriptionParams;
const isMounted = useIsMountedRef(); const isMounted = useIsMountedRef();
@ -107,13 +118,13 @@ export default class GuildSubscriptions {
}, [ fetchManagerFunc ]); }, [ fetchManagerFunc ]);
return [ fetchManagerFunc ]; return [ fetchManagerFunc ];
} }
private static useSingleGuildSubscription<T, UE extends keyof Connectable, CE extends keyof Conflictable>( function useSingleGuildSubscription<T, UE extends keyof Connectable, CE extends keyof Conflictable>(
guild: CombinedGuild, guild: CombinedGuild,
eventMappingParams: SingleEventMappingParams<T, UE, CE>, eventMappingParams: SingleEventMappingParams<T, UE, CE>,
fetchFunc: (() => Promise<T>) | (() => Promise<T | null>) fetchFunc: (() => Promise<T>) | (() => Promise<T | null>)
): [value: T | null, fetchError: unknown | null, events: EventEmitter<SingleSubscriptionEvents>] { ): [value: T | null, fetchError: unknown | null, events: EventEmitter<SingleSubscriptionEvents>] {
const { updatedEventName, updatedEventArgsMap, conflictEventName, conflictEventArgsMap } = eventMappingParams; const { updatedEventName, updatedEventArgsMap, conflictEventName, conflictEventArgsMap } = eventMappingParams;
const isMounted = useIsMountedRef(); const isMounted = useIsMountedRef();
@ -167,7 +178,7 @@ export default class GuildSubscriptions {
guild.off(conflictEventName, boundConflictFunc); guild.off(conflictEventName, boundConflictFunc);
}, []); }, []);
GuildSubscriptions.useGuildSubscriptionEffect({ useGuildSubscriptionEffect({
guild, guild,
onFetch, onFetch,
onFetchError, onFetchError,
@ -176,24 +187,24 @@ export default class GuildSubscriptions {
}, fetchFunc); }, fetchFunc);
return [ value, fetchError, events ]; return [ value, fetchError, events ];
} }
private static useMultipleGuildSubscription< function useMultipleGuildSubscription<
T extends { id: string }, T extends { id: string },
NE extends keyof Connectable, NE extends keyof Connectable,
UE extends keyof Connectable, UE extends keyof Connectable,
RE extends keyof Connectable, RE extends keyof Connectable,
CE extends keyof Conflictable CE extends keyof Conflictable
>( >(
guild: CombinedGuild, guild: CombinedGuild,
eventMappingParams: MultipleEventMappingParams<T, NE, UE, RE, CE>, eventMappingParams: MultipleEventMappingParams<T, NE, UE, RE, CE>,
fetchFunc: (() => Promise<T[]>) | (() => Promise<T[] | null>) fetchFunc: (() => Promise<T[]>) | (() => Promise<T[] | null>)
): [ ): [
fetchRetryCallable: () => Promise<void>, fetchRetryCallable: () => Promise<void>,
value: T[] | null, value: T[] | null,
fetchError: unknown | null, fetchError: unknown | null,
events: EventEmitter<MultipleSubscriptionEvents<T>> events: EventEmitter<MultipleSubscriptionEvents<T>>
] { ] {
const { const {
newEventName, newEventArgsMap, newEventName, newEventArgsMap,
updatedEventName, updatedEventArgsMap, updatedEventName, updatedEventArgsMap,
@ -290,7 +301,7 @@ export default class GuildSubscriptions {
guild.off(conflictEventName, boundConflictFunc); guild.off(conflictEventName, boundConflictFunc);
}, [ boundNewFunc, boundUpdateFunc, boundRemovedFunc, boundConflictFunc ]); }, [ boundNewFunc, boundUpdateFunc, boundRemovedFunc, boundConflictFunc ]);
const [ fetchRetryCallable ] = GuildSubscriptions.useGuildSubscriptionEffect({ const [ fetchRetryCallable ] = useGuildSubscriptionEffect({
guild, guild,
onFetch, onFetch,
onFetchError, onFetchError,
@ -299,15 +310,15 @@ export default class GuildSubscriptions {
}, fetchFunc); }, fetchFunc);
return [ fetchRetryCallable, value, fetchError, events ]; return [ fetchRetryCallable, value, fetchError, events ];
} }
private static useMultipleGuildSubscriptionScrolling< function useMultipleGuildSubscriptionScrolling<
T extends { id: string }, T extends { id: string },
NE extends keyof Connectable, NE extends keyof Connectable,
UE extends keyof Connectable, UE extends keyof Connectable,
RE extends keyof Connectable, RE extends keyof Connectable,
CE extends keyof Conflictable CE extends keyof Conflictable
>( >(
guild: CombinedGuild, guild: CombinedGuild,
eventMappingParams: MultipleEventMappingParams<T, NE, UE, RE, CE>, eventMappingParams: MultipleEventMappingParams<T, NE, UE, RE, CE>,
maxElements: number, maxElements: number,
@ -315,7 +326,7 @@ export default class GuildSubscriptions {
fetchFunc: (() => Promise<T[]>) | (() => Promise<T[] | null>), fetchFunc: (() => Promise<T[]>) | (() => Promise<T[] | null>),
fetchAboveFunc: ((reference: T) => Promise<T[] | null>), fetchAboveFunc: ((reference: T) => Promise<T[] | null>),
fetchBelowFunc: ((reference: T) => Promise<T[] | null>), fetchBelowFunc: ((reference: T) => Promise<T[] | null>),
): [ ): [
fetchRetryCallable: () => Promise<void>, fetchRetryCallable: () => Promise<void>,
fetchAboveCallable: () => Promise<{ hasMoreAbove: boolean, removedFromBottom: boolean }>, fetchAboveCallable: () => Promise<{ hasMoreAbove: boolean, removedFromBottom: boolean }>,
fetchBelowCallable: () => Promise<{ hasMoreBelow: boolean, removedFromTop: boolean }>, fetchBelowCallable: () => Promise<{ hasMoreBelow: boolean, removedFromTop: boolean }>,
@ -326,7 +337,7 @@ export default class GuildSubscriptions {
fetchAboveError: unknown | null, fetchAboveError: unknown | null,
fetchBelowError: unknown | null, fetchBelowError: unknown | null,
events: EventEmitter<MultipleSubscriptionEvents<T>> events: EventEmitter<MultipleSubscriptionEvents<T>>
] { ] {
const { const {
newEventName, newEventArgsMap, newEventName, newEventArgsMap,
updatedEventName, updatedEventArgsMap, updatedEventName, updatedEventArgsMap,
@ -525,7 +536,7 @@ export default class GuildSubscriptions {
guild.off(conflictEventName, boundConflictFunc); guild.off(conflictEventName, boundConflictFunc);
}, [ boundNewFunc, boundUpdateFunc, boundRemovedFunc, boundConflictFunc ]); }, [ boundNewFunc, boundUpdateFunc, boundRemovedFunc, boundConflictFunc ]);
const [ fetchRetryCallable ] = GuildSubscriptions.useGuildSubscriptionEffect({ const [ fetchRetryCallable ] = useGuildSubscriptionEffect({
guild, guild,
onFetch, onFetch,
onFetchError, onFetchError,
@ -545,37 +556,37 @@ export default class GuildSubscriptions {
fetchBelowError, fetchBelowError,
events events
]; ];
} }
static useGuildMetadataSubscription(guild: CombinedGuild) { export function useGuildMetadataSubscription(guild: CombinedGuild) {
const fetchMetadataFunc = useCallback(async () => { const fetchMetadataFunc = useCallback(async () => {
//LOG.silly('fetching metadata for subscription'); //LOG.silly('fetching metadata for subscription');
return await guild.fetchMetadata(); return await guild.fetchMetadata();
}, [ guild ]); }, [ guild ]);
return GuildSubscriptions.useSingleGuildSubscription<GuildMetadata, 'update-metadata', 'conflict-metadata'>(guild, { return useSingleGuildSubscription<GuildMetadata, 'update-metadata', 'conflict-metadata'>(guild, {
updatedEventName: 'update-metadata', updatedEventName: 'update-metadata',
updatedEventArgsMap: (guildMeta: GuildMetadata) => guildMeta, updatedEventArgsMap: (guildMeta: GuildMetadata) => guildMeta,
conflictEventName: 'conflict-metadata', conflictEventName: 'conflict-metadata',
conflictEventArgsMap: (changesType: AutoVerifierChangesType, oldGuildMeta: GuildMetadata, newGuildMeta: GuildMetadata) => newGuildMeta conflictEventArgsMap: (changesType: AutoVerifierChangesType, oldGuildMeta: GuildMetadata, newGuildMeta: GuildMetadata) => newGuildMeta
}, fetchMetadataFunc); }, fetchMetadataFunc);
} }
static useResourceSubscription(guild: CombinedGuild, resourceId: string | null) { export function useResourceSubscription(guild: CombinedGuild, resourceId: string | null) {
const fetchResourceFunc = useCallback(async () => { const fetchResourceFunc = useCallback(async () => {
//LOG.silly('fetching resource for subscription (resourceId: ' + resourceId + ')'); //LOG.silly('fetching resource for subscription (resourceId: ' + resourceId + ')');
if (resourceId === null) return null; if (resourceId === null) return null;
return await guild.fetchResource(resourceId); return await guild.fetchResource(resourceId);
}, [ guild, resourceId ]); }, [ guild, resourceId ]);
return GuildSubscriptions.useSingleGuildSubscription<Resource, 'update-resource', 'conflict-resource'>(guild, { return useSingleGuildSubscription<Resource, 'update-resource', 'conflict-resource'>(guild, {
updatedEventName: 'update-resource', updatedEventName: 'update-resource',
updatedEventArgsMap: (resource: Resource) => resource, updatedEventArgsMap: (resource: Resource) => resource,
conflictEventName: 'conflict-resource', conflictEventName: 'conflict-resource',
conflictEventArgsMap: (query: IDQuery, changesType: AutoVerifierChangesType, oldResource: Resource, newResource: Resource) => newResource conflictEventArgsMap: (query: IDQuery, changesType: AutoVerifierChangesType, oldResource: Resource, newResource: Resource) => newResource
}, fetchResourceFunc); }, fetchResourceFunc);
} }
static useSoftImageSrcResourceSubscription(guild: CombinedGuild, resourceId: string | null): [ imgSrc: string, resource: Resource | null, fetchError: unknown | null ] { export function useSoftImageSrcResourceSubscription(guild: CombinedGuild, resourceId: string | null): [ imgSrc: string, resource: Resource | null, fetchError: unknown | null ] {
const [ resource, fetchError ] = GuildSubscriptions.useResourceSubscription(guild, resourceId); const [ resource, fetchError ] = useResourceSubscription(guild, resourceId);
const [ imgSrc ] = useOneTimeAsyncAction( const [ imgSrc ] = useOneTimeAsyncAction(
async () => { async () => {
@ -588,13 +599,13 @@ export default class GuildSubscriptions {
); );
return [ imgSrc, resource, fetchError ]; return [ imgSrc, resource, fetchError ];
} }
static useChannelsSubscription(guild: CombinedGuild) { export function useChannelsSubscription(guild: CombinedGuild) {
const fetchChannelsFunc = useCallback(async () => { const fetchChannelsFunc = useCallback(async () => {
return await guild.fetchChannels(); return await guild.fetchChannels();
}, [ guild ]); }, [ guild ]);
return GuildSubscriptions.useMultipleGuildSubscription<Channel, 'new-channels', 'update-channels', 'remove-channels', 'conflict-channels'>(guild, { return useMultipleGuildSubscription<Channel, 'new-channels', 'update-channels', 'remove-channels', 'conflict-channels'>(guild, {
newEventName: 'new-channels', newEventName: 'new-channels',
newEventArgsMap: (channels: Channel[]) => channels, newEventArgsMap: (channels: Channel[]) => channels,
updatedEventName: 'update-channels', updatedEventName: 'update-channels',
@ -605,13 +616,13 @@ export default class GuildSubscriptions {
conflictEventArgsMap: (changesType: AutoVerifierChangesType, changes: Changes<Channel>) => changes, conflictEventArgsMap: (changesType: AutoVerifierChangesType, changes: Changes<Channel>) => changes,
sortFunc: Channel.sortByIndex sortFunc: Channel.sortByIndex
}, fetchChannelsFunc); }, fetchChannelsFunc);
} }
static useMembersSubscription(guild: CombinedGuild) { export function useMembersSubscription(guild: CombinedGuild) {
const fetchMembersFunc = useCallback(async () => { const fetchMembersFunc = useCallback(async () => {
return await guild.fetchMembers(); return await guild.fetchMembers();
}, [ guild ]); }, [ guild ]);
return GuildSubscriptions.useMultipleGuildSubscription<Member, 'new-members', 'update-members', 'remove-members', 'conflict-members'>(guild, { return useMultipleGuildSubscription<Member, 'new-members', 'update-members', 'remove-members', 'conflict-members'>(guild, {
newEventName: 'new-members', newEventName: 'new-members',
newEventArgsMap: (members: Member[]) => members, newEventArgsMap: (members: Member[]) => members,
updatedEventName: 'update-members', updatedEventName: 'update-members',
@ -622,10 +633,10 @@ export default class GuildSubscriptions {
conflictEventArgsMap: (changesType: AutoVerifierChangesType, changes: Changes<Member>) => changes, conflictEventArgsMap: (changesType: AutoVerifierChangesType, changes: Changes<Member>) => changes,
sortFunc: Member.sortForList sortFunc: Member.sortForList
}, fetchMembersFunc); }, fetchMembersFunc);
} }
static useSelfMemberSubscription(guild: CombinedGuild): [ selfMember: Member | null ] { export function useSelfMemberSubscription(guild: CombinedGuild): [ selfMember: Member | null ] {
const [ fetchRetryCallable, members, fetchError ] = GuildSubscriptions.useMembersSubscription(guild); const [ fetchRetryCallable, members, fetchError ] = useMembersSubscription(guild);
// TODO: Show an error if we can't fetch and allow retry // TODO: Show an error if we can't fetch and allow retry
@ -642,14 +653,14 @@ export default class GuildSubscriptions {
}, [ guild.memberId, members ]); }, [ guild.memberId, members ]);
return [ selfMember ]; return [ selfMember ];
} }
static useTokensSubscription(guild: CombinedGuild) { export function useTokensSubscription(guild: CombinedGuild) {
const fetchTokensFunc = useCallback(async () => { const fetchTokensFunc = useCallback(async () => {
//LOG.silly('fetching tokens for subscription'); //LOG.silly('fetching tokens for subscription');
return await guild.fetchTokens(); return await guild.fetchTokens();
}, [ guild ]); }, [ guild ]);
return GuildSubscriptions.useMultipleGuildSubscription<Token, 'new-tokens', 'update-tokens', 'remove-tokens', 'conflict-tokens'>(guild, { return useMultipleGuildSubscription<Token, 'new-tokens', 'update-tokens', 'remove-tokens', 'conflict-tokens'>(guild, {
newEventName: 'new-tokens', newEventName: 'new-tokens',
newEventArgsMap: (tokens: Token[]) => tokens, newEventArgsMap: (tokens: Token[]) => tokens,
updatedEventName: 'update-tokens', updatedEventName: 'update-tokens',
@ -660,9 +671,9 @@ export default class GuildSubscriptions {
conflictEventArgsMap: (changesType: AutoVerifierChangesType, changes: Changes<Token>) => changes, conflictEventArgsMap: (changesType: AutoVerifierChangesType, changes: Changes<Token>) => changes,
sortFunc: Token.sortRecentCreatedFirst sortFunc: Token.sortRecentCreatedFirst
}, fetchTokensFunc); }, fetchTokensFunc);
} }
static useMessagesScrollingSubscription(guild: CombinedGuild, channel: Channel) { export function useMessagesScrollingSubscription(guild: CombinedGuild, channel: Channel) {
const maxFetchElements = Globals.MESSAGES_PER_REQUEST; const maxFetchElements = Globals.MESSAGES_PER_REQUEST;
const maxElements = Globals.MAX_CURRENT_MESSAGES; const maxElements = Globals.MAX_CURRENT_MESSAGES;
const fetchMessagesFunc = useCallback(async () => { const fetchMessagesFunc = useCallback(async () => {
@ -674,7 +685,7 @@ export default class GuildSubscriptions {
const fetchBelowFunc = useCallback(async (reference: Message) => { const fetchBelowFunc = useCallback(async (reference: Message) => {
return await guild.fetchMessagesAfter(channel.id, reference.id, maxFetchElements); return await guild.fetchMessagesAfter(channel.id, reference.id, maxFetchElements);
}, [ guild, channel.id, maxFetchElements ]); }, [ guild, channel.id, maxFetchElements ]);
return GuildSubscriptions.useMultipleGuildSubscriptionScrolling( return useMultipleGuildSubscriptionScrolling(
guild, { guild, {
newEventName: 'new-messages', newEventName: 'new-messages',
newEventArgsMap: (messages: Message[]) => messages, newEventArgsMap: (messages: Message[]) => messages,
@ -689,5 +700,4 @@ export default class GuildSubscriptions {
maxElements, maxFetchElements, maxElements, maxFetchElements,
fetchMessagesFunc, fetchAboveFunc, fetchBelowFunc fetchMessagesFunc, fetchAboveFunc, fetchBelowFunc
) )
}
} }

View File

@ -4,7 +4,7 @@ import CombinedGuild from '../../guild-combined';
import ChannelList from '../lists/channel-list'; import ChannelList from '../lists/channel-list';
import MemberList from '../lists/member-list'; import MemberList from '../lists/member-list';
import MessageList from '../lists/message-list'; import MessageList from '../lists/message-list';
import GuildSubscriptions from '../require/guild-subscriptions'; import { useSelfMemberSubscription, useGuildMetadataSubscription, useMembersSubscription, useChannelsSubscription } from '../require/guild-subscriptions';
import ChannelTitle from './channel-title'; import ChannelTitle from './channel-title';
import ConnectionInfo from './connection-info'; import ConnectionInfo from './connection-info';
import GuildTitle from './guild-title'; import GuildTitle from './guild-title';
@ -23,10 +23,10 @@ const GuildElement: FC<GuildElementProps> = (props: GuildElementProps) => {
// TODO: React set hasMessagesAbove and hasMessagesBelow when re-verified? // TODO: React set hasMessagesAbove and hasMessagesBelow when re-verified?
// TODO: React jump messages to bottom when the current user sent a message // TODO: React jump messages to bottom when the current user sent a message
const [ selfMember ] = GuildSubscriptions.useSelfMemberSubscription(guild); const [ selfMember ] = useSelfMemberSubscription(guild);
const [ guildMeta, guildMetaFetchError ] = GuildSubscriptions.useGuildMetadataSubscription(guild); const [ guildMeta, guildMetaFetchError ] = useGuildMetadataSubscription(guild);
const [ membersRetry, members, membersFetchError ] = GuildSubscriptions.useMembersSubscription(guild); const [ membersRetry, members, membersFetchError ] = useMembersSubscription(guild);
const [ channelsRetry, channels, channelsFetchError ] = GuildSubscriptions.useChannelsSubscription(guild); const [ channelsRetry, channels, channelsFetchError ] = useChannelsSubscription(guild);
const [ activeChannel, setActiveChannel ] = useState<Channel | null>(null); const [ activeChannel, setActiveChannel ] = useState<Channel | null>(null);