diff --git a/app/mobile/src/session/conversation/Conversation.jsx b/app/mobile/src/session/conversation/Conversation.jsx index 9a73cb46..533aa4fb 100644 --- a/app/mobile/src/session/conversation/Conversation.jsx +++ b/app/mobile/src/session/conversation/Conversation.jsx @@ -1,5 +1,5 @@ import { useRef, useEffect, useState, useContext } from 'react'; -import { ActivityIndicator, FlatList, View, Text, TouchableOpacity } from 'react-native'; +import { Alert, Modal, KeyboardAvoidingView, ActivityIndicator, FlatList, View, TextInput, Text, TouchableOpacity } from 'react-native'; import { ConversationContext } from 'context/ConversationContext'; import { useConversation } from './useConversation.hook'; import { styles } from './Conversation.styled'; @@ -11,17 +11,7 @@ import { TopicItem } from './topicItem/TopicItem'; export function Conversation({ navigation, cardId, channelId, closeConversation, openDetails }) { - const [ready, setReady] = useState(true); - const conversation = useContext(ConversationContext); const { state, actions } = useConversation(); - const ref = useRef(); - - const latch = () => { - if (!state.momentum) { - actions.latch(); - ref.current.scrollToIndex({ animated: true, index: 0 }); - } - } const updateTopic = async () => { try { @@ -106,6 +96,36 @@ export function Conversation({ navigation, cardId, channelId, closeConversation, + + + + Edit Message Text: + + + + + + Cancel + + + { state.updateBusy && ( + + )} + { !state.updateBusy && ( + Save + )} + + + + + ); } diff --git a/app/mobile/src/session/conversation/Conversation.styled.js b/app/mobile/src/session/conversation/Conversation.styled.js index 4b191e64..a2aab419 100644 --- a/app/mobile/src/session/conversation/Conversation.styled.js +++ b/app/mobile/src/session/conversation/Conversation.styled.js @@ -87,5 +87,74 @@ export const styles = StyleSheet.create({ minHeight: 0, paddingTop: 8, }, + save: { + borderRadius: 4, + backgroundColor: Colors.primary, + width: 72, + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + }, + saveText: { + color: Colors.white, + }, + cancel: { + borderWidth: 1, + borderColor: Colors.lightgrey, + borderRadius: 4, + padding: 8, + marginRight: 8, + width: 72, + display: 'flex', + alignItems: 'center', + }, + inputField: { + width: '100%', + borderWidth: 1, + borderColor: Colors.lightgrey, + borderRadius: 4, + padding: 8, + marginBottom: 8, + maxHeight: 92, + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + }, + input: { + fontSize: 14, + flexGrow: 1, + }, + editControls: { + display: 'flex', + flexDirection: 'row', + justifyContent: 'flex-end', + }, + editWrapper: { + display: 'flex', + width: '100%', + height: '100%', + alignItems: 'center', + justifyContent: 'center', + backgroundColor: 'rgba(52, 52, 52, 0.8)' + }, + editContainer: { + backgroundColor: Colors.formBackground, + padding: 16, + width: '80%', + maxWidth: 400, + }, + editHeader: { + fontSize: 18, + paddingBottom: 16, + }, + modal: { + width: '100%', + height: '100%', + backgroundColor: 'rgba(0, 0, 0, 0.9)', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + }, }); diff --git a/app/mobile/src/session/conversation/topicItem/TopicItem.jsx b/app/mobile/src/session/conversation/topicItem/TopicItem.jsx index d8c0cff7..a9d6efb8 100644 --- a/app/mobile/src/session/conversation/topicItem/TopicItem.jsx +++ b/app/mobile/src/session/conversation/topicItem/TopicItem.jsx @@ -179,7 +179,7 @@ export function TopicItem({ item, focused, focus, hosting, remove, update, block { focused && ( { state.editable && ( - update(item.topicId, state.editData)}> + update(item.topicId, state.editType, state.editData)}> )} diff --git a/app/mobile/src/session/conversation/topicItem/audioAsset/AudioAsset.jsx b/app/mobile/src/session/conversation/topicItem/audioAsset/AudioAsset.jsx index c3051459..4de7a4c0 100644 --- a/app/mobile/src/session/conversation/topicItem/audioAsset/AudioAsset.jsx +++ b/app/mobile/src/session/conversation/topicItem/audioAsset/AudioAsset.jsx @@ -30,8 +30,10 @@ export function AudioAsset({ topicId, asset, dismiss }) { - ); } diff --git a/app/mobile/src/session/conversation/topicItem/imageAsset/ImageAsset.jsx b/app/mobile/src/session/conversation/topicItem/imageAsset/ImageAsset.jsx index 67c4c835..82468daa 100644 --- a/app/mobile/src/session/conversation/topicItem/imageAsset/ImageAsset.jsx +++ b/app/mobile/src/session/conversation/topicItem/imageAsset/ImageAsset.jsx @@ -14,21 +14,21 @@ export function ImageAsset({ topicId, asset, dismiss }) { style={{ borderRadius: 4, width: state.imageWidth, height: state.imageHeight }} resizeMode={'cover'} /> )} - { state.controls && ( + { state.loaded && state.controls && ( )} { state.failed && ( - + - + )} { !state.loaded && !state.failed && ( - + - + )} ); diff --git a/app/mobile/src/session/conversation/topicItem/useTopicItem.hook.js b/app/mobile/src/session/conversation/topicItem/useTopicItem.hook.js index 1a74bc48..f2330a4c 100644 --- a/app/mobile/src/session/conversation/topicItem/useTopicItem.hook.js +++ b/app/mobile/src/session/conversation/topicItem/useTopicItem.hook.js @@ -177,7 +177,7 @@ export function useTopicItem(item, hosting, remove, contentKey) { const editable = guid === identity?.guid && parsed; const deletable = editable || hosting; - updateState({ logo, name, nameSet, known, sealed, message, fontSize, fontColor, timestamp, transform, status, assets, deletable, editable, editData: parsed, editMessage: message }); + updateState({ logo, name, nameSet, known, sealed, message, fontSize, fontColor, timestamp, transform, status, assets, deletable, editable, editData: parsed, editMessage: message, editType: dataType }); }, [conversation.state, card.state, account.state, item, contentKey]); const unsealTopic = async (topicId, revision, topicDetail) => { diff --git a/app/mobile/src/session/conversation/useConversation.hook.js b/app/mobile/src/session/conversation/useConversation.hook.js index b3cc807d..1f385ce3 100644 --- a/app/mobile/src/session/conversation/useConversation.hook.js +++ b/app/mobile/src/session/conversation/useConversation.hook.js @@ -4,7 +4,7 @@ import { CardContext } from 'context/CardContext'; import { AccountContext } from 'context/AccountContext'; import { ConversationContext } from 'context/ConversationContext'; import { getChannelSubjectLogo } from 'context/channelUtil'; -import { getChannelSeals, isUnsealed, getContentKey, decryptTopicSubject } from 'context/sealUtil'; +import { getChannelSeals, isUnsealed, getContentKey, encryptTopicSubject, decryptTopicSubject } from 'context/sealUtil'; export function useConversation() { const [state, setState] = useState({ @@ -13,6 +13,13 @@ export function useConversation() { topic: [], loaded: false, contentKey: null, + focus: null, + editing: false, + editTopicId: null, + editType: null, + editMessage: null, + editData: null, + updateBusy: false, }); const updateState = (value) => { @@ -87,7 +94,45 @@ export function useConversation() { }, [conversation.state, profile.state]); - const actions = {}; + const actions = { + setFocus: (focus) => { + updateState({ focus }); + }, + editTopic: async (topicId, type, data) => { + console.log("EDIT:", topicId, type, data); + updateState({ editing: true, editTopicId: topicId, editType: type, editMessage: data?.text, editData: data }); + }, + hideEdit: () => { + updateState({ editing: false }); + }, + setEditMessage: (editMessage) => { + updateState({ editMessage }); + }, + updateTopic: async () => { + if (!state.updateBusy) { + try { + updateState({ updateBusy: true }); + const message = { ...state.editData, text: state.editMessage }; + if (state.editType === 'superbasictopic') { + await conversation.actions.setTopicSubject(state.editTopicId, state.editType, message); + } + else { + const sealed = encryptTopicSubject({ message }, state.contentKey); + await conversation.actions.setTopicSubject(state.editTopicId, state.editType, sealed); + } + updateState({ updateBusy: false }); + } + catch(err) { + console.log(err); + updateState({ updateBusy: false }); + throw new Error("failed to update"); + } + } + }, + removeTopic: async (topicId) => { + await conversation.actions.removeTopic(topicId); + }, + }; return { state, actions }; }