Files
notesnook/apps/mobile/src/components/JumpToDialog/index.js

165 lines
4.6 KiB
JavaScript
Raw Normal View History

2020-11-04 15:42:39 +05:00
import React, {useEffect, useState} from 'react';
import {ScrollView, Text, View} from 'react-native';
2020-11-04 15:06:06 +05:00
import BaseDialog from '../../components/Dialog/base-dialog';
2020-11-04 15:42:39 +05:00
import {PressableButton} from '../../components/PressableButton';
2020-11-04 15:06:06 +05:00
import Seperator from '../../components/Seperator';
2020-11-04 15:42:39 +05:00
import {useTracked} from '../../provider';
import {DDS} from '../../services/DeviceDetection';
import {eSubscribeEvent, eUnSubscribeEvent} from '../../services/EventManager';
import {getElevation, scrollRef} from '../../utils';
2020-11-04 15:06:06 +05:00
import {
2020-11-04 15:42:39 +05:00
eCloseJumpToDialog,
eOpenJumpToDialog,
eScrollEvent,
2020-11-04 15:06:06 +05:00
} from '../../utils/Events';
2020-11-04 15:42:39 +05:00
import {SIZE, WEIGHT} from '../../utils/SizeUtils';
2020-11-04 15:06:06 +05:00
import Paragraph from '../Typography/Paragraph';
2020-11-04 15:42:39 +05:00
const offsets = [];
let timeout = null;
2020-11-04 15:06:06 +05:00
const JumpToDialog = () => {
2020-11-04 15:42:39 +05:00
const [state] = useTracked();
const {notes, colors, settings} = state;
const [visible, setVisible] = useState(false);
const [currentIndex, setCurrentIndex] = useState(0);
const onPress = (item, index) => {
let offset = 30 * index;
let ind = notes.findIndex(
(i) => i.title === item.title && i.type === 'header',
);
ind = ind + 1;
ind = ind - (index + 1);
offset = offset + ind * 100;
scrollRef.current?.scrollToOffset(0, index === 0 ? 0 : offset + 50, true);
close();
};
useEffect(() => {
eSubscribeEvent(eOpenJumpToDialog, open);
eSubscribeEvent(eCloseJumpToDialog, close);
eSubscribeEvent(eScrollEvent, onScroll);
return () => {
eUnSubscribeEvent(eOpenJumpToDialog, open);
eUnSubscribeEvent(eCloseJumpToDialog, close);
eUnSubscribeEvent(eScrollEvent, onScroll);
};
}, []);
const onScroll = (y) => {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
timeout = setTimeout(() => {
let index = offsets.findIndex((o, i) => o <= y && offsets[i + 1] > y);
setCurrentIndex(index);
}, 30);
};
const open = () => {
setVisible(true);
2020-11-04 15:06:06 +05:00
};
2020-11-04 15:42:39 +05:00
const close = () => {
setVisible(false);
};
useEffect(() => {
loadOffsets();
}, [notes]);
const loadOffsets = () => {
notes
.filter((i) => i.type === 'header')
.map((item, index) => {
let offset = 30 * index;
let ind = notes.findIndex(
(i) => i.title === item.title && i.type === 'header',
);
ind = ind + 1;
ind = ind - (index + 1);
offset = offset + ind * 100;
offsets.push(offset);
});
};
return (
<BaseDialog
onShow={() => {
loadOffsets();
}}
onRequestClose={close}
visible={visible}>
<View
style={{
...getElevation(5),
width: DDS.isTab ? 500 : '80%',
backgroundColor: colors.bg,
zIndex: 100,
bottom: 20,
maxHeight: '65%',
borderRadius: 5,
alignSelf: 'center',
padding: 10,
}}>
<Text
style={{
fontSize: SIZE.xl,
fontFamily: WEIGHT.bold,
color: colors.heading,
alignSelf: 'center',
}}>
{settings.sort.slice(0, 1).toUpperCase() +
settings.sort.slice(1, settings.sort.length)}
</Text>
<Seperator />
<ScrollView
style={{
maxHeight: '100%',
}}>
<View
style={{
flexDirection: 'row',
flexWrap: 'wrap',
alignSelf: 'center',
justifyContent: 'center',
}}>
{notes
.filter((i) => i.type === 'header')
.map((item, index) => (
<PressableButton
onPress={() => onPress(item, index)}
color={currentIndex === index ? colors.shade : 'transparent'}
selectedColor={
currentIndex === index ? colors.accent : colors.nav
}
alpha={!colors.night ? -0.02 : 0.02}
opacity={currentIndex === index ? 0.12 : 1}
customStyle={{
minWidth: '20%',
maxWidth: '46%',
width: null,
padding: 15,
margin: 5,
}}>
<Paragraph
size={SIZE.xs}
color={currentIndex === index ? colors.accent : null}
style={{
textAlign: 'center',
}}>
{item.title}
</Paragraph>
</PressableButton>
))}
</View>
</ScrollView>
</View>
</BaseDialog>
);
};
export default JumpToDialog;