From 2cdf4aa68379b9cd6a3a5e70d4c5d50bdc68b53b Mon Sep 17 00:00:00 2001 From: Nikita Date: Fri, 17 Feb 2023 11:28:29 +0300 Subject: [PATCH 1/6] =?UTF-8?q?Backmerge:=20#2228=20=E2=80=93=20There=20ar?= =?UTF-8?q?e=20freezes=20in=20application=20when=20Chrome=20DevTools=20are?= =?UTF-8?q?=20opened=20(#2232)=20(#2234)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * #2228 – There are freezes in application when Chrome DevTools are opened * #2228 – changed throttle to debounce; fixed issue of InfoPanel appearing at (0;0) coordinates --- .../src/script/ui/state/functionalGroups/index.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/ketcher-react/src/script/ui/state/functionalGroups/index.ts b/packages/ketcher-react/src/script/ui/state/functionalGroups/index.ts index 9cb2a017ac..7dfca64b89 100644 --- a/packages/ketcher-react/src/script/ui/state/functionalGroups/index.ts +++ b/packages/ketcher-react/src/script/ui/state/functionalGroups/index.ts @@ -23,6 +23,7 @@ import { Struct } from 'ketcher-core' import templatesRawData from '../../../../templates/fg.sdf' +import _ from 'lodash' interface FGState { lib: [] @@ -58,10 +59,12 @@ const highlightFGroup = (group: any) => ({ payload: group }) -export function highlightFG(dispatch, group: any) { +function notDebouncedHighlightFG(dispatch, group: any) { dispatch(highlightFGroup(group)) } +export const highlightFG = _.debounce(notDebouncedHighlightFG, 200) + export function initFGTemplates() { return async (dispatch) => { const provider = FunctionalGroupsProvider.getInstance() From 983f35e909aa7b60576612368d3a44142074f520 Mon Sep 17 00:00:00 2001 From: Nikita Date: Fri, 17 Feb 2023 16:27:22 +0300 Subject: [PATCH 2/6] =?UTF-8?q?Backmerge:=20#2233=20=E2=80=93=20The=20sctu?= =?UTF-8?q?cture=20with=20different=20atoms=20is=20vanished=20after=20appl?= =?UTF-8?q?ying=20'Exact=20change'=20(#2236)=20(#2239)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/script/ui/state/modal/atoms.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/ketcher-react/src/script/ui/state/modal/atoms.ts b/packages/ketcher-react/src/script/ui/state/modal/atoms.ts index 1d000ec758..defe43a04f 100644 --- a/packages/ketcher-react/src/script/ui/state/modal/atoms.ts +++ b/packages/ketcher-react/src/script/ui/state/modal/atoms.ts @@ -35,6 +35,18 @@ export function generateCommonProperties( return resultAtomAttributes } +function castAtomPropToType(property, value) { + const typesMapping = { + charge: Number, + exactChangeFlag: Number, + unsaturatedAtom: Number + } + if (typesMapping[property]) { + return typesMapping[property](value) + } + return value +} + export function updateOnlyChangedProperties(atomId, userChangedAtom, molecule) { const unchangedAtom = molecule.atoms.get(atomId) const updatedKeys = Object.getOwnPropertyNames(userChangedAtom).filter( @@ -44,10 +56,7 @@ export function updateOnlyChangedProperties(atomId, userChangedAtom, molecule) { (updatedAtom, key) => { const isPropertyChanged = updatedKeys.includes(key) if (isPropertyChanged) { - updatedAtom[key] = userChangedAtom[key] - if (key === 'charge') { - updatedAtom[key] = Number(updatedAtom[key]) - } + updatedAtom[key] = castAtomPropToType(key, userChangedAtom[key]) } else { updatedAtom[key] = unchangedAtom[key] } From 643dbc48db4e0f78c741611c6c8dfc5236eeb4e7 Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 20 Feb 2023 16:55:08 +0300 Subject: [PATCH 3/6] =?UTF-8?q?Backmerge:=20#2215=20=E2=80=93=20When=20mov?= =?UTF-8?q?ing=20mouse=20cursor=20over=20created=20S-Group=20pop-up=20tool?= =?UTF-8?q?=20tip=20does=20not=20disappear=20(#2240)=20(#2244)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ketcher-react/src/script/editor/Editor.ts | 29 ++------------ .../editor/utils/functionalGroupsTooltip.ts | 40 +++++++++++++++++++ .../script/ui/state/functionalGroups/index.ts | 9 ++++- .../src/script/ui/utils/index.ts | 28 +++++++++++++ .../components/StructEditor/InfoPanel.tsx | 11 +---- 5 files changed, 79 insertions(+), 38 deletions(-) create mode 100644 packages/ketcher-react/src/script/editor/utils/functionalGroupsTooltip.ts diff --git a/packages/ketcher-react/src/script/editor/Editor.ts b/packages/ketcher-react/src/script/editor/Editor.ts index 472cfc4bdb..657c8eb86f 100644 --- a/packages/ketcher-react/src/script/editor/Editor.ts +++ b/packages/ketcher-react/src/script/editor/Editor.ts @@ -22,8 +22,7 @@ import { Struct, Vec2, fromDescriptorsAlign, - fromNewCanvas, - FunctionalGroup + fromNewCanvas } from 'ketcher-core' import { DOMSubscription, @@ -36,6 +35,7 @@ import { customOnChangeHandler } from './utils' import { isEqual } from 'lodash/fp' import toolMap from './tool' import { Highlighter } from './highlighter' +import { showFunctionalGroupsTooltip } from './utils/functionalGroupsTooltip' const SCALE = 40 const HISTORY_SIZE = 32 // put me to options @@ -372,8 +372,6 @@ class Editor implements KetcherEditor { hover(ci: any, newTool?: any, event?: PointerEvent) { const tool = newTool || this._tool // eslint-disable-line - let infoPanelData: any = null - if ( 'ci' in tool && (!ci || tool.ci.map !== ci.map || tool.ci.id !== ci.id) @@ -386,28 +384,7 @@ class Editor implements KetcherEditor { if (!event) return - const checkFunctionGroupTypes = ['sgroups', 'functionalGroups'] - const closestCollapsibleStructures = this.findItem( - event, - checkFunctionGroupTypes - ) - if (closestCollapsibleStructures) { - const sGroup = this.struct()?.sgroups.get(closestCollapsibleStructures.id) - if (sGroup && !sGroup.data.expanded) { - const groupName = sGroup.data.name - const groupStruct = FunctionalGroup.getFunctionalGroupByName(groupName) - infoPanelData = { - groupStruct, - event, - sGroup - } - } - } - if (infoPanelData) { - this.event.showInfo.dispatch(infoPanelData) - } else { - this.event.showInfo.dispatch(null) - } + showFunctionalGroupsTooltip(this) } update(action: Action | true, ignoreHistory?: boolean) { diff --git a/packages/ketcher-react/src/script/editor/utils/functionalGroupsTooltip.ts b/packages/ketcher-react/src/script/editor/utils/functionalGroupsTooltip.ts new file mode 100644 index 0000000000..debb7e3db4 --- /dev/null +++ b/packages/ketcher-react/src/script/editor/utils/functionalGroupsTooltip.ts @@ -0,0 +1,40 @@ +import { FunctionalGroup } from 'ketcher-core' + +let showTooltipTimer: ReturnType | null = null + +export const TOOLTIP_DELAY = 300 + +export function showTooltip(editor, infoPanelData) { + editor.event.showInfo.dispatch(null) + + if (showTooltipTimer) { + clearTimeout(showTooltipTimer) + } + if (infoPanelData) { + showTooltipTimer = setTimeout(() => { + editor.event.showInfo.dispatch(infoPanelData) + }, TOOLTIP_DELAY) + } +} + +export function showFunctionalGroupsTooltip(editor) { + let infoPanelData: any = null + const checkFunctionGroupTypes = ['sgroups', 'functionalGroups'] + const closestCollapsibleStructures = editor.findItem( + event, + checkFunctionGroupTypes + ) + if (closestCollapsibleStructures) { + const sGroup = editor.struct()?.sgroups.get(closestCollapsibleStructures.id) + if (sGroup && !sGroup.data.expanded) { + const groupName = sGroup.data.name + const groupStruct = FunctionalGroup.getFunctionalGroupByName(groupName) + infoPanelData = { + groupStruct, + event, + sGroup + } + } + } + showTooltip(editor, infoPanelData) +} diff --git a/packages/ketcher-react/src/script/ui/state/functionalGroups/index.ts b/packages/ketcher-react/src/script/ui/state/functionalGroups/index.ts index 7dfca64b89..8cbd13d9ef 100644 --- a/packages/ketcher-react/src/script/ui/state/functionalGroups/index.ts +++ b/packages/ketcher-react/src/script/ui/state/functionalGroups/index.ts @@ -23,7 +23,8 @@ import { Struct } from 'ketcher-core' import templatesRawData from '../../../../templates/fg.sdf' -import _ from 'lodash' +import { memoizedDebounce } from '../../utils' +import { TOOLTIP_DELAY } from '../../../editor/utils/functionalGroupsTooltip' interface FGState { lib: [] @@ -63,7 +64,11 @@ function notDebouncedHighlightFG(dispatch, group: any) { dispatch(highlightFGroup(group)) } -export const highlightFG = _.debounce(notDebouncedHighlightFG, 200) +export const highlightFG = memoizedDebounce( + notDebouncedHighlightFG, + TOOLTIP_DELAY / 3, + [0] +) export function initFGTemplates() { return async (dispatch) => { diff --git a/packages/ketcher-react/src/script/ui/utils/index.ts b/packages/ketcher-react/src/script/ui/utils/index.ts index 447c531199..0b80baa4d7 100644 --- a/packages/ketcher-react/src/script/ui/utils/index.ts +++ b/packages/ketcher-react/src/script/ui/utils/index.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ +import _ from 'lodash' import { escapeRegExp, filter as _filter, flow, reduce } from 'lodash/fp' import { Option } from '../component/form/Select' @@ -84,5 +85,32 @@ export const getSelectOptionsFromSchema = (schema): Array