-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(example): reset to beginning of the list when pressing back (#85)
* feat(lists): expose currently focused item index in ref Co-authored-by: JulienIzz <[email protected]> * chore(example): add example back button usage for lists * chore(example): add missing forwardRef * chore(example): add missing useEffect * chore(example): more GoBackConfiguration so that each page has its own Otherwise we can't catch hardware back press properly --------- Co-authored-by: JulienIzz <[email protected]> Co-authored-by: JulienIzz <[email protected]> Co-authored-by: Pierre Poupin <[email protected]>
- Loading branch information
1 parent
4d55b25
commit aeb548e
Showing
19 changed files
with
229 additions
and
121 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,38 @@ | ||
import { useNavigation } from '@react-navigation/native'; | ||
import { useEffect } from 'react'; | ||
import RemoteControlManager from './remote-control/RemoteControlManager'; | ||
import { SupportedKeys } from './remote-control/SupportedKeys'; | ||
import { useKey } from '../hooks/useKey'; | ||
import { useCallback, useEffect } from 'react'; | ||
import { BackHandler } from 'react-native'; | ||
|
||
export const GoBackConfiguration = () => { | ||
const navigation = useNavigation(); | ||
|
||
useEffect(() => { | ||
const remoteControlListener = (pressedKey: SupportedKeys) => { | ||
if (pressedKey !== SupportedKeys.Back) return; | ||
const event = BackHandler.addEventListener('hardwareBackPress', () => { | ||
return true; | ||
}); | ||
|
||
return () => { | ||
event.remove(); | ||
}; | ||
}, []); | ||
|
||
const goBackOnBackPress = useCallback( | ||
(pressedKey: SupportedKeys) => { | ||
if (!navigation.isFocused) { | ||
return false; | ||
} | ||
if (pressedKey !== SupportedKeys.Back) return false; | ||
if (navigation.canGoBack()) { | ||
navigation.goBack(); | ||
return true; | ||
} | ||
}; | ||
RemoteControlManager.addKeydownListener(remoteControlListener); | ||
return false; | ||
}, | ||
[navigation], | ||
); | ||
|
||
return () => RemoteControlManager.removeKeydownListener(remoteControlListener); | ||
}, [navigation]); | ||
useKey(SupportedKeys.Back, goBackOnBackPress); | ||
|
||
return <></>; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
packages/example/src/components/remote-control/CustomEventEmitter.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/** | ||
* This event emitter is a minimal reimplementation of `mitt` with the support of stoppable event propagation | ||
*/ | ||
|
||
export type EventType = string | symbol; | ||
|
||
// An event handler can take an optional event argument | ||
// and should return a boolean indicating whether or not to stop event propagation | ||
export type Handler<T = unknown> = (event: T) => boolean; | ||
|
||
// An array of all currently registered event handlers for a type | ||
export type EventHandlerList<T = unknown> = Array<Handler<T>>; | ||
|
||
// A map of event types and their corresponding event handlers. | ||
export type EventHandlerMap<Events extends Record<EventType, unknown>> = Map< | ||
keyof Events, | ||
EventHandlerList<Events[keyof Events]> | ||
>; | ||
|
||
export default class CustomEventEmitter<Events extends Record<EventType, unknown>> { | ||
private handlers: EventHandlerMap<Events> = new Map(); | ||
|
||
on = <Key extends keyof Events>(eventType: Key, handler: Handler<Events[keyof Events]>) => { | ||
const eventTypeHandlers = this.handlers.get(eventType); | ||
if (!Array.isArray(eventTypeHandlers)) this.handlers.set(eventType, [handler]); | ||
else eventTypeHandlers.push(handler); | ||
}; | ||
|
||
off = <Key extends keyof Events>(eventType: Key, handler?: Handler<Events[keyof Events]>) => { | ||
this.handlers.set( | ||
eventType, | ||
this.handlers.get(eventType).filter((h) => h !== handler), | ||
); | ||
}; | ||
|
||
emit = <Key extends keyof Events>(eventType: Key, evt?: Events[Key]) => { | ||
const eventTypeHandlers = this.handlers.get(eventType); | ||
for (let index = eventTypeHandlers.length - 1; index >= 0; index--) { | ||
const handler = eventTypeHandlers[index]; | ||
if (handler(evt)) { | ||
return; | ||
} | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
packages/example/src/components/remote-control/RemoteControlManager.interface.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
import { SupportedKeys } from './SupportedKeys'; | ||
|
||
export interface RemoteControlManagerInterface { | ||
addKeydownListener: (listener: (event: SupportedKeys) => void) => void; | ||
removeKeydownListener: (listener: (event: SupportedKeys) => void) => void; | ||
addKeydownListener: (listener: (event: SupportedKeys) => boolean) => void; | ||
removeKeydownListener: (listener: (event: SupportedKeys) => boolean) => void; | ||
emitKeyDown: (key: SupportedKeys) => void; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { useEffect } from 'react'; | ||
import RemoteControlManager from '../components/remote-control/RemoteControlManager'; | ||
import { SupportedKeys } from '../components/remote-control/SupportedKeys'; | ||
|
||
/** | ||
* A convenient hook to listen to a key and react to it | ||
* | ||
* @example useKey(SupportedKeys.Back, () => { console.log('pressed back!') }) | ||
*/ | ||
export const useKey = (key: SupportedKeys, callback: (pressedKey: SupportedKeys) => boolean) => { | ||
useEffect(() => { | ||
const remoteControlListener = (actualKey: SupportedKeys) => { | ||
if (actualKey !== key) return; | ||
return callback(key); | ||
}; | ||
RemoteControlManager.addKeydownListener(remoteControlListener); | ||
return () => RemoteControlManager.removeKeydownListener(remoteControlListener); | ||
}, [key, callback]); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.