improve multi-select ux

This commit is contained in:
ammarahm-ed
2020-03-02 10:25:38 +05:00
parent 9b1c2971b7
commit 5864ebe6d6
4 changed files with 76 additions and 46 deletions

View File

@@ -11,7 +11,7 @@ import {db, DDS} from '../../../App';
import {opacity, ph, pv, SIZE, WEIGHT} from '../../common/common'; import {opacity, ph, pv, SIZE, WEIGHT} from '../../common/common';
import {ACTIONS} from '../../provider/actions'; import {ACTIONS} from '../../provider/actions';
import NavigationService from '../../services/NavigationService'; import NavigationService from '../../services/NavigationService';
import {getElevation, ToastEvent, editing} from '../../utils/utils'; import {getElevation, ToastEvent, editing, history} from '../../utils/utils';
import {dialogActions, updateEvent} from '../DialogManager'; import {dialogActions, updateEvent} from '../DialogManager';
import {eSendEvent} from '../../services/eventManager'; import {eSendEvent} from '../../services/eventManager';
import {eCloseFullscreenEditor, eOnLoadNote} from '../../services/events'; import {eCloseFullscreenEditor, eOnLoadNote} from '../../services/events';
@@ -21,6 +21,7 @@ export class Dialog extends Component {
super(props); super(props);
this.state = { this.state = {
visible: false, visible: false,
selecteItemsLength: 0,
}; };
} }
@@ -29,23 +30,29 @@ export class Dialog extends Component {
switch (template.action) { switch (template.action) {
case dialogActions.ACTION_DELETE: { case dialogActions.ACTION_DELETE: {
if (item.type === 'note') { if (item.id && history.selectedItemsList.length === 0) {
await db.notes.delete(item.id); history.selectedItemsList = [];
history.selectedItemsList.push(item);
ToastEvent.show('Note moved to trash', 'error', 3000);
updateEvent({type: item.type});
} else if (item.type === 'topic') {
await db.notebooks
.notebook(item.notebookId)
.topics.delete(item.title);
updateEvent({type: 'notebook'});
ToastEvent.show('Topic deleted', 'error', 3000);
} else if (item.type === 'notebook') {
await db.notebooks.delete(item.id);
updateEvent({type: item.type});
ToastEvent.show('Notebook moved to trash', 'error', 3000);
} }
history.selectedItemsList.forEach(async i => {
if (i.type === 'note') {
await db.notes.delete(i.id);
ToastEvent.show('Notes moved to trash', 'error', 3000);
updateEvent({type: i.type});
} else if (i.type === 'topic') {
await db.notebooks.notebook(i.notebookId).topics.delete(i.title);
updateEvent({type: 'notebook'});
ToastEvent.show('Topics deleted', 'error', 3000);
} else if (i.type === 'notebook') {
await db.notebooks.delete(i.id);
updateEvent({type: i.type});
ToastEvent.show('Notebooks moved to trash', 'error', 3000);
}
});
updateEvent({type: ACTIONS.CLEAR_SELECTION});
updateEvent({type: ACTIONS.SELECTION_MODE, enabled: false});
this.setState({ this.setState({
visible: false, visible: false,
@@ -87,7 +94,7 @@ export class Dialog extends Component {
break; break;
} }
case dialogActions.ACTION_TRASH: { case dialogActions.ACTION_TRASH: {
db.trash.restore(item.id); await db.trash.restore(i.id);
ToastEvent.show( ToastEvent.show(
item.type.slice(0, 1).toUpperCase() + item.type.slice(0, 1).toUpperCase() +
item.type.slice(1) + item.type.slice(1) +
@@ -95,6 +102,7 @@ export class Dialog extends Component {
'success', 'success',
3000, 3000,
); );
updateEvent({type: ACTIONS.TRASH}); updateEvent({type: ACTIONS.TRASH});
this.hide(); this.hide();
break; break;
@@ -114,8 +122,10 @@ export class Dialog extends Component {
}; };
show = () => { show = () => {
console.log(history.selectedItemsList.length, 'length');
this.setState({ this.setState({
visible: true, visible: true,
selectedItemsLength: history.selectedItemsList.length,
}); });
}; };
hide = () => { hide = () => {
@@ -193,7 +203,11 @@ export class Dialog extends Component {
textAlign: 'center', textAlign: 'center',
marginTop: 10, marginTop: 10,
}}> }}>
{paragraph} {this.state.selectedItemsLength > 0
? 'Delete ' +
this.state.selectedItemsLength +
' selected items?'
: paragraph}
</Text> </Text>
) : null} ) : null}

View File

@@ -14,8 +14,9 @@ import {useTracked} from '../../provider';
import {ACTIONS} from '../../provider/actions'; import {ACTIONS} from '../../provider/actions';
import {w, ToastEvent} from '../../utils/utils'; import {w, ToastEvent} from '../../utils/utils';
import {eSendEvent} from '../../services/eventManager'; import {eSendEvent} from '../../services/eventManager';
import {eOpenMoveNoteDialog} from '../../services/events'; import {eOpenMoveNoteDialog, eOpenSimpleDialog} from '../../services/events';
import {db} from '../../../App'; import {db} from '../../../App';
import {TEMPLATE_DELETE} from '../DialogManager';
export const AnimatedSafeAreaView = Animatable.createAnimatableComponent( export const AnimatedSafeAreaView = Animatable.createAnimatableComponent(
SafeAreaView, SafeAreaView,
@@ -105,6 +106,7 @@ export const SelectionHeader = ({navigation}) => {
<TouchableOpacity <TouchableOpacity
onPress={() => { onPress={() => {
dispatch({type: ACTIONS.SELECTION_MODE, enabled: false}); dispatch({type: ACTIONS.SELECTION_MODE, enabled: false});
dispatch({type: ACTIONS.CLEAR_SELECTION});
eSendEvent(eOpenMoveNoteDialog); eSendEvent(eOpenMoveNoteDialog);
}}> }}>
<Icon <Icon
@@ -144,6 +146,8 @@ export const SelectionHeader = ({navigation}) => {
{currentScreen === 'trash' ? null : ( {currentScreen === 'trash' ? null : (
<TouchableOpacity <TouchableOpacity
onPress={async () => { onPress={async () => {
eSendEvent(eOpenSimpleDialog, TEMPLATE_DELETE('item'));
return;
if (selectedItemsList.length > 0) { if (selectedItemsList.length > 0) {
let noteIds = []; let noteIds = [];
selectedItemsList.forEach(item => { selectedItemsList.forEach(item => {

View File

@@ -20,6 +20,11 @@ export const getElevation = elevation => {
export const editing = { export const editing = {
currentlyEditing: false, currentlyEditing: false,
isFullscreen: false,
};
export const history = {
selectedItemsList: [],
}; };
export function timeSince(date) { export function timeSince(date) {

View File

@@ -355,17 +355,11 @@ const Editor = ({navigation, noMenu}) => {
{noMenu ? null : ( {noMenu ? null : (
<TouchableOpacity <TouchableOpacity
onPress={() => { onPress={async () => {
if (DDS.isTab) { if (DDS.isTab) {
simpleDialogEvent(TEMPLATE_EXIT_FULLSCREEN()); simpleDialogEvent(TEMPLATE_EXIT_FULLSCREEN());
} else { } else {
tapCount = 0; await closeEditor();
title = null;
content = null;
note = null;
id = null;
ToastEvent.show('Note Saved!', 'success');
NavigationService.goBack();
} }
}} }}
style={{ style={{
@@ -534,6 +528,33 @@ const Editor = ({navigation, noMenu}) => {
}; };
}); });
const closeEditor = async () => {
await saveNote();
title = null;
content = null;
note = null;
id = null;
dateEdited = null;
tapCount = 0;
NavigationService.goBack();
ToastEvent.show('Note Saved!', 'success');
};
const _onHardwareBackPress = async () => {
if (tapCount > 0) {
await closeEditor();
return true;
} else {
tapCount = 1;
setTimeout(() => {
tapCount = 0;
}, 3000);
ToastEvent.show('Press back again to exit editor', 'success');
return true;
}
};
useEffect(() => { useEffect(() => {
editing.currentlyEditing = true; editing.currentlyEditing = true;
@@ -545,24 +566,10 @@ const Editor = ({navigation, noMenu}) => {
return true; return true;
}); });
} else if (!DDS.isTab) { } else if (!DDS.isTab) {
handleBack = BackHandler.addEventListener('hardwareBackPress', () => { handleBack = BackHandler.addEventListener(
if (tapCount > 0) { 'hardwareBackPress',
tapCount = 0; _onHardwareBackPress,
title = null; );
content = null;
note = null;
id = null;
ToastEvent.show('Note Saved!', 'success');
return false;
} else {
tapCount = 1;
setTimeout(() => {
tapCount = 0;
}, 3000);
ToastEvent.show('Press back again to exit editor', 'success');
return true;
}
});
} else { } else {
if (handleBack) { if (handleBack) {
handleBack.remove(); handleBack.remove();