Skip to content

Commit

Permalink
Add in changes before stream
Browse files Browse the repository at this point in the history
  • Loading branch information
AluTheCrow committed Dec 7, 2024
1 parent 08502e6 commit a1c7cd0
Show file tree
Hide file tree
Showing 12 changed files with 168 additions and 132 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useMemo } from 'react';
import { TeamResponse } from '../../../utils/twitch-api-types/team-types';
import { TabList, Tab, Image, makeStyles, tokens, SelectTabEvent, SelectTabData } from '@fluentui/react-components';

Expand Down Expand Up @@ -45,27 +45,8 @@ const useStyles = makeStyles({
}
});



export const HeaderNav: React.FC<HeaderNavProps> = ({ teams, defaultTab, onTabChange }: HeaderNavProps) => {
const styles = useStyles();
const renderTabs = () => {
return (
<>
{
teams.map((team) => (
<Tab key={team.team_name} value={team.id} aria-label={team.team_display_name}>
<Image src={team.thumbnail_url}
fit='contain'
shape="circular"
alt={`${team.team_display_name} logo`}
className={styles.tabImage} />
</Tab>
))}
</>
);
};

return (
<nav className={styles.headerNavRow}>
<TabList
Expand All @@ -74,7 +55,15 @@ export const HeaderNav: React.FC<HeaderNavProps> = ({ teams, defaultTab, onTabCh
selectTabOnFocus={true}
className={styles.headerTitleRow}>
{
renderTabs()
teams.map((team) => (
<Tab id={team.team_name} value={team.id} aria-label={team.team_display_name}>
<Image src={team.thumbnail_url}
fit='contain'
shape="circular"
alt={`${team.team_display_name} logo`}
className={styles.tabImage} />
</Tab>
))
}
</TabList>
</nav >
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { makeStyles, tokens } from "@fluentui/react-components";

const useStyles = makeStyles({
sectionLayout: {
width: "100%",
justifyContent: "stretch",
alignContent: "center"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
// src/components/TeamContainer.tsx
import React, { useState } from 'react';
import React, { useEffect, useMemo, useState } from 'react';
import { Footer } from '../bars/footers/footer-nav';
import { HeaderComponent } from '../bars/headers/header-component';
import { Body1Strong, Spinner, makeStyles, tokens } from '@fluentui/react-components';
import type { SelectTabData, SelectTabEvent,TabValue} from "@fluentui/react-components";
import type { SelectTabData, SelectTabEvent, TabValue } from "@fluentui/react-components";
import { TeamTabPanel } from '../teams/teams-list/team-tab-panel';
import { HeaderNav } from '../bars/headers/header-nav-component';
import { useQuery } from '../../utils/axios-instance';
import { getBroadcasterInfo } from '../../utils/twitchApi';
import { TwitchBroadcasterResponse } from '../../utils/twitch-api-types/user-types';
import { useTeamInfo } from '../../hooks/team-hooks/use-team-info';
import { TeamResponse } from '../../utils/twitch-api-types/team-types';
import { ContentLayout } from './content-layout';
import { TeamPanels } from '../teams/teams-list/team-panels-view';
interface MainLayoutProps {
broadcasterId: string;
}
Expand All @@ -28,11 +31,12 @@ const useStyles = makeStyles({
justifyContent: 'center',
width: '100%',
marginTop: tokens.spacingVerticalL,
marginBottom: tokens.spacingVerticalL,
zIndex: tokens.zIndexContent
},
footerNavBar: {
width: '100%',
bottom:0,
bottom: 0,
paddingTop: tokens.spacingVerticalL,
color: tokens.colorNeutralForeground1,
justifyContent: "space-evenly",
Expand All @@ -46,65 +50,38 @@ const useStyles = makeStyles({
});



export const MainLayout: React.FC<MainLayoutProps> = ({ broadcasterId }) => {
const { teams, loading, error } = useTeamInfo(broadcasterId);
const [broadcasterInfo, { loading: broadcasterLoading, error: broadcasterError }] = useQuery<TwitchBroadcasterResponse, string>(getBroadcasterInfo, broadcasterId);
const [selectedValue, setSelectedValue] = useState<TabValue>(teams[0]?.id);
const styles = useStyles();
const [broadcasterInfo, {loading: broadcasterLoading, error: broadcasterError}] = useQuery<TwitchBroadcasterResponse, string>(getBroadcasterInfo, broadcasterId);
const {teams, loading, error } = useTeamInfo(broadcasterId);
const [selectedValue, setSelectedValue] = useState<TabValue>(teams[0]?.id ?? "");

if (loading || broadcasterLoading) return <Spinner appearance='primary' label={'Loading broadcaster data...'} labelPosition='before' />;
if (broadcasterError) return <Body1Strong as="strong" align='center'>Error loading broadcaster information: [broadcasterError]</Body1Strong>;
if (error) return <Body1Strong as="strong" align='center'>Error loading broadcaster information: <code>[error]</code></Body1Strong>;

const onTabSelect = (event: SelectTabEvent, data: SelectTabData) => {
setSelectedValue(data.value);
};
if (loading || broadcasterLoading) return <Spinner appearance='primary' label={'Loading broadcaster data...'} labelPosition='before' />;
if (broadcasterError) return <Body1Strong as="strong" align='center'>Error loading broadcaster information: <code>{broadcasterError}</code></Body1Strong>;
if (error) return <Body1Strong as="strong" align='center'>Error loading broadcaster information: <code>{error.message}</code></Body1Strong>;

const renderHeader = () => {
return (
const onTabSelect = (event: SelectTabEvent, data: SelectTabData) => {
setSelectedValue(data.value);
};
const team = teams?.find((team) => team?.id === selectedValue) ?? teams[0];
return (
<div className={styles.removeOverflow}>
{/* Header content */}
<header className={styles.headerProp}>
<HeaderComponent broadcasterName={broadcasterInfo[0].broadcaster_name ?? ""} />
<HeaderNav teams={teams} defaultTab={teams[0]?.id} onTabChange={onTabSelect}/>
<HeaderNav teams={teams} defaultTab={team?.id} onTabChange={onTabSelect} />
</header>
);
};

const renderMainContent = () => {
return (
{/* Main content */}
<main className={styles.mainLayout}>
{
teams.map(team => {
return(
<div role="tabpanel" aria-labelledby={team.id}>
<TeamTabPanel teamId={team.id} />
</div>
);
})
}
<ContentLayout>
<div></div>
</ContentLayout>
</main>
);
};
const renderFooter = () => {
return (
{/* Footer content */}
<footer className={styles.footerNavBar}>
<Footer />
</footer>
);
};
return (
<div className={styles.removeOverflow}>
{
/* Header with navigation and broadcaster name */
renderHeader()
}
{
/* Main content area */
renderMainContent()
}
{
/* Footer */
renderFooter()
}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// src/components/TeamListItem.tsx
import React from 'react';
import React, { memo, useMemo } from 'react';
import { Body1Strong, Button, buttonClassNames, Caption1, Card, CardFooter, CardHeader, CardPreview, Image, InfoLabel, makeResetStyles, makeStyles, mergeClasses, Spinner, tokens } from '@fluentui/react-components';
import { TwitchUser } from '../../../utils/twitch-api-types/user-types';
import { ArrowReplyRegular } from '@fluentui/react-icons';
import { TwitchPersona } from '../../../features/profiles/twitch-persona';
import { ListItem } from '@fluentui/react-list-preview';
import { areEqual } from 'react-window';

interface TeamListItemProps {
member: TwitchUser;
Expand Down Expand Up @@ -49,12 +50,11 @@ const useStyles = makeStyles({
}
});

const renderPersonaDetails = (user: TwitchUser) =>
<InfoLabel id={`btn-${user.id}`} onClick={e => e.preventDefault()} info={<TwitchPersona twitchUser={user} links={[]} />} />;

export const TeamListItem: React.FC<TeamListItemProps> = ({ member }: TeamListItemProps) => {
const [loading, setLoading] = React.useState<boolean>(false);
const [followedChannel, setFollowedChannel] = React.useState<boolean>(false);
const memoizedPersona = useMemo(() => <InfoLabel id={`btn-${member.id}`} onClick={e => e.preventDefault()} info={<TwitchPersona twitchUser={member} links={[]} />} />, [member]);
const styles = useStyles();
const determineButtonIcon = loading ? <Spinner size="tiny" /> : <ArrowReplyRegular fontSize={16} />;
const didTheyFollow = (didFollow: boolean, channelName: string) => {
Expand All @@ -63,13 +63,14 @@ export const TeamListItem: React.FC<TeamListItemProps> = ({ member }: TeamListIt
}
setLoading(false);
};
const buttonClassName = !loading || followedChannel ? undefined : styles.buttonNonInteractive;

const followMember = (e: React.MouseEvent) => {
setLoading(true);
e.preventDefault();
window.Twitch.ext.actions.onFollow(didTheyFollow);
window.Twitch.ext.actions.followChannel(member.login);
};

const buttonClassName = !loading || followedChannel ? undefined : styles.buttonNonInteractive;

return (
<Card appearance='filled-alternative'
Expand All @@ -89,19 +90,17 @@ export const TeamListItem: React.FC<TeamListItemProps> = ({ member }: TeamListIt
}
}
description={<Caption1 as="p" className={styles.caption}>{member.broadcaster_type}</Caption1>}
action={renderPersonaDetails(member)}
action={
<div role="gridcell">
{memoizedPersona}
</div>
}
/>
<Caption1 as="p" className={styles.caption}>{member.description}</Caption1>
<CardFooter>
<Button
id={`btn-follow-${member.id}`}
className={buttonClassName}
iconPosition='before'
icon={determineButtonIcon}
onClick={followMember}
appearance='primary'>
Follow
</Button>
<div role="gridcell">
<Button id={`btn-follow-${member.id}`} className={buttonClassName} iconPosition='before' icon={determineButtonIcon} onClick={followMember} appearance='primary'>Follow</Button>
</div>
</CardFooter>
</Card>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// src/components/TeamList.tsx
import React, { memo, useCallback } from 'react';
import React, { memo, useCallback, useMemo } from 'react';
import { areEqual, FixedSizeList } from "react-window";
import { List, ListItem } from "@fluentui/react-list-preview";
import { TeamListItem } from './team-list-item';
import { BasicTwitchUser } from '../../../utils/twitch-api-types/team-types';
import { Body1, makeResetStyles, makeStyles, mergeClasses, tokens } from '@fluentui/react-components';
import { Body1, Caption1, makeResetStyles, makeStyles, mergeClasses, tokens } from '@fluentui/react-components';
import { useBatchRequests } from '../../../hooks/batch-request-hooks/use-batch-requests';
import { TableSkeleton } from '../../skeletons/initializer-skeleton';
import { TwitchUser } from '../../../utils/twitch-api-types/user-types';
Expand All @@ -20,54 +20,61 @@ const useListItemRootStyles = makeResetStyles({
gridTemplate: `"preview preview preview" auto
"header action secondary_action" auto / 1fr auto auto
`,
});
});
const useStyles = makeStyles({
list: {
display: "flex",
flexDirection: "column",
gap: "1em",
maxWidth: "300px",
width: "100%",
height: "500px",
overflowX: "hidden",
overflowY: "scroll"
},
listItem: {
display: "grid",
padding: "8px",
},
caption: {
width: "100%",
height: "100%",
marginLeft: tokens.spacingHorizontalXL,
marginRight: tokens.spacingHorizontalXL,

},
caption: {
color: tokens.colorNeutralForeground3,
},
image: {
},
image: {
height: "160px",
maxWidth: "100%",
borderRadius: "5px",
},
title: {
},
title: {
color: tokens.colorNeutralForeground1,
fontWeight: 600,
display: "block",
}
}
});


// Inside the TeamList component, use the useQuery hook to fetch the user details
export const TeamList: React.FC<TeamListProps> = ({ members }: TeamListProps) => {
const { userDetails, loading, error } = useBatchRequests(members);
const rootStyles = useListItemRootStyles();
const styles = useStyles();
if (loading) return <TableSkeleton />;
if (error) return <div>Error: <code>{error}</code></div>;

if (error) return <div><Body1 as="h2">Error: </Body1><Caption1 as="p"><code>{error}</code></Caption1></div>;

return (
<List navigationMode="composite"
className={mergeClasses(rootStyles,styles.list)}>
{userDetails.map((member, index) => (
className={mergeClasses(rootStyles, styles.list)}>
{userDetails.map((member) => (
<ListItem key={member.id}
value={member.display_name}
data-value={member.display_name}
aria-label={member.display_name}
className={styles.listItem}
checkmark={null}>
<TeamListItem key={index} member={member} />
value={member.display_name}
data-value={member.display_name}
aria-label={member.display_name}
className={styles.listItem}
checkmark={null}>
<div role="gridcell" className={styles.listItem}>
<TeamListItem member={member} />
</div>
</ListItem>
))}
</List>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React, { useState } from "react";
import { TeamResponse } from "../../../utils/twitch-api-types/team-types";
import { useTeamParticipants } from "../../../hooks/team-hooks/use-team-participant-info";
import { Body1, Caption1, Spinner, Title2 } from "@fluentui/react-components";
import { TeamList } from "./team-list";
import { areEqual } from "react-window";

interface TeamPanelsProps {
teams: TeamResponse[];
}

export const TeamPanels: React.FC<TeamPanelsProps> = ({ teams }: TeamPanelsProps) => {
const { resolvedTeamMembersbyTeam, loading, error } = useTeamParticipants(teams.map(team => team.id));

if (loading) return <Spinner appearance="inverted" labelPosition="before" label="Loading team information" />;
if (error) return <div><Body1 as="h2">An error occured:</Body1><Caption1 as="p">{JSON.stringify(error)}</Caption1></div>

const teamIds = Object.keys(resolvedTeamMembersbyTeam).forEach(teamId => {
});
const teampanels: React.ReactElement[] = [];
teams.forEach(team => {
const panel = <div role="tabpanel" aria-labelledby={team.id}>
<Title2>{team.team_display_name}</Title2>
</div>;
teampanels.push(panel);});

return (
<div>
{teampanels}
</div>
);
}
Loading

0 comments on commit a1c7cd0

Please sign in to comment.