diff --git a/packages/react/.gitpod.yml b/packages/react/.gitpod.yml index 9b69587c0..31aed150e 100644 --- a/packages/react/.gitpod.yml +++ b/packages/react/.gitpod.yml @@ -9,5 +9,3 @@ tasks: npm install cd .. command: npm run dev - - diff --git a/packages/react/.storybook/main.js b/packages/react/.storybook/main.js index 7c981da60..e2f163823 100644 --- a/packages/react/.storybook/main.js +++ b/packages/react/.storybook/main.js @@ -1,6 +1,10 @@ /** @type { import('@storybook/react-webpack5').StorybookConfig } */ const config = { - stories: ['../src/**/stories/*.stories.@(js|jsx|ts|tsx)', '../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], + stories: [ + '../src/**/stories/*.stories.@(js|jsx|ts|tsx)', + '../src/**/*.mdx', + '../src/**/*.stories.@(js|jsx|ts|tsx)', + ], addons: [ '@storybook/addon-links', '@storybook/addon-essentials', diff --git a/packages/react/.storybook/preview.js b/packages/react/.storybook/preview.js index 477bc6b4a..82acdc77c 100644 --- a/packages/react/.storybook/preview.js +++ b/packages/react/.storybook/preview.js @@ -1,4 +1,4 @@ -import 'normalize.css' +import 'normalize.css'; /** @type { import('@storybook/react').Preview } */ const preview = { diff --git a/packages/react/README.md b/packages/react/README.md index f01457506..8cbd49d13 100644 --- a/packages/react/README.md +++ b/packages/react/README.md @@ -13,6 +13,7 @@ _EmbeddedChat is a full-stack React component node module of the RocketChat appl ## Installation + ```bash npm install @embeddedchat/react # or @@ -32,10 +33,7 @@ import { EmbeddedChat } from '@embeddedchat/react'; To use the `EmbeddedChat` component, include it in your component's render method or return statement. Here's a basic example: ```jsx - + ``` ### Props @@ -152,6 +150,7 @@ You can pass a `theme` object to customize the appearance according to your appl theme={myCustomTheme} /> ``` + Follow [theming.md](docs/theming.md) to know more about EmbeddedChat's theming. ## Handling the Closable State @@ -167,9 +166,9 @@ If `isClosable` is `true`, provide a `setClosableState` function to manage the s ``` ## Development + Follow this [EmbeddedChat Readme](https://github.com/RocketChat/EmbeddedChat) to setup EmbeddedChat for development. ## Conclusion The `EmbeddedChat` component offers a flexible and feature-rich solution for integrating RocketChat into your application. Customize it according to your needs to enhance your app's chat functionality. - diff --git a/packages/react/docker-compose.yml b/packages/react/docker-compose.yml index 99ea1bf65..40ae5ea59 100644 --- a/packages/react/docker-compose.yml +++ b/packages/react/docker-compose.yml @@ -6,8 +6,8 @@ services: image: registry.rocket.chat/rocketchat/rocket.chat:latest restart: on-failure environment: - MONGO_URL: "mongodb://mongodb:27017/rocketchat?replicaSet=rs0" - MONGO_OPLOG_URL: "mongodb://mongodb:27017/local?replicaSet=rs0" + MONGO_URL: 'mongodb://mongodb:27017/rocketchat?replicaSet=rs0' + MONGO_OPLOG_URL: 'mongodb://mongodb:27017/local?replicaSet=rs0' ROOT_URL: http://localhost:3000 PORT: 3000 depends_on: @@ -15,7 +15,7 @@ services: expose: - 3000 ports: - - "0.0.0.0:3000:3000" + - '0.0.0.0:3000:3000' mongodb: image: docker.io/bitnami/mongodb:4.4 diff --git a/packages/react/docs/theming.md b/packages/react/docs/theming.md index aeca9eda1..abb7c27c6 100644 --- a/packages/react/docs/theming.md +++ b/packages/react/docs/theming.md @@ -27,14 +27,16 @@ For example: ``` In the above example: - - theme.components.ChatInput.styleOverrides would be applied to the style of the ChatInput component. - - theme.components.ChatInput.classNames would be applied to the className of the ChatInput component. + +- theme.components.ChatInput.styleOverrides would be applied to the style of the ChatInput component. +- theme.components.ChatInput.classNames would be applied to the className of the ChatInput component. ## Using the useComponentsOverrides Hook + We provide a `useComponentsOverrides` hook that returns the necessary data for component customization. ```jsx -import { useComponentOverrides } from '../../theme/useComponentOverrides'; +import { useComponentOverrides } from '../../theme/useComponentOverrides'; export const MessageBody = ({ children, @@ -60,11 +62,13 @@ export const MessageBody = ({ ); }; ``` + ## Adding Classes to Components + We also add a class to each component. For example, `ec-message-body` for the MessageBody component. Feel free to explore and customize these components according to your project's needs. If you have any questions or need further assistance, please don't hesitate to ask. -Happy theming! \ No newline at end of file +Happy theming! diff --git a/packages/react/rollup.config.js b/packages/react/rollup.config.js index 807cb997a..ad76a9d97 100644 --- a/packages/react/rollup.config.js +++ b/packages/react/rollup.config.js @@ -7,7 +7,7 @@ import json from '@rollup/plugin-json'; import bundleSize from 'rollup-plugin-bundle-size'; import { terser } from 'rollup-plugin-terser'; import replace from '@rollup/plugin-replace'; -import analyze from 'rollup-plugin-analyzer' +import analyze from 'rollup-plugin-analyzer'; const packageJson = require('./package.json'); const PRODUCTION = process.env.NODE_ENV === 'production'; @@ -40,7 +40,10 @@ export default [ } : {} ), - resolve({ browser: true, extensions: ['.js', '.jsx', '.ts', '.tsx', '.mjs'] }), + resolve({ + browser: true, + extensions: ['.js', '.jsx', '.ts', '.tsx', '.mjs'], + }), commonjs({ include: ['node_modules/**', '../../node_modules/**'] }), babel({ exclude: 'node_modules/**', diff --git a/packages/react/src/components/Icon/icons/Copy.js b/packages/react/src/components/Icon/icons/Copy.js new file mode 100644 index 000000000..f32df0edd --- /dev/null +++ b/packages/react/src/components/Icon/icons/Copy.js @@ -0,0 +1,35 @@ +import React from 'react'; + +const Copy = () => ( + + + + + + + + +); + +export default Copy; diff --git a/packages/react/src/components/Icon/icons/index.js b/packages/react/src/components/Icon/icons/index.js index 2ea3fa05a..490e0982b 100644 --- a/packages/react/src/components/Icon/icons/index.js +++ b/packages/react/src/components/Icon/icons/index.js @@ -38,6 +38,7 @@ import ArrowDown from './ArrowDown'; import PinFilled from './PinFilled'; import VideoRecorder from './VideoRecoder'; import DisabledRecorder from './DisableRecorder'; +import Copy from './Copy'; const icons = { file: File, @@ -80,6 +81,7 @@ const icons = { 'error-circle': ErrorCircle, 'arrow-down': ArrowDown, 'pin-filled': PinFilled, + copy: Copy, }; export default icons; diff --git a/packages/react/src/components/Message/Message.js b/packages/react/src/components/Message/Message.js index f07cc9727..11a30a788 100644 --- a/packages/react/src/components/Message/Message.js +++ b/packages/react/src/components/Message/Message.js @@ -123,6 +123,43 @@ const Message = ({ }); } }; + const handleCopyMessage = async (msg) => { + navigator.clipboard + .writeText(msg.msg) + .then(() => { + dispatchToastMessage({ + type: 'success', + message: 'Message copied successfully', + }); + }) + .catch(() => { + dispatchToastMessage({ + type: 'error', + message: 'Error in copying message', + }); + }); + }; + const getMessageLink = async (id) => { + const host = await RCInstance.getHost(); + const res = await RCInstance.channelInfo(); + return `${host}/channel/${res.room.name}/?msg=${id}`; + }; + + const handleCopyMessageLink = async (msg) => { + try { + const messageLink = await getMessageLink(msg._id); + await navigator.clipboard.writeText(messageLink); + dispatchToastMessage({ + type: 'success', + message: 'Message link copied successfully', + }); + } catch (err) { + dispatchToastMessage({ + type: 'error', + message: 'Error in copying message link', + }); + } + }; const handleEmojiClick = async (e, msg, canReact) => { const emoji = (e.names?.[0] || e.name).replace(/\s/g, '_'); @@ -224,6 +261,8 @@ const Message = ({ handleDeleteMessage={handleDeleteMessage} handleStarMessage={handleStarMessage} handlePinMessage={handlePinMessage} + handleCopyMessage={handleCopyMessage} + handleCopyMessageLink={handleCopyMessageLink} handleEditMessage={() => { if (editMessage._id === message._id) { setEditMessage({}); diff --git a/packages/react/src/components/Message/MessageToolbox.js b/packages/react/src/components/Message/MessageToolbox.js index 8826bc026..1b9c01e16 100644 --- a/packages/react/src/components/Message/MessageToolbox.js +++ b/packages/react/src/components/Message/MessageToolbox.js @@ -57,6 +57,8 @@ export const MessageToolbox = ({ handleDeleteMessage, handlerReportMessage, handleEditMessage, + handleCopyMessage, + handleCopyMessageLink, isEditing = false, ...props }) => { @@ -143,6 +145,18 @@ export const MessageToolbox = ({ icon="edit" onClick={() => handleEditMessage(message)} /> + handleCopyMessageLink(message)} + /> + handleCopyMessage(message)} + />