USER
import { CryptoUtils, RandomUtils } from "@openchat/framework"
import {
AttachmentKindEnum,
FileType,
MessageKindEnum,
MessageMetadataType,
MessagePackType,
MessageType,
PollType,
} from "@openchat/types"
import { useAccountId, useChannel, useLogger, useMemberBy } from "@openchat/ui"
import { useState, useEffect } from "react"
import { Alert, Modal, Pressable, View } from "react-native"
import { isCancel, pick } from "react-native-document-picker"
import { launchImageLibrary } from "react-native-image-picker"
import { AppColors } from "../../../app/app-colors"
import { AppControllers } from "../../../app/app-context"
import { NavigationRef } from "../../../navigation/navigation.hooks"
import { Icon } from "../../../ui-components/icon/icon.component"
import { useModal } from "../../../ui-components/modal/modal.hook"
import { StyledText } from "../../../ui-components/styled-text/styled-text"
import { FileUtils } from "../../../utils/file/file.utils"
import { useStyles } from "./message-input-popup.style"
import { Region } from "react-native-maps"
import { RoomUtils } from "@openchat/models"
import { ProgressBar } from "../../../ui-components/progress-bar/progress-bar.component"
export function MessageInputPopup({
roomId,
onProfileSelect,
onFilesSelected,
onLocationSelect,
isShowFileAndProfile = false,
newMessagePacks,
}: {
roomId: string
onProfileSelect: (
users: {
id: string
name: string
photo: FileType | null
}[],
) => void
onLocationSelect: (coordinate: Region) => void
onFilesSelected: (files: FileType[], kind: AttachmentKindEnum) => void
isShowFileAndProfile?: boolean
newMessagePacks: (messagePack: MessagePackType) => void
}) {
// ---------------------------------------------------------------------------
// variables
// ---------------------------------------------------------------------------
const styles = useStyles()
const logger = useLogger("MessageInputPopup")
const modal = useModal()
const accountId = useAccountId()
const [files, setFiles] = useState<FileType[]>([])
const [loading, setLoading] = useState(false)
const { communityId, channelId } = RoomUtils.extractIds(roomId)
const channel = useChannel(channelId)
const currentMember = useMemberBy({
communityId: communityId,
identityId: accountId,
})
const [modalVisible, setModalVisible] = useState(false)
// ---------------------------------------------------------------------------
// useEffect
// ---------------------------------------------------------------------------
useEffect(() => {
setModalVisible(loading)
}, [loading])
// ---------------------------------------------------------------------------
// functions
// ---------------------------------------------------------------------------
async function onGallerySelect() {
try {
setTimeout(() => {
setLoading(true)
console.log("==================1111111111111==================")
console.log("1111111111111")
console.log("=================end 1111111111111===================")
}, 500)
const files = await launchImageLibrary({
mediaType: "mixed",
includeBase64: true,
includeExtra: true,
selectionLimit: 50,
maxHeight: 110,
})
if (!files.assets) return
const newFiles: FileType[] = []
for (let selectedFile of files.assets) {
if (!selectedFile.uri) continue
const file = await fetch(selectedFile.uri).then((response) => {
return response.blob()
})
const reader = new FileReader()
await new Promise((resolve) => {
reader.onload = () => {
const dataUrl = reader.result as string
newFiles.push({
id: CryptoUtils.sha256(dataUrl),
name: selectedFile.fileName ? selectedFile.fileName : "",
size: file.size,
mimeType: file.type,
data: dataUrl,
duration: null,
})
resolve(null)
}
reader.readAsDataURL(file)
})
}
onFilesSelected(newFiles, AttachmentKindEnum.media)
setTimeout(() => {
setLoading(false)
}, 500)
} catch (error) {
console.log(error)
}
}
async function onFileSelect() {
const files = await pick({ allowMultiSelection: true })
try {
const file = await FileUtils.builtFileType(files)
onFilesSelected(file, AttachmentKindEnum.file)
setFiles(file)
} catch (err) {
if (isCancel(err)) {
logger.log("Canceled: ", err)
} else {
logger.log(err)
}
}
}
async function save(poll: {
isPrivate: boolean
title: string
isMultiple: boolean
options: {
id: string
order: number
name: string
votedUserIds: string[]
}[]
}) {
if (!accountId) return
const newPoll: PollType = {
id: RandomUtils.uuid(),
createdAt: Date.now(),
isMultiple: poll.isMultiple,
isPrivate: poll.isPrivate,
title: poll.title,
isClosed: false,
pollOptions: poll.options.filter((option) => option.name !== ""),
totalVotedUsersCount: 0,
roomId: roomId,
}
const newMessage: MessageType = {
id: RandomUtils.uuid(),
createdAt: Date.now(),
text: "",
roomId: roomId,
isEdited: false,
isDeleted: false,
isDelivered: false,
senderId: !currentMember ? accountId : null,
senderMemberId: currentMember ? currentMember.id : null,
forward: null,
regular: {
kind: MessageKindEnum.poll,
quote: null,
sharedUser: null,
sticker: null,
location: null,
},
question: null,
answer: null,
news: null,
issue: null,
board: null,
}
const metadata: MessageMetadataType = {
id: newMessage.id,
updatedAt: Date.now(),
replyCount: 0,
reactionsCount: {},
currentUserIdReactions: [],
}
newMessagePacks({
message: newMessage,
metadata,
links: [],
attachments: [],
files: [],
poll: newPoll,
})
await AppControllers.message.insert([
{
message: newMessage,
metadata,
attachments: [],
links: [],
files: [],
poll: newPoll,
},
])
}
// ---------------------------------------------------------------------------
return (
<View style={styles.inputPopupContainer}>
{/* --------------------------------------------------------------------------- */}
{/* SHARE IMAGE OR VIDEO */}
{/* --------------------------------------------------------------------------- */}
{isShowFileAndProfile && (
<Pressable
onPress={() => {
onGallerySelect()
modal.close()
}}
style={({ pressed }) => [
pressed
? { backgroundColor: AppColors.backgroundDark }
: { backgroundColor: AppColors.light },
styles.itemWrapper,
]}
>
{({ pressed }) => (
<>
<View
style={[
pressed
? { backgroundColor: AppColors.primary }
: { backgroundColor: AppColors.backgroundLight },
styles.iconWrapper,
]}
>
<Icon
name="fal fa-photo-film"
size={20}
fill={pressed ? AppColors.light : AppColors.iconDefault}
/>
</View>
<StyledText style={styles.text}>Image & Video</StyledText>
</>
)}
</Pressable>
)}
<>
{/* {loading && (
<Modal
animationType="fade"
transparent={true}
onShow={() => setModalVisible(true)}
visible={modalVisible} // visibility tied to loading state
onRequestClose={() => setModalVisible(!modalVisible)}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<ProgressBar
description="Loading"
containerStyle={{ flexShrink: 1, width: 300 }}
/>
<Pressable
style={[styles.button, styles.buttonClose]}
onPress={() => setModalVisible(!modalVisible)}
>
<StyledText style={styles.textStyle}>Hide Modal</StyledText>
</Pressable>
</View>
</View>
</Modal>
)} */}
{loading && Alert.alert("Alert Title")}
</>
{/* --------------------------------------------------------------------------- */}
{/* SHARE FILE */}
{/* --------------------------------------------------------------------------- */}
<Pressable
onPress={() => {
modal.close()
onFileSelect()
}}
style={({ pressed }) => [
pressed
? { backgroundColor: AppColors.backgroundDark }
: { backgroundColor: "white" },
styles.itemWrapper,
]}
>
{({ pressed }) => (
<>
<View
style={[
pressed
? { backgroundColor: AppColors.primary }
: { backgroundColor: AppColors.backgroundLight },
styles.iconWrapper,
]}
>
<Icon
name="fal fa-file"
size={20}
fill={pressed ? "white" : AppColors.iconDefault}
/>
</View>
<StyledText style={styles.text}>File</StyledText>
</>
)}
</Pressable>
{/* --------------------------------------------------------------------------- */}
{/* CREATE POLL */}
{/* --------------------------------------------------------------------------- */}
{isShowFileAndProfile && (
<>
{/* {channel && channel.isPollsEnabled && ( */}
<Pressable
onPress={() => {
modal.close()
NavigationRef.navigate("PollUpsert", {
onSend: (poll: any) => save(poll),
})
}}
style={({ pressed }) => [
pressed
? { backgroundColor: AppColors.backgroundDark }
: { backgroundColor: "white" },
styles.itemWrapper,
]}
>
{({ pressed }) => (
<>
<View
style={[
pressed
? { backgroundColor: AppColors.primary }
: { backgroundColor: AppColors.backgroundLight },
styles.iconWrapper,
]}
>
<Icon
name="fal fa-poll-people"
size={20}
fill={pressed ? "white" : AppColors.iconDefault}
/>
</View>
<StyledText style={styles.text}> Create poll </StyledText>
</>
)}
</Pressable>
{/* )} */}
{/* --------------------------------------------------------------------------- */}
{/* LOCATION */}
{/* --------------------------------------------------------------------------- */}
<Pressable
onPress={() => {
modal.close()
// AppConfig.isTablet?
NavigationRef.navigate("MessageLocation", {
onSend: (coordinate) => onLocationSelect(coordinate),
})
// : modal.open({
// background: "pattern",
// footer: "rgb",
// component: (
// <MessageLocationModal
// // onSend={(coordinate) => onLocationSelect(coordinate)}
// />
// ),
// })
}}
style={({ pressed }) => [
pressed
? { backgroundColor: AppColors.backgroundDark }
: { backgroundColor: "white" },
styles.itemWrapper,
]}
>
{({ pressed }) => (
<>
<View
style={[
pressed
? { backgroundColor: AppColors.primary }
: { backgroundColor: AppColors.backgroundLight },
styles.iconWrapper,
]}
>
<Icon
name="fal fa-location-dot"
size={20}
fill={pressed ? "white" : AppColors.iconDefault}
/>
</View>
<StyledText style={styles.text}> Location</StyledText>
</>
)}
</Pressable>
</>
)}
{/* --------------------------------------------------------------------------- */}
{/* SHARE PROFILE */}
{/* --------------------------------------------------------------------------- */}
<Pressable
onPress={() => {
modal.close()
NavigationRef.navigate("MessageInputProfileModal", {
onSend: (users) => onProfileSelect(users),
})
}}
style={({ pressed }) => [
pressed
? { backgroundColor: AppColors.backgroundDark }
: { backgroundColor: "white" },
styles.itemWrapper,
]}
>
{({ pressed }) => (
<>
<View
style={[
pressed
? { backgroundColor: AppColors.primary }
: { backgroundColor: AppColors.backgroundLight },
styles.iconWrapper,
]}
>
<Icon
name="fal fa-share-nodes"
size={20}
fill={pressed ? "white" : AppColors.iconDefault}
/>
</View>
<StyledText style={styles.text}>Share profile</StyledText>
</>
)}
</Pressable>
</View>
)
}
how to make alert shows up after selecting image