Skip to content

Commit

Permalink
refactor: misc formating and code review changes, comment tidyup
Browse files Browse the repository at this point in the history
  • Loading branch information
AndyTWF committed Nov 7, 2024
1 parent b8674a0 commit 70b684b
Show file tree
Hide file tree
Showing 16 changed files with 66 additions and 47 deletions.
20 changes: 18 additions & 2 deletions demo/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, useState } from 'react';
import { FC, useEffect, useState } from 'react';
import { Chat } from './containers/Chat';
import { OccupancyComponent } from './components/OccupancyComponent';
import { UserPresenceComponent } from './components/UserPresenceComponent';
Expand Down Expand Up @@ -28,10 +28,26 @@ const App: FC<AppProps> = () => {
const updateRoomId = (newRoomId: string) => {
const params = new URLSearchParams(window.location.search);
params.set('room', newRoomId);
history.replaceState(null, '', '?' + params.toString());
history.pushState(null, '', '?' + params.toString());
setRoomId(newRoomId);
};

// Add a useEffect that handles the popstate event to update the roomId when
// the user navigates back and forth in the browser history.
useEffect(() => {
const handlePopState = () => {
const params = new URLSearchParams(window.location.search);
const newRoomId = params.get('room') || 'abcd';
setRoomId(newRoomId);
};

window.addEventListener('popstate', handlePopState);

return () => {
window.removeEventListener('popstate', handlePopState);
};
}, []);

return (
<ChatRoomProvider
id={roomIdState}
Expand Down
7 changes: 2 additions & 5 deletions demo/src/containers/Chat/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,9 @@ export const Chat = (props: { roomId: string; setRoomId: (roomId: string) => voi
chatClient.logger.error('Error fetching initial messages', error);
});
}
}
};

