From aa4d42b36cb64f9518e55058a92441cfa4c165af Mon Sep 17 00:00:00 2001 From: DarkSky Date: Thu, 21 Dec 2023 12:52:38 +0000 Subject: [PATCH] feat: use baseurl from server config (#5369) --- packages/backend/server/src/modules/config.ts | 4 ++ packages/backend/server/src/schema.gql | 3 + packages/frontend/core/.webpack/config.ts | 1 - .../frontend/core/.webpack/runtime-config.ts | 2 +- .../new-workspace-setting-detail/index.tsx | 2 +- .../setting-modal/account-setting/index.tsx | 2 +- .../setting-modal/general-setting/index.tsx | 2 +- .../share-menu/share-export.tsx | 3 +- .../share-menu/share-page.tsx | 13 +++- .../share-menu/use-share-url.ts | 61 +++++++++++-------- ...-server-flavor.ts => use-server-config.ts} | 29 ++++++++- .../core/src/hooks/affine/use-share-link.ts | 15 ----- .../core/src/hooks/use-subscription.ts | 2 +- .../frontend/graphql/src/graphql/index.ts | 1 + .../graphql/src/graphql/server-config.gql | 1 + packages/frontend/graphql/src/schema.ts | 1 + 16 files changed, 88 insertions(+), 54 deletions(-) rename packages/frontend/core/src/hooks/affine/{use-server-flavor.ts => use-server-config.ts} (60%) delete mode 100644 packages/frontend/core/src/hooks/affine/use-share-link.ts diff --git a/packages/backend/server/src/modules/config.ts b/packages/backend/server/src/modules/config.ts index 5d9b05e790..7ebd5b5a4c 100644 --- a/packages/backend/server/src/modules/config.ts +++ b/packages/backend/server/src/modules/config.ts @@ -10,6 +10,9 @@ export class ServerConfigType { @Field({ description: 'server flavor' }) flavor!: string; + + @Field({ description: 'server base url' }) + baseUrl!: string; } export class ServerConfigResolver { @@ -20,6 +23,7 @@ export class ServerConfigResolver { return { version: AFFiNE.version, flavor: SERVER_FLAVOR, + baseUrl: AFFiNE.baseUrl, }; } } diff --git a/packages/backend/server/src/schema.gql b/packages/backend/server/src/schema.gql index 6707d700df..e7a348b317 100644 --- a/packages/backend/server/src/schema.gql +++ b/packages/backend/server/src/schema.gql @@ -8,6 +8,9 @@ type ServerConfigType { """server flavor""" flavor: String! + + """server base url""" + baseUrl: String! } type UserQuotaHumanReadable { diff --git a/packages/frontend/core/.webpack/config.ts b/packages/frontend/core/.webpack/config.ts index 228180d684..438e71ea8c 100644 --- a/packages/frontend/core/.webpack/config.ts +++ b/packages/frontend/core/.webpack/config.ts @@ -391,7 +391,6 @@ export const createConfiguration: ( proxy: { '/api/worker/': { target: 'https://affine-worker.toeverything.workers.dev', - pathRewrite: { '^/api/worker/': '/api/' }, changeOrigin: true, secure: false, }, diff --git a/packages/frontend/core/.webpack/runtime-config.ts b/packages/frontend/core/.webpack/runtime-config.ts index c899a40a90..6faf651feb 100644 --- a/packages/frontend/core/.webpack/runtime-config.ts +++ b/packages/frontend/core/.webpack/runtime-config.ts @@ -33,7 +33,7 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig { enablePayment: true, enablePageHistory: false, enableCopilot: false, - serverUrlPrefix: 'https://insider.affine.pro', // Let insider be stable environment temporarily. + serverUrlPrefix: 'https://app.affine.pro', editorFlags, appVersion: packageJson.version, editorVersion: packageJson.dependencies['@blocksuite/presets'], diff --git a/packages/frontend/core/src/components/affine/new-workspace-setting-detail/index.tsx b/packages/frontend/core/src/components/affine/new-workspace-setting-detail/index.tsx index 24ea8c997c..6a1acc2299 100644 --- a/packages/frontend/core/src/components/affine/new-workspace-setting-detail/index.tsx +++ b/packages/frontend/core/src/components/affine/new-workspace-setting-detail/index.tsx @@ -8,7 +8,7 @@ import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useWorkspace } from '@toeverything/hooks/use-workspace'; import { useWorkspaceInfo } from '@toeverything/hooks/use-workspace-info'; -import { useSelfHosted } from '../../../hooks/affine/use-server-flavor'; +import { useSelfHosted } from '../../../hooks/affine/use-server-config'; import { DeleteLeaveWorkspace } from './delete-leave-workspace'; import { EnableCloudPanel } from './enable-cloud'; import { ExportPanel } from './export'; diff --git a/packages/frontend/core/src/components/affine/setting-modal/account-setting/index.tsx b/packages/frontend/core/src/components/affine/setting-modal/account-setting/index.tsx index 1bfd2d714d..49f5b88fcc 100644 --- a/packages/frontend/core/src/components/affine/setting-modal/account-setting/index.tsx +++ b/packages/frontend/core/src/components/affine/setting-modal/account-setting/index.tsx @@ -34,7 +34,7 @@ import { openSignOutModalAtom, } from '../../../../atoms'; import { useCurrentUser } from '../../../../hooks/affine/use-current-user'; -import { useSelfHosted } from '../../../../hooks/affine/use-server-flavor'; +import { useSelfHosted } from '../../../../hooks/affine/use-server-config'; import { useUserSubscription } from '../../../../hooks/use-subscription'; import { validateAndReduceImage } from '../../../../utils/reduce-image'; import { Upload } from '../../../pure/file-upload'; diff --git a/packages/frontend/core/src/components/affine/setting-modal/general-setting/index.tsx b/packages/frontend/core/src/components/affine/setting-modal/general-setting/index.tsx index 2f63a3b1a4..31e344396f 100644 --- a/packages/frontend/core/src/components/affine/setting-modal/general-setting/index.tsx +++ b/packages/frontend/core/src/components/affine/setting-modal/general-setting/index.tsx @@ -8,7 +8,7 @@ import { import type { ReactElement, SVGProps } from 'react'; import { useCurrentLoginStatus } from '../../../../hooks/affine/use-current-login-status'; -import { useSelfHosted } from '../../../../hooks/affine/use-server-flavor'; +import { useSelfHosted } from '../../../../hooks/affine/use-server-config'; import { AboutAffine } from './about'; import { AppearanceSettings } from './appearance'; import { BillingSettings } from './billing'; diff --git a/packages/frontend/core/src/components/affine/share-page-modal/share-menu/share-export.tsx b/packages/frontend/core/src/components/affine/share-page-modal/share-menu/share-export.tsx index 6ce92be6cd..f30b059819 100644 --- a/packages/frontend/core/src/components/affine/share-page-modal/share-menu/share-export.tsx +++ b/packages/frontend/core/src/components/affine/share-page-modal/share-menu/share-export.tsx @@ -19,7 +19,7 @@ export const ShareExport = ({ const t = useAFFiNEI18N(); const workspaceId = workspace.id; const pageId = currentPage.id; - const { onClickCopyLink } = useSharingUrl({ + const { sharingUrl, onClickCopyLink } = useSharingUrl({ workspaceId, pageId, urlType: 'workspace', @@ -57,6 +57,7 @@ export const ShareExport = ({ onClick={onClickCopyLink} icon={} type="plain" + disabled={!sharingUrl} > {t['com.affine.share-menu.copy-private-link']()} diff --git a/packages/frontend/core/src/components/affine/share-page-modal/share-menu/share-page.tsx b/packages/frontend/core/src/components/affine/share-page-modal/share-menu/share-page.tsx index 282685330d..db286f45eb 100644 --- a/packages/frontend/core/src/components/affine/share-page-modal/share-menu/share-page.tsx +++ b/packages/frontend/core/src/components/affine/share-page-modal/share-menu/share-page.tsx @@ -18,6 +18,7 @@ import { useCallback } from 'react'; import type { PageMode } from '../../../../atoms'; import { currentModeAtom } from '../../../../atoms/mode'; import { useIsSharedPage } from '../../../../hooks/affine/use-is-shared-page'; +import { useServerBaseUrl } from '../../../../hooks/affine/use-server-config'; import * as styles from './index.css'; import type { ShareMenuProps } from './share-menu'; import { useSharingUrl } from './use-share-url'; @@ -98,6 +99,7 @@ export const AffineSharePage = (props: ShareMenuProps) => { pageId, urlType: 'share', }); + const baseUrl = useServerBaseUrl(); const t = useAFFiNEI18N(); const onClickCreateLink = useCallback(() => { @@ -140,9 +142,13 @@ export const AffineSharePage = (props: ShareMenuProps) => { lineHeight: '20px', }} value={ - isSharedPage - ? sharingUrl - : `${location.protocol}//${location.hostname}/...` + (isSharedPage && sharingUrl) || + `${ + baseUrl || + `${location.protocol}${ + location.port ? `:${location.port}` : '' + }//${location.hostname}` + }/...` } readOnly /> @@ -151,6 +157,7 @@ export const AffineSharePage = (props: ShareMenuProps) => { onClick={onClickCopyLink} data-testid="share-menu-copy-link-button" style={{ padding: '4px 12px', whiteSpace: 'nowrap' }} + disabled={!sharingUrl} > {t.Copy()} diff --git a/packages/frontend/core/src/components/affine/share-page-modal/share-menu/use-share-url.ts b/packages/frontend/core/src/components/affine/share-page-modal/share-menu/use-share-url.ts index c2f6772bc0..dc5328a74e 100644 --- a/packages/frontend/core/src/components/affine/share-page-modal/share-menu/use-share-url.ts +++ b/packages/frontend/core/src/components/affine/share-page-modal/share-menu/use-share-url.ts @@ -1,4 +1,5 @@ import { toast } from '@affine/component'; +import { useServerBaseUrl } from '@affine/core/hooks/affine/use-server-config'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useCallback, useMemo } from 'react'; @@ -10,22 +11,27 @@ type UseSharingUrl = { urlType: UrlType; }; -export const generateUrl = ({ - workspaceId, - pageId, - urlType, -}: UseSharingUrl) => { - // to generate a private url like https://affine.app/workspace/123/456 - // to generate a public url like https://affine.app/share/123/456 - // or https://affine.app/share/123/456?mode=edgeless +const useGenerateUrl = ({ workspaceId, pageId, urlType }: UseSharingUrl) => { + // to generate a private url like https://app.affine.app/workspace/123/456 + // to generate a public url like https://app.affine.app/share/123/456 + // or https://app.affine.app/share/123/456?mode=edgeless - const { protocol, hostname, port } = window.location; - const url = new URL( - `${protocol}//${hostname}${ - port ? `:${port}` : '' - }/${urlType}/${workspaceId}/${pageId}` - ); - return url.toString(); + const baseUrl = useServerBaseUrl(); + + const url = useMemo(() => { + // baseUrl is null when running in electron and without network + if (!baseUrl) return null; + + try { + return new URL( + `${baseUrl}/${urlType}/${workspaceId}/${pageId}` + ).toString(); + } catch (e) { + return null; + } + }, [baseUrl, pageId, urlType, workspaceId]); + + return url; }; export const useSharingUrl = ({ @@ -34,20 +40,21 @@ export const useSharingUrl = ({ urlType, }: UseSharingUrl) => { const t = useAFFiNEI18N(); - const sharingUrl = useMemo( - () => generateUrl({ workspaceId, pageId, urlType }), - [workspaceId, pageId, urlType] - ); + const sharingUrl = useGenerateUrl({ workspaceId, pageId, urlType }); const onClickCopyLink = useCallback(() => { - navigator.clipboard - .writeText(sharingUrl) - .then(() => { - toast(t['Copied link to clipboard']()); - }) - .catch(err => { - console.error(err); - }); + if (sharingUrl) { + navigator.clipboard + .writeText(sharingUrl) + .then(() => { + toast(t['Copied link to clipboard']()); + }) + .catch(err => { + console.error(err); + }); + } else { + toast('Network not available'); + } }, [sharingUrl, t]); return { diff --git a/packages/frontend/core/src/hooks/affine/use-server-flavor.ts b/packages/frontend/core/src/hooks/affine/use-server-config.ts similarity index 60% rename from packages/frontend/core/src/hooks/affine/use-server-flavor.ts rename to packages/frontend/core/src/hooks/affine/use-server-config.ts index 25a4be6535..89f84b336c 100644 --- a/packages/frontend/core/src/hooks/affine/use-server-flavor.ts +++ b/packages/frontend/core/src/hooks/affine/use-server-config.ts @@ -9,7 +9,7 @@ const errorHandler: Middleware = useSWRNext => (key, fetcher, config) => { return useSWRNext(key, wrappedFetcher.bind(null, fetcher), config); }; -export const useServerFlavor = () => { +const useServerConfig = () => { const { data: config, error } = useQueryImmutable( { query: serverConfigQuery }, { @@ -18,10 +18,20 @@ export const useServerFlavor = () => { ); if (error || !config) { + return null; + } + + return config.serverConfig; +}; + +export const useServerFlavor = () => { + const config = useServerConfig(); + + if (!config) { return 'local'; } - return config.serverConfig.flavor; + return config.flavor; }; export const useSelfHosted = () => { @@ -29,3 +39,18 @@ export const useSelfHosted = () => { return ['local', 'selfhosted'].includes(serverFlavor); }; + +export const useServerBaseUrl = () => { + const config = useServerConfig(); + + if (!config) { + if (environment.isDesktop) { + // don't use window.location in electron + return null; + } + const { protocol, hostname, port } = window.location; + return `${protocol}//${hostname}${port ? `:${port}` : ''}`; + } + + return config.baseUrl; +}; diff --git a/packages/frontend/core/src/hooks/affine/use-share-link.ts b/packages/frontend/core/src/hooks/affine/use-share-link.ts deleted file mode 100644 index 58e4fb37b9..0000000000 --- a/packages/frontend/core/src/hooks/affine/use-share-link.ts +++ /dev/null @@ -1,15 +0,0 @@ -'use client'; -import { useMemo } from 'react'; - -export function useShareLink(workspaceId: string): string { - return useMemo(() => { - if (environment.isServer) { - throw new Error('useShareLink is not available on server side'); - } - if (environment.isDesktop) { - return '???'; - } else { - return origin + '/share/' + workspaceId; - } - }, [workspaceId]); -} diff --git a/packages/frontend/core/src/hooks/use-subscription.ts b/packages/frontend/core/src/hooks/use-subscription.ts index 9ec556cb79..f7095033ea 100644 --- a/packages/frontend/core/src/hooks/use-subscription.ts +++ b/packages/frontend/core/src/hooks/use-subscription.ts @@ -2,7 +2,7 @@ import { type SubscriptionQuery, subscriptionQuery } from '@affine/graphql'; import { useQuery } from '@affine/workspace/affine/gql'; import { useAsyncCallback } from '@toeverything/hooks/affine-async-hooks'; -import { useSelfHosted } from './affine/use-server-flavor'; +import { useSelfHosted } from './affine/use-server-config'; export type Subscription = NonNullable< NonNullable['subscription'] diff --git a/packages/frontend/graphql/src/graphql/index.ts b/packages/frontend/graphql/src/graphql/index.ts index 5d2e01f89d..9178e0f355 100644 --- a/packages/frontend/graphql/src/graphql/index.ts +++ b/packages/frontend/graphql/src/graphql/index.ts @@ -655,6 +655,7 @@ query serverConfig { serverConfig { version flavor + baseUrl } }`, }; diff --git a/packages/frontend/graphql/src/graphql/server-config.gql b/packages/frontend/graphql/src/graphql/server-config.gql index 6f7a99a477..b18c3a8e96 100644 --- a/packages/frontend/graphql/src/graphql/server-config.gql +++ b/packages/frontend/graphql/src/graphql/server-config.gql @@ -2,5 +2,6 @@ query serverConfig { serverConfig { version flavor + baseUrl } } diff --git a/packages/frontend/graphql/src/schema.ts b/packages/frontend/graphql/src/schema.ts index cc7c293213..7f55ef17ff 100644 --- a/packages/frontend/graphql/src/schema.ts +++ b/packages/frontend/graphql/src/schema.ts @@ -632,6 +632,7 @@ export type ServerConfigQuery = { __typename?: 'ServerConfigType'; version: string; flavor: string; + baseUrl: string; }; };