diff --git a/apps/mobile/src/views/Editor/tiny/toolbar/index.js b/apps/mobile/src/views/Editor/tiny/toolbar/index.js
index 47cbc761b..c23670bce 100644
--- a/apps/mobile/src/views/Editor/tiny/toolbar/index.js
+++ b/apps/mobile/src/views/Editor/tiny/toolbar/index.js
@@ -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'
}}>
-
-
-
- {config.map((item, index) =>
- typeof item !== 'string' ? (
-
- ) : (
-
- )
- )}
-
+ {searchReplace ? (
+
+ ) : (
+ <>
+
+
+
+ {config.map((item, index) =>
+ typeof item !== 'string' ? (
+
+ ) : (
+
+ )
+ )}
+
+ >
+ )}
>
);
diff --git a/apps/mobile/src/views/Editor/tiny/toolbar/searchreplace.js b/apps/mobile/src/views/Editor/tiny/toolbar/searchreplace.js
new file mode 100644
index 000000000..28717235b
--- /dev/null
+++ b/apps/mobile/src/views/Editor/tiny/toolbar/searchreplace.js
@@ -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 (
+
+
+ );
+};
+
+export default SearcReplace;