const {
send: sendMessage,
getPreviousMessages,
} = useMessages({
const { send: sendMessage, getPreviousMessages } = useMessages({
listener: (message: MessageEventPayload) => {
setMessages((prevMessage) => [...prevMessage, message.message]);
},
Expand Down
3 changes: 1 addition & 2 deletions src/core/discontinuity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import EventEmitter from './utils/event-emitter.js';
*/
export interface HandlesDiscontinuity {
/**
* A promise of the channel that this object is associated with. The promise
* is resolved when the feature has finished initializing.
* A channel that this object is associated with.
*/
get channel(): Ably.RealtimeChannel;

Expand Down
5 changes: 2 additions & 3 deletions src/core/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ export interface Messages extends EmitsDiscontinuities {
/**
* Get the underlying Ably realtime channel used for the messages in this chat room.
*
* @returns A promise of the realtime channel.
* @returns The realtime channel.
*/
get channel(): Ably.RealtimeChannel;
}
Expand Down Expand Up @@ -234,7 +234,6 @@ export class DefaultMessages
* @param chatApi An instance of the ChatApi.
* @param clientId The client ID of the user.
* @param logger An instance of the Logger.
* @param initAfter A promise that is awaited before creating any channels.
*/
constructor(roomId: string, realtime: Ably.Realtime, chatApi: ChatApi, clientId: string, logger: Logger) {
super();
Expand All @@ -249,7 +248,7 @@ export class DefaultMessages
}

/**
* Creates the realtime channel for messages. Called after initAfter is resolved.
* Creates the realtime channel for messages.
*/
private _makeChannel(roomId: string, realtime: Ably.Realtime): Ably.RealtimeChannel {
const channel = getChannel(messagesChannelName(roomId), realtime);
Expand Down
5 changes: 2 additions & 3 deletions src/core/occupancy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export interface Occupancy extends EmitsDiscontinuities {
/**
* Get underlying Ably channel for occupancy events.
*
* @returns A promise of the underlying Ably channel for occupancy events.
* @returns The underlying Ably channel for occupancy events.
*/
get channel(): Ably.RealtimeChannel;
}
Expand Down Expand Up @@ -109,7 +109,6 @@ export class DefaultOccupancy
* @param realtime An instance of the Ably Realtime client.
* @param chatApi An instance of the ChatApi.
* @param logger An instance of the Logger.
* @param initAfter A promise that is awaited before creating any channels.
*/
constructor(roomId: string, realtime: Ably.Realtime, chatApi: ChatApi, logger: Logger) {
super();
Expand All @@ -121,7 +120,7 @@ export class DefaultOccupancy
}

/**
* Creates the realtime channel for occupancy. Called after initAfter is resolved.
* Creates the realtime channel for occupancy.
*/
private _makeChannel(roomId: string, realtime: Ably.Realtime): Ably.RealtimeChannel {
const channel = getChannel(messagesChannelName(roomId), realtime, { params: { occupancy: 'metrics' } });
Expand Down
6 changes: 3 additions & 3 deletions src/core/presence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ export interface Presence extends EmitsDiscontinuities {

/**
* Get the underlying Ably realtime channel used for presence in this chat room.
* @returns A promise of the realtime channel.
* @returns The realtime channel.
*/
get channel(): Ably.RealtimeChannel;
}
Expand All @@ -203,7 +203,6 @@ export class DefaultPresence
* @param clientId The client ID, attached to presences messages as an identifier of the sender.
* A channel can have multiple connections using the same clientId.
* @param logger An instance of the Logger.
* @param initAfter A promise that is awaited before creating any channels.
*/
constructor(roomId: string, roomOptions: RoomOptions, realtime: Ably.Realtime, clientId: string, logger: Logger) {
super();
Expand All @@ -214,7 +213,7 @@ export class DefaultPresence
}

/**
* Creates the realtime channel for presence. Called after initAfter is resolved.
* Creates the realtime channel for presence.
*/
private _makeChannel(roomId: string, roomOptions: RoomOptions, realtime: Ably.Realtime): Ably.RealtimeChannel {
// Set our channel modes based on the room options
Expand Down Expand Up @@ -249,6 +248,7 @@ export class DefaultPresence
* @inheritDoc
*/
async get(params?: Ably.RealtimePresenceParams): Promise<PresenceMember[]> {
this._logger.trace('Presence.get()', { params });
const userOnPresence = await this._channel.presence.get(params);

// ably-js never emits the 'absent' event, so we can safely ignore it here.
Expand Down
2 changes: 1 addition & 1 deletion src/core/room-lifecycle-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export class RoomLifecycleManager {

/**
* Constructs a new `RoomLifecycleManager` instance.
* @param status The status to update.
* @param lifecycle The room lifecycle that manages status.
* @param contributors The features that contribute to the room status.
* @param logger An instance of the Logger.
* @param transientDetachTimeout The number of milliseconds to consider a detach to be "transient"
Expand Down
5 changes: 2 additions & 3 deletions src/core/room-reactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export interface RoomReactions extends EmitsDiscontinuities {
* Returns an instance of the Ably realtime channel used for room-level reactions.
* Avoid using this directly unless special features that cannot otherwise be implemented are needed.
*
* @returns A promise of the Ably realtime channel.
* @returns The Ably realtime channel.
*/
get channel(): Ably.RealtimeChannel;
}
Expand Down Expand Up @@ -146,7 +146,6 @@ export class DefaultRoomReactions
* @param realtime An instance of the Ably Realtime client.
* @param clientId The client ID of the user.
* @param logger An instance of the Logger.
* @param initAfter A promise that is awaited before creating any channels.
*/
constructor(roomId: string, realtime: Ably.Realtime, clientId: string, logger: Logger) {
super();
Expand All @@ -157,7 +156,7 @@ export class DefaultRoomReactions
}

/**
* Creates the realtime channel for room reactions. Called after initAfter is resolved.
* Creates the realtime channel for room reactions.
*/
private _makeChannel(roomId: string, realtime: Ably.Realtime): Ably.RealtimeChannel {
const channel = getChannel(`${roomId}::$chat::$reactions`, realtime);
Expand Down
1 change: 0 additions & 1 deletion src/core/room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ export class DefaultRoom implements Room {
* @param realtime An instance of the Ably Realtime client.
* @param chatApi An instance of the ChatApi.
* @param logger An instance of the Logger.
* @param initAfter The room will wait for this promise to finish before initializing
*/
constructor(
roomId: string,
Expand Down
5 changes: 3 additions & 2 deletions src/core/rooms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export interface Rooms {
* @param roomId The ID of the room.
* @param options The options for the room.
* @throws {@link ErrorInfo} if a room with the same ID but different options already exists.
* @returns Room A new or existing Room object.
* @returns Room A promise to a new or existing Room object.
*/
get(roomId: string, options: RoomOptions): Promise<Room>;

Expand Down Expand Up @@ -201,7 +201,8 @@ export class DefaultRooms implements Rooms {

// If the room doesn't currently exist
if (!existing) {
// existing the room is being released, forward the releasing promise
// There's no existing room, but there is a release in progress, so forward that releasing promise
// to the caller so they can watch that.
if (releasing) {
this._logger.debug('Rooms.release(); waiting for previous release call', {
roomId,
Expand Down
8 changes: 4 additions & 4 deletions src/core/typing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export interface Typing extends EmitsDiscontinuities {

/**
* Get the Ably realtime channel underpinning typing events.
* @returns A promise of the Ably realtime channel.
* @returns The Ably realtime channel.
*/
channel: Ably.RealtimeChannel;
}
Expand Down Expand Up @@ -136,7 +136,6 @@ export class DefaultTyping
* @param realtime An instance of the Ably Realtime client.
* @param clientId The client ID of the user.
* @param logger An instance of the Logger.
* @param initAfter A promise that is awaited before creating any channels.
*/
constructor(roomId: string, options: TypingOptions, realtime: Ably.Realtime, clientId: string, logger: Logger) {
super();
Expand All @@ -149,7 +148,7 @@ export class DefaultTyping
}

/**
* Creates the realtime channel for typing indicators. Called after initAfter is resolved.
* Creates the realtime channel for typing indicators.
*/
private _makeChannel(roomId: string, realtime: Ably.Realtime): Ably.RealtimeChannel {
const channel = getChannel(`${roomId}::$chat::$typingIndicators`, realtime);
Expand All @@ -164,6 +163,7 @@ export class DefaultTyping
* @inheritDoc
*/
get(): Promise<Set<string>> {
this._logger.trace(`DefaultTyping.get();`);
return this._channel.presence.get().then((members) => new Set<string>(members.map((m) => m.clientId)));
}

Expand Down Expand Up @@ -200,7 +200,7 @@ export class DefaultTyping

// Start typing and emit typingStarted event
this._startTypingTimer();
return this._channel.presence.enterClient(this._clientId).then();
return this._channel.presence.enterClient(this._clientId);
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/react/helper/room-promise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,8 @@ class DefaultRoomPromise implements RoomPromise {
}

/**
* Wait for the room promise to resolve, then execute the onResolve callback, if the component
* has not been unmounted. If the component has not been unmounted, then use the returned
* unmount function to clean up any resources later.
* Wait for the room promise to resolve, then execute the onResolve callback, storing its response as an unmount function.
* If the component is unmounted before the promise resolves,then this will do nothing.
*
* @param promise The promise that resolves to a Room instance.
* @returns A promise that we simply resolve when its done.
Expand Down Expand Up @@ -135,6 +134,7 @@ class DefaultRoomPromise implements RoomPromise {
* }, []);
* ```
*
* @internal
* @param room The promise that resolves to a Room instance.
* @param onResolve The callback that is called when the promise resolves to a Room instance.
* @param logger The logger to use for logging.
Expand Down
17 changes: 8 additions & 9 deletions src/react/helper/use-eventual-room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ import { useRoomContext } from './use-room-context.js';
import { useStableReference } from './use-stable-reference.js';

/**
* Given a room promise, this hook will return the room object once it has been resolved. This is useful
* in hooks like useRoom to provide a direct reference to the room object, as Promises aren't usually the best
* thing to be passing around React components.
* This hook will take the room promise from the current context and return the room object once it has been resolved.
* This is useful in hooks like useRoom to provide a direct reference to the room object, as Promises aren't usually
* the best thing to be passing around React components.
*
* @param roomId The roomId of the room
* @param room The room promise that we're waiting to resolve
* @internal
* @returns The room object if it has resolved, otherwise undefined
*/
export const useEventualRoom = (): Room | undefined => {
Expand Down Expand Up @@ -50,10 +49,10 @@ export const useEventualRoom = (): Room | undefined => {
* Similar to useEventualRoom, but instead of providing the room itself, it provides a property of the room - e.g.
* Messages. We use this to eventually provide access to underlying room interfaces as non-promise values
* in hooks like useMessages.
* @param roomId The roomId of the room
* @param room The room promise that we're waiting to resolve
* @param onResolve A function that will be called when the room promise resolves, and will return the property of the room
* @returns
*
* @internal
* @returns The property of the room object that's been resolved, as returned by the onResolve callback,
* or undefined if the room hasn't resolved yet.
*/
export const useEventualRoomProperty = <T>(onResolve: (room: Room) => T) => {
const [roomState, setRoomState] = useState<T | undefined>();
Expand Down
1 change: 1 addition & 0 deletions src/react/helper/use-room-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ChatRoomContext, ChatRoomContextType } from '../contexts/chat-room-cont
/**
* A hook that returns the current ChatRoomContext. This should be used within a ChatRoomProvider.
*
* @internal
* @param callingHook The name of the hook that is calling this function, for logging purposes.
* @throws {@link Ably.ErrorInfo} if the hook is not used within a ChatRoomProvider.
* @returns The ChatRoomContext.
Expand Down
21 changes: 15 additions & 6 deletions src/react/helper/use-room-status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,33 @@ export interface UseRoomStatusResponse {
readonly error?: Ably.ErrorInfo;
}

/**
* The parameters for the useRoomStatus hook.
*/
export interface UseRoomStatusParams {
/**
* A listener for room status changes.
*/
onRoomStatusChange?: (change: RoomStatusChange) => void;
}

/**
* A hook that returns the current status of the room, and listens for changes to the room status.
*
* @internal
* @param params An optional user-provided listener for room status changes.
* @returns The current status of the room, and an error if the room is in an errored state.
*/
export const useRoomStatus = (params?: {
onRoomStatusChange?: (change: RoomStatusChange) => void;
}): UseRoomStatusResponse => {
export const useRoomStatus = (params?: UseRoomStatusParams): UseRoomStatusResponse => {
const context = useRoomContext('useRoomStatus');

const [status, setStatus] = useState<RoomStatus>(RoomStatus.Initializing);
const [error, setError] = useState<Ably.ErrorInfo | undefined>();
const logger = useLogger();

// create stable references for the listeners and register the user-provided callbacks
const onRoomStatusChangeRef = useEventListenerRef(params?.onRoomStatusChange);

// create an internal listener to update the status
useEffect(() => {
const roomPromise = wrapRoomPromise(
Expand Down Expand Up @@ -66,9 +78,6 @@ export const useRoomStatus = (params?: {
return roomPromise.unmount();
}, [context, logger]);

// create stable references for the listeners and register the user-provided callbacks
const onRoomStatusChangeRef = useEventListenerRef(params?.onRoomStatusChange);

useEffect(() => {
const roomPromise = wrapRoomPromise(
context.room,
Expand Down
1 change: 1 addition & 0 deletions src/react/helper/use-stable-reference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type Callback<CallbackArguments extends unknown[], ReturnType> = (...args: Callb
* This function creates a stable reference to a callback, so that it can be used in a `useEffect` or `useCallback`
* without causing unnecessary re-renders.
*
* @internal
* @param callback The callback to turn into a stable reference
* @returns A stable reference to the callback
*/
Expand Down

0 comments on commit 70b684b

Please sign in to comment.