Skip to content

Commit

Permalink
Merge branch 'develop' into longMessage
Browse files Browse the repository at this point in the history
  • Loading branch information
Akshun-01 authored Feb 12, 2024
2 parents 008bbfb + 3fef94b commit 3daf25e
Show file tree
Hide file tree
Showing 63 changed files with 1,379 additions and 372 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ node_modules

.vscode

.gitpod.yml
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,8 @@ Similarly, the `api` package depends on the `auth` package. After changes to `au

This setup provides a comprehensive environment for developing and testing the `EmbeddedChat` component, along with its associated `api` and `auth` packages. Enjoy exploring and enhancing the capabilities of `EmbeddedChat`!

### Contributors

<a href="https://github.com/RocketChat/EmbeddedChat/graphs/contributors">
<img src="https://contrib.rocks/image?repo=RocketChat/EmbeddedChat" />
</a>
5 changes: 4 additions & 1 deletion packages/api/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import dts from 'rollup-plugin-dts'
import esbuild from 'rollup-plugin-esbuild'
import packageJson from './package.json' assert { type: 'json' };
import path from 'path';

const name = packageJson.main.replace(/\.js$/, '');

const bundle = config => ({
...config,
input: 'src/index.ts',
external: id => !/^[./]/.test(id),
external: id => {
return id[0] !== '.' && !path.isAbsolute(id);
},
})

export default [
Expand Down
27 changes: 17 additions & 10 deletions packages/api/src/EmbeddedChatApi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Rocketchat } from '@rocket.chat/sdk';
import cloneArray from './cloneArray';
import { IRocketChatAuthOptions, RocketChatAuth } from '@embeddedchat/auth';
import { IRocketChatAuthOptions, RocketChatAuth, ApiError } from '@embeddedchat/auth';

// mutliple typing status can come at the same time they should be processed in order.
let typingHandlerLock = 0;
Expand Down Expand Up @@ -133,6 +133,10 @@ export default class EmbeddedChatApi {
}
return { status: 'success', me: data.me };
} catch (error) {
if (error instanceof ApiError && error.response?.status === 401) {
const authErrorRes = await error.response.json();
return { error: authErrorRes?.error };
}
console.error(error);
}
}
Expand Down Expand Up @@ -407,7 +411,7 @@ export default class EmbeddedChatApi {
try {
const { userId, authToken } = await this.auth.getCurrentUser() || {};
const response = await fetch(
`${this.host}/api/v1/channels.info?roomId=${this.rid}`,
`${this.host}/api/v1/rooms.info?roomId=${this.rid}`,
{
headers: {
'Content-Type': 'application/json',
Expand Down Expand Up @@ -441,7 +445,8 @@ export default class EmbeddedChatApi {
} = {
query: undefined,
field: undefined
}) {
}, isChannelPrivate = false) {
const roomType = isChannelPrivate ? 'groups' : 'channels' ;
const endp = anonymousMode ? 'anonymousread' : 'messages';
const query = options?.query
? `&query=${JSON.stringify(options.query)}`
Expand All @@ -452,7 +457,7 @@ export default class EmbeddedChatApi {
try {
const { userId, authToken } = await this.auth.getCurrentUser() || {};
const messages = await fetch(
`${this.host}/api/v1/channels.${endp}?roomId=${this.rid}${query}${field}`,
`${this.host}/api/v1/${roomType}.${endp}?roomId=${this.rid}${query}${field}`,
{
headers: {
'Content-Type': 'application/json',
Expand All @@ -468,19 +473,20 @@ export default class EmbeddedChatApi {
}
}

async getThreadMessages(tmid: string) {
async getThreadMessages(tmid: string, isChannelPrivate = false) {
return this.getMessages(false, {
query: {
tmid,
},
});
}, isChannelPrivate);
}

async getChannelRoles() {
async getChannelRoles(isChannelPrivate = false) {
const roomType = isChannelPrivate ? 'groups' : 'channels';
try {
const { userId, authToken } = await this.auth.getCurrentUser() || {};
const roles = await fetch(
`${this.host}/api/v1/channels.roles?roomId=${this.rid}`,
`${this.host}/api/v1/${roomType}.roles?roomId=${this.rid}`,
{
headers: {
'Content-Type': 'application/json',
Expand Down Expand Up @@ -796,11 +802,12 @@ export default class EmbeddedChatApi {
}
}

async getChannelMembers() {
async getChannelMembers(isChannelPrivate = false) {
const roomType = isChannelPrivate ? 'groups' : 'channels';
try {
const { userId, authToken } = await this.auth.getCurrentUser() || {};
const response = await fetch(
`${this.host}/api/v1/channels.members?roomId=${this.rid}`,
`${this.host}/api/v1/${roomType}.members?roomId=${this.rid}`,
{
headers: {
'Content-Type': 'application/json',
Expand Down
6 changes: 4 additions & 2 deletions packages/auth/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import dts from 'rollup-plugin-dts'
import esbuild from 'rollup-plugin-esbuild'

import path from 'path';
import packageJson from './package.json' assert { type: 'json' };

const name = packageJson.main.replace(/\.js$/, '');

const bundle = config => ({
...config,
input: 'src/index.ts',
external: id => !/^[./]/.test(id),
external: id => {
return id[0] !== '.' && !path.isAbsolute(id);
},
})

export default [
Expand Down
3 changes: 2 additions & 1 deletion packages/auth/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './auth';
export { default as RocketChatAuth } from './RocketChatAuth';
export * from './IRocketChatAuthOptions';
export * from './IRocketChatAuthOptions';
export {ApiError} from './Api';
149 changes: 149 additions & 0 deletions packages/react/src/components/AllThreads/AllThreads.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import React, { useState, useMemo } from 'react';
import { css } from '@emotion/react';
import classes from './AllThreads.module.css';
import { Icon } from '../Icon';
import { Box } from '../Box';
import { ActionButton } from '../ActionButton';
import { useMessageStore, useUserStore, useThreadsMessageStore } from '../../store';
import { MessageBody } from '../Message/MessageBody';
import { MessageMetrics } from '../Message/MessageMetrics';
import MessageAvatarContainer from '../Message/MessageAvatarContainer';
import MessageBodyContainer from '../Message/MessageBodyContainer';
import MessageHeader from '../Message/MessageHeader';


const MessageCss = css`
display: flex;
flex-direction: row;
align-items: flex-start;
padding-top: 0.5rem;
-webkit-padding-before: 0.5rem;
padding-block-start: 0.5rem;
padding-bottom: 0.25rem;
-webkit-padding-after: 0.25rem;
padding-block-end: 0.25rem;
padding-left: 1.25rem;
padding-right: 1.25rem;
padding-inline: 1.25rem;
cursor: pointer;
&:hover {
background: #f2f3f5;
}
`;

const AllThreads = () => {
const showAvatar = useUserStore((state) => state.showAvatar);
const messages = useMessageStore((state) => state.messages);
const setShowAllThreads = useThreadsMessageStore((state) => state.setShowAllThreads);
const openThread = useMessageStore((state) => state.openThread);
const [text, setText] = useState('');

const toggleShowAllThreads = () => {
setShowAllThreads(false);
};

const handleOpenThread = (msg) => () => {
openThread(msg);
toggleShowAllThreads(false);
};

const handleInputChange = (e) => {
setText(e.target.value);
};

const filteredThreads = useMemo(() => {
return messages.filter((message) =>
message.msg.toLowerCase().includes(text.toLowerCase())
);
}, [messages, text]);

return (
<Box className={classes.component}>
<Box className={classes.wrapContainer}>

<Box style={{ padding: '16px' }}>
<Box css={css`display: flex;`}>
<h3 style={{ display: 'contents' }}>
<Icon
name="thread"
size="1.25rem"
style={{ padding: '0px 20px 20px 0px' }}
/>
<Box css={css`
width: 100%;
color: #4a4a4a;
`}
>
Threads
</Box>
<ActionButton onClick={toggleShowAllThreads} ghost size="small">
<Icon name="cross" size="1.25rem" />
</ActionButton>
</h3>
</Box>

<Box
className={classes.searchContainer}
style={{ border: '2px solid #ddd', position: 'relative' }}
>
<input
placeholder="Search Messages"
onChange={handleInputChange}
className={classes.textInput}
/>

<Icon name="magnifier" size="1.25rem" style={{ padding: '0.125em', cursor: 'pointer' }} />
</Box>
</Box>

<Box
style={{
flex: '1',
overflow: 'auto',
display: 'flex',
flexDirection: 'column',
justifyContent: filteredThreads.length === 0 ? 'center' : 'initial',
alignItems: filteredThreads.length === 0 ? 'center' : 'initial'
}}
>
{filteredThreads.length === 0 ? (
<Box style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', color: '#4a4a4a' }}>
<Icon name="magnifier" size="3rem" style={{ padding: '0.5rem' }} />
<span style={{ fontSize: '1.2rem', fontWeight: 'bold' }}>No threads found</span>
</Box>
) : (filteredThreads
.map((message) => (
!message.t && message.tcount && (
<Box key={message._id} css={MessageCss} onClick={handleOpenThread(message)}>
{showAvatar && (
<MessageAvatarContainer
message={message}
sequential={false}
isStarred={false}
/>
)}
<MessageBodyContainer>
{<MessageHeader message={message} isTimeStamped={false} />}
<MessageBody>
{message.attachments && message.attachments.length > 0 ? (
message.file.name
) : (
message.msg
)}
</MessageBody>

<MessageMetrics
message={message}
isReplyButton={false}
/>
</MessageBodyContainer>
</Box>
)
)))}
</Box>
</Box>
</Box>
);
};

export default AllThreads;
41 changes: 41 additions & 0 deletions packages/react/src/components/AllThreads/AllThreads.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
.component {
position: fixed;
right: 0;
top: 0;
width: 350px;
height: 100%;
overflow: hidden;
background-color: white;
box-shadow: -1px 0px 5px rgb(0 0 0 / 25%);
z-index: 100;
}

.wrapContainer {
height: 100%;
display: flex;
flex-direction: column;
}

.searchContainer {
display: flex;
align-items: center;
justify-content: center;
background-color: #fff;
}

.textInput {
width: 75%;
height: 2.5rem;
border: none;
outline: none;
}

.textInput::placeholder {
padding-left: 5px;
}

@media (max-width: 550px) {
.component {
width: 100vw;
}
}
Loading

0 comments on commit 3daf25e

Please sign in to comment.