@codewithvincent/react-native-love-chat 0.1.0

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE +21 -0
  3. package/README.md +152 -0
  4. package/dist/Chat.d.ts +3 -0
  5. package/dist/Chat.js +78 -0
  6. package/dist/components/Bubble.d.ts +21 -0
  7. package/dist/components/Bubble.js +55 -0
  8. package/dist/components/Composer.d.ts +14 -0
  9. package/dist/components/Composer.js +44 -0
  10. package/dist/components/FooterReplyPreview.d.ts +7 -0
  11. package/dist/components/FooterReplyPreview.js +130 -0
  12. package/dist/components/Icons.d.ts +21 -0
  13. package/dist/components/Icons.js +71 -0
  14. package/dist/components/InputToolbar.d.ts +17 -0
  15. package/dist/components/InputToolbar.js +110 -0
  16. package/dist/components/Message.d.ts +21 -0
  17. package/dist/components/Message.js +131 -0
  18. package/dist/components/MessageList.d.ts +6 -0
  19. package/dist/components/MessageList.js +111 -0
  20. package/dist/components/MessageStatus.d.ts +6 -0
  21. package/dist/components/MessageStatus.js +59 -0
  22. package/dist/components/ReactionBubble.d.ts +55 -0
  23. package/dist/components/ReactionBubble.js +262 -0
  24. package/dist/components/ReplyPreview.d.ts +7 -0
  25. package/dist/components/ReplyPreview.js +102 -0
  26. package/dist/components/UploadFooter.d.ts +4 -0
  27. package/dist/components/UploadFooter.js +33 -0
  28. package/dist/components/adapters/UniversalAudio.d.ts +8 -0
  29. package/dist/components/adapters/UniversalAudio.js +23 -0
  30. package/dist/components/adapters/UniversalBlurView.d.ts +3 -0
  31. package/dist/components/adapters/UniversalBlurView.js +26 -0
  32. package/dist/components/adapters/UniversalVideo.d.ts +8 -0
  33. package/dist/components/adapters/UniversalVideo.js +20 -0
  34. package/dist/components/media/AudioCard.d.ts +7 -0
  35. package/dist/components/media/AudioCard.js +187 -0
  36. package/dist/components/media/FileCard.d.ts +8 -0
  37. package/dist/components/media/FileCard.js +68 -0
  38. package/dist/components/media/ImageCard.d.ts +9 -0
  39. package/dist/components/media/ImageCard.js +76 -0
  40. package/dist/components/media/VideoCard.d.ts +10 -0
  41. package/dist/components/media/VideoCard.js +232 -0
  42. package/dist/index.d.ts +9 -0
  43. package/dist/index.js +36 -0
  44. package/dist/types.d.ts +71 -0
  45. package/dist/types.js +2 -0
  46. package/dist/utils/index.d.ts +14 -0
  47. package/dist/utils/index.js +44 -0
  48. package/dist/utils/theme.d.ts +77 -0
  49. package/dist/utils/theme.js +55 -0
  50. package/package.json +67 -0
