PluginProbe
Extendify / 0.11.1
Extendify v0.11.1
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / src / Library / components / notices / FooterNotice.js

FooterNotice.js in Extendify 0.11.1, at src/Library/components/notices/FooterNotice.js

111 lines 4.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { Button } from '@wordpress/components'
2 import { useState, useEffect, useRef } from '@wordpress/element'
3 import { __ } from '@wordpress/i18n'
4 import { Icon, closeSmall } from '@wordpress/icons'
5 import { General } from '@library/api/General'
6 import { useGlobalStore } from '@library/state/GlobalState'
7 import { useUserStore } from '@library/state/User'
8 import FeedbackNotice from './FeedbackNotice'
9 import { InstallStandaloneNotice } from './InstallStandaloneNotice'
10 import PromotionNotice from './PromotionNotice'
11
12 // import WelcomeNotice from './WelcomeNotice'
13
14 const NoticesByPriority = {
15 // welcome: WelcomeNotice,
16 promotion: PromotionNotice,
17 feedback: FeedbackNotice,
18 standalone: InstallStandaloneNotice,
19 }
20
21 export default function FooterNotice({ className = '' }) {
22 const [hasNotice, setHasNotice] = useState(null)
23 const once = useRef(false)
24 const promotionData = useGlobalStore(
25 (state) => state.metaData?.banners?.footer,
26 )
27
28 const showFeedback = () => {
29 const imports = useUserStore.getState().imports ?? 0
30 const firstLoadedOn =
31 useUserStore.getState()?.firstLoadedOn ?? new Date()
32 const timeDifference =
33 new Date().getTime() - new Date(firstLoadedOn).getTime()
34 const daysSinceActivated = timeDifference / 86_400_000 // 24 hours
35
36 return imports >= 3 && daysSinceActivated > 3
37 }
38
39 // Find the first notice key to use
40 // TODO: extract this logic into the individual component instead of controlling it here
41 const componentKey =
42 Object.keys(NoticesByPriority).find((key) => {
43 if (key === 'promotion') {
44 return (
45 // When checking promotions, use the key sent from the server
46 // to check whether it's been dismissed
47 !useUserStore.getState().apiKey?.length &&
48 promotionData?.key &&
49 !useUserStore.getState().noticesDismissedAt[
50 promotionData.key
51 ]
52 )
53 }
54
55 if (key === 'feedback') {
56 return (
57 showFeedback() &&
58 !useUserStore.getState().noticesDismissedAt[key]
59 )
60 }
61
62 if (key === 'standalone') {
63 return (
64 !window.extendifyData.standalone &&
65 !useUserStore.getState().noticesDismissedAt[key]
66 )
67 }
68
69 return !useUserStore.getState().noticesDismissedAt[key]
70 }) ?? null
71 const Notice = NoticesByPriority[componentKey]
72
73 const dismiss = async () => {
74 setHasNotice(false)
75 // The noticesDismissedAt key will either be the key from NoticesByPriority,
76 // or a key passed in from the server, such as 'holiday-sale2077'
77 const key =
78 componentKey === 'promotion' ? promotionData.key : componentKey
79 useUserStore.getState().markNoticeSeen(key, 'notices')
80 await General.ping(`footer-notice-x-${key}`)
81 }
82
83 useEffect(() => {
84 // Only show the notice once on main render and only if a notice exists.
85 if (NoticesByPriority[componentKey] && !once.current) {
86 setHasNotice(true)
87 once.current = true
88 }
89 }, [componentKey])
90
91 if (!hasNotice || !Notice) {
92 return null
93 }
94 return (
95 <div
96 className={`${className} relative mx-auto hidden max-w-screen-4xl items-center justify-center space-x-4 bg-extendify-secondary py-3 px-5 lg:flex`}>
97 {/* Pass all data to all components and let them decide what they use */}
98 <Notice promotionData={promotionData} />
99 <div className="absolute right-1">
100 <Button
101 className="text-extendify-black opacity-50 hover:opacity-100 focus:opacity-100"
102 icon={<Icon icon={closeSmall} />}
103 label={__('Dismiss this notice', 'extendify')}
104 onClick={dismiss}
105 showTooltip={false}
106 />
107 </div>
108 </div>
109 )
110 }
111