diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/database/DatabaseBlock.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/database/DatabaseBlock.tsx index a671c6ef43..d454f7b9f0 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/blocks/database/DatabaseBlock.tsx +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/database/DatabaseBlock.tsx @@ -100,7 +100,7 @@ export const DatabaseBlock = memo( > {notFound ? ( <> -
{t('publish.hasNotBeenPublished')}
+
{t('publish.hasNotBeenPublished')}
) : ( diff --git a/frontend/appflowy_web_app/src/components/publish/header/BreadcrumbItem.tsx b/frontend/appflowy_web_app/src/components/publish/header/BreadcrumbItem.tsx index 9d07ece56e..888339291d 100644 --- a/frontend/appflowy_web_app/src/components/publish/header/BreadcrumbItem.tsx +++ b/frontend/appflowy_web_app/src/components/publish/header/BreadcrumbItem.tsx @@ -43,7 +43,7 @@ function BreadcrumbItem({ crumb, disableClick = false }: { crumb: Crumb; disable return (
{ if (disableClick) return; try { diff --git a/frontend/appflowy_web_app/src/components/publish/header/PublishViewHeader.tsx b/frontend/appflowy_web_app/src/components/publish/header/PublishViewHeader.tsx index 2d3187f27c..4d3221249b 100644 --- a/frontend/appflowy_web_app/src/components/publish/header/PublishViewHeader.tsx +++ b/frontend/appflowy_web_app/src/components/publish/header/PublishViewHeader.tsx @@ -1,6 +1,8 @@ import { usePublishContext } from '@/application/publish'; +import { openOrDownload } from '@/components/publish/header/utils'; import React, { useMemo } from 'react'; import Breadcrumb from './Breadcrumb'; +import { ReactComponent as Logo } from '@/assets/logo.svg'; export function PublishViewHeader() { const viewMeta = usePublishContext()?.viewMeta; @@ -24,9 +26,12 @@ export function PublishViewHeader() { }, [viewMeta]); return ( -
+
+
); diff --git a/frontend/appflowy_web_app/src/components/publish/header/utils.ts b/frontend/appflowy_web_app/src/components/publish/header/utils.ts new file mode 100644 index 0000000000..05cf87e9cc --- /dev/null +++ b/frontend/appflowy_web_app/src/components/publish/header/utils.ts @@ -0,0 +1,99 @@ +export function openOrDownload() { + const getDeviceType = () => { + const ua = navigator.userAgent; + + if (/(iPad|iPhone|iPod)/g.test(ua)) { + return 'iOS'; + } else if (/Android/g.test(ua)) { + return 'Android'; + } else { + return 'Desktop'; + } + }; + + const deviceType = getDeviceType(); + const isMobile = deviceType !== 'Desktop'; + const getFallbackLink = () => { + if (deviceType === 'iOS') { + return 'https://testflight.apple.com/join/6CexvkDz'; + } else if (deviceType === 'Android') { + return 'https://play.google.com/store/apps/details?id=io.appflowy.appflowy'; + } else { + return 'https://appflowy.io/download/#pop'; + } + }; + + const getDuration = () => { + switch (deviceType) { + case 'iOS': + return 250; + default: + return 1500; + } + }; + + const APPFLOWY_SCHEME = 'appflowy-flutter://'; + + const iframe = document.createElement('iframe'); + + iframe.style.display = 'none'; + iframe.src = APPFLOWY_SCHEME; + + const openSchema = () => { + if (isMobile) return (window.location.href = APPFLOWY_SCHEME); + document.body.appendChild(iframe); + setTimeout(() => { + document.body.removeChild(iframe); + }, 1000); + }; + + const openAppFlowy = () => { + openSchema(); + + const initialTime = Date.now(); + let interactTime = initialTime; + let waitTime = 0; + const duration = getDuration(); + + const updateInteractTime = () => { + interactTime = Date.now(); + }; + + document.removeEventListener('mousemove', updateInteractTime); + document.removeEventListener('mouseenter', updateInteractTime); + + const checkOpen = setInterval(() => { + waitTime = Date.now() - initialTime; + + if (waitTime > duration) { + clearInterval(checkOpen); + if (isMobile || Date.now() - interactTime < duration) { + window.open(getFallbackLink(), '_current'); + } + } + }, 20); + + if (!isMobile) { + document.addEventListener('mouseenter', updateInteractTime); + document.addEventListener('mousemove', updateInteractTime); + } + + document.addEventListener('visibilitychange', () => { + const isHidden = document.hidden; + + if (isHidden) { + clearInterval(checkOpen); + } + }); + + window.onpagehide = () => { + clearInterval(checkOpen); + }; + + window.onbeforeunload = () => { + clearInterval(checkOpen); + }; + }; + + openAppFlowy(); +}