Skip to content

Commit

Permalink
fix: avoid to observe external links (#1739)
Browse files Browse the repository at this point in the history
* fix: avoid to observe external links

* refactor: less is more

* refactor: lazy health check
  • Loading branch information
Kikobeats authored Aug 11, 2024
1 parent 2edfdfa commit 2d250c7
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 81 deletions.
26 changes: 26 additions & 0 deletions src/components/elements/IntersectionObserver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* global IntersectionObserver */

import React, { useState, useEffect, useRef } from 'react'

const LazyRender = ({ onView, placeholder, options }) => {
const [isVisible, setIsVisible] = useState(false)
const ref = useRef(null)

useEffect(() => {
const { current } = ref

const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
setIsVisible(true)
observer.disconnect()
}
}, options)

if (current) observer.observe(current)
return () => current && observer.unobserve(current)
}, [options])

return <div ref={ref}>{isVisible ? onView() : placeholder()}</div>
}

export default LazyRender
147 changes: 79 additions & 68 deletions src/components/patterns/Footer/Footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Mail } from 'react-feather'
import { issueUrl } from 'helpers'
import React from 'react'

import IntersectionObserver from '../../elements/IntersectionObserver'
import Healthcheck from '../Healthcheck/Healthcheck'

import {
Expand Down Expand Up @@ -35,6 +36,73 @@ const DARK_THEME = {
iconColor: colors.white80
}

const StatusPage = ({ isDark }) => {
return (
<LinkSolid
isDark={isDark}
data-event-location='Footer'
data-event-name='Status'
href='/status'
css={theme({
px: 0
})}
>
<Text
css={theme({
fontSize: [0, 0, 0, 1]
})}
>
Status Page
</Text>
</LinkSolid>
)
}

const Health = ({ isDark, textColor }) => (
<Healthcheck>
{({ isHealthy, isLoading }) => {
if (isLoading) return <StatusPage isDark={isDark} />
return (
<Link
data-event-location='Footer'
data-event-name='Status'
href='/status'
css={theme({
px: 0,
color: colors[textColor]
})}
>
<Text
css={theme({
fontSize: [0, 0, 0, 1],
pb: [3, 3, 3, 0]
})}
>
<Choose>
<Choose.When condition={isHealthy}>
<Dot.Success
css={theme({
mr: 2
})}
/>
All systems operational
</Choose.When>
<Choose.Otherwise>
<Dot.Warning
css={theme({
mr: 2
})}
/>
System performance degradation
</Choose.Otherwise>
</Choose>
</Text>
</Link>
)
}}
</Healthcheck>
)

const Footer = ({ isDark, ...props }) => {
const { background, textColor, inputIconColor } = isDark
? DARK_THEME
Expand Down Expand Up @@ -209,69 +277,12 @@ const Footer = ({ isDark, ...props }) => {
flexDirection: 'column'
})}
>
<Healthcheck>
{({ isHealthy, isLoading }) => {
if (isLoading) {
return (
<LinkSolid
isDark={isDark}
data-event-location='Footer'
data-event-name='Status'
href='/status'
css={theme({
px: 0
})}
>
<Text
css={theme({
fontSize: [0, 0, 0, 1]
})}
>
Status Page
</Text>
</LinkSolid>
)
}

return (
<Link
data-event-location='Footer'
data-event-name='Status'
href='/status'
css={theme({
px: 0,
color: colors[textColor]
})}
>
<Text
css={theme({
fontSize: [0, 0, 0, 1],
pb: [3, 3, 3, 0]
})}
>
<Choose>
<Choose.When condition={isHealthy}>
<Dot.Success
css={theme({
mr: 2
})}
/>
All systems operational
</Choose.When>
<Choose.Otherwise>
<Dot.Warning
css={theme({
mr: 2
})}
/>
System performance degradation
</Choose.Otherwise>
</Choose>
</Text>
</Link>
)
}}
</Healthcheck>
<IntersectionObserver
placeholder={() => <StatusPage isDark={isDark} />}
onView={() => (
<Health isDark={isDark} textColor={textColor} />
)}
/>
</Flex>
</Flex>

Expand Down Expand Up @@ -328,16 +339,16 @@ const Footer = ({ isDark, ...props }) => {
})}
>
{[
{
href: 'https://github.com/microlinkhq',
children: 'GitHub',
title: '@microlinkhq on GitHub'
},
{
href: 'https://x.com/microlinkhq',
children: 'X',
title: '@microlinkhq on x.com'
},
{
href: 'https://github.com/microlinkhq',
children: 'GitHub',
title: '@microlinkhq on GitHub'
},
{
href: 'mailto:[email protected]',
children: 'Email',
Expand Down
25 changes: 12 additions & 13 deletions src/helpers/hoc/with-link.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { Link as GatsbyLink } from 'gatsby'

import Flex from '../../components/elements/Flex'

const addActiveClass = isActive => (isActive ? { className: 'active' } : null)

const isInternalLink = (to = '/') => /^\/(?!\/)/.test(to)

const getHash = href => href.replace('/#', '#')
Expand Down Expand Up @@ -112,29 +114,26 @@ export const withLink = Component => {
}) => {
const [isIntersecting, setIsIntersecting] = useState(false)
const location = useLocation()
const isInternal = isInternalLink(href)
const isInternal = !href || isInternalLink(href)
const partiallyActive = actively === 'partial'

useEffect(() => {
if (actively === 'observer') {
if (isInternal && actively === 'observer') {
const node = document.querySelector(getHash(href))
onView(node, isBeingIntersecting =>
setIsIntersecting(isBeingIntersecting)
)
}
}, [actively, href])
}, [isInternal, actively, href])

const getProps = ({ isPartiallyCurrent, isCurrent, location }) => {
if (typeof actively === 'function') {
const result = actively({ location })
return result ? { className: 'active' } : null
}
const isActive = partiallyActive ? isPartiallyCurrent : isCurrent
if (!isActive && !isIntersecting) return null
return { className: 'active' }
}
const getProps = ({ isPartiallyCurrent, isCurrent, location }) =>
typeof actively === 'function'
? addActiveClass(actively({ location }))
: addActiveClass(
isIntersecting || partiallyActive ? isPartiallyCurrent : isCurrent
)

if (prefetch && (!href || isInternal)) {
if (prefetch && isInternal) {
return (
<Component {...props}>
<PrefetchLink
Expand Down

0 comments on commit 2d250c7

Please sign in to comment.