mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-23 23:19:40 +01:00
add JumpToDialog
This commit is contained in:
@@ -44,7 +44,8 @@ import {TEMPLATE_DELETE, TEMPLATE_PERMANANT_DELETE} from './Templates';
|
||||
import {hexToRGBA} from "../../utils/ColorUtils";
|
||||
import {DDS} from "../../services/DeviceDetection";
|
||||
import ResultDialog from '../ResultDialog';
|
||||
import Index from "../SortDialog";
|
||||
import SortDialog from "../SortDialog";
|
||||
import JumpToDialog from '../JumpToDialog';
|
||||
|
||||
export class DialogManager extends Component {
|
||||
constructor(props) {
|
||||
@@ -369,7 +370,8 @@ export class DialogManager extends Component {
|
||||
<ResultDialog/>
|
||||
<VaultDialog colors={colors} />
|
||||
<MoveNoteDialog colors={colors} />
|
||||
<Index colors={colors} />
|
||||
<SortDialog colors={colors} />
|
||||
<JumpToDialog/>
|
||||
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import React from 'react';
|
||||
import {useTracked} from '../../provider';
|
||||
import {SIZE, WEIGHT} from "../../utils/SizeUtils";
|
||||
import {Text, TouchableOpacity} from "react-native";
|
||||
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
|
||||
import {eSendEvent} from "../../services/EventManager";
|
||||
import {eOpenSortDialog} from "../../utils/Events";
|
||||
import {SIZE, WEIGHT} from '../../utils/SizeUtils';
|
||||
import {Text, TouchableOpacity} from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {eSendEvent} from '../../services/EventManager';
|
||||
import {eOpenSortDialog} from '../../utils/Events';
|
||||
|
||||
export const HeaderMenu = () => {
|
||||
const [state,] = useTracked();
|
||||
const [state] = useTracked();
|
||||
const {colors, settings} = state;
|
||||
|
||||
|
||||
return <TouchableOpacity
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
eSendEvent(eOpenSortDialog);
|
||||
}}
|
||||
@@ -25,12 +25,24 @@ export const HeaderMenu = () => {
|
||||
fontSize: SIZE.xs + 1,
|
||||
fontFamily: WEIGHT.regular,
|
||||
color: colors.pri,
|
||||
marginRight: 5
|
||||
marginRight: 5,
|
||||
height: 30,
|
||||
textAlignVertical: 'bottom',
|
||||
}}>
|
||||
{settings.sort.slice(0,1).toUpperCase() + settings.sort.slice(1,settings.sort.length)}
|
||||
{settings.sort.slice(0, 1).toUpperCase() +
|
||||
settings.sort.slice(1, settings.sort.length)}
|
||||
</Text>
|
||||
<Icon color={colors.pri}
|
||||
name={settings.sortOrder === "asc" ? "sort-ascending" : "sort-descending"}
|
||||
size={SIZE.md}/>
|
||||
<Icon
|
||||
color={colors.pri}
|
||||
name={
|
||||
settings.sortOrder === 'asc' ? 'sort-ascending' : 'sort-descending'
|
||||
}
|
||||
style={{
|
||||
textAlignVertical: 'bottom',
|
||||
height: 30,
|
||||
}}
|
||||
size={SIZE.md}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
|
||||
121
apps/mobile/src/components/JumpToDialog/index.js
Normal file
121
apps/mobile/src/components/JumpToDialog/index.js
Normal file
@@ -0,0 +1,121 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { ScrollView, Text, View } from 'react-native';
|
||||
import BaseDialog from '../../components/Dialog/base-dialog';
|
||||
import { PressableButton } from '../../components/PressableButton';
|
||||
import Seperator from '../../components/Seperator';
|
||||
import { useTracked } from '../../provider';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager';
|
||||
import { getElevation } from '../../utils';
|
||||
import {
|
||||
eCloseJumpToDialog,
|
||||
eOpenJumpToDialog
|
||||
} from '../../utils/Events';
|
||||
import { SIZE, WEIGHT } from '../../utils/SizeUtils';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
const JumpToDialog = () => {
|
||||
const [state] = useTracked();
|
||||
const {notes, colors, settings} = state;
|
||||
const [visible,setVisible] = useState(false)
|
||||
|
||||
useEffect(() => {});
|
||||
console.log(notes.filter((i) => i.type === 'header'));
|
||||
|
||||
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);
|
||||
|
||||
return () => {
|
||||
eUnSubscribeEvent(eOpenJumpToDialog, open);
|
||||
eUnSubscribeEvent(eCloseJumpToDialog, close);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const open = () => {
|
||||
setVisible(true);
|
||||
};
|
||||
|
||||
const close = () => {
|
||||
setVisible(false);
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<BaseDialog 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)}
|
||||
selectedColor={colors.nav}
|
||||
customStyle={{
|
||||
minWidth: '20%',
|
||||
maxWidth: '46%',
|
||||
width: null,
|
||||
padding: 15,
|
||||
margin: 5,
|
||||
}}>
|
||||
<Paragraph
|
||||
size={SIZE.xs}
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
}}>
|
||||
{item.title}
|
||||
</Paragraph>
|
||||
</PressableButton>
|
||||
))}
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
</BaseDialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default JumpToDialog
|
||||
@@ -1,17 +1,24 @@
|
||||
import React, {useCallback, useEffect, useMemo, useState} from 'react';
|
||||
import {Platform, RefreshControl, StyleSheet, Text, useWindowDimensions, View,} from 'react-native';
|
||||
import {initialWindowMetrics, useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
import {
|
||||
Platform,
|
||||
RefreshControl,
|
||||
StyleSheet,
|
||||
Text,
|
||||
useWindowDimensions,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {DataProvider, LayoutProvider, RecyclerListView} from 'recyclerlistview';
|
||||
import {useTracked} from '../../provider';
|
||||
import {Actions} from '../../provider/Actions';
|
||||
import {eSendEvent, ToastEvent} from '../../services/EventManager';
|
||||
import {eClearSearch, eOpenLoginDialog, eScrollEvent} from '../../utils/Events';
|
||||
import {eClearSearch, eOpenJumpToDialog, eOpenLoginDialog, eScrollEvent} from '../../utils/Events';
|
||||
import {PressableButton} from '../PressableButton';
|
||||
import {COLORS_NOTE} from '../../utils/Colors';
|
||||
import {SIZE, WEIGHT} from '../../utils/SizeUtils';
|
||||
import {db} from '../../utils/DB';
|
||||
import {HeaderMenu} from "../Header/HeaderMenu";
|
||||
import {HeaderMenu} from '../Header/HeaderMenu';
|
||||
|
||||
const header = {
|
||||
type: 'MAIN_HEADER',
|
||||
@@ -26,7 +33,9 @@ const SimpleList = ({
|
||||
customRefresh,
|
||||
customRefreshing,
|
||||
refreshCallback,
|
||||
sortMenuButton
|
||||
sortMenuButton,
|
||||
scrollRef,
|
||||
jumpToDialog
|
||||
}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors, selectionMode, messageBoardState} = state;
|
||||
@@ -67,28 +76,32 @@ const SimpleList = ({
|
||||
const RenderSectionHeader = ({item, index}) => (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
justifyContent: "space-between",
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
justifyContent: 'space-between',
|
||||
paddingHorizontal: 12,
|
||||
marginTop: 10,
|
||||
height: 25,
|
||||
}}
|
||||
>
|
||||
|
||||
height: 30,
|
||||
}}>
|
||||
<Text
|
||||
onPress={() => {
|
||||
console.log('clicekd');
|
||||
if (jumpToDialog) {
|
||||
eSendEvent(eOpenJumpToDialog);
|
||||
}
|
||||
}}
|
||||
style={[
|
||||
styles.sectionHeader,
|
||||
{
|
||||
color: colors.accent,
|
||||
height:30,
|
||||
minWidth:60,
|
||||
textAlignVertical:"bottom"
|
||||
},
|
||||
styles.sectionHeader,
|
||||
]}>
|
||||
{item.title}
|
||||
</Text>
|
||||
{
|
||||
index === 1 && sortMenuButton? <HeaderMenu/> : null
|
||||
}
|
||||
{index === 1 && sortMenuButton ? <HeaderMenu /> : null}
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -190,14 +203,15 @@ const SimpleList = ({
|
||||
);
|
||||
|
||||
const _renderRow = (type, data, index) => {
|
||||
|
||||
switch (type) {
|
||||
case 'note':
|
||||
return <RenderItem item={data} pinned={data.pinned} index={index} />;
|
||||
case 'notebook':
|
||||
return <RenderItem item={data} pinned={data.pinned} index={index} />;
|
||||
case 'MAIN_HEADER':
|
||||
return <ListHeaderComponent type={dataType} index={index} data={listData}/>;
|
||||
return (
|
||||
<ListHeaderComponent type={dataType} index={index} data={listData} />
|
||||
);
|
||||
case 'header':
|
||||
return <RenderSectionHeader item={data} index={index} />;
|
||||
default:
|
||||
@@ -217,7 +231,7 @@ const SimpleList = ({
|
||||
: 130 - 60
|
||||
: listData[0] && !selectionMode
|
||||
? 155 - insets.top
|
||||
: (155 - insets.top) - 60,
|
||||
: 155 - insets.top - 60,
|
||||
};
|
||||
}, [selectionMode, listData, colors, insets]);
|
||||
|
||||
@@ -225,6 +239,7 @@ const SimpleList = ({
|
||||
_ListEmptyComponent
|
||||
) : (
|
||||
<RecyclerListView
|
||||
ref={scrollRef}
|
||||
layoutProvider={_layoutProvider}
|
||||
dataProvider={dataProvider}
|
||||
rowRenderer={_renderRow}
|
||||
|
||||
@@ -18,7 +18,7 @@ import Seperator from "../Seperator";
|
||||
|
||||
const actionSheet = createRef();
|
||||
|
||||
class Index extends React.Component {
|
||||
class SortDialog extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
@@ -172,4 +172,4 @@ class Index extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default Index;
|
||||
export default SortDialog;
|
||||
|
||||
35
apps/mobile/src/components/Typography/Paragraph.js
Normal file
35
apps/mobile/src/components/Typography/Paragraph.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import React from 'react';
|
||||
import {Text} from 'react-native';
|
||||
import {useTracked} from '../../provider';
|
||||
import {SIZE, WEIGHT} from '../../utils/SizeUtils';
|
||||
|
||||
/**
|
||||
*
|
||||
* @typedef {import('react-native').TextProps} TextType
|
||||
* @typedef {Object} restTypes
|
||||
* @property {string} color color
|
||||
* @property {number} size color
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* @param {TextType | restTypes} props all props
|
||||
*/
|
||||
const Paragraph = ({color, size, style, ...restProps}) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
|
||||
return (
|
||||
<Text
|
||||
{...restProps}
|
||||
style={[
|
||||
{
|
||||
fontFamily: WEIGHT.regular,
|
||||
fontSize: size || SIZE.xs + 1,
|
||||
color: color || colors.pri,
|
||||
},
|
||||
style,
|
||||
]}></Text>
|
||||
);
|
||||
};
|
||||
|
||||
export default Paragraph
|
||||
@@ -117,3 +117,6 @@ export const eCloseResultDialog = '558';
|
||||
|
||||
export const eOpenSortDialog = '559';
|
||||
export const eCloseSortDialog = '560';
|
||||
|
||||
export const eOpenJumpToDialog = '561';
|
||||
export const eCloseJumpToDialog = '562';
|
||||
@@ -1,19 +1,22 @@
|
||||
import React, {useCallback, useEffect} from 'react';
|
||||
import React, { createRef, useCallback, useEffect } from 'react';
|
||||
import { ContainerBottomButton } from '../../components/Container/ContainerBottomButton';
|
||||
import { Placeholder } from '../../components/ListPlaceholders';
|
||||
import SimpleList from '../../components/SimpleList';
|
||||
import { NoteItemWrapper } from '../../components/SimpleList/NoteItemWrapper';
|
||||
import { useTracked } from '../../provider';
|
||||
import { Actions } from '../../provider/Actions';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import { eSendEvent } from '../../services/EventManager';
|
||||
import { sortSettings } from '../../utils';
|
||||
import { openEditorAnimation } from '../../utils/Animations';
|
||||
import {
|
||||
eOnLoadNote,
|
||||
|
||||
eScrollEvent,
|
||||
eUpdateSearchState,
|
||||
eUpdateSearchState
|
||||
} from '../../utils/Events';
|
||||
import {openEditorAnimation} from '../../utils/Animations';
|
||||
import {DDS} from '../../services/DeviceDetection';
|
||||
import {sortSettings} from "../../utils";
|
||||
|
||||
const scrollRef = createRef();
|
||||
|
||||
export const Home = ({navigation}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
@@ -87,6 +90,7 @@ export const Home = ({navigation}) => {
|
||||
<>
|
||||
<SimpleList
|
||||
data={notes}
|
||||
scrollRef={scrollRef}
|
||||
type="notes"
|
||||
isHome={true}
|
||||
pinned={true}
|
||||
@@ -95,6 +99,7 @@ export const Home = ({navigation}) => {
|
||||
RenderItem={NoteItemWrapper}
|
||||
placeholder={<Placeholder type="notes" />}
|
||||
placeholderText={`Notes you write appear here`}
|
||||
jumpToDialog={true}
|
||||
/>
|
||||
|
||||
<ContainerBottomButton
|
||||
@@ -106,3 +111,5 @@ export const Home = ({navigation}) => {
|
||||
};
|
||||
|
||||
export default Home;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user