Skip to content

Commit 279413c

Browse files
committed
feat: isNotificationVisible, hideById, isVisibleById, shakeById, updateById methods
1 parent 0821a3a commit 279413c

4 files changed

Lines changed: 99 additions & 33 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
- New `idStrategy` parameter, which defines how a default ID is generated if none is provided.
2121
- New `updateNotification` method that updates a _currently visible_ notification.
2222
- New `shakeNotification` method that shakes a _currently visible_ notification to attract the user's attention and optionally resets the `duration` timer.
23+
- New `isNotificationVisible` method: Returns a boolean indicating if any notification is currently visible.
24+
- New methods: `updateById`, `shakeById`, `isVisibleById`, and `hideById`. These methods only affect a notification if the provided ID matches the one of the currently visible notification.
2325
- Calling `showNotification` returns `update`, `hide`, `shake`, and `isVisible` functions for manipulating the notification.
2426
- You can mount multiple instances of `NotifierWrapper`/`NotifierRoot` and still control them using global `Notifier.*` methods. The most recently mounted instance is controlled first; if it unmounts, control reverts to the previously mounted instance.
2527
- It's possible to broadcast commands to all mounted instances of Notifier via `Notifier.broadcast.*`. This can be used, for example, to hide all notifications or clear the queue and hide them using `Notifier.broadcast.hideNotification()`.

src/components/Notifier.tsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,23 +106,40 @@ const broadcast = (fn: (ref: NotifierInterface) => void) => {
106106

107107
export const Notifier: GlobalNotifierInterface = {
108108
showNotification: (params) => getLastRef()?.showNotification(params),
109-
updateNotification: (params) => getLastRef()?.updateNotification(params),
109+
updateNotification: (params) =>
110+
getLastRef()?.updateNotification(params) ?? false,
110111
shakeNotification: (resetTimer) =>
111112
getLastRef()?.shakeNotification(resetTimer),
113+
isNotificationVisible: () => getLastRef()?.isNotificationVisible() ?? false,
112114
hideNotification: (onHidden) => getLastRef()?.hideNotification(onHidden),
113115
clearQueue: (hideDisplayedNotification) =>
114116
getLastRef()?.clearQueue(hideDisplayedNotification),
117+
118+
hideById: (id, onHidden) => getLastRef()?.hideById(id, onHidden),
119+
isVisibleById: (id) => getLastRef()?.isVisibleById(id) ?? false,
120+
shakeById: (id, resetTimer) => getLastRef()?.shakeById(id, resetTimer),
121+
updateById: (id, params) => getLastRef()?.updateById(id, params) ?? false,
122+
115123
broadcast: {
116124
showNotification: (params) =>
117125
broadcast((ref) => ref.showNotification(params)),
118126
updateNotification: (params) =>
119-
broadcast((ref) => ref.updateNotification(params)),
127+
refs.some((ref) => ref.current?.updateNotification(params)),
120128
shakeNotification: (resetTimer) =>
121129
broadcast((ref) => ref.shakeNotification(resetTimer)),
130+
isNotificationVisible: () =>
131+
refs.some((ref) => ref.current?.isNotificationVisible()),
122132
hideNotification: (onHidden) =>
123133
broadcast((ref) => ref.hideNotification(onHidden)),
124134
clearQueue: (hideDisplayedNotification) =>
125135
broadcast((ref) => ref.clearQueue(hideDisplayedNotification)),
136+
137+
hideById: (id, onHidden) => broadcast((ref) => ref.hideById(id, onHidden)),
138+
isVisibleById: (id) => refs.some((ref) => ref.current?.isVisibleById(id)),
139+
shakeById: (id, resetTimer) =>
140+
broadcast((ref) => ref.shakeById(id, resetTimer)),
141+
updateById: (id, params) =>
142+
refs.some((ref) => ref.current?.updateById(id, params)),
126143
},
127144
};
128145

src/components/NotifierManager.tsx

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ interface NotifierManagerProps {
2929
/** Component manages queue and exports methods to display/hide notification, and clear the queue
3030
* Responsibilities:
3131
* - manages queue and handle duplicates
32-
* - export methods "showNotification", "updateNotification", "shakeNotification", "hideNotification", "clearQueue" via reference
32+
* - export methods "showNotification", "updateNotification", "shakeNotification", "isNotificationVisible", "hideNotification", "clearQueue", "updateById", "shakeById", "isVisibleById", "hideById", via reference
3333
* - set currentNotification state and use default parameters passed via props
3434
* - mount NotifierRenderer when call "showNotification", and unmount it when NotifierRenderer calls onHidden.
3535
*/
@@ -83,32 +83,55 @@ const NotifierManagerComponent = React.forwardRef<
8383
[]
8484
);
8585

86+
const isNotificationVisible = useCallback(
87+
() => !!currentNotificationId.current,
88+
[]
89+
);
90+
91+
const hideById = useCallback(
92+
(id: string | number, callback?: Animated.EndCallback) => {
93+
if (id !== currentNotificationId.current) return;
94+
return hideNotification(callback);
95+
},
96+
[hideNotification]
97+
);
98+
99+
const updateById = useCallback(
100+
(id: string | number, params: UpdateNotificationParams<any>) => {
101+
if (id !== currentNotificationId.current) {
102+
const callStackItem = callStack.current.find((item) => item.id === id);
103+
if (callStackItem) {
104+
Object.assign(callStackItem, params);
105+
}
106+
return !!callStackItem;
107+
}
108+
return updateNotification(params);
109+
},
110+
[updateNotification]
111+
);
112+
113+
const shakeById = useCallback(
114+
(id: string | number, resetTimerParam?: boolean) => {
115+
if (id !== currentNotificationId.current) return;
116+
return shakeNotification(resetTimerParam);
117+
},
118+
[shakeNotification]
119+
);
120+
121+
const isVisibleById = useCallback(
122+
(id: string | number) => id === currentNotificationId.current,
123+
[]
124+
);
125+
86126
const getNotificationMethodsForId = useCallback(
87127
(id: string | number): ShowNotificationReturnType<any> => ({
88-
hide: (callback?: Animated.EndCallback) => {
89-
if (id !== currentNotificationId.current) return;
90-
return hideNotification(callback);
91-
},
92-
update: (params: UpdateNotificationParams<any>) => {
93-
if (id !== currentNotificationId.current) {
94-
const callStackItem = callStack.current.find(
95-
(item) => item.id === id
96-
);
97-
if (callStackItem) {
98-
Object.assign(callStackItem, params);
99-
}
100-
return !!callStackItem;
101-
}
102-
return updateNotification(params);
103-
},
104-
shake: (resetTimerParam?: boolean) => {
105-
if (id !== currentNotificationId.current) return;
106-
return shakeNotification(resetTimerParam);
107-
},
108-
isVisible: () => id === currentNotificationId.current,
128+
hide: (callback?: Animated.EndCallback) => hideById(id, callback),
129+
update: (params: UpdateNotificationParams<any>) => updateById(id, params),
130+
shake: (resetTimerParam?: boolean) => shakeById(id, resetTimerParam),
131+
isVisible: () => isVisibleById(id),
109132
id,
110133
}),
111-
[hideNotification, shakeNotification, updateNotification]
134+
[hideById, isVisibleById, shakeById, updateById]
112135
);
113136

114137
const showNotification = useCallback(
@@ -188,15 +211,25 @@ const NotifierManagerComponent = React.forwardRef<
188211
showNotification,
189212
updateNotification,
190213
shakeNotification,
214+
isNotificationVisible,
191215
hideNotification,
192216
clearQueue,
217+
updateById,
218+
shakeById,
219+
isVisibleById,
220+
hideById,
193221
}),
194222
[
195223
showNotification,
196224
updateNotification,
197225
shakeNotification,
226+
isNotificationVisible,
198227
hideNotification,
199228
clearQueue,
229+
updateById,
230+
shakeById,
231+
isVisibleById,
232+
hideById,
200233
]
201234
);
202235

