react-pro-messenger 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,50 +1,124 @@
1
- # React + TypeScript + Vite
2
-
3
- This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4
-
5
- Currently, two official plugins are available:
6
-
7
- - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8
- - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9
-
10
- ## Expanding the ESLint configuration
11
-
12
- If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
13
-
14
- - Configure the top-level `parserOptions` property like this:
15
-
16
- ```js
17
- export default tseslint.config({
18
- languageOptions: {
19
- // other options...
20
- parserOptions: {
21
- project: ['./tsconfig.node.json', './tsconfig.app.json'],
22
- tsconfigRootDir: import.meta.dirname,
23
- },
24
- },
25
- })
26
- ```
27
-
28
- - Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked`
29
- - Optionally add `...tseslint.configs.stylisticTypeChecked`
30
- - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config:
31
-
32
- ```js
33
- // eslint.config.js
34
- import react from 'eslint-plugin-react'
35
-
36
- export default tseslint.config({
37
- // Set the react version
38
- settings: { react: { version: '18.3' } },
39
- plugins: {
40
- // Add the react plugin
41
- react,
42
- },
43
- rules: {
44
- // other rules...
45
- // Enable its recommended rules
46
- ...react.configs.recommended.rules,
47
- ...react.configs['jsx-runtime'].rules,
48
- },
49
- })
50
- ```
1
+ ## React Pro Messenger
2
+
3
+ A feature-rich chat component with Telegram-inspired UI and modern messaging features.
4
+
5
+ ![Chat Interface Preview](https://github.com/user-attachments/assets/1989e6b1-e6c8-4c1b-a78b-10e979b7544c) ![image](https://github.com/user-attachments/assets/43d19d72-03fb-4637-b913-fedbbd2d58a6) ![image](https://github.com/user-attachments/assets/e47668bf-bae8-4a91-acf9-4ac2432fed39)
6
+
7
+
8
+
9
+ ---
10
+
11
+ ## Features ✨
12
+
13
+ ### Core Functionality
14
+ - Telegram-style messaging interface
15
+ - Multi-user chat support
16
+ - Message history with scroll
17
+ - Responsive design
18
+
19
+ ### Message Types
20
+ - **Text messages** with formatting
21
+ - **Voice messages** with audio player
22
+ - **File attachments** (images, documents)
23
+ - **Symbol integration** (@mentions, #tasks)
24
+
25
+ ### Interactive Features
26
+ - Context menu for message actions
27
+ - Delete/edit message functionality
28
+ - Dynamic symbol recognition:(for example :)
29
+ - `@` for user mentions
30
+ - `#` for task references
31
+ - Animated message transitions
32
+
33
+ ---
34
+
35
+ ## Installation 📦
36
+
37
+ ```bash
38
+ npm install react-pro-messenger
39
+ ```
40
+ # or
41
+ ```bash
42
+ yarn add react-pro-messenger
43
+ ```
44
+
45
+ ## Basic Usage 🚀
46
+
47
+ ```tsx
48
+ import { Chat, MessageEntity } from 'react-pro-messenger';
49
+
50
+ const App = () => {
51
+ const [messages, setMessages] = useState<MessageEntity[]>(initialMessages);
52
+ const currentUser = { id: "user-1", fullName: "John Doe" };
53
+
54
+ return (
55
+ <Chat
56
+ messages={messages}
57
+ user={currentUser}
58
+ onMessageSent={(newMsg) => setMessages([...messages, newMsg])}
59
+ onDeleteMessage={(id) => setMessages(messages.filter(msg => msg.id !== id))}
60
+ />
61
+ );
62
+ };
63
+ ```
64
+ ## Component Props ⚙️
65
+
66
+ ### Chat Component Configuration
67
+
68
+ | Prop | Type | Default | Description |
69
+ |---------------------------|-------------------------------|---------------|------------------------------------------|
70
+ | `messages` | `MessageEntity[]` | **Required** | Array of message objects |
71
+ | `user` | `UserInterface` | **Required** | Current user details |
72
+ | `width` | `string` | `"400px"` | Container width |
73
+ | `height` | `string` | `"600px"` | Container height |
74
+ | `dynamicSymbolAssignments`| `SymbolAssignment[]` | `[]` | Symbol-component mappings |
75
+ | `className` | `string` | `""` | Additional CSS classes |
76
+
77
+ **Key**:
78
+ 📌 `Type` = Expected prop type
79
+ 📌 `Default` = Default value if not required
80
+ 📌 **Required** = Must be provided
81
+
82
+ ## Customization 🎨
83
+
84
+ Symbol Integration
85
+
86
+ ```tsx
87
+ const taskComponent = ({ listsProps, onClick }) => (
88
+ <div className="task-item">
89
+ <span>📌</span>
90
+ <p>{listsProps.name}</p>
91
+ </div>
92
+ );
93
+
94
+ <Chat
95
+ dynamicSymbolAssignments={[{
96
+ symbol: '#',
97
+ component: taskComponent,
98
+ lists: tasksList
99
+ }]}
100
+ />
101
+
102
+ ```
103
+ ## Contributing 🤝
104
+ Fork the repository
105
+
106
+ Create feature branch:
107
+
108
+ ```bash
109
+ git checkout -b feature/new-feature
110
+ ```
111
+ Commit changes:
112
+
113
+ ```bash
114
+ git commit -m 'Add awesome feature'
115
+ ```
116
+ Push to branch:
117
+
118
+ ```bash
119
+ git push origin feature/new-feature
120
+ ```
121
+ Open a Pull Request
122
+
123
+ License 📜
124
+ MIT License © 2023 [mahdij98]
package/package.json CHANGED
@@ -1,18 +1,20 @@
1
1
  {
2
2
  "name": "react-pro-messenger",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Telegram-style chat component for React",
5
5
  "type": "module",
6
6
  "main": "dist/index.umd.js",
7
7
  "module": "dist/index.es.js",
8
8
  "types": "types/index.d.ts",
9
- "files": ["dist", "types"],
9
+ "files": [
10
+ "dist",
11
+ "types"
12
+ ],
10
13
  "scripts": {
11
14
  "dev": "vite --open",
12
15
  "build": "tsc && vite build",
13
- "prepublishOnly": "npm run build",
14
- "lint": "eslint .",
15
- "test": "jest"
16
+ "prepack": "npm run build",
17
+ "lint": "eslint ."
16
18
  },
17
19
  "peerDependencies": {
18
20
  "react": "^18.0.0 || ^19.0.0",
@@ -44,4 +46,4 @@
44
46
  "type": "git",
45
47
  "url": "https://github.com/yourusername/react-pro-messenger.git"
46
48
  }
47
- }
49
+ }
package/types/App.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ export interface TaskInterface {
2
+ id: string;
3
+ name: string;
4
+ }
5
+ export interface TasksProps {
6
+ symbol?: string;
7
+ task: TaskInterface;
8
+ onClick: (id: string, text: string) => void;
9
+ }
10
+ export interface UserPropsInterface {
11
+ id: string;
12
+ name: string;
13
+ }
14
+ export interface UserProps {
15
+ symbol?: string;
16
+ user: UserPropsInterface;
17
+ onClick: (id: string, value: string) => void;
18
+ }
19
+ declare function App(): import("react/jsx-runtime").JSX.Element;
20
+ export default App;
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ interface ConfirmationModalProps {
3
+ isOpen: boolean;
4
+ onClose: () => void;
5
+ onConfirm: () => void;
6
+ header: string;
7
+ question: string;
8
+ }
9
+ declare const ConfirmationModal: React.FC<ConfirmationModalProps>;
10
+ export default ConfirmationModal;
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ export interface ContextMenuItem {
3
+ name: string;
4
+ icon: React.JSX.Element;
5
+ onClick: (id: string) => void;
6
+ onlyCurrentUserMessage?: boolean;
7
+ }
8
+ interface ContextMenuProps {
9
+ items: ContextMenuItem[];
10
+ isVisible: boolean;
11
+ messageId: string;
12
+ position: {
13
+ x: number;
14
+ y: number;
15
+ };
16
+ isCurrentUserMessage: boolean;
17
+ }
18
+ declare const ContextMenu: React.FC<ContextMenuProps>;
19
+ export default ContextMenu;
@@ -0,0 +1,2 @@
1
+ declare const DoubleCheckIcon: () => import("react/jsx-runtime").JSX.Element;
2
+ export default DoubleCheckIcon;
@@ -0,0 +1,2 @@
1
+ declare const FileIcon: () => import("react/jsx-runtime").JSX.Element;
2
+ export default FileIcon;
@@ -0,0 +1,2 @@
1
+ declare const MicIcon: () => import("react/jsx-runtime").JSX.Element;
2
+ export default MicIcon;
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ declare const PlayIcon: (props: React.JSX.IntrinsicElements["svg"]) => import("react/jsx-runtime").JSX.Element;
3
+ export default PlayIcon;
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ declare const PauseIcon: (props: React.JSX.IntrinsicElements["svg"]) => import("react/jsx-runtime").JSX.Element;
3
+ export default PauseIcon;
@@ -0,0 +1,2 @@
1
+ declare const SendIcon: () => import("react/jsx-runtime").JSX.Element;
2
+ export default SendIcon;
@@ -0,0 +1,2 @@
1
+ declare const SpeechBubbleCornerIcon: (props: React.JSX.IntrinsicElements["svg"]) => import("react/jsx-runtime").JSX.Element;
2
+ export default SpeechBubbleCornerIcon;
@@ -0,0 +1,8 @@
1
+ import { SymbolAssignment } from "../../ts/interfaces";
2
+ declare const ChatInput: ({ onSendMessage, onSendVoice, onFileSend, dynamicSymbolAssignments, }: {
3
+ onSendMessage: (newMessage: string) => void;
4
+ onSendVoice: (voiceBlobUrl: string) => void;
5
+ onFileSend: (blob: Blob) => void;
6
+ dynamicSymbolAssignments?: SymbolAssignment<any>[];
7
+ }) => import("react/jsx-runtime").JSX.Element;
8
+ export default ChatInput;
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ interface FilePreviewProps {
3
+ format?: string;
4
+ fileName: string;
5
+ fileSize: number;
6
+ src: string;
7
+ }
8
+ declare const FilePreview: React.FC<FilePreviewProps>;
9
+ export default FilePreview;
@@ -0,0 +1,7 @@
1
+ import { AttachmentTypeEnum } from "../../ts/enum";
2
+ interface MediaProps {
3
+ attachment: string;
4
+ attachmentType?: AttachmentTypeEnum;
5
+ }
6
+ declare const Media: ({ attachment, attachmentType }: MediaProps) => import("react/jsx-runtime").JSX.Element | null | undefined;
7
+ export default Media;
@@ -0,0 +1,6 @@
1
+ interface VoicePlayerProps {
2
+ src: string;
3
+ className?: string;
4
+ }
5
+ declare const VoicePlayer: ({ src, className }: VoicePlayerProps) => import("react/jsx-runtime").JSX.Element;
6
+ export default VoicePlayer;
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { MessageEntity } from "../../../domain/MessageEntity";
3
+ declare const LeftSide: ({ message, showUserProfile, handleContextMenu, media, }: {
4
+ media: React.JSX.Element | null;
5
+ message: MessageEntity;
6
+ showUserProfile: boolean;
7
+ handleContextMenu: (event: React.MouseEvent, message: MessageEntity) => void;
8
+ }) => import("react/jsx-runtime").JSX.Element;
9
+ export default LeftSide;
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ import { MessageEntity } from "../../../domain/MessageEntity";
3
+ declare const RightSide: ({ handleContextMenu, media, message, }: {
4
+ media: React.JSX.Element | null;
5
+ message: MessageEntity;
6
+ handleContextMenu: (event: React.MouseEvent, message: MessageEntity) => void;
7
+ }) => import("react/jsx-runtime").JSX.Element;
8
+ export default RightSide;
@@ -0,0 +1,11 @@
1
+ export interface TaskInterface {
2
+ id: string;
3
+ name: string;
4
+ }
5
+ export interface TasksProps {
6
+ symbol?: string;
7
+ task: TaskInterface;
8
+ onClick: (id: string, text: string) => void;
9
+ }
10
+ declare const Tasks: ({ symbol, onClick, task }: TasksProps) => import("react/jsx-runtime").JSX.Element;
11
+ export default Tasks;
@@ -0,0 +1,34 @@
1
+ import { AttachmentTypeEnum } from "../ts/enum";
2
+ import { UserInterface } from "../ts/interfaces";
3
+ export declare class MessageEntity {
4
+ id: string;
5
+ text: string;
6
+ createdDate: string;
7
+ attachment: undefined | string;
8
+ attachmentType: AttachmentTypeEnum | undefined;
9
+ user: UserInterface;
10
+ isRightSided: boolean | undefined;
11
+ symbols: {
12
+ symbol: string;
13
+ value: {
14
+ name: string;
15
+ id: string;
16
+ };
17
+ } | undefined;
18
+ constructor({ id, text, createdDate, attachment, attachmentType, user, isRightSided, symbols, }: {
19
+ id: string;
20
+ text: string;
21
+ createdDate: string;
22
+ attachment?: string;
23
+ attachmentType?: AttachmentTypeEnum;
24
+ user: UserInterface;
25
+ isRightSided?: boolean;
26
+ symbols?: {
27
+ symbol: string;
28
+ value: {
29
+ name: string;
30
+ id: string;
31
+ };
32
+ } | undefined;
33
+ });
34
+ }
@@ -0,0 +1,18 @@
1
+ import React from "react";
2
+ import { MessageEntity } from "../../domain/MessageEntity";
3
+ import { SymbolAssignment, UserInterface } from "../../ts/interfaces";
4
+ export interface ChatPropsInterface {
5
+ messages: MessageEntity[];
6
+ user: UserInterface;
7
+ width?: string;
8
+ height?: string;
9
+ className?: string;
10
+ style?: React.CSSProperties;
11
+ updateMessages: (messages: MessageEntity[]) => void;
12
+ onMessageSent: (message: MessageEntity) => void;
13
+ dynamicSymbolAssignments?: SymbolAssignment<any>[];
14
+ onDeleteMessage: (id: string) => void;
15
+ onEditMessage: (id: string) => void;
16
+ }
17
+ declare const Chat: ({ width, height, className, style, messages, user, updateMessages, onMessageSent, onDeleteMessage, onEditMessage, dynamicSymbolAssignments, }: ChatPropsInterface) => import("react/jsx-runtime").JSX.Element;
18
+ export default Chat;
@@ -0,0 +1,29 @@
1
+ import React from "react";
2
+ import { ContextMenuItem } from "../../components/ContextMenu/ContextMenu";
3
+ import { MessageEntity } from "../../domain/MessageEntity";
4
+ import { UserInterface } from "../../ts/interfaces";
5
+ declare const Logic: ({ user, messages, updateMessages, onMessageSent, onEditMessage, onDeleteMessage, }: {
6
+ messages: MessageEntity[];
7
+ user: UserInterface;
8
+ updateMessages: (messages: MessageEntity[]) => void;
9
+ onMessageSent: (message: MessageEntity) => void;
10
+ onDeleteMessage: (id: string) => void;
11
+ onEditMessage: (id: string) => void;
12
+ }) => {
13
+ handleDeleteConfirmation: () => void;
14
+ handleCloseContextMenu: () => void;
15
+ contextMenuItems: ContextMenuItem[];
16
+ handleSendFile: (file: Blob) => void;
17
+ handleSendVoice: (voiceBlobUrl: string) => void;
18
+ handleSendMessage: (text: string) => void;
19
+ handleContextMenu: (event: React.MouseEvent, message: MessageEntity) => void;
20
+ isModalOpen: boolean;
21
+ contextMenu: {
22
+ x: number;
23
+ y: number;
24
+ message: MessageEntity | null;
25
+ } | null;
26
+ chatRef: React.RefObject<HTMLDivElement | null>;
27
+ setIsModalOpen: React.Dispatch<React.SetStateAction<boolean>>;
28
+ };
29
+ export default Logic;
@@ -0,0 +1,4 @@
1
+ export { MessageEntity } from "./domain/MessageEntity";
2
+ export { default as Chat } from "./features/Chat";
3
+ export { AttachmentTypeEnum } from "./ts/enum";
4
+ export type { SymbolAssignment, UserInterface } from "./ts/interfaces";
@@ -0,0 +1 @@
1
+ import "./index.css";
@@ -0,0 +1,6 @@
1
+ export declare enum AttachmentTypeEnum {
2
+ "File" = 0,
3
+ "Voice" = 1,
4
+ "Video" = 2,
5
+ "Image" = 3
6
+ }
@@ -0,0 +1,18 @@
1
+ import React from "react";
2
+ export interface UserInterface {
3
+ id: string;
4
+ profileImageUrl?: string;
5
+ fullName?: string;
6
+ firstName?: string;
7
+ lastName?: string;
8
+ }
9
+ export interface SymbolAssignment<T = any> {
10
+ symbol: string;
11
+ component?: ({ onClick, listsProps, }: {
12
+ onClick: (id: string, value: string) => void;
13
+ listsProps: T;
14
+ }) => React.JSX.Element;
15
+ lists?: T[];
16
+ pagNumber: number;
17
+ updatePageNumber: (newPage: number) => void;
18
+ }