From e57cba07bb372d1a3282471d03a4a5678165cc22 Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Thu, 19 Dec 2024 12:49:07 +0200 Subject: [PATCH 1/7] iframe communication posting page change & page height info --- components/iframeCommunication.js | 52 +++++++++++++++++++++++++++++++ pages/_app.js | 3 +- styles.css | 1 + 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 components/iframeCommunication.js diff --git a/components/iframeCommunication.js b/components/iframeCommunication.js new file mode 100644 index 0000000..1faa710 --- /dev/null +++ b/components/iframeCommunication.js @@ -0,0 +1,52 @@ +import { useEffect } from 'react'; +import { useRouter } from 'next/router'; + +// not used as there's no access to the parent origin it's not ideal as anyone can embed the documentation and receive messages +// const allowedOrigins = ['https://alkem.io', 'https://dev-alkem.io', 'https://acc-alkem.io', 'https://sandbox-alkem.io', 'http://localhost:3000']; +// const isOriginValid = (origin) => allowedOrigins.includes(origin); + +const sendMessageToParent = (message) => { + if (window.parent) { + window.parent.postMessage(message, '*'); + } else { + console.warn('Parent window not found or origin not allowed.'); + } +}; + +// copy in client-web +const SupportedMessageTypes = { + PageHeight: 'PAGE_HEIGHT', + PageChange: 'PAGE_CHANGE', +} + +let oldPath = ''; + +const IframeCommunication = () => { + const router = useRouter(); + + const sendPageHeight = () => { + const pageHeight = document.documentElement.scrollHeight || document.body.scrollHeight; + + if (oldPath !== router.pathname) { + sendMessageToParent({ type: SupportedMessageTypes.PageHeight, height: pageHeight }); + oldPath = router.pathname; + } + }; + + useEffect(() => { + // Send initial pathname and page height to the parent window + sendMessageToParent({ type: SupportedMessageTypes.PageChange, url: router.pathname }); + sendPageHeight(); + + // Send page height on resize + window.addEventListener('resize', sendPageHeight); + + return () => { + window.removeEventListener('resize', sendPageHeight); + }; + }, [router.pathname]); + + return null; +}; + +export default IframeCommunication; \ No newline at end of file diff --git a/pages/_app.js b/pages/_app.js index d3c3c5a..4dcf7a2 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -1,6 +1,7 @@ import '../styles.css' +import IframeCommunication from '../components/iframeCommunication'; // This default export is required in a new `pages/_app.js` file. export default function MyApp({ Component, pageProps }) { - return + return <>; } diff --git a/styles.css b/styles.css index 76da3be..d15cb5c 100644 --- a/styles.css +++ b/styles.css @@ -1,4 +1,5 @@ body { font-family: 'SF Pro Text', 'SF Pro Icons', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif; + overflow-y: hidden; } \ No newline at end of file From a06c18c9a723b1146334847d82f621823bbab592 Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Thu, 19 Dec 2024 15:16:28 +0200 Subject: [PATCH 2/7] pr and AI improvements --- components/iframeCommunication.js | 45 ++++++++++++++++++------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/components/iframeCommunication.js b/components/iframeCommunication.js index 1faa710..a51877e 100644 --- a/components/iframeCommunication.js +++ b/components/iframeCommunication.js @@ -1,52 +1,61 @@ -import { useEffect } from 'react'; +import { useEffect, useRef } from 'react'; import { useRouter } from 'next/router'; -// not used as there's no access to the parent origin it's not ideal as anyone can embed the documentation and receive messages +// not used as there's no access to the parent origin. This is not ideal as anyone can embed the documentation and receive messages. // const allowedOrigins = ['https://alkem.io', 'https://dev-alkem.io', 'https://acc-alkem.io', 'https://sandbox-alkem.io', 'http://localhost:3000']; // const isOriginValid = (origin) => allowedOrigins.includes(origin); const sendMessageToParent = (message) => { - if (window.parent) { + try { + // todo: check for isOriginValid here window.parent.postMessage(message, '*'); - } else { - console.warn('Parent window not found or origin not allowed.'); + } catch (error) { + console.warn('Failed to send message to parent: ', error); } }; -// copy in client-web const SupportedMessageTypes = { PageHeight: 'PAGE_HEIGHT', PageChange: 'PAGE_CHANGE', -} - -let oldPath = ''; +}; const IframeCommunication = () => { const router = useRouter(); + const lastHeight = useRef(0); + const debounceTimeout = useRef(null); const sendPageHeight = () => { const pageHeight = document.documentElement.scrollHeight || document.body.scrollHeight; - if (oldPath !== router.pathname) { - sendMessageToParent({ type: SupportedMessageTypes.PageHeight, height: pageHeight }); - oldPath = router.pathname; + // Only send if there's a meaningful difference in height + if (Math.abs(pageHeight - lastHeight.current) > 40) { + lastHeight.current = pageHeight; + + // Debounce the message to avoid excessive calls + clearTimeout(debounceTimeout.current); + debounceTimeout.current = setTimeout(() => { + sendMessageToParent({ type: SupportedMessageTypes.PageHeight, height: pageHeight }); + }, 50); } }; useEffect(() => { - // Send initial pathname and page height to the parent window + // Send initial page height and path sendMessageToParent({ type: SupportedMessageTypes.PageChange, url: router.pathname }); sendPageHeight(); - // Send page height on resize - window.addEventListener('resize', sendPageHeight); + // Observe changes to the body size + const resizeObserver = new ResizeObserver(sendPageHeight); + resizeObserver.observe(document.body); + // Cleanup return () => { - window.removeEventListener('resize', sendPageHeight); + resizeObserver.disconnect(); + clearTimeout(debounceTimeout.current); }; }, [router.pathname]); - return null; + return null; }; -export default IframeCommunication; \ No newline at end of file +export default IframeCommunication; From 453c8e56f261b6edaa2cdaed240003d4700ef4c9 Mon Sep 17 00:00:00 2001 From: Francesco Date: Fri, 20 Dec 2024 12:10:19 +0100 Subject: [PATCH 3/7] empty --- pages/getting-started/find-space.en-US.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/getting-started/find-space.en-US.mdx b/pages/getting-started/find-space.en-US.mdx index 1d1e937..c0b61e2 100644 --- a/pages/getting-started/find-space.en-US.mdx +++ b/pages/getting-started/find-space.en-US.mdx @@ -12,4 +12,4 @@ To change your personal details, click on the gear icon to the right of your nam ### Example ![Example Profile](/profile-example.png) As an employee at Alkemio, I will fill out my name, demographics, jobtitle in the tagline and some information about what I do, how I got here and what my interests are in the Bio. I also fill in some skills like Open Source, GitHub, Community Management and Customer Success in the Skills field, so people can quickly see my fields of expertise. I fill out my interests and values, like GreenTech and Sustainability in the Keywords section. -I will also add the link to my LinkedIn profile, my GitHub page and my X profile when I have those. \ No newline at end of file +I will also add the link to my LinkedIn profile, my GitHub page and my X profile when I have those. \ No newline at end of file From 698cc77358161b090c6ba2cffeae1e61fe776254 Mon Sep 17 00:00:00 2001 From: bobbykolev Date: Fri, 20 Dec 2024 16:54:01 +0200 Subject: [PATCH 4/7] readme.md updated with deployment info --- README.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 78c375d..8e1bcd0 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ `npm i` `npm run dev` -###### prerequisits +###### prerequisites It's recommended to use [volta](https://docs.volta.sh/guide/getting-started) ``` @@ -53,4 +53,24 @@ _meta.en-US.json At the moment the i18n is done manually by the nextra guide - https://nextra.site/docs/guide/i18n -We'll explore the option to use Crowdin instead. \ No newline at end of file +We'll explore the option to use Crowdin instead. + +### Build & Deployment + +The build and deployments are automatic on merge. + +In order to deploy it to dev/acc, merge to `develop` branch. + +For production release you need to merge to `main` branch. +For proper redeployment make sure you bump the version on every merge to main. + +Use the following: +``` +npm version patch +``` +this will bump the patch version and make a commit (e.g. 0.0.1 -> 0.0.2). + +Or manually update the npm version in the package.json file. +Then run `npm install` and commit the changes. + +Once merged into `main`, make sure to merge `main` back to `develop` (to sync the version). \ No newline at end of file From a479e1619189d3e456988b2101c958694c53a2b6 Mon Sep 17 00:00:00 2001 From: Bobby Kolev Date: Fri, 20 Dec 2024 17:08:10 +0200 Subject: [PATCH 5/7] 0.0.2 (#23) (#24) --- package-lock.json | 4 ++-- package.json | 32 +------------------------------- 2 files changed, 3 insertions(+), 33 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4d256bf..a83a672 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@alkemio/documentation", - "version": "0.0.1", + "version": "0.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@alkemio/documentation", - "version": "0.0.1", + "version": "0.0.2", "license": "EUPL-1.2", "dependencies": { "next": "^14.2.5", diff --git a/package.json b/package.json index e457885..a14c60f 100644 --- a/package.json +++ b/package.json @@ -1,31 +1 @@ -{ - "name": "@alkemio/documentation", - "version": "0.0.1", - "description": "Alkemio platform documentation", - "author": "Alkemio Foundation", - "repository": { - "type": "git", - "url": "https://github.com/alkem-io/documentation" - }, - "license": "EUPL-1.2", - "scripts": { - "dev": "next -p 3010", - "build": "next build", - "start": "next start -p 3010", - "export": "next export" - }, - "dependencies": { - "next": "^14.2.5", - "nextra": "^2.13.4", - "nextra-theme-docs": "^2.13.4", - "react": "^18.3.1", - "react-dom": "^18.3.1" - }, - "engines": { - "node": ">=20.9.0", - "npm": ">=10" - }, - "volta": { - "node": "20.13.1" - } -} +{"name":"@alkemio/documentation","version":"0.0.2","description":"Alkemio platform documentation","author":"Alkemio Foundation","repository":{"type":"git","url":"https://github.com/alkem-io/documentation"},"license":"EUPL-1.2","scripts":{"dev":"next -p 3010","build":"next build","start":"next start -p 3010","export":"next export"},"dependencies":{"next":"^14.2.5","nextra":"^2.13.4","nextra-theme-docs":"^2.13.4","react":"^18.3.1","react-dom":"^18.3.1"},"engines":{"node":">=20.9.0","npm":">=10"},"volta":{"node":"20.13.1"}} \ No newline at end of file From fe53a4d2cb34eff8b52b5bf8ca192a76680432de Mon Sep 17 00:00:00 2001 From: Bobby Kolev Date: Mon, 23 Dec 2024 11:43:44 +0200 Subject: [PATCH 6/7] version bump 0.0.3 (#25) --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a83a672..10de902 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@alkemio/documentation", - "version": "0.0.2", + "version": "0.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@alkemio/documentation", - "version": "0.0.2", + "version": "0.0.3", "license": "EUPL-1.2", "dependencies": { "next": "^14.2.5", diff --git a/package.json b/package.json index a14c60f..c0a08fc 100644 --- a/package.json +++ b/package.json @@ -1 +1 @@ -{"name":"@alkemio/documentation","version":"0.0.2","description":"Alkemio platform documentation","author":"Alkemio Foundation","repository":{"type":"git","url":"https://github.com/alkem-io/documentation"},"license":"EUPL-1.2","scripts":{"dev":"next -p 3010","build":"next build","start":"next start -p 3010","export":"next export"},"dependencies":{"next":"^14.2.5","nextra":"^2.13.4","nextra-theme-docs":"^2.13.4","react":"^18.3.1","react-dom":"^18.3.1"},"engines":{"node":">=20.9.0","npm":">=10"},"volta":{"node":"20.13.1"}} \ No newline at end of file +{"name":"@alkemio/documentation","version":"0.0.3","description":"Alkemio platform documentation","author":"Alkemio Foundation","repository":{"type":"git","url":"https://github.com/alkem-io/documentation"},"license":"EUPL-1.2","scripts":{"dev":"next -p 3010","build":"next build","start":"next start -p 3010","export":"next export"},"dependencies":{"next":"^14.2.5","nextra":"^2.13.4","nextra-theme-docs":"^2.13.4","react":"^18.3.1","react-dom":"^18.3.1"},"engines":{"node":">=20.9.0","npm":">=10"},"volta":{"node":"20.13.1"}} \ No newline at end of file From fa1da8db34802d57c8e126dbe58ee01b0b93b9df Mon Sep 17 00:00:00 2001 From: Bobby Kolev Date: Mon, 23 Dec 2024 12:24:56 +0200 Subject: [PATCH 7/7] set proper origin for the iframe communication (#26) --- components/iframeCommunication.js | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/components/iframeCommunication.js b/components/iframeCommunication.js index a51877e..70a0469 100644 --- a/components/iframeCommunication.js +++ b/components/iframeCommunication.js @@ -1,14 +1,28 @@ import { useEffect, useRef } from 'react'; import { useRouter } from 'next/router'; -// not used as there's no access to the parent origin. This is not ideal as anyone can embed the documentation and receive messages. -// const allowedOrigins = ['https://alkem.io', 'https://dev-alkem.io', 'https://acc-alkem.io', 'https://sandbox-alkem.io', 'http://localhost:3000']; -// const isOriginValid = (origin) => allowedOrigins.includes(origin); +const allowedOrigins = ['https://alkem.io', 'https://dev-alkem.io', 'https://acc-alkem.io', 'https://sandbox-alkem.io', 'http://localhost:3000']; +const isOriginValid = (origin) => allowedOrigins.includes(origin); + +const getCurrentOrigin = () => { + const { protocol, hostname, origin, port } = window.location; + if (port) { + return `${protocol}//${hostname}:3000`; // local client port + } + + return origin; +}; const sendMessageToParent = (message) => { try { - // todo: check for isOriginValid here - window.parent.postMessage(message, '*'); + const origin = getCurrentOrigin(); + + if (!isOriginValid(origin)) { + console.warn('Invalid origin: ', origin); + return; + } + + window.parent.postMessage(message, getCurrentOrigin()); } catch (error) { console.warn('Failed to send message to parent: ', error); }