diff --git a/src/client/webapp/elements/components/token-row.tsx b/src/client/webapp/elements/components/token-row.tsx index 3e7ca52..9627ad2 100644 --- a/src/client/webapp/elements/components/token-row.tsx +++ b/src/client/webapp/elements/components/token-row.tsx @@ -1,42 +1,44 @@ import moment from 'moment'; import React, { FC } from 'react'; -import { GuildMetadata, Member, Token } from '../../data-types'; -import CombinedGuild from '../../guild-combined'; +import { useRecoilValue } from 'recoil'; +import { Member, Token } from '../../data-types'; import Util from '../../util'; import { IAddGuildData } from '../overlays/overlay-add-guild'; +import { selectedGuildWithMetaState } from '../require/atoms'; import BaseElements from '../require/base-elements'; -import { SubscriptionResult, useSoftImageSrcResourceSubscription } from '../require/guild-subscriptions'; +import { useSoftImageSrcResourceSubscription } from '../require/guild-subscriptions'; import { useAsyncVoidCallback, useDownloadButton, useOneTimeAsyncAction } from '../require/react-helper'; import Button, { ButtonColorType } from './button'; export interface TokenRowProps { url: string; - guild: CombinedGuild; - guildMetaResult: SubscriptionResult; token: Token; } const TokenRow: FC = (props: TokenRowProps) => { - const { guild, guildMetaResult, token } = props; + const { token } = props; + const guildWithMeta = useRecoilValue(selectedGuildWithMetaState); + if (guildWithMeta === null || guildWithMeta.value === null) return null; const [ guildSocketConfigs ] = useOneTimeAsyncAction( - async () => await guild.fetchSocketConfigs(), + async () => await guildWithMeta.guild.fetchSocketConfigs(), null, - [ guild ] + [ guildWithMeta.guild ] ); - const [ iconSrc ] = useSoftImageSrcResourceSubscription(guild, guildMetaResult.value.iconResourceId, guildMetaResult.guild); + const [ iconSrc ] = useSoftImageSrcResourceSubscription(guildWithMeta.guild, guildWithMeta.value.iconResourceId, guildWithMeta.guild); const [ revoke ] = useAsyncVoidCallback(async () => { - await guild.requestDoRevokeToken(token.token); - }, [ guild, token ]); + await guildWithMeta.guild.requestDoRevokeToken(token.token); + }, [ guildWithMeta.guild, token ]); const [ downloadFunc, downloadText, downloadShaking ] = useDownloadButton( - guildMetaResult.value.name + '.cordis', + guildWithMeta.value.name + '.cordis', async () => { if (guildSocketConfigs === null) return null; + if (guildWithMeta === null || guildWithMeta.value === null) return null; const guildSocketConfig = Util.randomChoice(guildSocketConfigs); const addGuildData: IAddGuildData = { - name: guildMetaResult.value.name, + name: guildWithMeta.value.name, url: guildSocketConfig.url, cert: guildSocketConfig.cert, token: token.token, @@ -46,12 +48,12 @@ const TokenRow: FC = (props: TokenRowProps) => { const json = JSON.stringify(addGuildData); return Buffer.from(json); }, - [ guildSocketConfigs, guildMetaResult, token, iconSrc ] + [ guildSocketConfigs, guildWithMeta, token, iconSrc ] ); const userText = (token.member instanceof Member ? 'Used by ' + token.member.displayName : token.member?.id) ?? 'Unused Token'; return ( -
+
{userText}
{token.token}
diff --git a/src/client/webapp/elements/contexts/context-menu-guild-title.tsx b/src/client/webapp/elements/contexts/context-menu-guild-title.tsx index c7a9879..1f15740 100644 --- a/src/client/webapp/elements/contexts/context-menu-guild-title.tsx +++ b/src/client/webapp/elements/contexts/context-menu-guild-title.tsx @@ -1,36 +1,32 @@ import React, { FC, ReactNode, RefObject, useCallback, useMemo } from 'react'; import { useSetRecoilState } from 'recoil'; -import { GuildMetadata, Member } from '../../data-types'; -import CombinedGuild from '../../guild-combined'; +import { Member } from '../../data-types'; import { overlayState } from '../require/atoms'; import ChannelOverlay from '../overlays/overlay-channel'; import GuildSettingsOverlay from '../overlays/overlay-guild-settings'; import BaseElements from '../require/base-elements'; -import { SubscriptionResult } from '../require/guild-subscriptions'; import ContextMenu from './components/context-menu'; export interface GuildTitleContextMenuProps { close: () => void; relativeToRef: RefObject; - guild: CombinedGuild; - guildMetaResult: SubscriptionResult; selfMember: Member; } const GuildTitleContextMenu: FC = (props: GuildTitleContextMenuProps) => { - const { close, relativeToRef, guild, guildMetaResult, selfMember } = props; + const { close, relativeToRef, selfMember } = props; const setOverlay = useSetRecoilState(overlayState); const openGuildSettings = useCallback(() => { close(); - setOverlay(); - }, [ guild, guildMetaResult, close ]); + setOverlay(); + }, [ close ]); const openCreateChannel = useCallback(() => { close(); - setOverlay(); - }, [ guild, close ]); + setOverlay(); + }, [ close ]); const guildSettingsElement = useMemo(() => { if (!selfMember.privileges.includes('modify_profile')) return null; @@ -59,7 +55,7 @@ const GuildTitleContextMenu: FC = (props: GuildTitle }, []); return ( - +
{guildSettingsElement} {createChannelElement} diff --git a/src/client/webapp/elements/displays/display-guild-invites.tsx b/src/client/webapp/elements/displays/display-guild-invites.tsx index 8cf8151..17ca076 100644 --- a/src/client/webapp/elements/displays/display-guild-invites.tsx +++ b/src/client/webapp/elements/displays/display-guild-invites.tsx @@ -4,34 +4,31 @@ import Logger from '../../../../logger/logger'; const LOG = Logger.create(__filename, electronConsole); import React, { FC, useEffect, useMemo, useState } from 'react'; -import CombinedGuild from '../../guild-combined'; import Display from '../components/display'; import InvitePreview from '../components/invite-preview'; -import { GuildMetadata, Token } from '../../data-types'; +import { Token } from '../../data-types'; import { useAsyncSubmitButton } from '../require/react-helper'; import { Duration } from 'moment'; import moment from 'moment'; import DropdownInput from '../components/input-dropdown'; import Button from '../components/button'; -import { useTokensSubscription, useSoftImageSrcResourceSubscription, SubscriptionResult } from '../require/guild-subscriptions'; +import { useTokensSubscription, useSoftImageSrcResourceSubscription } from '../require/guild-subscriptions'; import TokenRow from '../components/token-row'; +import { useRecoilValue } from 'recoil'; +import { selectedGuildWithMetaState } from '../require/atoms'; - -export interface GuildInvitesDisplayProps { - guild: CombinedGuild; - guildMetaResult: SubscriptionResult; -} -const GuildInvitesDisplay: FC = (props: GuildInvitesDisplayProps) => { - const { guild, guildMetaResult } = props; +const GuildInvitesDisplay: FC = () => { + const guildWithMeta = useRecoilValue(selectedGuildWithMetaState); + if (guildWithMeta === null || guildWithMeta.value === null) return null; const url = 'https://localhost:3030'; // TODO: this will likely be a dropdown list at some point - const [ _fetchRetryCallable, tokensResult, tokensError ] = useTokensSubscription(guild); + const [ _fetchRetryCallable, tokensResult, tokensError ] = useTokensSubscription(guildWithMeta.guild); const [ expiresFromNow, setExpiresFromNow ] = useState(moment.duration(1, 'day')); const [ expiresFromNowText, setExpiresFromNowText ] = useState('1 day'); - const [ iconSrc ] = useSoftImageSrcResourceSubscription(guild, guildMetaResult.value.iconResourceId ?? null, guildMetaResult.guild); + const [ iconSrc ] = useSoftImageSrcResourceSubscription(guildWithMeta.guild, guildWithMeta.value.iconResourceId ?? null, guildWithMeta.guild); useEffect(() => { if (expiresFromNowText === 'never') { @@ -46,14 +43,14 @@ const GuildInvitesDisplay: FC = (props: GuildInvitesDi const [ createTokenFunc, tokenButtonText, tokenButtonShaking, _, createTokenFailMessage ] = useAsyncSubmitButton( async () => { try { - const createdToken = await guild.requestDoCreateToken(expiresFromNowText === 'never' ? null : expiresFromNowText) + const createdToken = await guildWithMeta.guild.requestDoCreateToken(expiresFromNowText === 'never' ? null : expiresFromNowText) return { result: createdToken, errorMessage: null }; } catch (e: unknown) { LOG.error('error creating token', e); return { result: null, errorMessage: 'Error creating token' }; } }, - [ guild, expiresFromNowText ], + [ guildWithMeta, expiresFromNowText ], { start: 'Create Token', done: 'Create Another Token' } ); @@ -67,11 +64,11 @@ const GuildInvitesDisplay: FC = (props: GuildInvitesDi // TODO: Try Again return
Unable to load tokens
; } - if (!guildMetaResult) { + if (!guildWithMeta?.value) { return
No Guild Metadata
; } - return tokensResult?.value?.map((token: Token) => ); - }, [ url, guild, tokensResult, tokensError ]); + return tokensResult?.value?.map((token: Token) => ); + }, [ url, guildWithMeta, tokensResult, tokensError ]); return ( = (props: GuildInvitesDi
diff --git a/src/client/webapp/elements/displays/display-guild-overview.tsx b/src/client/webapp/elements/displays/display-guild-overview.tsx index def1148..0462e32 100644 --- a/src/client/webapp/elements/displays/display-guild-overview.tsx +++ b/src/client/webapp/elements/displays/display-guild-overview.tsx @@ -6,22 +6,20 @@ const LOG = Logger.create(__filename, electronConsole); import React, { Dispatch, FC, SetStateAction, useCallback, useEffect, useMemo, useState } from 'react'; import Globals from '../../globals'; -import CombinedGuild from '../../guild-combined'; import Display from '../components/display'; import TextInput from '../components/input-text'; import ImageEditInput from '../components/input-image-edit'; -import { SubscriptionResult, useResourceSubscription } from '../require/guild-subscriptions'; -import { GuildMetadata } from '../../data-types'; +import { useResourceSubscription } from '../require/guild-subscriptions'; +import { useRecoilValue } from 'recoil'; +import { selectedGuildWithMetaState } from '../require/atoms'; -export interface GuildOverviewDisplayProps { - guild: CombinedGuild; - guildMetaResult: SubscriptionResult; -} -const GuildOverviewDisplay: FC = (props: GuildOverviewDisplayProps) => { - const { guild, guildMetaResult } = props; +const GuildOverviewDisplay: FC = () => { + const guildWithMeta = useRecoilValue(selectedGuildWithMetaState); + + if (guildWithMeta === null || guildWithMeta.value === null) return null; // TODO: Use the one from guild.tsx (for both of these?) - const [ iconResourceResult, iconResourceError ] = useResourceSubscription(guild, guildMetaResult.value.iconResourceId, guildMetaResult.guild); + const [ iconResourceResult, iconResourceError ] = useResourceSubscription(guildWithMeta.guild, guildWithMeta.value.iconResourceId, guildWithMeta.guild); const [ savedName, setSavedName ] = useState(null); const [ savedIconBuff, setSavedIconBuff ] = useState(null); @@ -39,11 +37,10 @@ const GuildOverviewDisplay: FC = (props: GuildOvervie const [ iconInputMessage, setIconInputMessage ] = useState(null); useEffect(() => { - if (guildMetaResult) { - if (name === savedName) setName(guildMetaResult.value.name); - setSavedName(guildMetaResult.value.name); - } - }, [ guildMetaResult ]); + if (guildWithMeta === null || guildWithMeta.value === null) return; + if (name === savedName) setName(guildWithMeta.value.name); + setSavedName(guildWithMeta.value.name); + }, [ guildWithMeta ]); useEffect(() => { if (iconResourceResult && iconResourceResult.value) { @@ -84,7 +81,7 @@ const GuildOverviewDisplay: FC = (props: GuildOvervie if (name !== savedName) { // Save name try { - await guild.requestSetGuildName(name); + await guildWithMeta.guild.requestSetGuildName(name); setSavedName(name); } catch (e: unknown) { LOG.error('error setting guild name', e); @@ -98,7 +95,7 @@ const GuildOverviewDisplay: FC = (props: GuildOvervie // Save icon try { LOG.debug('saving icon'); - await guild.requestSetGuildIcon(iconBuff); + await guildWithMeta.guild.requestSetGuildIcon(iconBuff); setSavedIconBuff(iconBuff); } catch (e: unknown) { LOG.error('error setting guild icon', e); diff --git a/src/client/webapp/elements/lists/components/channel-element.tsx b/src/client/webapp/elements/lists/components/channel-element.tsx index 0e5d44a..746bd2e 100644 --- a/src/client/webapp/elements/lists/components/channel-element.tsx +++ b/src/client/webapp/elements/lists/components/channel-element.tsx @@ -49,7 +49,7 @@ const ChannelElement: FC = (props: ChannelElementProps) => }, [ modifyRef, channel ]); const launchModify = useCallback(() => { - setOverlay(); + setOverlay(); }, [ guild, channel ]); return ( diff --git a/src/client/webapp/elements/overlays/overlay-channel.tsx b/src/client/webapp/elements/overlays/overlay-channel.tsx index 47d2115..cd3552b 100644 --- a/src/client/webapp/elements/overlays/overlay-channel.tsx +++ b/src/client/webapp/elements/overlays/overlay-channel.tsx @@ -4,7 +4,6 @@ import Logger from '../../../../logger/logger'; const LOG = Logger.create(__filename, electronConsole); import React, { FC, ReactNode, useEffect, useMemo, useRef, useState } from 'react'; -import CombinedGuild from '../../guild-combined'; import BaseElements from '../require/base-elements'; import TextInput from '../components/input-text'; import SubmitOverlayLower from '../components/submit-overlay-lower'; @@ -13,15 +12,17 @@ import { Channel } from '../../data-types'; import { useAsyncSubmitButton } from '../require/react-helper'; import Button from '../components/button'; import Overlay from '../components/overlay'; -import { useSetRecoilState } from 'recoil'; -import { overlayState } from '../require/atoms'; +import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { overlayState, selectedGuildState } from '../require/atoms'; export interface ChannelOverlayProps { - guild: CombinedGuild; - channel?: Channel; + channel?: Channel; // If this is undefined, this is an add-channel overlay } const ChannelOverlay: FC = (props: ChannelOverlayProps) => { - const { guild, channel } = props; + const { channel } = props; + + const guild = useRecoilValue(selectedGuildState); + if (guild === null) return null; const rootRef = useRef(null); const nameInputRef = useRef(null); diff --git a/src/client/webapp/elements/overlays/overlay-guild-settings.tsx b/src/client/webapp/elements/overlays/overlay-guild-settings.tsx index 73d28bf..31f54b7 100644 --- a/src/client/webapp/elements/overlays/overlay-guild-settings.tsx +++ b/src/client/webapp/elements/overlays/overlay-guild-settings.tsx @@ -1,18 +1,15 @@ import React, { FC, useEffect, useRef, useState } from "react"; -import CombinedGuild from "../../guild-combined"; import ChoicesControl from "../components/control-choices"; import GuildInvitesDisplay from "../displays/display-guild-invites"; import GuildOverviewDisplay from "../displays/display-guild-overview"; -import { GuildMetadata } from '../../data-types'; import Overlay from '../components/overlay'; -import { SubscriptionResult } from '../require/guild-subscriptions'; +import { useRecoilValue } from "recoil"; +import { selectedGuildWithMetaState } from "../require/atoms"; -export interface GuildSettingsOverlayProps { - guild: CombinedGuild; - guildMetaResult: SubscriptionResult; -} -const GuildSettingsOverlay: FC = (props: GuildSettingsOverlayProps) => { - const { guild, guildMetaResult } = props; +const GuildSettingsOverlay: FC = () => { + const guildWithMeta = useRecoilValue(selectedGuildWithMetaState); + + if (guildWithMeta === null || guildWithMeta.value === null) return null; const rootRef = useRef(null); @@ -20,15 +17,15 @@ const GuildSettingsOverlay: FC = (props: GuildSetting const [ display, setDisplay ] = useState(); useEffect(() => { - if (selectedId === 'overview') setDisplay(); + if (selectedId === 'overview') setDisplay(); //if (selectedId === 'roles' ) setDisplay(); - if (selectedId === 'invites' ) setDisplay(); + if (selectedId === 'invites' ) setDisplay(); }, [ selectedId ]); return (
- { //LOG.silly('fetching metadata for subscription'); return await guild.fetchMetadata(); diff --git a/src/client/webapp/elements/sections/guild-title.tsx b/src/client/webapp/elements/sections/guild-title.tsx index c03c77e..7e657bc 100644 --- a/src/client/webapp/elements/sections/guild-title.tsx +++ b/src/client/webapp/elements/sections/guild-title.tsx @@ -1,18 +1,19 @@ import React, { FC, useMemo, useRef } from 'react'; -import { GuildMetadata, Member } from '../../data-types'; -import CombinedGuild from '../../guild-combined'; +import { useRecoilValue } from 'recoil'; +import { Member } from '../../data-types'; import GuildTitleContextMenu from '../contexts/context-menu-guild-title'; +import { selectedGuildWithMetaState } from '../require/atoms'; import { isNonNullAndHasValue, SubscriptionResult } from '../require/guild-subscriptions'; import { useContextMenu } from '../require/react-helper'; export interface GuildTitleProps { - guild: CombinedGuild; - guildMetaResult: SubscriptionResult | null; selfMemberResult: SubscriptionResult | null; } const GuildTitle: FC = (props: GuildTitleProps) => { - const { guild, guildMetaResult, selfMemberResult } = props; + const { selfMemberResult } = props; + + const guildWithMeta = useRecoilValue(selectedGuildWithMetaState) const rootRef = useRef(null); @@ -25,16 +26,15 @@ const GuildTitle: FC = (props: GuildTitleProps) => { }, [ selfMemberResult ]); const [ contextMenu, toggleContextMenu ] = useContextMenu((close: () => void) => { - if (!isNonNullAndHasValue(guildMetaResult)) return null; if (!isNonNullAndHasValue(selfMemberResult)) return null; return ( ); - }, [ guild, guildMetaResult, selfMemberResult, rootRef ]); + }, [ selfMemberResult, rootRef ]); const nameStyle = useMemo(() => { if (hasContextMenu) { @@ -47,7 +47,7 @@ const GuildTitle: FC = (props: GuildTitleProps) => { return (
- {guildMetaResult?.value?.name ?? null} + {guildWithMeta?.value?.name ?? null}
{contextMenu}
diff --git a/src/client/webapp/elements/sections/guild.tsx b/src/client/webapp/elements/sections/guild.tsx index 99ed079..439e96e 100644 --- a/src/client/webapp/elements/sections/guild.tsx +++ b/src/client/webapp/elements/sections/guild.tsx @@ -9,7 +9,7 @@ import CombinedGuild from '../../guild-combined'; import ChannelList from '../lists/channel-list'; import MemberList from '../lists/member-list'; import MessageList from '../lists/message-list'; -import { useSelfMemberSubscription, useGuildMetadataSubscription, useMembersSubscription, useChannelsSubscription } from '../require/guild-subscriptions'; +import { useSelfMemberSubscription, useMembersSubscription, useChannelsSubscription } from '../require/guild-subscriptions'; import ChannelTitle from './channel-title'; import ConnectionInfo from './connection-info'; import GuildTitle from './guild-title'; @@ -28,7 +28,6 @@ const GuildElement: FC = (props: GuildElementProps) => { // TODO: React jump messages to bottom when the current user sent a message const [ selfMemberResult ] = useSelfMemberSubscription(guild); - const [ guildMetaResult, guildMetaFetchError ] = useGuildMetadataSubscription(guild); const [ membersRetry, membersResult, membersFetchError ] = useMembersSubscription(guild); const [ channelsRetry, channelsResult, channelsFetchError ] = useChannelsSubscription(guild); @@ -83,7 +82,7 @@ const GuildElement: FC = (props: GuildElementProps) => { return (
- +