add searchreplace in toolbar

This commit is contained in:
ammarahm-ed
2021-12-19 00:31:26 +05:00
parent e58fbc7719
commit 926c982097
2 changed files with 329 additions and 44 deletions

View File

@@ -1,19 +1,22 @@
import React, {useEffect} from 'react';
import {Platform} from 'react-native';
import {ScrollView, View} from 'react-native';
import {useTracked} from '../../../../provider';
import {normalize} from '../../../../utils/SizeUtils';
import React, { useEffect } from 'react';
import { ScrollView, View } from 'react-native';
import { useTracked } from '../../../../provider';
import { useEditorStore } from '../../../../provider/stores';
import { normalize } from '../../../../utils/SizeUtils';
import HistoryComponent from '../../HistoryComponent';
import {TOOLBAR_CONFIG} from './config';
import {properties, toolbarRef} from './constants';
import { TOOLBAR_CONFIG } from './config';
import { properties, toolbarRef } from './constants';
import ToolbarGroup from './group';
import SearcReplace from './searchreplace';
import Tooltip from './tooltip';
const EditorToolbar = React.memo(
() => {
const [state] = useTracked();
const {colors} = state;
const config = TOOLBAR_CONFIG;
const searchReplace = useEditorStore(state => state.searchReplace);
useEffect(() => {
properties.selection = {};
@@ -28,44 +31,50 @@ const EditorToolbar = React.memo(
style={{
width: '100%',
minHeight: normalize(50),
position: 'relative',
position: 'relative'
}}>
<Tooltip />
<ScrollView
ref={toolbarRef}
style={{
width: '100%',
maxWidth: '100%',
minHeight: normalize(50),
backgroundColor:colors.bg,
paddingLeft: 6,
zIndex: 11
}}
contentContainerStyle={{
alignItems: 'center'
}}
keyboardShouldPersistTaps="always"
keyboardDismissMode="none"
horizontal={true}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
bounces={false}>
<HistoryComponent />
{config.map((item, index) =>
typeof item !== 'string' ? (
<ToolbarGroup key={item[0].format} group={item} />
) : (
<View
style={{
height: 30,
width: 2,
marginHorizontal:2,
backgroundColor: colors.nav
}}
/>
)
)}
</ScrollView>
{searchReplace ? (
<SearcReplace />
) : (
<>
<Tooltip />
<ScrollView
ref={toolbarRef}
style={{
width: '100%',
maxWidth: '100%',
minHeight: normalize(50),
backgroundColor: colors.bg,
paddingLeft: 6,
zIndex: 11
}}
contentContainerStyle={{
alignItems: 'center'
}}
keyboardShouldPersistTaps="always"
keyboardDismissMode="none"
horizontal={true}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
bounces={false}>
<HistoryComponent />
{config.map((item, index) =>
typeof item !== 'string' ? (
<ToolbarGroup key={item[0].format} group={item} />
) : (
<View
style={{
height: 30,
width: 2,
marginHorizontal: 2,
backgroundColor: colors.nav
}}
/>
)
)}
</ScrollView>
</>
)}
</View>
</>
);

View File

@@ -0,0 +1,276 @@
import React, {useEffect, useRef, useState} from 'react';
import {View} from 'react-native';
import {Button} from '../../../../components/Button';
import Input from '../../../../components/Input';
import {useTracked} from '../../../../provider';
import {useSettingStore} from '../../../../provider/stores';
import {showTooltip, TOOLTIP_POSITIONS} from '../../../../utils';
import {SIZE} from '../../../../utils/SizeUtils';
import {EditorWebView} from '../../Functions';
import tiny from '../tiny';
import {endSearch} from './commands';
const SearcReplace = () => {
const [state] = useTracked();
const {colors} = state;
const [focusType, setFocusType] = useState(0);
const [enableReplace, setEnableReplace] = useState(false);
const [menu, setMenu] = useState(false);
const deviceMode = useSettingStore(state => state.deviceMode);
const findRef = useRef();
const [config, setConfig] = useState({
matchCase: false,
matchWholeWord: false
});
const values = useRef({
find: null,
replace: null
});
useEffect(() => {
setTimeout(() => {
findRef.current?.focus();
}, 300);
}, []);
function find() {
if (!values.current?.find) return;
tiny.call(
EditorWebView,
`tinymce.activeEditor.plugins.searchreplace.find("${values.current?.find}",${config.matchCase},${config.matchWholeWord})`
);
}
function replace(all = false) {
if (!values.current?.replace) return;
tiny.call(
EditorWebView,
`tinymce.activeEditor.plugins.searchreplace.replace("${
values.current?.replace
}",true${all ? ',true' : ''})`
);
}
function next() {
tiny.call(
EditorWebView,
`tinymce.activeEditor.plugins.searchreplace.next()`
);
}
function prev() {
tiny.call(
EditorWebView,
`tinymce.activeEditor.plugins.searchreplace.prev()`
);
}
function done() {
endSearch();
}
function toggleMatchCase() {
setConfig(c => {
c.matchCase = !c.matchCase;
return {...c};
});
}
function toggleMatchWholeWord() {
setConfig(c => {
c.matchWholeWord = !c.matchWholeWord;
return {...c};
});
}
const menuButtons = [
{
icon: 'chevron-left',
type: 'gray',
press: () => setMenu(false),
fullname: 'Go back'
},
{
icon: 'format-letter-case',
type: 'gray',
press: toggleMatchCase,
on: config.matchCase,
fullname: 'Match case'
},
{
icon: 'format-letter-matches',
type: 'gray',
press: toggleMatchWholeWord,
on: config.matchWholeWord,
fullname: 'Match whole word'
}
];
const searchButtons = menu
? menuButtons
: [
{
icon: 'arrow-up',
type: 'gray',
press: prev,
fullname: 'Previous'
},
{
icon: 'arrow-down',
type: 'gray',
press: next,
fullname: 'Next'
},
{
icon: 'close',
type: 'gray',
press: done,
fullname: 'End search'
},
{
icon: 'dots-vertical',
type: 'gray',
press: () => setMenu(true),
fullname: 'Show options'
}
];
const replaceButtons = [
{
text: 'Replace',
type: 'grayBg',
press: replace
},
{
text: 'Replace all',
type: 'gray',
press: () => replace(true)
}
];
return (
<View
style={{
width: '100%',
backgroundColor: colors.bg,
paddingHorizontal: 12,
paddingVertical: 6,
paddingLeft: 0,
paddingBottom: 0,
borderTopRightRadius: 10,
borderTopLeftRadius: 10,
flexDirection: 'row',
alignItems: 'center'
}}>
<Button
height="93%"
iconSize={SIZE.md + 4}
icon={enableReplace ? 'chevron-down' : 'chevron-right'}
style={{
paddingHorizontal: 3,
marginBottom: 10
}}
iconColor={enableReplace ? colors.accent : colors.icon}
onPress={() => {
if (enableReplace) {
if (focusType === 2) {
findRef.current?.focus();
}
setEnableReplace(false);
} else {
setEnableReplace(true);
}
}}
/>
<View
style={{
flexGrow: 1,
flexDirection: deviceMode !== 'mobile' ? 'row' : 'column',
flexShrink: 1
}}>
<Input
fwdRef={findRef}
onChangeText={value => {
values.current.find = value;
}}
onFocusInput={() => setFocusType(1)}
onSubmit={find}
blurOnSubmit={false}
returnKeyType="search"
returnKeyLabel="Search"
buttons={
<>
{searchButtons.map(button => (
<Button
title={button.text}
fontSize={SIZE.xs}
height={28}
onLongPress={event => {
console.log(event);
showTooltip(event, button.fullname, TOOLTIP_POSITIONS.TOP);
}}
iconSize={SIZE.md + 4}
width={null}
style={{
paddingHorizontal: button.icon ? 6 : 10
}}
iconColor={button.on ? colors.accent : null}
buttonType={{
text: button.text && colors.accent
}}
onPress={button.press}
icon={button.icon}
type={button.type}
/>
))}
</>
}
placeholder={'Find'}
fontSize={SIZE.xs + 1}
height={40}
marginRight={deviceMode !== 'mobile' ? 10 : 0}
/>
{enableReplace ? (
<>
<Input
onSubmit={replace}
onChangeText={value => {
values.current.replace = value;
}}
blurOnSubmit={false}
buttons={
<>
{replaceButtons.map(button => (
<Button
title={button.text}
fontSize={SIZE.xs + 1}
height={28}
width={null}
buttonType={{
text: colors.accent
}}
onPress={button.press}
style={{
paddingHorizontal: button.icon ? 6 : 12
}}
icon={button.icon}
type={button.type}
/>
))}
</>
}
placeholder={'Replace with'}
fontSize={SIZE.xs + 1}
onFocusInput={() => setFocusType(2)}
height={40}
/>
</>
) : null}
</View>
</View>
);
};
export default SearcReplace;