Skip to content

Commit 0017f48

Browse files
committed
Modificaciones de video y FAQ
1 parent a051c41 commit 0017f48

File tree

2 files changed

+187
-39
lines changed

2 files changed

+187
-39
lines changed

src/components/videoBackground/VideoBackground.js

Lines changed: 138 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import CustomLink from "../CustomLink/CustomLink"
44
import PropTypes from "prop-types"
55
import { GatsbyImage, getImage } from "gatsby-plugin-image"
66

7-
// ✅ CAMBIO: detectar versión de iOS
87
function getIOSVersion() {
98
if (typeof window === "undefined" || typeof navigator === "undefined") return null
109
const userAgent = navigator.userAgent
@@ -25,6 +24,39 @@ function isIOSPriorTo(version) {
2524
if (currentVersion.major > majorVersion) return false
2625
return currentVersion.minor < minorVersion
2726
}
27+
function getQS(name) {
28+
if (typeof window === "undefined") return null
29+
return new URLSearchParams(window.location.search).get(name)
30+
}
31+
32+
33+
function resolvePoster(poster, image) {
34+
const posterLocal =
35+
poster?.localFile ||
36+
poster?.data?.attributes?.localFile ||
37+
null
38+
const sharp = posterLocal ? getImage(posterLocal) : null
39+
40+
const rawUrl =
41+
poster?.url ||
42+
poster?.data?.attributes?.url ||
43+
poster?.formats?.large?.url ||
44+
poster?.formats?.medium?.url ||
45+
poster?.formats?.small?.url ||
46+
poster?.formats?.thumbnail?.url ||
47+
null
48+
49+
const toAbs = u =>
50+
!u ? null : (u.startsWith("http")
51+
? u
52+
: `https://strapi-s3-bitlogic.s3.sa-east-1.amazonaws.com${u}`)
53+
54+
const url = toAbs(rawUrl)
55+
56+
const imageSharp = image?.localFile ? getImage(image.localFile) : null
57+
58+
return { sharp: sharp || imageSharp, url }
59+
}
2860

2961
function getVideoContent(
3062
video,
@@ -36,29 +68,14 @@ function getVideoContent(
3668
image,
3769
posterData
3870
) {
39-
const posterUrl = posterData?.url?.startsWith("http")
40-
? getImage(posterData.url)
41-
: getImage(`https://strapi-s3-bitlogic.s3.sa-east-1.amazonaws.com${posterData?.url}`)
42-
const posterSharp = posterData?.localFile && getImage(posterData.localFile)
71+
const { sharp: pSharp, url: pUrl } = resolvePoster(posterData, image)
72+
const posterUrl = pUrl || pSharp?.images?.fallback?.src
4373

4474
const url = videoUrl?.replace("watch?v=", "embed/")
4575
let code = url?.substring(url.lastIndexOf("/") + 1) || ""
4676
const codeIndex = code.indexOf("?")
4777
if (codeIndex !== -1) code = code.substring(0, codeIndex)
4878

49-
const isOldIOS = isIOSPriorTo("17.4")
50-
if (isOldIOS && posterSharp) {
51-
return (
52-
<GatsbyImage
53-
className="video-poster"
54-
image={posterSharp}
55-
alt={posterData.alternativeText || "Video poster"}
56-
loading="eager"
57-
style={{ width: "100%", maxWidth: "100vw", height: "auto" }}
58-
/>
59-
)
60-
}
61-
6279
if (video?.url) {
6380
return (
6481
<video
@@ -100,8 +117,8 @@ function getVideoContent(
100117
allowFullScreen
101118
title="benefits_video"
102119
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
103-
webkitallowfullscreen
104-
mozallowfullscreen
120+
webkitallowfullscreen="true"
121+
mozallowfullscreen="true"
105122
style={{
106123
width: "100%",
107124
maxWidth: "100vw",
@@ -115,12 +132,12 @@ function getVideoContent(
115132
)
116133
}
117134

118-
if (posterSharp) {
135+
if (pSharp) {
119136
return (
120137
<GatsbyImage
121138
className="video-poster"
122-
image={posterSharp}
123-
alt={posterData.alternativeText || "Video poster"}
139+
image={pSharp}
140+
alt={posterData?.alternativeText || "Video poster"}
124141
loading="eager"
125142
style={{ width: "100%", maxWidth: "100vw", height: "auto" }}
126143
/>
@@ -141,6 +158,12 @@ const VideoBackground = ({ data }) => {
141158
poster,
142159
} = data
143160

161+
const forced = getQS("forceOldIOS") === "1"
162+
const initialIsOldIOS =
163+
forced ||
164+
(typeof navigator !== "undefined" && /iPhone/.test(navigator.userAgent) && isIOSPriorTo("17.4"))
165+
const [isOldIOS] = useState(initialIsOldIOS)
166+
144167
const [isVideoPause, setIsVideoPause] = useState(false)
145168
const [isIntersecting, setIsIntersecting] = useState(false)
146169
const videoRef = useRef(null)
@@ -157,10 +180,12 @@ const VideoBackground = ({ data }) => {
157180
pausePlay()
158181
}
159182
}
160-
161183
useEffect(() => {
184+
if (isOldIOS) return
185+
162186
const elem = videoRef.current
163187
if (!elem) return
188+
164189
const observer = new IntersectionObserver(
165190
([entry]) => {
166191
if (entry.isIntersecting) {
@@ -172,11 +197,83 @@ const VideoBackground = ({ data }) => {
172197
)
173198
observer.observe(elem)
174199
return () => observer.disconnect()
175-
}, [])
200+
}, [isOldIOS])
176201

177202
useEffect(() => {
178203
localStorage.setItem("videoPaused", isVideoPause)
179204
}, [isVideoPause])
205+
if (isOldIOS) {
206+
const { sharp: posterSharp, url: posterFromUrl } = resolvePoster(poster, image)
207+
208+
return (
209+
<div
210+
style={{
211+
backgroundImage: backgroundImage ? `url(${backgroundImage.url})` : "",
212+
backgroundRepeatY: "no-repeat",
213+
backgroundPosition: "center",
214+
}}
215+
>
216+
<div className="container videoBackground-container">
217+
<section className="videoBackground" key="poster">
218+
{posterSharp ? (
219+
<GatsbyImage
220+
className="video-poster"
221+
image={posterSharp}
222+
alt={poster?.alternativeText || "Video poster"}
223+
loading="eager"
224+
style={{ width: "100%", maxWidth: "100vw", height: "auto" }}
225+
/>
226+
) : posterFromUrl ? (
227+
<img
228+
className="video-poster"
229+
src={posterFromUrl}
230+
alt={poster?.alternativeText || "Video poster"}
231+
loading="eager"
232+
style={{
233+
width: "100%",
234+
maxWidth: "100vw",
235+
height: "auto",
236+
display: "block",
237+
borderRadius: "5px",
238+
objectFit: "cover",
239+
aspectRatio: "16/9",
240+
}}
241+
/>
242+
) : (
243+
<div
244+
style={{
245+
width: "100%",
246+
maxWidth: "100vw",
247+
aspectRatio: "16/9",
248+
borderRadius: "5px",
249+
background: "#2e2e2e",
250+
display: "grid",
251+
placeItems: "center",
252+
color: "#ccc",
253+
fontSize: 14,
254+
}}
255+
>
256+
(sin poster disponible)
257+
</div>
258+
)}
259+
260+
{description && (
261+
<div className="videoBackground-card">
262+
<h2>{description}</h2>
263+
{button && (
264+
<CustomLink
265+
content={button.content}
266+
url={button.url}
267+
landing={button.landing_page}
268+
/>
269+
)}
270+
</div>
271+
)}
272+
</section>
273+
</div>
274+
</div>
275+
)
276+
}
180277

181278
const videoContent = getVideoContent(
182279
video,
@@ -200,7 +297,7 @@ const VideoBackground = ({ data }) => {
200297
}}
201298
>
202299
<div className="container videoBackground-container">
203-
<section className="videoBackground">
300+
<section className="videoBackground" key="video">
204301
{videoContent}
205302
{description && (
206303
<div className="videoBackground-card">
@@ -223,31 +320,38 @@ const VideoBackground = ({ data }) => {
223320
VideoBackground.propTypes = {
224321
data: PropTypes.shape({
225322
video: PropTypes.shape({
226-
url: PropTypes.string.isRequired,
227-
mime: PropTypes.string.isRequired,
323+
url: PropTypes.string,
324+
mime: PropTypes.string,
228325
}),
229326
videoUrl: PropTypes.string,
230327
description: PropTypes.string,
231-
backgroundImage: PropTypes.shape({ url: PropTypes.string.isRequired }),
328+
backgroundImage: PropTypes.shape({ url: PropTypes.string }),
232329
image: PropTypes.shape({
233330
alternativeText: PropTypes.string,
234331
localFile: PropTypes.object,
235332
}),
236333
poster: PropTypes.shape({
237-
url: PropTypes.string.isRequired,
334+
url: PropTypes.string,
238335
alternativeText: PropTypes.string,
239336
localFile: PropTypes.shape({
240-
childImageSharp: PropTypes.object.isRequired,
337+
childImageSharp: PropTypes.object,
338+
}),
339+
formats: PropTypes.object,
340+
data: PropTypes.shape({
341+
attributes: PropTypes.shape({
342+
url: PropTypes.string,
343+
localFile: PropTypes.object,
344+
}),
241345
}),
242346
}),
243347
button: PropTypes.shape({
244-
content: PropTypes.string.isRequired,
348+
content: PropTypes.string,
245349
url: PropTypes.string,
246350
landing_page: PropTypes.shape({
247-
slug: PropTypes.string.isRequired,
351+
slug: PropTypes.string,
248352
}),
249353
}),
250354
}),
251355
}
252356

253-
export default VideoBackground
357+
export default VideoBackground

src/templates/LandingPage.js

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,70 @@
11
import React, { useRef } from "react"
22
import { graphql } from "gatsby"
3-
import Layout from "../components/layout"
4-
import { CustomSection, Seo, Navigation } from "../components/index"
53
import PropTypes from "prop-types"
4+
import { Helmet } from "react-helmet"
5+
import { Seo, CustomSection, Navigation, Layout } from "../components"
66

77
const LandingPage = ({ data, location }) => {
88
const { name, slug, parent_page, seo, body, navigation } =
99
data?.allStrapiLandingPage?.nodes[0] || {}
1010

1111
const wrapperRef = useRef(null)
12+
13+
const faqs = (body || [])
14+
.filter(block => block.strapi_component === "components.banner-list")
15+
.flatMap(block =>
16+
(block.Card || [])
17+
.filter(card => card.description && card.description.trim() !== "")
18+
.map(({ id, title, description }) => ({
19+
"@type": "Question",
20+
name: title,
21+
acceptedAnswer: {
22+
"@type": "Answer",
23+
text: description,
24+
},
25+
"@id": `#faq-${id}`,
26+
}))
27+
)
28+
const pageLd = {
29+
"@context": "https://schema.org",
30+
"@type": "WebPage",
31+
name: seo?.pageTitle || name,
32+
description: seo?.pageDescription,
33+
url: `https://en.bitlogic.io/${slug}`,
34+
}
35+
const faqLd =
36+
faqs.length > 0
37+
? {
38+
"@context": "https://schema.org",
39+
"@type": "FAQPage",
40+
mainEntity: faqs,
41+
}
42+
: null
43+
1244
const landing = {
1345
name,
1446
slug,
1547
parent_page,
1648
ref: wrapperRef,
1749
}
1850

19-
const {pageTitle, pageKeywords, pageDescription } = seo || {}
20-
2151
return (
2252
<Layout location={location} options={{ hasHeader: true }}>
23-
<Seo title={pageTitle} description={pageDescription} keywords={pageKeywords} location={location} />
53+
<Seo
54+
title={seo?.pageTitle || name}
55+
description={seo?.pageDescription}
56+
keywords={seo?.pageKeywords}
57+
/>
58+
<Helmet>
59+
<script type="application/ld+json">
60+
{JSON.stringify(pageLd)}
61+
</script>
62+
{faqLd && (
63+
<script type="application/ld+json">
64+
{JSON.stringify(faqLd)}
65+
</script>
66+
)}
67+
</Helmet>
2468
{body?.length > 0 && navigation ? (
2569
<>
2670
<CustomSection sections={body.slice(0, 1)} />

0 commit comments

Comments
 (0)