mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
refactored details page
This commit is contained in:
parent
408a16f018
commit
fa2927d5ba
@ -109,6 +109,7 @@ const Strings = [
|
|||||||
actionDelete: 'Delete',
|
actionDelete: 'Delete',
|
||||||
actionBlock: 'Block',
|
actionBlock: 'Block',
|
||||||
actionReport: 'Report',
|
actionReport: 'Report',
|
||||||
|
actionLeave: 'Leave',
|
||||||
|
|
||||||
// contact list page
|
// contact list page
|
||||||
add: 'Add',
|
add: 'Add',
|
||||||
@ -137,6 +138,10 @@ const Strings = [
|
|||||||
members: 'Members',
|
members: 'Members',
|
||||||
editSubject: 'Edit Subject',
|
editSubject: 'Edit Subject',
|
||||||
topicMembers: 'Topic Members',
|
topicMembers: 'Topic Members',
|
||||||
|
leaveTopic: 'Leave Topic',
|
||||||
|
deleteTopic: 'Delete Topic',
|
||||||
|
blockTopic: 'Block Topic',
|
||||||
|
reportTopic: 'Report Topic',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
visibleRegistry: 'Visible dans le Registre',
|
visibleRegistry: 'Visible dans le Registre',
|
||||||
@ -271,6 +276,10 @@ const Strings = [
|
|||||||
members: 'Membres',
|
members: 'Membres',
|
||||||
editSubject: 'Modifier le Title',
|
editSubject: 'Modifier le Title',
|
||||||
topicMembers: 'Membres du Sujet',
|
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',
|
visibleRegistry: 'Visible en el Registro',
|
||||||
@ -405,6 +414,10 @@ const Strings = [
|
|||||||
members: 'Miembros',
|
members: 'Miembros',
|
||||||
editSubject: 'Editar Título',
|
editSubject: 'Editar Título',
|
||||||
topicMembers: 'Miembros del Tema',
|
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',
|
visibleRegistry: 'Sichtbar in der Registrierung',
|
||||||
@ -539,6 +552,10 @@ const Strings = [
|
|||||||
members: 'Mitglieder',
|
members: 'Mitglieder',
|
||||||
editSubject: 'Titel bearbeiten',
|
editSubject: 'Titel bearbeiten',
|
||||||
topicMembers: 'Themenmitglieder',
|
topicMembers: 'Themenmitglieder',
|
||||||
|
leaveTopic: 'Verlasse das Thema',
|
||||||
|
deleteTopic: 'Das Thema Löschen',
|
||||||
|
blockTopic: 'Blockiere das Thema',
|
||||||
|
reportTopic: 'Das Thema Melden',
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ export function useChannels() {
|
|||||||
|
|
||||||
const setChannelItem = async (loginTimestamp, cardId, channelId, item) => {
|
const setChannelItem = async (loginTimestamp, cardId, channelId, item) => {
|
||||||
const timestamp = item.summary.lastTopic.created;
|
const timestamp = item.summary.lastTopic.created;
|
||||||
const { readRevision, topicRevision } = item;
|
const { readRevision, topicRevision, blocked } = item;
|
||||||
|
|
||||||
// decrypt subject and message
|
// decrypt subject and message
|
||||||
let locked = false;
|
let locked = false;
|
||||||
@ -113,7 +113,7 @@ export function useChannels() {
|
|||||||
|
|
||||||
const updated = (loginTimestamp < timestamp) && (readRevision < topicRevision);
|
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(() => {
|
useEffect(() => {
|
||||||
@ -176,7 +176,6 @@ export function useChannels() {
|
|||||||
items.push({ loginTimestamp, channelId, channelItem: item });
|
items.push({ loginTimestamp, channelId, channelItem: item });
|
||||||
});
|
});
|
||||||
card.state.cards.forEach((cardItem, cardId) => {
|
card.state.cards.forEach((cardItem, cardId) => {
|
||||||
|
|
||||||
cardItem.channels.forEach((channelItem, channelId) => {
|
cardItem.channels.forEach((channelItem, channelId) => {
|
||||||
items.push({ loginTimestamp, cardId, channelId, channelItem });
|
items.push({ loginTimestamp, cardId, channelId, channelItem });
|
||||||
});
|
});
|
||||||
@ -187,6 +186,9 @@ export function useChannels() {
|
|||||||
channels.push(await setChannelItem(loginTimestamp, cardId, channelId, channelItem));
|
channels.push(await setChannelItem(loginTimestamp, cardId, channelId, channelItem));
|
||||||
}
|
}
|
||||||
const filtered = channels.filter(item => {
|
const filtered = channels.filter(item => {
|
||||||
|
if (item.blocked) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (!filter.current) {
|
if (!filter.current) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { ActivityIndicator, KeyboardAvoidingView, FlatList, Alert, Modal, View, Text, Switch, TouchableOpacity, TextInput } from 'react-native';
|
import { ActivityIndicator, KeyboardAvoidingView, FlatList, Alert, Modal, View, Text, Switch, TouchableOpacity, TextInput } from 'react-native';
|
||||||
|
import { useState } from 'react';
|
||||||
import { styles } from './Details.styled';
|
import { styles } from './Details.styled';
|
||||||
import { useDetails } from './useDetails.hook';
|
import { useDetails } from './useDetails.hook';
|
||||||
import { Logo } from 'utils/Logo';
|
import { Logo } from 'utils/Logo';
|
||||||
@ -11,7 +12,8 @@ import { InputField } from 'utils/InputField';
|
|||||||
|
|
||||||
export function Details({ channel, clearConversation }) {
|
export function Details({ channel, clearConversation }) {
|
||||||
|
|
||||||
const { state, actions } = useDetails();
|
const [busy, setBusy] = useState(false);
|
||||||
|
const { state, actions } = useDetails(clearConversation);
|
||||||
|
|
||||||
const toggle = async (cardId, selected) => {
|
const toggle = async (cardId, selected) => {
|
||||||
try {
|
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 = () => {
|
const remove = () => {
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
"Removing Topic",
|
"Removing Topic",
|
||||||
@ -164,45 +187,6 @@ export function Details({ channel, clearConversation }) {
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.controls}>
|
<View style={styles.controls}>
|
||||||
{ !state.hostId && (
|
|
||||||
<TouchableOpacity style={styles.button} onPress={remove}>
|
|
||||||
{ state.deleteBusy && (
|
|
||||||
<ActivityIndicator color={Colors.white} />
|
|
||||||
)}
|
|
||||||
{ !state.deleteBusy && (
|
|
||||||
<Text style={styles.buttonText}>Delete Topic</Text>
|
|
||||||
)}
|
|
||||||
</TouchableOpacity>
|
|
||||||
)}
|
|
||||||
{ state.hostId && (
|
|
||||||
<TouchableOpacity style={styles.button} onPress={remove}>
|
|
||||||
{ state.deleteBusy && (
|
|
||||||
<ActivityIndicator color={Colors.white} />
|
|
||||||
)}
|
|
||||||
{ !state.deleteBusy && (
|
|
||||||
<Text style={styles.buttonText}>Leave Topic</Text>
|
|
||||||
)}
|
|
||||||
</TouchableOpacity>
|
|
||||||
)}
|
|
||||||
<TouchableOpacity style={styles.button} onPress={block}>
|
|
||||||
{ state.blockBusy && (
|
|
||||||
<ActivityIndicator color={Colors.white} />
|
|
||||||
)}
|
|
||||||
{ !state.blockBusy && (
|
|
||||||
<Text style={styles.buttonText}>Block Topic</Text>
|
|
||||||
)}
|
|
||||||
</TouchableOpacity>
|
|
||||||
{ state.hostId && (
|
|
||||||
<TouchableOpacity style={styles.button} onPress={report}>
|
|
||||||
<Text style={styles.buttonText}>Report Topic</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
)}
|
|
||||||
{ !state.hostId && !state.locked && (
|
|
||||||
<TouchableOpacity style={styles.button} onPress={actions.showEditMembers}>
|
|
||||||
<Text style={styles.buttonText}>Edit Membership</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<View style={styles.notify}>
|
<View style={styles.notify}>
|
||||||
<TouchableOpacity onPress={() => setNotifications(!state.notification)} activeOpacity={1}>
|
<TouchableOpacity onPress={() => setNotifications(!state.notification)} activeOpacity={1}>
|
||||||
<Text style={styles.notifyText}>{ state.strings.enableNotifications }</Text>
|
<Text style={styles.notifyText}>{ state.strings.enableNotifications }</Text>
|
||||||
@ -211,7 +195,42 @@ export function Details({ channel, clearConversation }) {
|
|||||||
<Switch style={styles.switch} value={state.notification} onValueChange={setNotifications} trackColor={styles.track}/>
|
<Switch style={styles.switch} value={state.notification} onValueChange={setNotifications} trackColor={styles.track}/>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.control}>
|
||||||
|
{ busy && (
|
||||||
|
<ActivityIndicator animating={true} color={Colors.text} size={'large'} />
|
||||||
|
)}
|
||||||
|
{ !busy && (
|
||||||
|
<View style={styles.drawerActions}>
|
||||||
|
{ !state.hostId && !state.locked && (
|
||||||
|
<TouchableOpacity style={styles.action} activeOpacity={1} onPress={actions.showEditMembers}>
|
||||||
|
<MatIcons name="account-group-outline" style={styles.actionIcon} size={44} color={Colors.linkText} />
|
||||||
|
<Text style={styles.actionLabel}>{ state.strings.members }</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
{ !state.hostId && (
|
||||||
|
<TouchableOpacity style={styles.action} activeOpacity={1} onPress={() => promptAction(actions.deletePrompt, actions.removeTopic)}>
|
||||||
|
<MatIcons name="text-box-remove-outline" style={styles.actionIcon} size={44} color={Colors.linkText} />
|
||||||
|
<Text style={styles.actionLabel}>{ state.strings.delete }</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
{ state.hostId && (
|
||||||
|
<TouchableOpacity style={styles.action} activeOpacity={1} onPress={() => promptAction(actions.leavePrompt, actions.removeTopic)}>
|
||||||
|
<MatIcons name="text-box-minus-outline" style={styles.actionIcon} size={44} color={Colors.linkText} />
|
||||||
|
<Text style={styles.actionLabel}>{ state.strings.leave }</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
<TouchableOpacity style={styles.action} activeOpacity={1} onPress={() => promptAction(actions.blockPrompt, actions.blockTopic)}>
|
||||||
|
<MatIcons name="comment-remove-outline" style={styles.actionIcon} size={44} color={Colors.linkText} />
|
||||||
|
<Text style={styles.actionLabel}>{ state.strings.actionBlock }</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity style={styles.action} activeOpacity={1} onPress={() => promptAction(actions.reportPrompt, actions.reportTopic)}>
|
||||||
|
<MatIcons name="comment-alert-outline" style={styles.actionIcon} size={44} color={Colors.linkText} />
|
||||||
|
<Text style={styles.actionLabel}>{ state.strings.actionReport }</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.members}>
|
<View style={styles.members}>
|
||||||
|
@ -249,4 +249,38 @@ export const styles = StyleSheet.create({
|
|||||||
width: '100%',
|
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,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
@ -14,7 +14,7 @@ export function MemberItem({ item, hostId, toggle }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<TouchableOpacity style={styles.container} activeOpacity={1} onPress={select}>
|
<TouchableOpacity style={styles.container} activeOpacity={1} onPress={select}>
|
||||||
<Logo src={item.logo} width={32} height={32} radius={6} />
|
<Logo src={item.logo} width={48} height={48} radius={6} />
|
||||||
<View style={styles.detail}>
|
<View style={styles.detail}>
|
||||||
<Text style={styles.name} numberOfLines={1} ellipsizeMode={'tail'}>{ item.name }</Text>
|
<Text style={styles.name} numberOfLines={1} ellipsizeMode={'tail'}>{ item.name }</Text>
|
||||||
<Text style={styles.handle} numberOfLines={1} ellipsizeMode={'tail'}>{ item.handle }</Text>
|
<Text style={styles.handle} numberOfLines={1} ellipsizeMode={'tail'}>{ item.handle }</Text>
|
||||||
|
@ -6,7 +6,7 @@ export const styles = StyleSheet.create({
|
|||||||
width: '100%',
|
width: '100%',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
height: 48,
|
height: 64,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
borderBottomWidth: 1,
|
borderBottomWidth: 1,
|
||||||
borderColor: Colors.itemDivider,
|
borderColor: Colors.itemDivider,
|
||||||
|
@ -8,9 +8,10 @@ import { getChannelSubjectLogo } from 'context/channelUtil';
|
|||||||
import { getCardByGuid } from 'context/cardUtil';
|
import { getCardByGuid } from 'context/cardUtil';
|
||||||
import { getChannelSeals, isUnsealed, getContentKey, updateChannelSubject } from 'context/sealUtil';
|
import { getChannelSeals, isUnsealed, getContentKey, updateChannelSubject } from 'context/sealUtil';
|
||||||
import { getLanguageStrings } from 'constants/Strings';
|
import { getLanguageStrings } from 'constants/Strings';
|
||||||
|
import { DisplayContext } from 'context/DisplayContext';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
export function useDetails() {
|
export function useDetails(clear) {
|
||||||
|
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
strings: getLanguageStrings(),
|
strings: getLanguageStrings(),
|
||||||
@ -38,6 +39,7 @@ export function useDetails() {
|
|||||||
const account = useContext(AccountContext);
|
const account = useContext(AccountContext);
|
||||||
const conversation = useContext(ConversationContext);
|
const conversation = useContext(ConversationContext);
|
||||||
const profile = useContext(ProfileContext);
|
const profile = useContext(ProfileContext);
|
||||||
|
const display = useContext(DisplayContext);
|
||||||
|
|
||||||
const updateState = (value) => {
|
const updateState = (value) => {
|
||||||
setState((s) => ({ ...s, ...value }));
|
setState((s) => ({ ...s, ...value }));
|
||||||
@ -200,41 +202,53 @@ export function useDetails() {
|
|||||||
await conversation.actions.setChannelSubject('superbasic', subject);
|
await conversation.actions.setChannelSubject('superbasic', subject);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
remove: async () => {
|
removeTopic: async () => {
|
||||||
if (!state.deleteBusy) {
|
await conversation.actions.removeChannel();
|
||||||
try {
|
clear();
|
||||||
updateState({ deleteBusy: true });
|
|
||||||
await conversation.actions.removeChannel();
|
|
||||||
updateState({ deleteBusy: false });
|
|
||||||
}
|
|
||||||
catch(err) {
|
|
||||||
console.log(err);
|
|
||||||
updateState({ deleteBusy: false });
|
|
||||||
throw new Error("delete failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
block: async() => {
|
blockTopic: async() => {
|
||||||
if (!state.deleteBusy) {
|
await conversation.actions.setChannelFlag();
|
||||||
try {
|
clear();
|
||||||
updateState({ blockBusy: true });
|
|
||||||
await conversation.actions.setChannelFlag();
|
|
||||||
updateState({ blockBusy: false });
|
|
||||||
}
|
|
||||||
catch(err) {
|
|
||||||
console.log(err);
|
|
||||||
updateState({ blockBusy: false });
|
|
||||||
throw new Error("block failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
report: async() => {
|
reportTopic: async() => {
|
||||||
await conversation.actions.addChannelAlert();
|
await conversation.actions.addChannelAlert();
|
||||||
},
|
},
|
||||||
setNotifications: async (notification) => {
|
setNotifications: async (notification) => {
|
||||||
await conversation.actions.setNotifications(notification);
|
await conversation.actions.setNotifications(notification);
|
||||||
updateState({ 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 };
|
return { state, actions };
|
||||||
|
Loading…
Reference in New Issue
Block a user