From aa4d42b36cb64f9518e55058a92441cfa4c165af Mon Sep 17 00:00:00 2001 From: DarkSky Date: Thu, 21 Dec 2023 12:52:38 +0000 Subject: [PATCH 1/4] 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; }; }; From cfb77e8243463b3c9c4c1232d00e967457365492 Mon Sep 17 00:00:00 2001 From: Joooye_34 Date: Thu, 21 Dec 2023 14:15:22 +0000 Subject: [PATCH 2/4] chore: fix about version in client (#5371) --- .github/workflows/release-desktop.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/release-desktop.yml b/.github/workflows/release-desktop.yml index 45d1593c4b..12beff675d 100644 --- a/.github/workflows/release-desktop.yml +++ b/.github/workflows/release-desktop.yml @@ -93,6 +93,9 @@ jobs: SKIP_GENERATE_ASSETS: 1 steps: - uses: actions/checkout@v4 + - name: Setup Version + id: version + uses: ./.github/actions/setup-version - name: Setup Node.js timeout-minutes: 10 uses: ./.github/actions/setup-node @@ -167,6 +170,9 @@ jobs: SKIP_GENERATE_ASSETS: 1 steps: - uses: actions/checkout@v4 + - name: Setup Version + id: version + uses: ./.github/actions/setup-version - name: Setup Node.js timeout-minutes: 10 uses: ./.github/actions/setup-node From ec7f73f1688f49af10ffe846c5a33c5333f7faf7 Mon Sep 17 00:00:00 2001 From: Joooye_34 Date: Thu, 21 Dec 2023 14:27:07 +0000 Subject: [PATCH 3/4] chore: catch and ignore page upgrade error (#5373) --- .../common/infra/src/blocksuite/migration/blocksuite.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/common/infra/src/blocksuite/migration/blocksuite.ts b/packages/common/infra/src/blocksuite/migration/blocksuite.ts index a5e71013ea..7afe5ca74d 100644 --- a/packages/common/infra/src/blocksuite/migration/blocksuite.ts +++ b/packages/common/infra/src/blocksuite/migration/blocksuite.ts @@ -28,7 +28,12 @@ export async function migratePages( const oldVersions = versions?.toJSON() ?? {}; spaces.forEach((space: YDoc) => { - schema.upgradePage(0, oldVersions, space); + try { + // Catch page upgrade error to avoid blocking the whole workspace migration. + schema.upgradePage(0, oldVersions, space); + } catch (e) { + console.error(e); + } }); schema.upgradeWorkspace(rootDoc); From 06912c6885f0a12196d5a3e5019c5a1457e171f8 Mon Sep 17 00:00:00 2001 From: DarkSky <25152247+darkskygit@users.noreply.github.com> Date: Thu, 21 Dec 2023 23:52:05 +0800 Subject: [PATCH 4/4] fix: websocket prefix (#5372) --- .../frontend/workspace/src/utils/affine-io.ts | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/packages/frontend/workspace/src/utils/affine-io.ts b/packages/frontend/workspace/src/utils/affine-io.ts index b3d4afb630..71055dd5a4 100644 --- a/packages/frontend/workspace/src/utils/affine-io.ts +++ b/packages/frontend/workspace/src/utils/affine-io.ts @@ -2,21 +2,25 @@ import { Manager } from 'socket.io-client'; let ioManager: Manager | null = null; +function getBaseUrl(): string { + if (environment.isDesktop) { + return runtimeConfig.serverUrlPrefix; + } + const { protocol, hostname, port } = window.location; + return `${protocol === 'https:' ? 'wss' : 'ws'}://${hostname}${ + port ? `:${port}` : '' + }`; +} + // use lazy initialization socket.io io manager export function getIoManager(): Manager { if (ioManager) { return ioManager; } - const { protocol, hostname, port } = window.location; - ioManager = new Manager( - `${protocol === 'https:' ? 'wss' : 'ws'}://${hostname}${ - port ? `:${port}` : '' - }/`, - { - autoConnect: false, - transports: ['websocket'], - secure: location.protocol === 'https:', - } - ); + ioManager = new Manager(`${getBaseUrl()}/`, { + autoConnect: false, + transports: ['websocket'], + secure: location.protocol === 'https:', + }); return ioManager; }