-
Notifications
You must be signed in to change notification settings - Fork 1.5k
refactor: migrate RoomView to a function component #7482
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
ad71bdd
425a635
abaf4c5
6f3682d
1f045e6
39167bd
854e457
263729b
1bc61ac
8e7ce17
2e91b79
c49a81b
dac3e90
6010df4
6dedc8c
542d982
3118d50
66964e0
4059a49
f9ab6a6
4ddd704
a3fe56f
be3b34a
4708c13
304b241
d3c448d
dda147c
80bda4e
6110f85
c8cfc84
96c8d7c
8330912
7f5bffd
4ca8a76
a7a8bc7
941c090
85cdf40
5e76409
4de1b09
5ae9832
9c4386e
e404870
47fdf5f
0607227
f05a225
430d920
2f00bd2
5ce3f4b
273326b
b503abd
5d687aa
ff9f162
715c48a
7a058b1
00e9bbe
2a82113
ec77896
3aa1092
dbef733
cfad92a
6be3190
a01f1f5
4af3c80
49ecae7
e84f436
541e85b
a3e2898
cfc0e5a
233b131
9e11259
529e69b
061658c
3eec1c1
722f0d4
67a6de9
dbac499
ca23750
06e966b
00027bc
0a3d98f
ce3d8ee
4c906ea
81760b8
827dc4d
14e5726
5dd2032
112cdb9
5dd895a
c6b44d5
d316bda
7278a62
d2b29fc
f41a8ba
954b18f
e83d3f3
b8c9a90
f98690c
10521f4
da66df3
f27d8aa
e81c177
4afdf9f
3512115
0381b55
f0c61cc
b074fee
01ad242
b0b3516
289d65e
5b9bc59
052ba9b
9e1d3f8
82637b9
cf2b383
f768034
49ceb59
ffb81e9
5827c9c
43494d2
d3283db
0a12d2f
780456c
5e560b7
f2a428f
b907bc8
954a30a
387fd4a
de784df
149d7e1
6459910
8db26c4
0a95808
555f941
e5b0a68
5ec4755
514c18d
681691d
73004e8
e09d96c
e796a59
f03920e
be9f9eb
abe0f0c
bba78b1
59e8990
0e6f1c1
9a8ccd6
901c0af
82e5e6f
2cbffca
a61d2b6
d32fd36
7a32745
bf47367
8e442c5
eabf381
f44d17c
855d9b5
34e17bf
0bc4c5c
59f97b0
5dec20a
d5990e2
9417a85
a3e2801
3af0880
fa8b597
72488db
2f12a58
482f2c5
8f7bb24
bcc5918
2b37d2b
ea36011
eb14e7d
a29e7c5
8ee630b
535cc49
70f090f
56bff8a
5da0337
380a9bf
a7d720a
a59c9c9
d80fbb5
fa8eb96
269eaee
ff421d2
a498ce3
37a16f0
f98c852
b4c9067
8bc6793
d6c9e97
2312900
3fbc2b4
5ebf8c6
53e5d21
3457574
198fc39
07198fc
dcc4565
f43feb5
266e3f0
05b2db6
545fce6
8ccdb24
f4f33cc
635241e
29bbe91
b1aceca
1615f6d
afb6a3e
ed710d8
1fa03be
a6e80df
5bfeaf8
8a6d4df
fe17027
c54bb03
71d2451
9ad61cd
6d54182
3717594
36f27a5
74b28bd
cd162f9
6bf89cf
71ffc1d
eaa7412
916cb5f
784d171
7c29414
ad4187b
a137b83
9b1dbc7
8ac3e8b
e33a09f
ab7a54d
0a46316
1067f85
0f7cd47
036d593
17989a5
ced8ac4
b8c148f
40fb713
36bf5cc
cf9ed60
ad78362
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,8 @@ import { AutocompleteItem } from './AutocompleteItem'; | |
| import { useAutocomplete } from '../../hooks'; | ||
| import { type IAutocompleteItemProps } from '../../interfaces'; | ||
| import { AutocompletePreview } from './AutocompletePreview'; | ||
| import { useRoomContext } from '../../../../views/RoomView/context'; | ||
| import { useComposerRid, useUpdateAutocompleteVisible } from '../../../../views/RoomView/stores/ComposerStore'; | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No import from RoomView |
||
| import { useAutocompleteA11yAnnounce } from './useAutocompleteA11yAnnounce'; | ||
| import { useStyle } from './styles'; | ||
|
|
||
| export const Autocomplete = ({ | ||
|
|
@@ -20,7 +21,10 @@ export const Autocomplete = ({ | |
| style: AnimatedStyle<ViewStyle>; | ||
| accessibilityFocusOnInput: () => void; | ||
| }): ReactElement | null => { | ||
| const { rid, updateAutocompleteVisible } = useRoomContext(); | ||
| useAutocompleteA11yAnnounce(); | ||
|
|
||
| const rid = useComposerRid(); | ||
| const updateAutocompleteVisible = useUpdateAutocompleteVisible(); | ||
| const { text, type, params } = useAutocompleteParams(); | ||
| const items = useAutocomplete({ | ||
| rid, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| import { act, renderHook } from '@testing-library/react-native'; | ||
| import { AccessibilityInfo } from 'react-native'; | ||
| import { type ReactNode } from 'react'; | ||
|
|
||
| import { useAutocompleteA11yAnnounce } from './useAutocompleteA11yAnnounce'; | ||
| import { createComposerStore, ComposerStoreContext } from '../../../../views/RoomView/stores/ComposerStore'; | ||
| import { type ComposerStore } from '../../../../views/RoomView/definitions'; | ||
|
|
||
| const externalState = { | ||
| rid: 'rid-1', | ||
| t: 'c', | ||
| tmid: undefined, | ||
| room: { rid: 'rid-1', t: 'c' }, | ||
| sharing: false, | ||
| editCancel: jest.fn(), | ||
| editRequest: jest.fn(() => Promise.resolve()), | ||
| onRemoveQuoteMessage: jest.fn(), | ||
| onSendMessage: jest.fn(), | ||
| setQuotesAndText: jest.fn(), | ||
| getText: jest.fn(() => '') | ||
| }; | ||
|
|
||
| const setup = () => { | ||
| const store: ComposerStore = createComposerStore(externalState); | ||
| const wrapper = ({ children }: { children: ReactNode }) => ( | ||
| <ComposerStoreContext.Provider value={store}>{children}</ComposerStoreContext.Provider> | ||
| ); | ||
| const view = renderHook(() => useAutocompleteA11yAnnounce(), { wrapper }); | ||
| return { store, ...view }; | ||
| }; | ||
|
|
||
| describe('useAutocompleteA11yAnnounce', () => { | ||
| let announceSpy: jest.SpyInstance; | ||
|
|
||
| beforeEach(() => { | ||
| jest.useFakeTimers(); | ||
| announceSpy = jest.spyOn(AccessibilityInfo, 'announceForAccessibility').mockImplementation(() => {}); | ||
| }); | ||
|
|
||
| afterEach(() => { | ||
| announceSpy.mockRestore(); | ||
| jest.useRealTimers(); | ||
| }); | ||
|
|
||
| it('announces 800ms after a false→true transition', () => { | ||
| const { store } = setup(); | ||
|
|
||
| act(() => store.getState().updateAutocompleteVisible(true)); | ||
| expect(announceSpy).not.toHaveBeenCalled(); | ||
|
|
||
| act(() => jest.advanceTimersByTime(800)); | ||
| expect(announceSpy).toHaveBeenCalledTimes(1); | ||
| }); | ||
|
|
||
| it('clears the pending timeout when visibility flips back before 800ms', () => { | ||
| const { store } = setup(); | ||
|
|
||
| act(() => store.getState().updateAutocompleteVisible(true)); | ||
| act(() => jest.advanceTimersByTime(400)); | ||
| act(() => store.getState().updateAutocompleteVisible(false)); | ||
|
|
||
| act(() => jest.advanceTimersByTime(800)); | ||
| expect(announceSpy).not.toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| it('clears the pending timeout on unmount', () => { | ||
| const { store, unmount } = setup(); | ||
|
|
||
| act(() => store.getState().updateAutocompleteVisible(true)); | ||
| unmount(); | ||
|
|
||
| act(() => jest.advanceTimersByTime(800)); | ||
| expect(announceSpy).not.toHaveBeenCalled(); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| import { useEffect } from 'react'; | ||
| import { AccessibilityInfo } from 'react-native'; | ||
|
|
||
| import I18n from '../../../../i18n'; | ||
| import { useIsAutocompleteVisible } from '../../../../views/RoomView/stores/ComposerStore'; | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no import from RoomView here |
||
|
|
||
| export const useAutocompleteA11yAnnounce = (): void => { | ||
| const isAutocompleteVisible = useIsAutocompleteVisible(); | ||
|
|
||
| useEffect(() => { | ||
| if (!isAutocompleteVisible) { | ||
| return; | ||
| } | ||
|
|
||
| // timeout to prevent conflict with default keyboard announcement. | ||
| const timeout = setTimeout(() => { | ||
| AccessibilityInfo.announceForAccessibility(I18n.t('The_autocomplete_options_are_available_above_the_input_composer')); | ||
| }, 800); | ||
|
|
||
| return () => clearTimeout(timeout); | ||
| }, [isAutocompleteVisible]); | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,10 +9,12 @@ import Navigation from '../../../../lib/navigation/appNavigation'; | |
| import { useMasterDetail } from '../../../../lib/hooks/useMasterDetail'; | ||
| import { usePermissions } from '../../../../lib/hooks/usePermissions'; | ||
| import { useCanUploadFile, useChooseMedia } from '../../hooks'; | ||
| import { useRoomContext } from '../../../../views/RoomView/context'; | ||
| import { useComposerRid, useComposerTmid, useComposerType } from '../../../../views/RoomView/stores/ComposerStore'; | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. composer shouldn't import from RoomView |
||
|
|
||
| export const ActionsButton = () => { | ||
| const { rid, tmid, t } = useRoomContext(); | ||
| const rid = useComposerRid(); | ||
| const tmid = useComposerTmid(); | ||
| const t = useComposerType(); | ||
| const { closeEmojiKeyboardAndAction } = useContext(MessageInnerContext); | ||
| const permissionToUpload = useCanUploadFile(rid); | ||
| const [permissionToViewCannedResponses] = usePermissions(['view-canned-responses'], rid); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Data that comes from the same hook should be single liners. Use shallow if needed for perf.