|
6 | 6 | * Side Public License, v 1. |
7 | 7 | */ |
8 | 8 |
|
9 | | -import React, { useState, Fragment, useEffect } from 'react'; |
10 | | -import * as Rx from 'rxjs'; |
| 9 | +import React, { useState, useEffect, useMemo, useCallback } from 'react'; |
11 | 10 | import { EuiHeaderSectionItemButton, EuiIcon } from '@elastic/eui'; |
12 | 11 | import { i18n } from '@kbn/i18n'; |
| 12 | +import type { NewsfeedApi } from '../lib/api'; |
13 | 13 | import { NewsfeedFlyout } from './flyout_list'; |
14 | 14 | import { FetchResult } from '../types'; |
15 | 15 |
|
16 | 16 | export interface INewsfeedContext { |
17 | 17 | setFlyoutVisible: React.Dispatch<React.SetStateAction<boolean>>; |
18 | 18 | newsFetchResult: FetchResult | void | null; |
19 | 19 | } |
20 | | -export const NewsfeedContext = React.createContext({} as INewsfeedContext); |
21 | 20 |
|
22 | | -export type NewsfeedApiFetchResult = Rx.Observable<void | FetchResult | null>; |
| 21 | +export const NewsfeedContext = React.createContext({} as INewsfeedContext); |
23 | 22 |
|
24 | 23 | export interface Props { |
25 | | - apiFetchResult: NewsfeedApiFetchResult; |
| 24 | + newsfeedApi: NewsfeedApi; |
26 | 25 | } |
27 | 26 |
|
28 | | -export const NewsfeedNavButton = ({ apiFetchResult }: Props) => { |
29 | | - const [showBadge, setShowBadge] = useState<boolean>(false); |
| 27 | +export const NewsfeedNavButton = ({ newsfeedApi }: Props) => { |
30 | 28 | const [flyoutVisible, setFlyoutVisible] = useState<boolean>(false); |
31 | 29 | const [newsFetchResult, setNewsFetchResult] = useState<FetchResult | null | void>(null); |
| 30 | + const hasNew = useMemo(() => { |
| 31 | + return newsFetchResult ? newsFetchResult.hasNew : false; |
| 32 | + }, [newsFetchResult]); |
32 | 33 |
|
33 | 34 | useEffect(() => { |
34 | | - function handleStatusChange(fetchResult: FetchResult | void | null) { |
35 | | - if (fetchResult) { |
36 | | - setShowBadge(fetchResult.hasNew); |
37 | | - } |
38 | | - setNewsFetchResult(fetchResult); |
39 | | - } |
40 | | - |
41 | | - const subscription = apiFetchResult.subscribe((res) => handleStatusChange(res)); |
| 35 | + const subscription = newsfeedApi.fetchResults$.subscribe((results) => { |
| 36 | + setNewsFetchResult(results); |
| 37 | + }); |
42 | 38 | return () => subscription.unsubscribe(); |
43 | | - }, [apiFetchResult]); |
| 39 | + }, [newsfeedApi]); |
44 | 40 |
|
45 | | - function showFlyout() { |
46 | | - setShowBadge(false); |
| 41 | + const showFlyout = useCallback(() => { |
| 42 | + if (newsFetchResult) { |
| 43 | + newsfeedApi.markAsRead(newsFetchResult.feedItems.map((item) => item.hash)); |
| 44 | + } |
47 | 45 | setFlyoutVisible(!flyoutVisible); |
48 | | - } |
| 46 | + }, [newsfeedApi, newsFetchResult, flyoutVisible]); |
49 | 47 |
|
50 | 48 | return ( |
51 | 49 | <NewsfeedContext.Provider value={{ setFlyoutVisible, newsFetchResult }}> |
52 | | - <Fragment> |
| 50 | + <> |
53 | 51 | <EuiHeaderSectionItemButton |
54 | 52 | data-test-subj="newsfeed" |
55 | 53 | aria-controls="keyPadMenu" |
56 | 54 | aria-expanded={flyoutVisible} |
57 | 55 | aria-haspopup="true" |
58 | 56 | aria-label={ |
59 | | - showBadge |
| 57 | + hasNew |
60 | 58 | ? i18n.translate('newsfeed.headerButton.unreadAriaLabel', { |
61 | 59 | defaultMessage: 'Newsfeed menu - unread items available', |
62 | 60 | }) |
63 | 61 | : i18n.translate('newsfeed.headerButton.readAriaLabel', { |
64 | 62 | defaultMessage: 'Newsfeed menu - all items read', |
65 | 63 | }) |
66 | 64 | } |
67 | | - notification={showBadge ? true : null} |
| 65 | + notification={hasNew ? true : null} |
68 | 66 | onClick={showFlyout} |
69 | 67 | > |
70 | 68 | <EuiIcon type="cheer" size="m" /> |
71 | 69 | </EuiHeaderSectionItemButton> |
72 | 70 | {flyoutVisible ? <NewsfeedFlyout /> : null} |
73 | | - </Fragment> |
| 71 | + </> |
74 | 72 | </NewsfeedContext.Provider> |
75 | 73 | ); |
76 | 74 | }; |
0 commit comments