src/types.ts

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -440,31 +440,45 @@ export interface NotifierInterface {
440440
/** Shakes currently visible notification to attract the user's attention. If pass true as the first parameter, the `duration` timer will reset(prolong) */
441441
shakeNotification(resetTimer?: boolean): void;
442442

443+
/** Is any notification currently visible. */
444+
isNotificationVisible(): boolean;
445+
443446
/** Hide currently visible notification and run callback function when notification completely hidden. */
444447
hideNotification(onHidden?: Animated.EndCallback): void;
445448

446449
/** Clear [notifications queue](#queue-mode) and optionally hide currently displayed notification.
447450
*
448451
* Might be useful to run after logout, after which queued notifications should not be displayed. */
449452
clearQueue(hideDisplayedNotification?: boolean): void;
453+
454+
/** Update notification by ID, if visible - will be updated immediately,
455+
* if it waits in the queue - it will be updated in the queue and will be displayed with updated parameters.
456+
*
457+
* Returns true if notification was updated */
458+
updateById<ComponentType extends ElementType = typeof NotificationComponent>(
459+
id: string | number,
460+
params: UpdateNotificationParams<ComponentType>
461+
): boolean;
462+
463+
/** Shakes notification by ID to attract the user's attention. If pass true as the second parameter, the `duration` timer will reset(prolong) */
464+
shakeById(id: string | number, resetTimer?: boolean): void;
465+
466+
/** Is notification with provided ID currently visible */
467+
isVisibleById(id: string | number): boolean;
468+
469+
/** Hide notification by ID */
470+
hideById(id: string | number, onHidden?: Animated.EndCallback): void;
450471
}
451472

452473
export interface GlobalNotifierInterface
453-
extends Omit<NotifierInterface, 'showNotification' | 'updateNotification'> {
474+
extends Omit<NotifierInterface, 'showNotification'> {
454475
/** Show notification with params. Returns `update`, `hide`, `shake`, `isVisible` functions and `id` field if at least one Notifier is mounted. */
455476
showNotification<
456477
ComponentType extends ElementType = typeof NotificationComponent,
457478
>(
458479
params: ShowNotificationParams<ComponentType>
459480
): ShowNotificationReturnType<ComponentType> | undefined;
460481

461-
/** Update currently visible notification. Returns true if notification was updated */
462-
updateNotification<
463-
ComponentType extends ElementType = typeof NotificationComponent,
464-
>(
465-
params: UpdateNotificationParams<ComponentType>
466-
): boolean | undefined;
467-
468482
/** Broadcasts the command to all currently mounted instances of Notifier, not only to the last one.
469483
*
470484
* Useful to hide all currently visible notifications via `Notifier.broadcast.hideNotification()` or clear queue.*/

0 commit comments

Comments
 (0)