Skip to content

Commit

Permalink
Merge pull request #227 from ably-labs/refactor-MessageComponent-in-demo
Browse files Browse the repository at this point in the history
Show createdAt and clientId in demo app + rename Message to MessageComponent
  • Loading branch information
vladvelici authored Jun 26, 2024
2 parents c4b4b1a + 34a74af commit bf95d5d
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 50 deletions.
39 changes: 0 additions & 39 deletions demo/src/components/Message/Message.tsx

This file was deleted.

1 change: 0 additions & 1 deletion demo/src/components/Message/index.ts

This file was deleted.

60 changes: 60 additions & 0 deletions demo/src/components/MessageComponent/MessageComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Message } from '@ably-labs/chat';
import React, { useCallback } from 'react';
import clsx from 'clsx';

function twoDigits(input : number) : string {
if (input === 0) {
return "00";
}
if (input < 10) {
return "0"+input;
}
return ""+input;
}

interface MessageProps {
id: string;
self?: boolean;
message: Message;
onMessageClick?(id: string): void;
}
export const MessageComponent: React.FC<MessageProps> = ({ id, self = false, message, onMessageClick }) => {
const handleMessageClick = useCallback(() => {
onMessageClick?.(id);
}, [id, onMessageClick]);

let displayCreatedAt : string;
if (new Date().getTime() - message.createdAt.getTime() < 1000 * 60 * 60 * 24) {
// last 24h show the time
displayCreatedAt = twoDigits(message.createdAt.getHours()) + ":" + twoDigits(message.createdAt.getMinutes());
} else {
// older, show full date
displayCreatedAt = message.createdAt.getDate()+"/"+message.createdAt.getMonth()+"/"+message.createdAt.getFullYear() + " " + twoDigits(message.createdAt.getHours()) + ":" + twoDigits(message.createdAt.getMinutes());
}

return (
<div
className="chat-message"
onClick={handleMessageClick}
>
<div className={clsx('flex items-end', { ['justify-end']: self, ['justify-start']: !self })}>
<div
className={clsx('flex flex-col text max-w-xs mx-2', {
['items-end order-1']: self,
['items-start order-2']: !self,
})}
>
<div className="text-xs"><span>{ message.clientId }</span> &middot; <span className="sent-at-time"><span className="short">{ displayCreatedAt }</span><span className="long">{ message.createdAt.toLocaleString() }</span></span></div>
<div
className={clsx('px-4 py-2 rounded-lg inline-block', {
['rounded-br bg-blue-600 text-white']: self,
['rounded-bl justify-start bg-gray-300 text-gray-600']: !self,
})}
>
{ message.content }
</div>
</div>
</div>
</div>
);
};
1 change: 1 addition & 0 deletions demo/src/components/MessageComponent/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { MessageComponent } from './MessageComponent.tsx';
8 changes: 4 additions & 4 deletions demo/src/components/MessageInput/MessageInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,22 @@ export const MessageInput: FC<MessageInputProps> = ({
return (
<form
onSubmit={handleFormSubmit}
className="relative flex"
className="flex"
>
<input
type="text"
value={value}
onChange={handleValueChange}
disabled={disabled}
placeholder="Type.."
className="w-full focus:outline-none focus:placeholder-gray-400 text-gray-600 placeholder-gray-600 pl-2 bg-gray-200 rounded-md py-1"
className="w-full focus:outline-none focus:placeholder-gray-400 text-gray-600 placeholder-gray-600 pl-2 pr-2 bg-gray-200 rounded-l-md py-1"
autoFocus
/>
<div className="absolute right-0 items-center inset-y-0 hidden sm:flex">
<div className="items-center inset-y-0 hidden sm:flex">
<button
disabled={disabled}
type="submit"
className="inline-flex items-center justify-center rounded-md px-3 py-1 transition duration-500 ease-in-out text-white bg-blue-500 hover:bg-blue-400 focus:outline-none"
className="inline-flex items-center justify-center rounded-r-md px-3 py-1 transition duration-500 ease-in-out text-white bg-blue-500 hover:bg-blue-400 focus:outline-none"
>
Send
<svg
Expand Down
45 changes: 39 additions & 6 deletions demo/src/containers/Chat/Chat.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useCallback, useEffect, useState } from 'react';
import { Message as MessageComponent } from '../../components/Message';
import { MessageComponent } from '../../components/MessageComponent';
import { MessageInput } from '../../components/MessageInput';
import { useMessages } from '../../hooks/useMessages';
import { useTypingIndicators } from '../../hooks/useTypingIndicators.ts';
Expand Down Expand Up @@ -28,8 +28,44 @@ export const Chat = () => {
[sendMessage],
);

/**
* In a real app, changing the logged in user typically means navigating to
* some sort of login page and then navigating back to the main app.
*
* There is no real login here. We just have to specify a clientId in the
* request that we sent to get a valid token from our function at
* demo/api/ably-token-request. This happens when the demo app loads the
* first time and periodically to refresh the token (handled by ably-js).
*
* See demo/src/main.tsx to see how the clientId is initially set (random
* and saved in sessionStorage for consistency between page refreshes). This
* function sets the given clientId in sessionStorage and refreshes the page,
* meaning the new clientId will be read and set on page load.
*
* In a live app if you need to re-authenticate with another clientId you
* will need to stop everything including the Ably Pubsub Client and restart
* with the new clientId. Neither libraries support changing the clientId
* witohut reconnecting. Typically changing user is achieved by navigating to
* a login page and back, unless the login page is part of the same single-
* page app as the chat.
*
* Ably and Ably Chat also offer a feature called Presence where user profile
* data can be attached (things like avatar URLs or display names). Editing a
* profile through Presence is possible without dropping the connection and
* it does not change the clientId. See @todo link to docs for Presence.
*/
function changeClientId() {
const newClientId = prompt("Enter your new clientId");
if (!newClientId) {
return;
}
sessionStorage.setItem("ably-chat-demo-clientId", newClientId);
window.location.reload();
}

return (
<div className="flex-1 p:2 sm:p-12 justify-between flex flex-col h-screen">
<div className="text-xs p-3" style={{"backgroundColor": "#333"}}>You are <strong>{clientId}</strong>. <a href="#" className="text-blue-600 dark:text-blue-500 hover:underline" onClick={changeClientId} >Change clientId</a>.</div>
{loading && <div>loading...</div>}
{!loading && (
<div
Expand All @@ -41,11 +77,8 @@ export const Chat = () => {
id={msg.timeserial}
key={msg.timeserial}
self={msg.clientId === clientId}
>
<div className="flex flex-col">
<div>{msg.content}</div>
</div>
</MessageComponent>
message={msg}
></MessageComponent>
))}
</div>
)}
Expand Down
16 changes: 16 additions & 0 deletions demo/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,20 @@ body {
.reactions-picker > a:active {
scale: 1.4;
transform: rotate(7deg);
}

.sent-at-time > .short {
display: inline;
}

.sent-at-time > .long {
display: none;
}

.sent-at-time:hover > .long {
display: inline;
}

.sent-at-time:hover > .short {
display: none;
}

0 comments on commit bf95d5d

Please sign in to comment.