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 };