From 25f7672ce9d2762174386ecd33fccabafc623da2 Mon Sep 17 00:00:00 2001 From: Jogendra Singh Date: Sun, 18 Feb 2024 21:19:06 +0530 Subject: [PATCH 1/4] Implemented Delete Full mentioned String on Single Backspace --- src/components/mention-input.tsx | 4 +++- src/types/types.ts | 2 ++ src/utils/utils.ts | 14 +++++++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/components/mention-input.tsx b/src/components/mention-input.tsx index 5be83d4..86c50eb 100644 --- a/src/components/mention-input.tsx +++ b/src/components/mention-input.tsx @@ -30,6 +30,8 @@ const MentionInput: FC = ( onSelectionChange, + deleteFullMentioned, + ...textInputProps }, ) => { @@ -54,7 +56,7 @@ const MentionInput: FC = ( * @param changedText */ const onChangeInput = (changedText: string) => { - onChange(generateValueFromPartsAndChangedText(parts, plainText, changedText)); + onChange(generateValueFromPartsAndChangedText(parts, plainText, changedText, deleteFullMentioned)); }; /** diff --git a/src/types/types.ts b/src/types/types.ts index 5ec7d99..fbd8f34 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -100,6 +100,8 @@ type MentionInputProps = Omit & { inputRef?: Ref; containerStyle?: StyleProp; + + deleteFullMentioned?: boolean; }; export type { diff --git a/src/utils/utils.ts b/src/utils/utils.ts index d38db13..f8b01de 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -185,7 +185,7 @@ const getMentionPartSuggestionKeywords = ( * @param originalText original plain text * @param changedText changed plain text */ -const generateValueFromPartsAndChangedText = (parts: Part[], originalText: string, changedText: string) => { +const generateValueFromPartsAndChangedText = (parts: Part[], originalText: string, changedText: string, deleteFullMentioned? :string) => { const changes = diffChars(originalText, changedText) as CharactersDiffChange[]; let newParts: Part[] = []; @@ -222,6 +222,10 @@ const generateValueFromPartsAndChangedText = (parts: Part[], originalText: strin default: { if (change.count !== 0) { newParts = newParts.concat(getPartsInterval(parts, cursor, change.count)); + + if (deleteFullMentioned && originalText.length > changedText.length) { + newParts = removeFullMentionPart(parts, newParts); + } cursor += change.count; } @@ -234,6 +238,14 @@ const generateValueFromPartsAndChangedText = (parts: Part[], originalText: strin return getValueFromParts(newParts); }; +const removeFullMentionPart = (parts: Part[], newParts: Part[]): Part[] => + parts.filter((item1) => { + const correspondingItem2 = newParts.find((item2) => item1.text === item2.text); + + // If item1 has data.id and correspondingItem2 doesn't have data.id, remove item1 + return !(item1.data?.id && !correspondingItem2?.data?.id); + }); + /** * Method for adding suggestion to the parts and generating value. We should: * - Find part with plain text where we were tracking mention typing using selection state From 00be6f7e40130a9c4e516b12d83680182ff47e5d Mon Sep 17 00:00:00 2001 From: Jogendra Singh Date: Tue, 30 Apr 2024 20:17:27 +0530 Subject: [PATCH 2/4] Update utils.ts --- src/utils/utils.ts | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/utils/utils.ts b/src/utils/utils.ts index f8b01de..07e94ad 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -51,7 +51,7 @@ const getPartIndexByCursor = (parts: Part[], cursor: number, isIncludeEnd?: bool * @param cursor current cursor position * @param count count of characters that didn't change */ -const getPartsInterval = (parts: Part[], cursor: number, count: number): Part[] => { +const getPartsInterval = (parts: Part[], cursor: number, count: number, deleteFullMentioned: boolean): Part[] => { const newCursor = cursor + count; const currentPartIndex = getPartIndexByCursor(parts, cursor); @@ -69,6 +69,12 @@ const getPartsInterval = (parts: Part[], cursor: number, count: number): Part[] // Push whole first affected part or sub-part of the first affected part if (currentPart.position.start === cursor && currentPart.position.end <= newCursor) { partsInterval.push(currentPart); + } else if (deleteFullMentioned && currentPart.data?.trigger === "@") { + partsInterval.push( + generatePlainTextPart( + currentPart.text.substring(0, -(cursor - currentPart.position.start)) + ) + ); } else { partsInterval.push(generatePlainTextPart(currentPart.text.substr(cursor - currentPart.position.start, count))); } @@ -80,6 +86,12 @@ const getPartsInterval = (parts: Part[], cursor: number, count: number): Part[] // Push whole last affected part or sub-part of the last affected part if (newPart.position.end === newCursor && newPart.position.start >= cursor) { partsInterval.push(newPart); + } else if (deleteFullMentioned && newPart.data?.trigger === "@") { + partsInterval.push( + generatePlainTextPart( + newPart.text.substring(0, -(newCursor - newPart.position.start)) + ) + ); } else { partsInterval.push(generatePlainTextPart(newPart.text.substr(0, newCursor - newPart.position.start))); } @@ -185,7 +197,7 @@ const getMentionPartSuggestionKeywords = ( * @param originalText original plain text * @param changedText changed plain text */ -const generateValueFromPartsAndChangedText = (parts: Part[], originalText: string, changedText: string, deleteFullMentioned? :string) => { +const generateValueFromPartsAndChangedText = (parts: Part[], originalText: string, changedText: string, deleteFullMentioned = false) => { const changes = diffChars(originalText, changedText) as CharactersDiffChange[]; let newParts: Part[] = []; @@ -222,11 +234,6 @@ const generateValueFromPartsAndChangedText = (parts: Part[], originalText: strin default: { if (change.count !== 0) { newParts = newParts.concat(getPartsInterval(parts, cursor, change.count)); - - if (deleteFullMentioned && originalText.length > changedText.length) { - newParts = removeFullMentionPart(parts, newParts); - } - cursor += change.count; } @@ -238,14 +245,6 @@ const generateValueFromPartsAndChangedText = (parts: Part[], originalText: strin return getValueFromParts(newParts); }; -const removeFullMentionPart = (parts: Part[], newParts: Part[]): Part[] => - parts.filter((item1) => { - const correspondingItem2 = newParts.find((item2) => item1.text === item2.text); - - // If item1 has data.id and correspondingItem2 doesn't have data.id, remove item1 - return !(item1.data?.id && !correspondingItem2?.data?.id); - }); - /** * Method for adding suggestion to the parts and generating value. We should: * - Find part with plain text where we were tracking mention typing using selection state From c65baf671aacdb2e7e8c636b2194777adcab33fb Mon Sep 17 00:00:00 2001 From: Jogendra Singh Date: Tue, 30 Apr 2024 20:23:17 +0530 Subject: [PATCH 3/4] Update utils.ts --- src/utils/utils.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 07e94ad..7d62eb9 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -233,7 +233,8 @@ const generateValueFromPartsAndChangedText = (parts: Part[], originalText: strin */ default: { if (change.count !== 0) { - newParts = newParts.concat(getPartsInterval(parts, cursor, change.count)); + newParts = newParts.concat(getPartsInterval(parts, cursor, change.count, deleteFullMentioned)); + cursor += change.count; } From a98157b360db0a748fafea22ba54496796932b1d Mon Sep 17 00:00:00 2001 From: Jogendra Singh Date: Tue, 30 Apr 2024 20:25:17 +0530 Subject: [PATCH 4/4] Update utils.ts