-
Notifications
You must be signed in to change notification settings - Fork 955
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(mobile/html-renderer): Add WrappedElementProvider for dynamic el…
…ement tracking - Introduce WrappedElementProvider to track element size and position - Create ProviderComposer for composing multiple context providers - Add hooks for accessing wrapped element details - Update HTML component to use new provider - Enhance image rendering with dynamic width calculation Signed-off-by: Innei <tukon479@gmail.com>
- Loading branch information
Showing
8 changed files
with
1,009 additions
and
2,224 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
10 changes: 10 additions & 0 deletions
10
apps/mobile/web-app/html-renderer/src/common/ProviderComposer.tsx
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,10 @@ | ||
import type { JSX } from "react" | ||
import * as React from "react" | ||
|
||
export const ProviderComposer: Component<{ | ||
contexts: JSX.Element[] | ||
}> = ({ contexts, children }) => { | ||
return contexts.reduceRight((kids: any, parent: any) => { | ||
return React.cloneElement(parent, { children: kids }) | ||
}, children) | ||
} |
103 changes: 103 additions & 0 deletions
103
apps/mobile/web-app/html-renderer/src/common/WrappedElementProvider.tsx
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,103 @@ | ||
import { cn } from "@follow/utils/utils" | ||
import { createContextState } from "foxact/create-context-state" | ||
import { useIsomorphicLayoutEffect } from "foxact/use-isomorphic-layout-effect" | ||
import type * as React from "react" | ||
import { memo } from "react" | ||
|
||
import { ProviderComposer } from "./ProviderComposer" | ||
|
||
const [WrappedElementProviderInternal, useWrappedElement, useSetWrappedElement] = | ||
createContextState<HTMLDivElement | null>(undefined as any) | ||
|
||
const [ElementSizeProviderInternal, useWrappedElementSize, useSetWrappedElementSize] = | ||
createContextState({ | ||
h: 0, | ||
w: 0, | ||
}) | ||
|
||
const [ElementPositionProviderInternal, useWrappedElementPosition, useSetElementPosition] = | ||
createContextState({ | ||
x: 0, | ||
y: 0, | ||
}) | ||
|
||
const Providers = [ | ||
<WrappedElementProviderInternal key="ArticleElementProviderInternal" />, | ||
<ElementSizeProviderInternal key="ElementSizeProviderInternal" />, | ||
<ElementPositionProviderInternal key="ElementPositionProviderInternal" />, | ||
] | ||
|
||
interface WrappedElementProviderProps { | ||
as?: keyof React.JSX.IntrinsicElements | ||
} | ||
|
||
export const WrappedElementProvider: Component<WrappedElementProviderProps> = ({ | ||
children, | ||
className, | ||
...props | ||
}) => ( | ||
<ProviderComposer contexts={Providers}> | ||
<ElementResizeObserver /> | ||
<Content {...props} className={className}> | ||
{children} | ||
</Content> | ||
</ProviderComposer> | ||
) | ||
const ElementResizeObserver = () => { | ||
const setSize = useSetWrappedElementSize() | ||
const setPos = useSetElementPosition() | ||
const $element = useWrappedElement() | ||
useIsomorphicLayoutEffect(() => { | ||
if (!$element) return | ||
const { height, width, left, top } = $element.getBoundingClientRect() | ||
setSize({ h: height, w: width }) | ||
|
||
const pageX = window.scrollX + left | ||
const pageY = window.scrollY + top | ||
setPos({ x: pageX, y: pageY }) | ||
|
||
const observer = new ResizeObserver((entries) => { | ||
const entry = entries[0] | ||
|
||
if (!entry) return | ||
|
||
const { height, width } = entry.contentRect | ||
const { left, top } = $element.getBoundingClientRect() | ||
const pageX = window.scrollX + left | ||
const pageY = window.scrollY + top | ||
|
||
setSize((size) => { | ||
if (size.h === height && size.w === width) return size | ||
return { h: height, w: width } | ||
}) | ||
setPos((pos) => { | ||
if (pos.x === pageX && pos.y === pageY) return pos | ||
return { x: pageX, y: pageY } | ||
}) | ||
}) | ||
observer.observe($element) | ||
return () => { | ||
observer.unobserve($element) | ||
observer.disconnect() | ||
} | ||
}, [$element]) | ||
|
||
return null | ||
} | ||
|
||
const Content: Component<WrappedElementProviderProps> = memo( | ||
({ children, className, as = "div" }) => { | ||
const setElement = useSetWrappedElement() | ||
|
||
const As = as as any | ||
return ( | ||
<As className={cn("relative", className)} ref={setElement}> | ||
{children} | ||
</As> | ||
) | ||
}, | ||
) | ||
|
||
Content.displayName = "ArticleElementProviderContent" | ||
|
||
export { useSetWrappedElement, useWrappedElement, useWrappedElementPosition, useWrappedElementSize } |
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
Oops, something went wrong.