From f875b3764178d8cf1eccec45671223fb3fb6a93f Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Thu, 18 May 2023 07:16:22 +0800 Subject: [PATCH] fix: configurable changelog url (#2418) --- .../layers/main/src/application-menu.ts | 7 +++ apps/web/preset.config.mjs | 3 ++ .../affine/affine-error-eoundary.tsx | 45 +++---------------- .../panel/collaboration/index.tsx | 2 +- .../panel/publish/index.tsx | 2 +- .../header-right-items/share-menu.tsx | 2 +- .../web/src/components/page-detail-editor.tsx | 2 +- .../src/components/pure/help-island/index.tsx | 7 +-- .../pages/public-workspace/[workspaceId].tsx | 2 +- .../workspace/[workspaceId]/[pageId].tsx | 2 +- .../src/pages/workspace/[workspaceId]/all.tsx | 5 +-- .../pages/workspace/[workspaceId]/setting.tsx | 2 +- apps/web/src/plugins/affine/fetcher.ts | 2 +- apps/web/src/plugins/affine/index.tsx | 2 +- apps/web/src/plugins/local/index.tsx | 2 +- .../app-sidebar/add-page-button/index.css.ts | 6 +++ .../app-sidebar/app-updater-button/index.tsx | 34 +++++++------- packages/env/src/config.ts | 1 + packages/env/src/constant.ts | 39 ++++++++++++++++ 19 files changed, 94 insertions(+), 73 deletions(-) diff --git a/apps/electron/layers/main/src/application-menu.ts b/apps/electron/layers/main/src/application-menu.ts index e0ad8dada8..fe638dd46b 100644 --- a/apps/electron/layers/main/src/application-menu.ts +++ b/apps/electron/layers/main/src/application-menu.ts @@ -3,6 +3,7 @@ import { app, Menu } from 'electron'; import { isMacOS } from '../../utils'; import { subjects } from './events'; import { checkForUpdatesAndNotify } from './handlers/updater'; +import { revealLogFile } from './logger'; // Unique id for menuitems const MENUITEM_NEW_PAGE = 'affine:new-page'; @@ -115,6 +116,12 @@ export function createApplicationMenu() { await shell.openExternal('https://affine.pro/'); }, }, + { + label: 'Open logs folder', + click: async () => { + revealLogFile(); + }, + }, { label: 'Check for Updates', click: async () => { diff --git a/apps/web/preset.config.mjs b/apps/web/preset.config.mjs index d0061c95f3..a7c1c3dbfc 100644 --- a/apps/web/preset.config.mjs +++ b/apps/web/preset.config.mjs @@ -33,4 +33,7 @@ export const buildFlags = { enableDebugPage: Boolean( process.env.ENABLE_DEBUG_PAGE ?? process.env.NODE_ENV === 'development' ), + changelogUrl: + process.env.CHANGELOG_URL ?? + 'https://affine.pro/blog/whats-new-affine-0518', }; diff --git a/apps/web/src/components/affine/affine-error-eoundary.tsx b/apps/web/src/components/affine/affine-error-eoundary.tsx index 4afae97191..5003c90cf8 100644 --- a/apps/web/src/components/affine/affine-error-eoundary.tsx +++ b/apps/web/src/components/affine/affine-error-eoundary.tsx @@ -1,52 +1,19 @@ +import type { + QueryParamError, + Unreachable, + WorkspaceNotFoundError, +} from '@affine/env/constant'; +import { PageNotFoundError } from '@affine/env/constant'; import { RequestError } from '@affine/workspace/affine/api'; import type { NextRouter } from 'next/router'; import type { ErrorInfo, ReactNode } from 'react'; import type React from 'react'; import { Component } from 'react'; -import type { BlockSuiteWorkspace } from '../../shared'; - export type AffineErrorBoundaryProps = React.PropsWithChildren<{ router: NextRouter; }>; -export class PageNotFoundError extends TypeError { - readonly workspace: BlockSuiteWorkspace; - readonly pageId: string; - - constructor(workspace: BlockSuiteWorkspace, pageId: string) { - super(); - this.workspace = workspace; - this.pageId = pageId; - } -} - -export class WorkspaceNotFoundError extends TypeError { - readonly workspaceId: string; - - constructor(workspaceId: string) { - super(); - this.workspaceId = workspaceId; - } -} - -export class QueryParamError extends TypeError { - readonly targetKey: string; - readonly query: unknown; - - constructor(targetKey: string, query: unknown) { - super(); - this.targetKey = targetKey; - this.query = query; - } -} - -export class Unreachable extends Error { - constructor(message?: string) { - super(message); - } -} - type AffineError = | QueryParamError | Unreachable diff --git a/apps/web/src/components/affine/workspace-setting-detail/panel/collaboration/index.tsx b/apps/web/src/components/affine/workspace-setting-detail/panel/collaboration/index.tsx index e5cd7fca3f..48390e339d 100644 --- a/apps/web/src/components/affine/workspace-setting-detail/panel/collaboration/index.tsx +++ b/apps/web/src/components/affine/workspace-setting-detail/panel/collaboration/index.tsx @@ -1,5 +1,6 @@ import { Button, IconButton, Menu, MenuItem, Wrapper } from '@affine/component'; import { config } from '@affine/env'; +import { Unreachable } from '@affine/env/constant'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { PermissionType } from '@affine/workspace/affine/api'; import type { @@ -17,7 +18,6 @@ import { useCallback, useState } from 'react'; import { useMembers } from '../../../../../hooks/affine/use-members'; import { toast } from '../../../../../utils'; -import { Unreachable } from '../../../affine-error-eoundary'; import { TmpDisableAffineCloudModal } from '../../../tmp-disable-affine-cloud-modal'; import { TransformWorkspaceToAffineModal } from '../../../transform-workspace-to-affine-modal'; import type { PanelProps } from '../../index'; diff --git a/apps/web/src/components/affine/workspace-setting-detail/panel/publish/index.tsx b/apps/web/src/components/affine/workspace-setting-detail/panel/publish/index.tsx index 28e022cea5..4d636885ff 100644 --- a/apps/web/src/components/affine/workspace-setting-detail/panel/publish/index.tsx +++ b/apps/web/src/components/affine/workspace-setting-detail/panel/publish/index.tsx @@ -6,6 +6,7 @@ import { Wrapper, } from '@affine/component'; import { config } from '@affine/env'; +import { Unreachable } from '@affine/env/constant'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import type { AffineLegacyCloudWorkspace, @@ -19,7 +20,6 @@ import { useCallback, useEffect, useState } from 'react'; import { useToggleWorkspacePublish } from '../../../../../hooks/affine/use-toggle-workspace-publish'; import type { AffineOfficialWorkspace } from '../../../../../shared'; import { toast } from '../../../../../utils'; -import { Unreachable } from '../../../affine-error-eoundary'; import { EnableAffineCloudModal } from '../../../enable-affine-cloud-modal'; import { TmpDisableAffineCloudModal } from '../../../tmp-disable-affine-cloud-modal'; import type { WorkspaceSettingDetailProps } from '../../index'; diff --git a/apps/web/src/components/blocksuite/workspace-header/header-right-items/share-menu.tsx b/apps/web/src/components/blocksuite/workspace-header/header-right-items/share-menu.tsx index bbab7f768f..1192231ee4 100644 --- a/apps/web/src/components/blocksuite/workspace-header/header-right-items/share-menu.tsx +++ b/apps/web/src/components/blocksuite/workspace-header/header-right-items/share-menu.tsx @@ -1,5 +1,6 @@ import { ShareMenu } from '@affine/component/share-menu'; import { config } from '@affine/env'; +import { Unreachable } from '@affine/env/constant'; import type { AffineLegacyCloudWorkspace, LocalWorkspace, @@ -15,7 +16,6 @@ import { useToggleWorkspacePublish } from '../../../../hooks/affine/use-toggle-w import { useOnTransformWorkspace } from '../../../../hooks/root/use-on-transform-workspace'; import { useRouterHelper } from '../../../../hooks/use-router-helper'; import { WorkspaceSubPath } from '../../../../shared'; -import { Unreachable } from '../../../affine/affine-error-eoundary'; import { TransformWorkspaceToAffineModal } from '../../../affine/transform-workspace-to-affine-modal'; import type { BaseHeaderProps } from '../header'; diff --git a/apps/web/src/components/page-detail-editor.tsx b/apps/web/src/components/page-detail-editor.tsx index cef2f37a6b..0042664686 100644 --- a/apps/web/src/components/page-detail-editor.tsx +++ b/apps/web/src/components/page-detail-editor.tsx @@ -1,3 +1,4 @@ +import { PageNotFoundError } from '@affine/env/constant'; import type { EditorContainer } from '@blocksuite/editor'; import type { Page } from '@blocksuite/store'; import { assertExists } from '@blocksuite/store'; @@ -11,7 +12,6 @@ import { startTransition, useCallback } from 'react'; import { currentEditorAtom, workspacePreferredModeAtom } from '../atoms'; import type { AffineOfficialWorkspace } from '../shared'; -import { PageNotFoundError } from './affine/affine-error-eoundary'; import { BlockSuiteEditor as Editor } from './blocksuite/block-suite-editor'; import { WorkspaceHeader } from './blocksuite/workspace-header'; diff --git a/apps/web/src/components/pure/help-island/index.tsx b/apps/web/src/components/pure/help-island/index.tsx index 1ecd7bd387..dc36b81388 100644 --- a/apps/web/src/components/pure/help-island/index.tsx +++ b/apps/web/src/components/pure/help-island/index.tsx @@ -1,5 +1,5 @@ import { MuiFade, Tooltip } from '@affine/component'; -import { getEnvironment } from '@affine/env'; +import { config, getEnvironment } from '@affine/env'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { CloseIcon, NewIcon } from '@blocksuite/icons'; import { useAtom } from 'jotai'; @@ -74,10 +74,7 @@ export const HelpIsland = ({ { - window.open( - 'https://github.com/toeverything/AFFiNE/releases', - '_blank' - ); + window.open(config.changelogUrl, '_blank'); }} > diff --git a/apps/web/src/pages/public-workspace/[workspaceId].tsx b/apps/web/src/pages/public-workspace/[workspaceId].tsx index 0fb24bb798..e48e2459ce 100644 --- a/apps/web/src/pages/public-workspace/[workspaceId].tsx +++ b/apps/web/src/pages/public-workspace/[workspaceId].tsx @@ -1,5 +1,6 @@ import { Breadcrumbs, IconButton, ListSkeleton } from '@affine/component'; import { StyledTableContainer } from '@affine/component/page-list'; +import { QueryParamError } from '@affine/env/constant'; import { SearchIcon } from '@blocksuite/icons'; import { useBlockSuiteWorkspaceAvatarUrl } from '@toeverything/hooks/use-block-suite-workspace-avatar-url'; import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name'; @@ -13,7 +14,6 @@ import { publicWorkspaceAtom, publicWorkspaceIdAtom, } from '../../atoms/public-workspace'; -import { QueryParamError } from '../../components/affine/affine-error-eoundary'; import { WorkspaceAvatar } from '../../components/pure/footer'; import { PageLoading } from '../../components/pure/loading'; import { diff --git a/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx b/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx index e1a0b6cff8..146d103ab7 100644 --- a/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx +++ b/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx @@ -1,6 +1,7 @@ import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton'; import type { BlockSuiteFeatureFlags } from '@affine/env'; import { config } from '@affine/env'; +import { Unreachable } from '@affine/env/constant'; import { rootCurrentPageIdAtom } from '@affine/workspace/atom'; import { WorkspaceFlavour } from '@affine/workspace/type'; import { assertExists } from '@blocksuite/store'; @@ -15,7 +16,6 @@ import type React from 'react'; import { useCallback, useEffect } from 'react'; import { rootCurrentWorkspaceAtom } from '../../../atoms/root'; -import { Unreachable } from '../../../components/affine/affine-error-eoundary'; import { useReferenceLinkEffect } from '../../../hooks/affine/use-reference-link-effect'; import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace'; import { usePinboardHandler } from '../../../hooks/use-pinboard-handler'; diff --git a/apps/web/src/pages/workspace/[workspaceId]/all.tsx b/apps/web/src/pages/workspace/[workspaceId]/all.tsx index 307f96d88a..9793daadae 100644 --- a/apps/web/src/pages/workspace/[workspaceId]/all.tsx +++ b/apps/web/src/pages/workspace/[workspaceId]/all.tsx @@ -1,3 +1,4 @@ +import { QueryParamError, Unreachable } from '@affine/env/constant'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { WorkspaceFlavour } from '@affine/workspace/type'; import { FolderIcon } from '@blocksuite/icons'; @@ -6,10 +7,6 @@ import Head from 'next/head'; import { useRouter } from 'next/router'; import React, { useCallback } from 'react'; -import { - QueryParamError, - Unreachable, -} from '../../../components/affine/affine-error-eoundary'; import { PageLoading } from '../../../components/pure/loading'; import { WorkspaceTitle } from '../../../components/pure/workspace-title'; import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace'; diff --git a/apps/web/src/pages/workspace/[workspaceId]/setting.tsx b/apps/web/src/pages/workspace/[workspaceId]/setting.tsx index b86a2f9eca..11b3e6de5e 100644 --- a/apps/web/src/pages/workspace/[workspaceId]/setting.tsx +++ b/apps/web/src/pages/workspace/[workspaceId]/setting.tsx @@ -1,3 +1,4 @@ +import { Unreachable } from '@affine/env/constant'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom'; import type { SettingPanel } from '@affine/workspace/type'; @@ -15,7 +16,6 @@ import type { NextRouter } from 'next/router'; import { useRouter } from 'next/router'; import React, { useCallback, useEffect } from 'react'; -import { Unreachable } from '../../../components/affine/affine-error-eoundary'; import { PageLoading } from '../../../components/pure/loading'; import { WorkspaceTitle } from '../../../components/pure/workspace-title'; import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace'; diff --git a/apps/web/src/plugins/affine/fetcher.ts b/apps/web/src/plugins/affine/fetcher.ts index 66d26b0936..25e1db1cda 100644 --- a/apps/web/src/plugins/affine/fetcher.ts +++ b/apps/web/src/plugins/affine/fetcher.ts @@ -1,3 +1,4 @@ +import { Unreachable } from '@affine/env/constant'; import { rootStore } from '@affine/workspace/atom'; import type { AffineLegacyCloudWorkspace } from '@affine/workspace/type'; import { WorkspaceFlavour } from '@affine/workspace/type'; @@ -6,7 +7,6 @@ import { assertExists } from '@blocksuite/store'; import { workspacesAtom } from '../../atoms'; import { createAffineProviders } from '../../blocksuite'; -import { Unreachable } from '../../components/affine/affine-error-eoundary'; import { affineApis } from '../../shared/apis'; type Query = (typeof QueryKey)[keyof typeof QueryKey]; diff --git a/apps/web/src/plugins/affine/index.tsx b/apps/web/src/plugins/affine/index.tsx index ec1dd31ebd..ccd884d88b 100644 --- a/apps/web/src/plugins/affine/index.tsx +++ b/apps/web/src/plugins/affine/index.tsx @@ -1,5 +1,6 @@ import { AFFINE_STORAGE_KEY, config, prefixUrl } from '@affine/env'; import { initPage } from '@affine/env/blocksuite'; +import { PageNotFoundError } from '@affine/env/constant'; import { currentAffineUserAtom } from '@affine/workspace/affine/atom'; import { clearLoginStorage, @@ -30,7 +31,6 @@ import { z } from 'zod'; import { createAffineProviders } from '../../blocksuite'; import { createAffineDownloadProvider } from '../../blocksuite/providers/affine'; -import { PageNotFoundError } from '../../components/affine/affine-error-eoundary'; import { WorkspaceSettingDetail } from '../../components/affine/workspace-setting-detail'; import { BlockSuitePageList } from '../../components/blocksuite/block-suite-page-list'; import { PageDetailEditor } from '../../components/page-detail-editor'; diff --git a/apps/web/src/plugins/local/index.tsx b/apps/web/src/plugins/local/index.tsx index 497a12e0cd..a52b68b383 100644 --- a/apps/web/src/plugins/local/index.tsx +++ b/apps/web/src/plugins/local/index.tsx @@ -4,6 +4,7 @@ import { DEFAULT_WORKSPACE_NAME, } from '@affine/env'; import { initPage } from '@affine/env/blocksuite'; +import { PageNotFoundError } from '@affine/env/constant'; import { CRUD, saveWorkspaceToLocalStorage, @@ -18,7 +19,6 @@ import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils'; import { nanoid } from '@blocksuite/store'; import React from 'react'; -import { PageNotFoundError } from '../../components/affine/affine-error-eoundary'; import { WorkspaceSettingDetail } from '../../components/affine/workspace-setting-detail'; import { BlockSuitePageList } from '../../components/blocksuite/block-suite-page-list'; import { PageDetailEditor } from '../../components/page-detail-editor'; diff --git a/packages/component/src/components/app-sidebar/add-page-button/index.css.ts b/packages/component/src/components/app-sidebar/add-page-button/index.css.ts index c7bde86623..9f1ff48913 100644 --- a/packages/component/src/components/app-sidebar/add-page-button/index.css.ts +++ b/packages/component/src/components/app-sidebar/add-page-button/index.css.ts @@ -13,6 +13,12 @@ export const root = style({ userSelect: 'none', cursor: 'pointer', padding: '0 24px', + transition: 'background 0.2s ease', + selectors: { + '&:active': { + background: 'var(--affine-white-40)', + }, + }, }); export const icon = style({ diff --git a/packages/component/src/components/app-sidebar/app-updater-button/index.tsx b/packages/component/src/components/app-sidebar/app-updater-button/index.tsx index c16a416507..68b16f84f8 100644 --- a/packages/component/src/components/app-sidebar/app-updater-button/index.tsx +++ b/packages/component/src/components/app-sidebar/app-updater-button/index.tsx @@ -1,3 +1,5 @@ +import { config } from '@affine/env/config'; +import { Unreachable } from '@affine/env/constant'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { CloseIcon, NewIcon, ResetIcon } from '@blocksuite/icons'; import clsx from 'clsx'; @@ -46,18 +48,11 @@ export function AppUpdaterButton({ className, style }: AddPageButtonProps) { const updateAvailable = useAtomValue(updateAvailableAtom); const currentVersion = useAtomValue(currentVersionAtom); const downloadProgress = useAtomValue(downloadProgressAtom); - const onReadOrDismissChangelog = useSetAtom(changelogCheckedAtom); - - const onReadOrDismissCurrentChangelog = (visit: boolean) => { - if (visit) { - window.open( - `https://github.com/toeverything/AFFiNE/releases/tag/v${currentVersion}`, - '_blank' - ); - } + const setChangelogCheckAtom = useSetAtom(changelogCheckedAtom); + const onDismissCurrentChangelog = () => { startTransition(() => - onReadOrDismissChangelog(mapping => { + setChangelogCheckAtom(mapping => { return { ...mapping, [currentVersion!]: true, @@ -79,10 +74,19 @@ export function AppUpdaterButton({ className, style }: AddPageButtonProps) { onClick={() => { if (updateReady) { window.apis?.updater.quitAndInstall(); - } else if (updateAvailable?.allowAutoUpdate) { - // wait for download to finish - } else if (updateAvailable || currentChangelogUnread) { - onReadOrDismissCurrentChangelog(true); + } else if (updateAvailable) { + if (updateAvailable.allowAutoUpdate) { + // wait for download to finish + } else { + window.open( + `https://github.com/toeverything/AFFiNE/releases/tag/v${currentVersion}`, + '_blank' + ); + } + } else if (currentChangelogUnread) { + window.open(config.changelogUrl, '_blank'); + } else { + throw new Unreachable(); } }} > @@ -155,7 +159,7 @@ export function AppUpdaterButton({ className, style }: AddPageButtonProps) {
{ - onReadOrDismissCurrentChangelog(false); + onDismissCurrentChangelog(); e.stopPropagation(); }} > diff --git a/packages/env/src/config.ts b/packages/env/src/config.ts index f49db2c41a..97e3ac5af0 100644 --- a/packages/env/src/config.ts +++ b/packages/env/src/config.ts @@ -11,6 +11,7 @@ export const buildFlagsSchema = z.object({ enableBroadCastChannelProvider: z.boolean(), enableDebugPage: z.boolean(), enableLegacyCloud: z.boolean(), + changelogUrl: z.string(), }); export const blockSuiteFeatureFlags = z.object({ diff --git a/packages/env/src/constant.ts b/packages/env/src/constant.ts index 4f8581c0bf..9a7128f52b 100644 --- a/packages/env/src/constant.ts +++ b/packages/env/src/constant.ts @@ -1,3 +1,5 @@ +import type { Workspace } from '@blocksuite/store'; + export const AFFINE_STORAGE_KEY = 'affine-local-storage-v2'; export const DEFAULT_WORKSPACE_NAME = 'Demo Workspace'; export const UNTITLED_WORKSPACE_NAME = 'Untitled'; @@ -76,3 +78,40 @@ export const Messages = { message: string; }; }; + +export class PageNotFoundError extends TypeError { + readonly workspace: Workspace; + readonly pageId: string; + + constructor(workspace: Workspace, pageId: string) { + super(); + this.workspace = workspace; + this.pageId = pageId; + } +} + +export class WorkspaceNotFoundError extends TypeError { + readonly workspaceId: string; + + constructor(workspaceId: string) { + super(); + this.workspaceId = workspaceId; + } +} + +export class QueryParamError extends TypeError { + readonly targetKey: string; + readonly query: unknown; + + constructor(targetKey: string, query: unknown) { + super(); + this.targetKey = targetKey; + this.query = query; + } +} + +export class Unreachable extends Error { + constructor(message?: string) { + super(message); + } +}