@@ -0,0 +1,71 @@
1
+ import { PartialTheme } from './utils/theme';
2
+ export interface IUser {
3
+ _id: string | number;
4
+ name?: string;
5
+ avatar?: string | number;
6
+ }
7
+ export interface IMessage {
8
+ _id: string | number;
9
+ text: string;
10
+ createdAt: Date | number;
11
+ user: IUser;
12
+ image?: string;
13
+ video?: string;
14
+ audio?: string;
15
+ system?: boolean;
16
+ sent?: boolean;
17
+ received?: boolean;
18
+ pending?: boolean;
19
+ quickReplies?: any;
20
+ caption?: string;
21
+ fileName?: string;
22
+ fileType?: string;
23
+ fileUrl?: string;
24
+ replyTo?: IMessage;
25
+ reactions?: any[];
26
+ status?: 'pending' | 'sent' | 'delivered' | 'read';
27
+ isMine?: boolean;
28
+ }
29
+ export interface ChatProps {
30
+ messages: IMessage[];
31
+ user: IUser;
32
+ onSend: (messages: IMessage[]) => void;
33
+ placeholder?: string;
34
+ text?: string;
35
+ onInputTextChanged?: (text: string) => void;
36
+ dateFormat?: string;
37
+ timeFormat?: string;
38
+ renderBubble?: (props: any) => React.ReactNode;
39
+ renderInputToolbar?: (props: any) => React.ReactNode;
40
+ renderComposer?: (props: any) => React.ReactNode;
41
+ renderSend?: (props: any) => React.ReactNode;
42
+ renderAvatar?: (props: any) => React.ReactNode;
43
+ renderMessage?: (props: any) => React.ReactNode;
44
+ renderMessageText?: (props: any) => React.ReactNode;
45
+ renderMessageImage?: (props: any) => React.ReactNode;
46
+ renderMessageVideo?: (props: any) => React.ReactNode;
47
+ renderMessageAudio?: (props: any) => React.ReactNode;
48
+ renderFooter?: () => React.ReactNode;
49
+ renderChatFooter?: () => React.ReactNode;
50
+ renderUploadFooter?: (props: any) => React.ReactNode;
51
+ loadEarlier?: boolean;
52
+ onLoadEarlier?: () => void;
53
+ isLoadingEarlier?: boolean;
54
+ inverted?: boolean;
55
+ listViewProps?: any;
56
+ onPressActionButton?: () => void;
57
+ renderActions?: (props: any) => React.ReactNode;
58
+ textInputProps?: any;
59
+ minInputToolbarHeight?: number;
60
+ onPressAttachment?: (type: string) => void;
61
+ onReply?: (message: IMessage) => void;
62
+ onClearReply?: () => void;
63
+ onReaction?: (message: IMessage, reaction: string) => void;
64
+ onDeleteMessage?: (message: IMessage) => void;
65
+ onDownloadFile?: (message: IMessage) => void;
66
+ keyboardShouldPersistTaps?: 'always' | 'never' | 'handled';
67
+ isTyping?: boolean;
68
+ theme?: PartialTheme;
69
+ containerStyle?: any;
70
+ messagesContainerStyle?: any;
71
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,14 @@
1
+ export declare const appSize: {
2
+ width: (percent: number) => number;
3
+ height: (percent: number) => number;
4
+ font: (size: number) => number;
5
+ SCREEN_WIDTH: number;
6
+ SCREEN_HEIGHT: number;
7
+ };
8
+ export declare const Logger: {
9
+ info: (...args: any[]) => void;
10
+ error: (...args: any[]) => void;
11
+ debug: (...args: any[]) => void;
12
+ };
13
+ export declare const isSameUser: (currentMessage: any, diffMessage: any) => boolean;
14
+ export declare const isSameDay: (currentMessage: any, diffMessage: any) => boolean;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isSameDay = exports.isSameUser = exports.Logger = exports.appSize = void 0;
4
+ const react_native_1 = require("react-native");
5
+ const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = react_native_1.Dimensions.get('window');
6
+ const widthPercentageToDP = (widthPercent) => {
7
+ const elemWidth = typeof widthPercent === "number" ? widthPercent : parseFloat(widthPercent);
8
+ return react_native_1.PixelRatio.roundToNearestPixel((SCREEN_WIDTH * elemWidth) / 100);
9
+ };
10
+ const heightPercentageToDP = (heightPercent) => {
11
+ const elemHeight = typeof heightPercent === "number" ? heightPercent : parseFloat(heightPercent);
12
+ return react_native_1.PixelRatio.roundToNearestPixel((SCREEN_HEIGHT * elemHeight) / 100);
13
+ };
14
+ // Layout utility similar to the original appSize
15
+ exports.appSize = {
16
+ width: (percent) => widthPercentageToDP(percent),
17
+ height: (percent) => heightPercentageToDP(percent),
18
+ font: (size) => size * (SCREEN_WIDTH / 375), // approximate scaling
19
+ SCREEN_WIDTH,
20
+ SCREEN_HEIGHT,
21
+ };
22
+ exports.Logger = {
23
+ info: (...args) => console.log('[Chat]', ...args),
24
+ error: (...args) => console.error('[Chat Error]', ...args),
25
+ debug: (...args) => console.debug('[Chat Debug]', ...args),
26
+ };
27
+ const isSameUser = (currentMessage, diffMessage) => {
28
+ return !!(diffMessage &&
29
+ diffMessage.user &&
30
+ currentMessage.user &&
31
+ diffMessage.user._id === currentMessage.user._id);
32
+ };
33
+ exports.isSameUser = isSameUser;
34
+ const isSameDay = (currentMessage, diffMessage) => {
35
+ if (!diffMessage || !diffMessage.createdAt) {
36
+ return false;
37
+ }
38
+ const currentCreatedAt = new Date(currentMessage.createdAt);
39
+ const diffCreatedAt = new Date(diffMessage.createdAt);
40
+ return (currentCreatedAt.getDate() === diffCreatedAt.getDate() &&
41
+ currentCreatedAt.getMonth() === diffCreatedAt.getMonth() &&
42
+ currentCreatedAt.getFullYear() === diffCreatedAt.getFullYear());
43
+ };
44
+ exports.isSameDay = isSameDay;
@@ -0,0 +1,77 @@
1
+ import React from 'react';
2
+ export declare const defaultTheme: {
3
+ colors: {
4
+ primary: string;
5
+ darkPrimary: string;
6
+ lightRed: string;
7
+ darkRed: string;
8
+ black: string;
9
+ lightBlack: string;
10
+ gray: string;
11
+ white: string;
12
+ darkBrown: string;
13
+ lightGrey: string;
14
+ softGray: string;
15
+ borderGray: string;
16
+ textGray: string;
17
+ softRed: string;
18
+ verySoftGray: string;
19
+ timestamp: string;
20
+ ownMessageBubble: string;
21
+ otherMessageBubble: string;
22
+ ownMessageText: string;
23
+ otherMessageText: string;
24
+ ownFileBg: string;
25
+ otherFileBg: string;
26
+ };
27
+ fonts: {
28
+ light: string;
29
+ regular: string;
30
+ medium: string;
31
+ semiBold: string;
32
+ bold: string;
33
+ extraBold: string;
34
+ };
35
+ };
36
+ export type Theme = typeof defaultTheme;
37
+ export type PartialTheme = {
38
+ [K in keyof Theme]?: Partial<Theme[K]>;
39
+ };
40
+ export declare const useTheme: () => {
41
+ colors: {
42
+ primary: string;
43
+ darkPrimary: string;
44
+ lightRed: string;
45
+ darkRed: string;
46
+ black: string;
47
+ lightBlack: string;
48
+ gray: string;
49
+ white: string;
50
+ darkBrown: string;
51
+ lightGrey: string;
52
+ softGray: string;
53
+ borderGray: string;
54
+ textGray: string;
55
+ softRed: string;
56
+ verySoftGray: string;
57
+ timestamp: string;
58
+ ownMessageBubble: string;
59
+ otherMessageBubble: string;
60
+ ownMessageText: string;
61
+ otherMessageText: string;
62
+ ownFileBg: string;
63
+ otherFileBg: string;
64
+ };
65
+ fonts: {
66
+ light: string;
67
+ regular: string;
68
+ medium: string;
69
+ semiBold: string;
70
+ bold: string;
71
+ extraBold: string;
72
+ };
73
+ };
74
+ export declare const ThemeProvider: ({ theme, children, }: {
75
+ theme?: PartialTheme;
76
+ children: React.ReactNode;
77
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ThemeProvider = exports.useTheme = exports.defaultTheme = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ exports.defaultTheme = {
7
+ colors: {
8
+ primary: '#e6e1e1',
9
+ darkPrimary: '#e3e3e4ff',
10
+ lightRed: '#EB5757',
11
+ darkRed: '#ef4136',
12
+ black: '#000',
13
+ lightBlack: '#605e5eff',
14
+ gray: '#999',
15
+ white: '#fff',
16
+ darkBrown: '#54392A',
17
+ lightGrey: '#f8f8f8',
18
+ softGray: '#fafafa',
19
+ borderGray: '#eee',
20
+ textGray: '#eee',
21
+ softRed: '#fff7f7',
22
+ verySoftGray: '#f9f9f9',
23
+ timestamp: '#8b8b8b',
24
+ ownMessageBubble: '#EB5757',
25
+ otherMessageBubble: '#f9f9f9',
26
+ ownMessageText: '#fff',
27
+ otherMessageText: '#000',
28
+ ownFileBg: 'rgba(0, 0, 0, 0.1)',
29
+ otherFileBg: 'rgba(0, 0, 0, 0.05)',
30
+ },
31
+ fonts: {
32
+ light: 'System',
33
+ regular: 'System',
34
+ medium: 'System',
35
+ semiBold: 'System',
36
+ bold: 'System',
37
+ extraBold: 'System',
38
+ },
39
+ };
40
+ const ThemeContext = (0, react_1.createContext)(exports.defaultTheme);
41
+ const useTheme = () => (0, react_1.useContext)(ThemeContext);
42
+ exports.useTheme = useTheme;
43
+ const ThemeProvider = ({ theme, children, }) => {
44
+ const mergedTheme = (0, react_1.useMemo)(() => {
45
+ if (!theme)
46
+ return exports.defaultTheme;
47
+ return {
48
+ ...exports.defaultTheme,
49
+ colors: { ...exports.defaultTheme.colors, ...theme.colors },
50
+ fonts: { ...exports.defaultTheme.fonts, ...theme.fonts },
51
+ };
52
+ }, [theme]);
53
+ return ((0, jsx_runtime_1.jsx)(ThemeContext.Provider, { value: mergedTheme, children: children }));
54
+ };
55
+ exports.ThemeProvider = ThemeProvider;
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@codewithvincent/react-native-love-chat",
3
+ "version": "0.1.0",
4
+ "description": "A fully featured React Native chat UI component with replies, reactions, media, and theming.",
5
+ "license": "MIT",
6
+ "private": false,
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "files": [
10
+ "dist",
11
+ "README.md",
12
+ "LICENSE",
13
+ "CHANGELOG.md"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc -p tsconfig.json",
17
+ "prepare": "npm run build",
18
+ "test": "jest",
19
+ "typecheck": "tsc --noEmit -p tsconfig.json",
20
+ "lint": "echo \"No lint configured\""
21
+ },
22
+ "peerDependencies": {
23
+ "react": ">=18.0.0",
24
+ "react-native": ">=0.73.0",
25
+ "react-native-gesture-handler": ">=2.12.0",
26
+ "react-native-reanimated": ">=3.6.0",
27
+ "react-native-safe-area-context": ">=4.10.0",
28
+ "react-native-root-siblings": ">=4.2.1",
29
+ "@shopify/flash-list": ">=1.6.3",
30
+ "react-native-svg": ">=15.0.0"
31
+ },
32
+ "peerDependenciesMeta": {
33
+ "@react-native-community/blur": {
34
+ "optional": true
35
+ },
36
+ "expo-blur": {
37
+ "optional": true
38
+ }
39
+ },
40
+ "devDependencies": {
41
+ "typescript": "^5.3.3",
42
+ "jest": "^29.7.0",
43
+ "@types/jest": "^29.5.11",
44
+ "ts-jest": "^29.2.4",
45
+ "jest-environment-jsdom": "^29.7.0",
46
+ "babel-jest": "^29.7.0",
47
+ "@babel/core": "^7.23.9",
48
+ "metro-react-native-babel-preset": "^0.76.8",
49
+ "@testing-library/react-native": "^12.4.3",
50
+ "react-test-renderer": "18.2.0",
51
+ "react-native": "0.73.6",
52
+ "react": "18.2.0"
53
+ },
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "https://github.com/your-org/react-native-standalone-chat.git"
57
+ },
58
+ "keywords": [
59
+ "react-native",
60
+ "chat",
61
+ "ui",
62
+ "messages",
63
+ "reactions",
64
+ "reply",
65
+ "components"
66
+ ]
67
+ }