Skip to content

Commit ce9d64e

Browse files
authored
fix: the reset text appears in the next input (#889)
- fix: even though reset the input with innerHTML, incomplete text compositions from the previous input are displayed in the next input. - ticket: [CLNP-1698] [CLNP-1698]: https://sendbird.atlassian.net/browse/CLNP-1698?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
1 parent cff6545 commit ce9d64e

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

src/ui/MessageInput/index.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import { tokenizeMessage } from '../../modules/Message/utils/tokens/tokenize';
1919
import { USER_MENTION_PREFIX } from '../../modules/Message/consts';
2020
import { TOKEN_TYPES } from '../../modules/Message/utils/tokens/types';
2121
import { checkIfFileUploadEnabled } from './messageInputUtils';
22+
import { isMobileIOS } from '../../utils/utils';
23+
2224
import { GroupChannel } from '@sendbird/chat/groupChannel';
2325
import { User } from '@sendbird/chat';
2426
import { OpenChannel } from '@sendbird/chat/openChannel';
@@ -460,7 +462,16 @@ const MessageInput = React.forwardRef<HTMLInputElement, MessageInputProps>((prop
460462
&& internalRef?.current?.textContent?.trim().length > 0
461463
&& e?.nativeEvent?.isComposing !== true
462464
) {
463-
e.preventDefault();
465+
/**
466+
* NOTE: contentEditable does not work as expected in mobile WebKit(Safari).
467+
* Events and properties related to composing, necessary for combining characters like Hangul, also seem to be not handled properly.
468+
* When calling e.preventDefault(), it appears that string composition-related behaviors, in addition to the default actions, are also prevented. (maybe)
469+
*
470+
* Due to this issue, even though reset the input with innerHTML, incomplete text compositions from the previous input are displayed in the next input.
471+
* */
472+
if (!isMobileIOS(navigator.userAgent)) {
473+
e.preventDefault();
474+
}
464475
sendMessage();
465476
}
466477
if (

src/utils/__tests__/utils.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
isMultipleFilesMessage,
88
} from '../index';
99
import { AdminMessage, FileMessage, MultipleFilesMessage, UserMessage } from '@sendbird/chat/message';
10+
import { isMobileIOS } from '../utils';
1011

1112
describe('Global-utils', () => {
1213
it('should find right index with binarySearch', () => {
@@ -190,3 +191,25 @@ describe('isURL', () => {
190191
});
191192
});
192193
});
194+
195+
describe('isMobileIOS', () => {
196+
it('should return true for mobile webkit', () => {
197+
const userAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148';
198+
expect(isMobileIOS(userAgent)).toBe(true);
199+
});
200+
201+
it('should return true for mobile safari', () => {
202+
const userAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1';
203+
expect(isMobileIOS(userAgent)).toBe(true);
204+
});
205+
206+
it('should return true for ios mobile chrome', () => {
207+
const chromeIOS = 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/120.0.6099.101 Mobile/15E148 Safari/604.1';
208+
expect(isMobileIOS(chromeIOS)).toBe(true);
209+
});
210+
211+
it('should return false for android mobile chrome', () => {
212+
const chromeAndroid = 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36';
213+
expect(isMobileIOS(chromeAndroid)).toBe(false);
214+
});
215+
});

src/utils/utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ export const getSenderName = (message: SendableMessageType) => (
1010
)
1111
);
1212
export const isAboutSame = (a: number, b: number, px: number) => Math.abs(a - b) <= px;
13+
export const isMobileIOS = (userAgent: string) => {
14+
const isIOS = /iPhone|iPad|iPod/i.test(userAgent);
15+
const isWebkit = /WebKit/i.test(userAgent);
16+
const isSafari = /Safari/i.test(userAgent);
17+
18+
return isIOS && (isWebkit || isSafari);
19+
};
1320

1421
export default {
1522
getSenderName,

0 commit comments

Comments
 (0)