Skip to content

Commit

Permalink
Import Spaces library directly
Browse files Browse the repository at this point in the history
This allows us to test and debug easily.
  • Loading branch information
Dominik Piatek authored and dpiatek committed Aug 9, 2023
1 parent a7d82c8 commit fd39e27
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 40 deletions.
8 changes: 5 additions & 3 deletions demo/src/components/Avatar.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import cn from 'classnames';
import { SpaceMember } from '@ably-labs/spaces';
import { type SpaceMember } from '../../../src/types';

import { AvatarInfo } from './AvatarInfo';
import { LightningSvg } from './svg';
import { type ProfileData } from '../utils/types';

export interface AvatarProps extends SpaceMember {
export type AvatarProps = Omit<SpaceMember, 'profileData'> & {
isInContent?: boolean;
isSelf?: boolean;
}
profileData: ProfileData;
};

export const Avatar = ({
isSelf = false,
Expand Down
9 changes: 6 additions & 3 deletions demo/src/components/AvatarInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import cn from 'classnames';
import { AvatarProps } from './Avatar';
import { type SpaceMember } from '../../../src/types';
import { type ProfileData } from '../utils/types';

interface Props extends AvatarProps {
type Props = Omit<SpaceMember, 'profileData'> & {
isSelf?: boolean;
isList?: boolean;
}
profileData: ProfileData;
};

export const AvatarInfo = ({ isSelf, isConnected, profileData, isList = false }: Props) => {
return isSelf ? (
Expand Down
6 changes: 4 additions & 2 deletions demo/src/components/AvatarStack.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { Avatar } from './Avatar';

import cn from 'classnames';
import { AvatarInfo } from './AvatarInfo';
import { SpaceMember } from '@ably-labs/spaces';

import { type AvatarProps } from './Avatar';

interface Props {
isInContent?: boolean;
avatars: SpaceMember[];
avatars: AvatarProps[];
}

export const AvatarStack = ({ isInContent = false, avatars }: Props) => {
Expand Down
8 changes: 4 additions & 4 deletions demo/src/components/Cursors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import find from 'lodash.find';
import omit from 'lodash.omit';
import { CursorSvg, SpacesContext } from '.';
import { useMembers, CURSOR_ENTER, CURSOR_LEAVE, CURSOR_MOVE } from '../hooks';
import { SpaceMember } from '@ably-labs/spaces';
import { type Member } from '../utils/types';

type ActionType = 'move' | 'enter' | 'leave';

interface Action {
type: ActionType;
data: {
connectionId: string;
members?: SpaceMember[];
members?: Member[];
position?: {
x: number;
y: number;
Expand All @@ -22,7 +22,7 @@ interface Action {
}

interface State {
[connectionId: string]: SpaceMember & Action['data'];
[connectionId: string]: Member & Action['data'];
}

const reducer = (state: State, action: Action): State => {
Expand Down Expand Up @@ -62,7 +62,7 @@ export const Cursors = () => {

space.cursors.subscribe('cursorsUpdate', (cursorUpdate) => {
const { connectionId } = cursorUpdate;
const member = find<SpaceMember>(members, { connectionId });
const member = find<Member>(members, { connectionId });

if (
connectionId !== self?.connectionId &&
Expand Down
6 changes: 3 additions & 3 deletions demo/src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { SpaceMember } from '@ably-labs/spaces';
import { Avatar } from './Avatar';
import { AvatarStack } from './AvatarStack';
import { ExternalLinkSvg, InfoSvg } from './svg';
import { type Member } from '../utils/types';

interface Props {
self?: SpaceMember;
others?: SpaceMember[];
self?: Member;
others?: Member[];
}

export const Header = ({ self, others }: Props) => {
Expand Down
4 changes: 2 additions & 2 deletions demo/src/components/SlidePreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ export interface SlidePreviewProps {
export const SlidePreview = ({ children, index }: SlidePreviewProps) => {
const space = useContext(SpacesContext);
const { self, members } = useMembers();
const membersOnASlide = (members || []).filter(({ location }) => location?.slide === index);
const isActive = self?.location?.slide === index;
const membersOnASlide = (members || []).filter(({ location }) => location?.slide === `${index}`);
const isActive = self?.location?.slide === `${index}`;

const handleSlideClick = () => {
if (!space || !self) return;
Expand Down
2 changes: 1 addition & 1 deletion demo/src/components/SpacesContext.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import Spaces, { type Space } from '@ably-labs/spaces';
import Spaces, { type Space } from '../../../src/index';
import { Realtime } from 'ably';
import { nanoid } from 'nanoid';

Expand Down
57 changes: 39 additions & 18 deletions demo/src/hooks/useMembers.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,58 @@
import { useEffect, useState, useContext } from 'react';
import { type SpaceMember } from '@ably-labs/spaces';
import { type SpaceMember } from '../../../src/types';
import { SpacesContext } from '../components';

const membersToOthers = (members: SpaceMember[] = [], self: SpaceMember | undefined): SpaceMember[] =>
import { type Member } from '../utils/types';

const isMember = (obj: unknown): obj is Member => {
return !!(obj as Member)?.profileData?.name && !!(obj as Member)?.profileData?.color;
};

const areMembers = (arr: unknown): arr is Member[] => {
return (arr as Member[]).every((m) => isMember(m));
};

const membersToOthers = (members: Member[] = [], self: SpaceMember | undefined): Member[] =>
members.filter((m) => m.connectionId !== self?.connectionId);

export const useMembers: () => Partial<{ self?: SpaceMember; others: SpaceMember[]; members: SpaceMember[] }> = () => {
export const useMembers: () => Partial<{ self?: Member; others: Member[]; members: Member[] }> = () => {
const space = useContext(SpacesContext);
const [members, setMembers] = useState<SpaceMember[]>([]);
const [others, setOthers] = useState<SpaceMember[]>([]);
const [self, setSelf] = useState<SpaceMember | undefined>(undefined);
const [members, setMembers] = useState<Member[]>([]);
const [others, setOthers] = useState<Member[]>([]);
const [self, setSelf] = useState<Member | undefined>(undefined);

useEffect(() => {
if (!space) return;

const initSelf = space.getSelf();
const initMembers = space.getMembers();
const initSelf = space.members.getSelf();
const initMembers = space.members.getAll();

if (isMember(initSelf)) {
setSelf(initSelf);
}

if (areMembers(initMembers)) {
setMembers(initMembers);
setOthers(membersToOthers(initMembers, initSelf));
}

const handler = ({ members }: { members: SpaceMember[] }) => {
const self = space.members.getSelf();

setSelf(initSelf);
setMembers(initMembers);
setOthers(membersToOthers(initMembers, initSelf));
if (isMember(self)) {
setSelf(self);
}

const handler = (members: SpaceMember[]) => {
const self = space.getSelf();
setSelf(self);
setMembers([...members]);
setOthers((members ?? []).filter((m) => m.connectionId !== self?.connectionId));
if (areMembers(members)) {
setMembers([...members]);
setOthers(membersToOthers([...members], self));
}
};

space.subscribe('membersUpdate', handler);
space.subscribe('update', handler);

return () => {
space.unsubscribe('membersUpdate', handler);
space.unsubscribe('update', handler);
};
}, [space]);

Expand Down
8 changes: 4 additions & 4 deletions demo/src/utils/active-member.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { SpaceMember } from '@ably-labs/spaces';
import { Member } from './types';

export const findActiveMember = (id: string, slide: string, members?: SpaceMember[]) => {
export const findActiveMember = (id: string, slide: string, members?: Member[]) => {
if (!members) return;
return members.find((member) => member.location?.element === id && member.location?.slide === slide);
};

export const getMemberFirstName = (member?: SpaceMember) => {
export const getMemberFirstName = (member?: Member) => {
if (!member) return '';
return member.profileData.name.split(' ')[0];
};

export const getOutlineClasses = (member?: SpaceMember) => {
export const getOutlineClasses = (member?: Member) => {
if (!member) return '';
const { color } = member.profileData;
const { name } = color;
Expand Down
25 changes: 25 additions & 0 deletions demo/src/utils/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { type SpaceMember } from '../../../src';

interface ProfileData {
name: string;
color: {
name: string;
gradientStart: {
tw: string;
intensity: string;
hex: string;
};
gradientEnd: {
tw: string;
intensity: string;
hex: string;
};
};
}

type Member = Omit<SpaceMember, 'location' | 'profileData'> & {
profileData: ProfileData;
location: { slide: string; element: string };
};

export { ProfileData, Member };

0 comments on commit fd39e27

Please sign in to comment.