softchatjs-react-native
Version:
React native UI SDK for softchatjs-core. Create a free account at: https://www.softchatjs.com
554 lines (536 loc) • 18.9 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/components/Chat/ChatItem/Quoted.tsx
var Quoted_exports = {};
__export(Quoted_exports, {
default: () => Quoted
});
module.exports = __toCommonJS(Quoted_exports);
var import_react8 = __toESM(require("react"));
var import_react_native5 = require("react-native");
var import_softchatjs_core2 = require("softchatjs-core");
// src/components/Chat/ChatItem/Sticker.tsx
var import_react = __toESM(require("react"));
var import_expo_image = require("expo-image");
function Sticker(props) {
const { message } = props;
const renderSicker = (0, import_react.useCallback)(() => {
return /* @__PURE__ */ import_react.default.createElement(
import_expo_image.Image,
{
source: { uri: message.attachedMedia[0].mediaUrl },
cachePolicy: "disk",
style: { height: 70, width: 70, borderRadius: 8 }
}
);
}, []);
return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, renderSicker());
}
// src/components/Chat/MessageAvatar.tsx
var import_react5 = __toESM(require("react"));
var import_react_native2 = require("react-native");
// src/constants/Colors.ts
var Colors = {
greyLighter: "#F0F0F0"
};
// src/components/Chat/MessageAvatar.tsx
var import_expo_image2 = require("expo-image");
// src/contexts/ChatProvider.tsx
var import_react4 = __toESM(require("react"));
// src/contexts/ModalProvider.tsx
var import_react2 = __toESM(require("react"));
var import_react_native = require("react-native");
var initial = {
displayModal: () => {
},
resetModal: () => {
},
modalProps: {
dismissable: true,
justifyContent: "center",
children: null,
animation: "slide",
containerWidth: "100%"
}
};
var ModalProviderContext = (0, import_react2.createContext)(initial);
// src/theme/colors.ts
var teal = {
50: "#DCF2F0",
100: "#A9DFD8",
200: "#73CABE",
300: "#3AB4A4",
400: "#00A391",
500: "#00927E",
600: "#008572",
700: "#007662",
800: "#006654",
900: "#004A38"
};
var green = {
50: "#E6F5E4",
100: "#C2E6BD",
200: "#9AD693",
300: "#6FC666",
400: "#4ABA42",
500: "#17AE13",
600: "#029F04",
700: "#008D00",
800: "#007C00",
900: "#005E00"
};
var grey = {
50: "#F6F6FF",
100: "#F2F1FF",
200: "#EBEBF9",
300: "#CAC9D7",
400: "#ACACB9",
500: "#82818F",
600: "#6D6D7A",
700: "#4D4D59",
800: "#2B2B36",
900: "#21222D",
A100: "#1D1E26"
};
var stone = {
50: "#F8F8F8",
100: "#EFEFEF",
200: "#E8E8E8",
300: "#D9D9D9",
400: "#D2D2D2",
500: "#A0A0A0",
600: "#87888C",
700: "#2C2D33",
800: "#1D1E26",
900: "#171821"
};
// src/theme/index.ts
var theme = {
background: {
primary: stone[900],
secondary: grey[900],
disabled: grey[800]
},
text: {
primary: "black",
secondary: stone[200],
disabled: stone[500]
},
action: {
primary: teal[50],
secondary: stone[300]
},
chatBubble: {
left: {
bgColor: grey[900],
messageColor: stone[200],
messageTimeColor: "grey",
replyBorderColor: stone[200]
},
right: {
bgColor: "#474952",
messageColor: "white",
messageTimeColor: "grey",
replyBorderColor: green[900]
}
},
icon: "white",
divider: stone[700]
};
var theme_default = theme;
// src/contexts/MessageStateContext.tsx
var import_react3 = __toESM(require("react"));
var import_expo_av = require("expo-av");
// src/constants/defaultUser.ts
var defaultUser_default = {
id: "",
uid: "",
username: "",
firstname: "",
lastname: "",
profileUrl: "",
color: "",
custom: {}
};
// src/contexts/MessageStateContext.tsx
var initialMessageStateContext = {
globalTextMessage: "",
setGlobalTextMessage: () => {
},
stickers: [],
setStickers: () => {
},
pendingMessages: [],
addNewPendingMessages: (message) => {
},
removePendingMessage: (messageId) => {
},
updatePendingMessage: (messageId, message) => {
},
playVoiceMessage: (media) => {
},
pauseVoiceMessage: () => {
},
resumeVoiceMessage: () => {
},
audioState: null,
unload: () => {
},
sound: null,
activeVoiceMessage: null,
avPlayBackStatus: null,
userMeta: defaultUser_default,
setUserMeta: () => {
},
conversationList: [],
setConversationList: () => {
}
};
var MessageStateContext = (0, import_react3.createContext)(
initialMessageStateContext
);
// src/contexts/ChatProvider.tsx
var ConfigContext = (0, import_react4.createContext)({
theme: theme_default,
client: null,
fontFamily: void 0,
fontScale: 1
});
function useConfig() {
return (0, import_react4.useContext)(ConfigContext);
}
// src/components/Chat/MessageAvatar.tsx
function MessageAvatar(props) {
const { imgUrl, initials, size = 40, style } = props;
const { fontFamily } = useConfig();
return /* @__PURE__ */ import_react5.default.createElement(
import_react_native2.TouchableOpacity,
{
style: {
height: size,
width: size,
borderRadius: size,
backgroundColor: "black",
alignItems: "center",
justifyContent: "center",
...style
}
},
imgUrl ? /* @__PURE__ */ import_react5.default.createElement(
import_expo_image2.Image,
{
source: { uri: imgUrl },
cachePolicy: "disk",
style: {
height: size,
width: size,
borderRadius: size,
backgroundColor: Colors.greyLighter
}
}
) : /* @__PURE__ */ import_react5.default.createElement(
import_react_native2.Text,
{
style: {
fontSize: size / 2,
textTransform: "uppercase",
color: "white",
fontFamily
}
},
initials
)
);
}
// src/utils/index.ts
var import_moment = __toESM(require("moment"));
var import_softchatjs_core = require("softchatjs-core");
var truncate = (str, len) => {
return str.length > len ? str.substring(0, len) + "..." : str;
};
function convertToMinutes(seconds) {
var _seconds = Number(seconds.toFixed(0));
const minutes = Math.floor(_seconds / 60);
const remainingSeconds = _seconds % 60;
const paddedMinutes = String(minutes).padStart(2, "0");
const paddedSeconds = String(remainingSeconds).padStart(2, "0");
return `${paddedMinutes}:${paddedSeconds}`;
}
// src/assets/icons.tsx
var import_react6 = __toESM(require("react"));
var import_react_native3 = require("react-native");
var import_react_native_svg = require("react-native-svg");
function MicIcon(props) {
const { size = 25, color = "black" } = props;
return /* @__PURE__ */ import_react6.default.createElement(import_react_native_svg.Svg, { width: size, height: size, viewBox: "0 0 256 256", fill: "none" }, /* @__PURE__ */ import_react6.default.createElement(
import_react_native_svg.Path,
{
d: "M128 176C140.726 175.987 152.928 170.925 161.927 161.927C170.925 152.928 175.987 140.726 176 128V64C176 51.2696 170.943 39.0606 161.941 30.0589C152.939 21.0571 140.73 16 128 16C115.27 16 103.061 21.0571 94.0589 30.0589C85.0571 39.0606 80 51.2696 80 64V128C80.0132 140.726 85.0746 152.928 94.0735 161.927C103.072 170.925 115.274 175.987 128 176ZM96 64C96 55.5131 99.3714 47.3737 105.373 41.3726C111.374 35.3714 119.513 32 128 32C136.487 32 144.626 35.3714 150.627 41.3726C156.629 47.3737 160 55.5131 160 64V128C160 136.487 156.629 144.626 150.627 150.627C144.626 156.629 136.487 160 128 160C119.513 160 111.374 156.629 105.373 150.627C99.3714 144.626 96 136.487 96 128V64ZM136 207.6V232C136 234.122 135.157 236.157 133.657 237.657C132.157 239.157 130.122 240 128 240C125.878 240 123.843 239.157 122.343 237.657C120.843 236.157 120 234.122 120 232V207.6C100.276 205.593 81.9976 196.344 68.6984 181.641C55.3992 166.938 48.0244 147.825 48 128C48 125.878 48.8429 123.843 50.3431 122.343C51.8434 120.843 53.8783 120 56 120C58.1217 120 60.1566 120.843 61.6569 122.343C63.1571 123.843 64 125.878 64 128C64 144.974 70.7428 161.253 82.7452 173.255C94.7475 185.257 111.026 192 128 192C144.974 192 161.253 185.257 173.255 173.255C185.257 161.253 192 144.974 192 128C192 125.878 192.843 123.843 194.343 122.343C195.843 120.843 197.878 120 200 120C202.122 120 204.157 120.843 205.657 122.343C207.157 123.843 208 125.878 208 128C207.976 147.825 200.601 166.938 187.302 181.641C174.002 196.344 155.724 205.593 136 207.6Z",
fill: color
}
));
}
var LinkIcon = (props) => {
const { size = 25, color = "black" } = props;
return /* @__PURE__ */ import_react6.default.createElement(import_react_native_svg.Svg, { width: size, height: size, viewBox: "0 0 24 24", fill: "none" }, /* @__PURE__ */ import_react6.default.createElement(
import_react_native_svg.Path,
{
d: "M11 17H7C5.61667 17 4.43767 16.5123 3.463 15.537C2.48833 14.5617 2.00067 13.3827 2 12C1.99933 10.6173 2.487 9.43833 3.463 8.463C4.439 7.48767 5.618 7 7 7H11V9H7C6.16667 9 5.45833 9.29167 4.875 9.875C4.29167 10.4583 4 11.1667 4 12C4 12.8333 4.29167 13.5417 4.875 14.125C5.45833 14.7083 6.16667 15 7 15H11V17ZM8 13V11H16V13H8ZM13 17V15H17C17.8333 15 18.5417 14.7083 19.125 14.125C19.7083 13.5417 20 12.8333 20 12C20 11.1667 19.7083 10.4583 19.125 9.875C18.5417 9.29167 17.8333 9 17 9H13V7H17C18.3833 7 19.5627 7.48767 20.538 8.463C21.5133 9.43833 22.0007 10.6173 22 12C21.9993 13.3827 21.5117 14.562 20.537 15.538C19.5623 16.514 18.3833 17.0013 17 17H13Z",
fill: color
}
));
};
// src/components/Chat/ChatItem/Preview.tsx
var import_react_native4 = require("react-native");
var import_react7 = __toESM(require("react"));
var import_react_native_link_preview = require("@flyerhq/react-native-link-preview");
var import_expo_image3 = require("expo-image");
function Preview({
message,
color
}) {
const { theme: theme2, fontFamily, fontScale } = useConfig();
const urlRegex = /(https?:\/\/[^\s]+)/gi;
if (!urlRegex.test(message)) {
return null;
}
return /* @__PURE__ */ import_react7.default.createElement(
import_react_native_link_preview.LinkPreview,
{
text: message,
renderLinkPreview: (data) => /* @__PURE__ */ import_react7.default.createElement(
import_react_native4.View,
{
style: {
flexDirection: "row",
alignItems: "flex-start",
width: "100%",
minWidth: 220,
// marginBottom: 5,
// borderWidth: 1,
// borderColor: theme?.icon,
padding: 8,
borderRadius: 10
}
},
data.previewData?.image?.url ? /* @__PURE__ */ import_react7.default.createElement(import_react_native4.View, { style: { height: 80, width: 80, borderRadius: 10, backgroundColor: "lightgrey", alignItems: "center", justifyContent: "center" } }, /* @__PURE__ */ import_react7.default.createElement(LinkIcon, { color: "black" })) : /* @__PURE__ */ import_react7.default.createElement(
import_expo_image3.Image,
{
source: { uri: data.previewData?.image?.url },
cachePolicy: "disk",
style: { backgroundColor: "lightgrey", borderRadius: 10, height: 80, width: 80 }
}
),
/* @__PURE__ */ import_react7.default.createElement(import_react_native4.View, { style: { flex: 1, width: "100%" } }, /* @__PURE__ */ import_react7.default.createElement(
import_react_native4.Text,
{
style: {
display: data.previewData?.title ? "flex" : "none",
flex: 1,
color,
marginStart: 8,
textDecorationLine: "underline",
fontFamily
}
},
data.previewData?.title
), /* @__PURE__ */ import_react7.default.createElement(
import_react_native4.Text,
{
style: {
display: data.previewData?.description ? "flex" : "none",
flex: 1,
color,
fontSize: 12 * fontScale,
marginStart: 8,
textDecorationLine: "underline",
fontFamily
}
},
truncate(data.previewData?.description || "", 100)
))
)
}
);
}
// src/components/Chat/ChatItem/Quoted.tsx
function Quoted(props) {
const { quotedMessage, layout, onPress, theme: theme2, position, chatUserId } = props;
const { fontFamily, fontScale } = useConfig();
if (!quotedMessage) {
return null;
}
const renderMediaPreview = () => {
switch (quotedMessage.attachmentType) {
case import_softchatjs_core2.AttachmentTypes.STICKER:
return /* @__PURE__ */ import_react8.default.createElement(Sticker, { message: quotedMessage });
case import_softchatjs_core2.AttachmentTypes.MEDIA:
var mediaType = quotedMessage.attachedMedia[0]?.type;
if (mediaType === import_softchatjs_core2.MediaType.IMAGE) {
return /* @__PURE__ */ import_react8.default.createElement(Sticker, { message: quotedMessage });
} else if (mediaType === import_softchatjs_core2.MediaType.AUDIO) {
return /* @__PURE__ */ import_react8.default.createElement(import_react_native5.View, { style: { flexDirection: "row", alignItems: "center" } }, /* @__PURE__ */ import_react8.default.createElement(MicIcon, { size: 20, color: "white" }), /* @__PURE__ */ import_react8.default.createElement(
import_react_native5.Text,
{
style: {
color: "white",
marginStart: 5
}
},
convertToMinutes(
quotedMessage.attachedMedia[0]?.meta?.audioDurationSec ?? 0
)
));
}
}
};
if (layout === "stacked") {
return /* @__PURE__ */ import_react8.default.createElement(
import_react_native5.TouchableOpacity,
{
onPress: () => onPress?.(),
style: { flexDirection: "row", alignItems: "center" }
},
/* @__PURE__ */ import_react8.default.createElement(
import_react_native5.View,
{
style: {
height: "70%",
width: "100%",
flex: 1,
borderLeftWidth: 2,
borderTopWidth: 2,
borderTopLeftRadius: 10,
marginStart: 22,
borderColor: theme2?.divider
}
}
),
/* @__PURE__ */ import_react8.default.createElement(
import_react_native5.View,
{
style: {
width: "85%",
top: -8,
flexDirection: "row",
alignItems: "center"
}
},
/* @__PURE__ */ import_react8.default.createElement(
MessageAvatar,
{
size: 20,
initials: quotedMessage?.messageOwner?.username.substring(0, 2),
imgUrl: quotedMessage.messageOwner.profileUrl,
style: {
marginEnd: 5,
backgroundColor: quotedMessage.messageOwner.color
}
}
),
quotedMessage.message ? /* @__PURE__ */ import_react8.default.createElement(import_react_native5.Text, { style: { flex: 1, color: theme2?.text.disabled, fontFamily } }, truncate(quotedMessage?.message, 100)) : /* @__PURE__ */ import_react8.default.createElement(import_react8.default.Fragment, null, renderMediaPreview())
)
);
}
let rightStyle = {
borderRadius: 10,
alignItems: "flex-end",
padding: 8,
backgroundColor: theme2?.chatBubble.right.bgColor
};
let leftStyle = {
padding: 8,
borderRadius: 10,
alignItems: "flex-start",
backgroundColor: theme2?.chatBubble.left.bgColor
};
return /* @__PURE__ */ import_react8.default.createElement(
import_react_native5.TouchableOpacity,
{
onPress: () => onPress?.(),
style: [
{
backgroundColor: "rgba(0,0,0,.3)",
padding: 8,
marginTop: 8,
marginLeft: 8,
marginRight: 8,
borderRadius: 10,
borderLeftWidth: 4,
borderTopWidth: 4,
borderTopColor: "transparent",
borderLeftColor: quotedMessage.messageOwner.color
}
]
},
/* @__PURE__ */ import_react8.default.createElement(
import_react_native5.Text,
{
style: {
color: quotedMessage.messageOwner.color,
textTransform: "capitalize",
fontFamily,
marginBottom: 5,
textShadowColor: "rgba(0, 0, 0, 0.3)",
textShadowOffset: { width: 0.5, height: 0.5 },
textShadowRadius: 5
}
},
quotedMessage.messageOwner.uid === chatUserId ? "You" : quotedMessage.messageOwner.username
),
/* @__PURE__ */ import_react8.default.createElement(import_react8.default.Fragment, null, renderMediaPreview()),
/* @__PURE__ */ import_react8.default.createElement(
Preview,
{
message: quotedMessage.message,
color: position === "left" ? theme2?.chatBubble.left.messageColor : theme2?.chatBubble.right.messageColor
}
),
quotedMessage.message && /* @__PURE__ */ import_react8.default.createElement(
import_react_native5.Text,
{
style: {
display: quotedMessage.message ? "flex" : "none",
fontFamily,
color: "white",
fontSize: 14 * fontScale,
marginTop: 5
}
},
quotedMessage.message
)
);
}
var styles = import_react_native5.StyleSheet.create({
main: {
padding: 5,
borderLeftWidth: 2,
marginBottom: 5
}
});
//# sourceMappingURL=Quoted.js.map