From fa2927d5bab64e6cd68060125a4ae439f13f63e3 Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Mon, 25 Sep 2023 14:35:09 -0700 Subject: [PATCH] refactored details page --- app/mobile/src/constants/Strings.js | 17 ++++ .../src/session/channels/useChannels.hook.js | 8 +- app/mobile/src/session/details/Details.jsx | 99 +++++++++++-------- .../src/session/details/Details.styled.js | 34 +++++++ .../session/details/memberItem/MemberItem.jsx | 2 +- .../details/memberItem/MemberItem.styled.js | 2 +- .../src/session/details/useDetails.hook.js | 70 +++++++------ 7 files changed, 159 insertions(+), 73 deletions(-) diff --git a/app/mobile/src/constants/Strings.js b/app/mobile/src/constants/Strings.js index f0d1685e..cd739a70 100644 --- a/app/mobile/src/constants/Strings.js +++ b/app/mobile/src/constants/Strings.js @@ -109,6 +109,7 @@ const Strings = [ actionDelete: 'Delete', actionBlock: 'Block', actionReport: 'Report', + actionLeave: 'Leave', // contact list page add: 'Add', @@ -137,6 +138,10 @@ const Strings = [ members: 'Members', editSubject: 'Edit Subject', topicMembers: 'Topic Members', + leaveTopic: 'Leave Topic', + deleteTopic: 'Delete Topic', + blockTopic: 'Block Topic', + reportTopic: 'Report Topic', }, { visibleRegistry: 'Visible dans le Registre', @@ -271,6 +276,10 @@ const Strings = [ members: 'Membres', editSubject: 'Modifier le Title', topicMembers: 'Membres du Sujet', + leaveTopic: 'Quitter le Sujet', + deleteTopic: 'Supprimer le Sujet', + blockTopic: 'Bloquer le Sujet', + reportTopic: 'Signaler le Sujet', }, { visibleRegistry: 'Visible en el Registro', @@ -405,6 +414,10 @@ const Strings = [ members: 'Miembros', editSubject: 'Editar Título', topicMembers: 'Miembros del Tema', + leaveTopic: 'Dejar el Tema', + deleteTopic: 'Borrar el Tema', + blockTopic: 'Bloquer el Tema', + reportTopic: 'Reportar el Tema', }, { visibleRegistry: 'Sichtbar in der Registrierung', @@ -539,6 +552,10 @@ const Strings = [ members: 'Mitglieder', editSubject: 'Titel bearbeiten', topicMembers: 'Themenmitglieder', + leaveTopic: 'Verlasse das Thema', + deleteTopic: 'Das Thema Löschen', + blockTopic: 'Blockiere das Thema', + reportTopic: 'Das Thema Melden', } ]; diff --git a/app/mobile/src/session/channels/useChannels.hook.js b/app/mobile/src/session/channels/useChannels.hook.js index 20cb5d7c..3e0b5566 100644 --- a/app/mobile/src/session/channels/useChannels.hook.js +++ b/app/mobile/src/session/channels/useChannels.hook.js @@ -39,7 +39,7 @@ export function useChannels() { const setChannelItem = async (loginTimestamp, cardId, channelId, item) => { const timestamp = item.summary.lastTopic.created; - const { readRevision, topicRevision } = item; + const { readRevision, topicRevision, blocked } = item; // decrypt subject and message let locked = false; @@ -113,7 +113,7 @@ export function useChannels() { const updated = (loginTimestamp < timestamp) && (readRevision < topicRevision); - return { cardId, channelId, subject, message, logo, timestamp, updated, locked, unlocked }; + return { cardId, channelId, subject, message, logo, timestamp, updated, locked, unlocked, blocked }; } useEffect(() => { @@ -176,7 +176,6 @@ export function useChannels() { items.push({ loginTimestamp, channelId, channelItem: item }); }); card.state.cards.forEach((cardItem, cardId) => { - cardItem.channels.forEach((channelItem, channelId) => { items.push({ loginTimestamp, cardId, channelId, channelItem }); }); @@ -187,6 +186,9 @@ export function useChannels() { channels.push(await setChannelItem(loginTimestamp, cardId, channelId, channelItem)); } const filtered = channels.filter(item => { + if (item.blocked) { + return false; + } if (!filter.current) { return true; } diff --git a/app/mobile/src/session/details/Details.jsx b/app/mobile/src/session/details/Details.jsx index e5afe99f..11de6b1c 100644 --- a/app/mobile/src/session/details/Details.jsx +++ b/app/mobile/src/session/details/Details.jsx @@ -1,4 +1,5 @@ import { ActivityIndicator, KeyboardAvoidingView, FlatList, Alert, Modal, View, Text, Switch, TouchableOpacity, TextInput } from 'react-native'; +import { useState } from 'react'; import { styles } from './Details.styled'; import { useDetails } from './useDetails.hook'; import { Logo } from 'utils/Logo'; @@ -11,7 +12,8 @@ import { InputField } from 'utils/InputField'; export function Details({ channel, clearConversation }) { - const { state, actions } = useDetails(); + const [busy, setBusy] = useState(false); + const { state, actions } = useDetails(clearConversation); const toggle = async (cardId, selected) => { try { @@ -58,6 +60,27 @@ export function Details({ channel, clearConversation }) { } } + const promptAction = (prompt, action) => { + prompt(async () => { + if (!busy) { + try { + setBusy(true); + await action(); + setBusy(false); + } + catch (err) { + console.log(err); + setBusy(false); + Alert.alert( + state.strings.error, + state.strings.tryAgain, + ); + throw err; + } + } + }); + } + const remove = () => { Alert.alert( "Removing Topic", @@ -164,45 +187,6 @@ export function Details({ channel, clearConversation }) { - { !state.hostId && ( - - { state.deleteBusy && ( - - )} - { !state.deleteBusy && ( - Delete Topic - )} - - )} - { state.hostId && ( - - { state.deleteBusy && ( - - )} - { !state.deleteBusy && ( - Leave Topic - )} - - )} - - { state.blockBusy && ( - - )} - { !state.blockBusy && ( - Block Topic - )} - - { state.hostId && ( - - Report Topic - - )} - { !state.hostId && !state.locked && ( - - Edit Membership - - )} - setNotifications(!state.notification)} activeOpacity={1}> { state.strings.enableNotifications } @@ -211,7 +195,42 @@ export function Details({ channel, clearConversation }) { )} + + + { busy && ( + + )} + { !busy && ( + + { !state.hostId && !state.locked && ( + + + { state.strings.members } + + )} + { !state.hostId && ( + promptAction(actions.deletePrompt, actions.removeTopic)}> + + { state.strings.delete } + + )} + { state.hostId && ( + promptAction(actions.leavePrompt, actions.removeTopic)}> + + { state.strings.leave } + + )} + promptAction(actions.blockPrompt, actions.blockTopic)}> + + { state.strings.actionBlock } + + promptAction(actions.reportPrompt, actions.reportTopic)}> + + { state.strings.actionReport } + + + )} diff --git a/app/mobile/src/session/details/Details.styled.js b/app/mobile/src/session/details/Details.styled.js index ba5aa908..c1c5673a 100644 --- a/app/mobile/src/session/details/Details.styled.js +++ b/app/mobile/src/session/details/Details.styled.js @@ -249,4 +249,38 @@ export const styles = StyleSheet.create({ width: '100%', }, }, + control: { + width: '100%', + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + paddingTop: 12, + }, + drawerActions: { + display: 'flex', + flexDirection: 'row', + alignItems: 'flex-end', + justifyContent: 'center', + width: '80%', + borderRadius: 8, + paddingTop: 8, + paddingBottom: 8, + }, + actionList: { + alignItems: 'flex-end', + }, + action: { + display: 'flex', + alignItems: 'center', + paddingRight: 12, + paddingLeft: 12, + paddingBottom: 12, + }, + actionIcon: { + }, + actionLabel: { + color: Colors.linkText, + fontSize: 10, + }, }) diff --git a/app/mobile/src/session/details/memberItem/MemberItem.jsx b/app/mobile/src/session/details/memberItem/MemberItem.jsx index 1f880257..7cf6943d 100644 --- a/app/mobile/src/session/details/memberItem/MemberItem.jsx +++ b/app/mobile/src/session/details/memberItem/MemberItem.jsx @@ -14,7 +14,7 @@ export function MemberItem({ item, hostId, toggle }) { return ( - + { item.name } { item.handle } diff --git a/app/mobile/src/session/details/memberItem/MemberItem.styled.js b/app/mobile/src/session/details/memberItem/MemberItem.styled.js index 936710bc..5ae21db5 100644 --- a/app/mobile/src/session/details/memberItem/MemberItem.styled.js +++ b/app/mobile/src/session/details/memberItem/MemberItem.styled.js @@ -6,7 +6,7 @@ export const styles = StyleSheet.create({ width: '100%', display: 'flex', flexDirection: 'row', - height: 48, + height: 64, alignItems: 'center', borderBottomWidth: 1, borderColor: Colors.itemDivider, diff --git a/app/mobile/src/session/details/useDetails.hook.js b/app/mobile/src/session/details/useDetails.hook.js index 65b42647..890d794c 100644 --- a/app/mobile/src/session/details/useDetails.hook.js +++ b/app/mobile/src/session/details/useDetails.hook.js @@ -8,9 +8,10 @@ import { getChannelSubjectLogo } from 'context/channelUtil'; import { getCardByGuid } from 'context/cardUtil'; import { getChannelSeals, isUnsealed, getContentKey, updateChannelSubject } from 'context/sealUtil'; import { getLanguageStrings } from 'constants/Strings'; +import { DisplayContext } from 'context/DisplayContext'; import moment from 'moment'; -export function useDetails() { +export function useDetails(clear) { const [state, setState] = useState({ strings: getLanguageStrings(), @@ -38,6 +39,7 @@ export function useDetails() { const account = useContext(AccountContext); const conversation = useContext(ConversationContext); const profile = useContext(ProfileContext); + const display = useContext(DisplayContext); const updateState = (value) => { setState((s) => ({ ...s, ...value })); @@ -200,41 +202,53 @@ export function useDetails() { await conversation.actions.setChannelSubject('superbasic', subject); } }, - remove: async () => { - if (!state.deleteBusy) { - try { - updateState({ deleteBusy: true }); - await conversation.actions.removeChannel(); - updateState({ deleteBusy: false }); - } - catch(err) { - console.log(err); - updateState({ deleteBusy: false }); - throw new Error("delete failed"); - } - } + removeTopic: async () => { + await conversation.actions.removeChannel(); + clear(); }, - block: async() => { - if (!state.deleteBusy) { - try { - updateState({ blockBusy: true }); - await conversation.actions.setChannelFlag(); - updateState({ blockBusy: false }); - } - catch(err) { - console.log(err); - updateState({ blockBusy: false }); - throw new Error("block failed"); - } - } + blockTopic: async() => { + await conversation.actions.setChannelFlag(); + clear(); }, - report: async() => { + reportTopic: async() => { await conversation.actions.addChannelAlert(); }, setNotifications: async (notification) => { await conversation.actions.setNotifications(notification); updateState({ notification }); }, + deletePrompt: (action) => { + display.actions.showPrompt({ + title: state.strings.deleteTopic, + centerButtons: true, + ok: { label: state.strings.confirmDelete, action, failed: () => {}}, + cancel: { label: state.strings.cancel }, + }); + }, + leavePrompt: (action) => { + display.actions.showPrompt({ + title: state.strings.leaveTopic, + centerButtons: true, + ok: { label: state.strings.leave, action, failed: () => {}}, + cancel: { label: state.strings.cancel }, + }); + }, + blockPrompt: (action) => { + display.actions.showPrompt({ + title: state.strings.blockTopic, + centerButtons: true, + ok: { label: state.strings.confirmBlock, action, failed: () => {}}, + cancel: { label: state.strings.cancel }, + }); + }, + reportPrompt: (action) => { + display.actions.showPrompt({ + title: state.strings.reportTopic, + centerButtons: true, + ok: { label: state.strings.confirmReport, action, failed: () => {}}, + cancel: { label: state.strings.cancel }, + }); + }, }; return { state, actions };