mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-15 05:37:32 +00:00
fix(electron): always show traffic light for mac (#7773)
fix AF-1209, fix PD-1550
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
import { apis } from '@affine/electron-api';
|
|
||||||
import { ArrowRightSmallIcon } from '@blocksuite/icons/rc';
|
import { ArrowRightSmallIcon } from '@blocksuite/icons/rc';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import type { Location } from 'react-router-dom';
|
import type { Location } from 'react-router-dom';
|
||||||
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
|
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
|
||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
@@ -123,15 +122,6 @@ export const OnboardingPage = ({
|
|||||||
const isMacosDesktop = environment.isDesktop && environment.isMacOs;
|
const isMacosDesktop = environment.isDesktop && environment.isMacOs;
|
||||||
const isWindowsDesktop = environment.isDesktop && environment.isWindows;
|
const isWindowsDesktop = environment.isDesktop && environment.isWindows;
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (environment.isDesktop) {
|
|
||||||
// to hide macOS window control buttons
|
|
||||||
apis?.ui.handleSidebarVisibilityChange(false).catch(err => {
|
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (!questions) {
|
if (!questions) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ import {
|
|||||||
} from '@affine/core/modules/explorer';
|
} from '@affine/core/modules/explorer';
|
||||||
import { ExplorerTags } from '@affine/core/modules/explorer/views/sections/tags';
|
import { ExplorerTags } from '@affine/core/modules/explorer/views/sections/tags';
|
||||||
import { CMDKQuickSearchService } from '@affine/core/modules/quicksearch/services/cmdk';
|
import { CMDKQuickSearchService } from '@affine/core/modules/quicksearch/services/cmdk';
|
||||||
import { apis, events } from '@affine/electron-api';
|
import { events } from '@affine/electron-api';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { AllDocsIcon, SettingsIcon } from '@blocksuite/icons/rc';
|
import { AllDocsIcon, SettingsIcon } from '@blocksuite/icons/rc';
|
||||||
import type { Doc } from '@blocksuite/store';
|
import type { Doc } from '@blocksuite/store';
|
||||||
import type { Workspace } from '@toeverything/infra';
|
import type { Workspace } from '@toeverything/infra';
|
||||||
import { useLiveData, useService, WorkspaceService } from '@toeverything/infra';
|
import { useLiveData, useService, WorkspaceService } from '@toeverything/infra';
|
||||||
import { useAtomValue, useSetAtom } from 'jotai';
|
import { useSetAtom } from 'jotai';
|
||||||
import type { MouseEvent, ReactElement } from 'react';
|
import type { MouseEvent, ReactElement } from 'react';
|
||||||
import { useCallback, useEffect } from 'react';
|
import { useCallback, useEffect } from 'react';
|
||||||
|
|
||||||
@@ -25,7 +25,6 @@ import {
|
|||||||
AddPageButton,
|
AddPageButton,
|
||||||
AppDownloadButton,
|
AppDownloadButton,
|
||||||
AppSidebar,
|
AppSidebar,
|
||||||
appSidebarOpenAtom,
|
|
||||||
CategoryDivider,
|
CategoryDivider,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
MenuLinkItem,
|
MenuLinkItem,
|
||||||
@@ -111,15 +110,6 @@ export const RootAppSidebar = (): ReactElement => {
|
|||||||
track.$.navigationPanel.$.openSettings();
|
track.$.navigationPanel.$.openSettings();
|
||||||
}, [setOpenSettingModalAtom]);
|
}, [setOpenSettingModalAtom]);
|
||||||
|
|
||||||
const sidebarOpen = useAtomValue(appSidebarOpenAtom);
|
|
||||||
useEffect(() => {
|
|
||||||
if (environment.isDesktop) {
|
|
||||||
apis?.ui.handleSidebarVisibilityChange(sidebarOpen).catch(err => {
|
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [sidebarOpen]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppSidebar
|
<AppSidebar
|
||||||
clientBorder={appSettings.clientBorder}
|
clientBorder={appSettings.clientBorder}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import {
|
|||||||
useDropTarget,
|
useDropTarget,
|
||||||
} from '@affine/component';
|
} from '@affine/component';
|
||||||
import {
|
import {
|
||||||
appSidebarFloatingAtom,
|
|
||||||
appSidebarOpenAtom,
|
appSidebarOpenAtom,
|
||||||
appSidebarResizingAtom,
|
appSidebarResizingAtom,
|
||||||
} from '@affine/core/components/app-sidebar';
|
} from '@affine/core/components/app-sidebar';
|
||||||
@@ -233,7 +232,6 @@ export const AppTabsHeader = ({
|
|||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
const sidebarWidth = useAtomValue(appSidebarWidthAtom);
|
const sidebarWidth = useAtomValue(appSidebarWidthAtom);
|
||||||
const sidebarOpen = useAtomValue(appSidebarOpenAtom);
|
const sidebarOpen = useAtomValue(appSidebarOpenAtom);
|
||||||
const sidebarFloating = useAtomValue(appSidebarFloatingAtom);
|
|
||||||
const sidebarResizing = useAtomValue(appSidebarResizingAtom);
|
const sidebarResizing = useAtomValue(appSidebarResizingAtom);
|
||||||
const isMacosDesktop = environment.isDesktop && environment.isMacOs;
|
const isMacosDesktop = environment.isDesktop && environment.isMacOs;
|
||||||
const fullScreen = useIsFullScreen();
|
const fullScreen = useIsFullScreen();
|
||||||
@@ -314,6 +312,8 @@ export const AppTabsHeader = ({
|
|||||||
[onDrop]
|
[onDrop]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const trafficLightOffset = isMacosDesktop && !fullScreen ? 70 : 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={clsx(styles.root, className)}
|
className={clsx(styles.root, className)}
|
||||||
@@ -324,13 +324,10 @@ export const AppTabsHeader = ({
|
|||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
transition: sidebarResizing ? 'none' : undefined,
|
transition: sidebarResizing ? 'none' : undefined,
|
||||||
paddingLeft:
|
paddingLeft: 12 + trafficLightOffset,
|
||||||
isMacosDesktop && sidebarOpen && !sidebarFloating && !fullScreen
|
width: sidebarOpen ? sidebarWidth : 120 + trafficLightOffset,
|
||||||
? 90
|
|
||||||
: 16,
|
|
||||||
width: sidebarOpen && !sidebarFloating ? sidebarWidth : 130,
|
|
||||||
// minus 16 to account for the padding on the right side of the header (for box shadow)
|
// minus 16 to account for the padding on the right side of the header (for box shadow)
|
||||||
marginRight: sidebarOpen && !sidebarFloating ? -16 : 0,
|
marginRight: sidebarOpen ? -16 : 0,
|
||||||
}}
|
}}
|
||||||
className={styles.headerLeft}
|
className={styles.headerLeft}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -23,11 +23,12 @@ export const headerLeft = style({
|
|||||||
flexFlow: 'row',
|
flexFlow: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
padding: '0 16px',
|
paddingRight: 12,
|
||||||
|
gap: 10,
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
selectors: {
|
selectors: {
|
||||||
[`${root}[data-mode="app"] &`]: {
|
[`${root}[data-mode="app"] &`]: {
|
||||||
transition: 'width 0.3s, padding 0.3s',
|
transition: 'all 0.3s',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ export const NavigationButtons = () => {
|
|||||||
data-testid="app-navigation-button-back"
|
data-testid="app-navigation-button-back"
|
||||||
disabled={!backable}
|
disabled={!backable}
|
||||||
onClick={handleBack}
|
onClick={handleBack}
|
||||||
|
size={24}
|
||||||
>
|
>
|
||||||
<ArrowLeftSmallIcon />
|
<ArrowLeftSmallIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
@@ -85,6 +86,7 @@ export const NavigationButtons = () => {
|
|||||||
data-testid="app-navigation-button-forward"
|
data-testid="app-navigation-button-forward"
|
||||||
disabled={!forwardable}
|
disabled={!forwardable}
|
||||||
onClick={handleForward}
|
onClick={handleForward}
|
||||||
|
size={24}
|
||||||
>
|
>
|
||||||
<ArrowRightSmallIcon />
|
<ArrowRightSmallIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { app, nativeTheme, shell } from 'electron';
|
import { app, nativeTheme, shell } from 'electron';
|
||||||
import { getLinkPreview } from 'link-preview-js';
|
import { getLinkPreview } from 'link-preview-js';
|
||||||
|
|
||||||
import { isMacOS } from '../../shared/utils';
|
|
||||||
import { persistentConfig } from '../config-storage/persist';
|
import { persistentConfig } from '../config-storage/persist';
|
||||||
import { logger } from '../logger';
|
import { logger } from '../logger';
|
||||||
import type { NamespaceHandlers } from '../type';
|
import type { NamespaceHandlers } from '../type';
|
||||||
@@ -43,12 +42,6 @@ export const uiHandlers = {
|
|||||||
handleThemeChange: async (_, theme: (typeof nativeTheme)['themeSource']) => {
|
handleThemeChange: async (_, theme: (typeof nativeTheme)['themeSource']) => {
|
||||||
nativeTheme.themeSource = theme;
|
nativeTheme.themeSource = theme;
|
||||||
},
|
},
|
||||||
handleSidebarVisibilityChange: async (_, visible: boolean) => {
|
|
||||||
if (isMacOS()) {
|
|
||||||
const window = await getMainWindow();
|
|
||||||
window?.setWindowButtonVisibility(visible);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleMinimizeApp: async () => {
|
handleMinimizeApp: async () => {
|
||||||
const window = await getMainWindow();
|
const window = await getMainWindow();
|
||||||
window?.minimize();
|
window?.minimize();
|
||||||
@@ -68,8 +61,8 @@ export const uiHandlers = {
|
|||||||
window.maximize();
|
window.maximize();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleWindowResize: async () => {
|
handleWindowResize: async e => {
|
||||||
await handleWebContentsResize();
|
await handleWebContentsResize(e.sender);
|
||||||
},
|
},
|
||||||
handleCloseApp: async () => {
|
handleCloseApp: async () => {
|
||||||
app.quit();
|
app.quit();
|
||||||
|
|||||||
@@ -658,6 +658,8 @@ export class WebContentViewsManager {
|
|||||||
sorted.forEach(({ view }, idx) => {
|
sorted.forEach(({ view }, idx) => {
|
||||||
this.mainWindow?.contentView.addChildView(view, idx);
|
this.mainWindow?.contentView.addChildView(view, idx);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
handleWebContentsResize(activeView?.webContents).catch(logger.error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -894,12 +896,12 @@ export async function getCookie(url?: string, name?: string) {
|
|||||||
|
|
||||||
// there is no proper way to listen to webContents resize event
|
// there is no proper way to listen to webContents resize event
|
||||||
// we will rely on window.resize event in renderer instead
|
// we will rely on window.resize event in renderer instead
|
||||||
export async function handleWebContentsResize() {
|
export async function handleWebContentsResize(webContents?: WebContents) {
|
||||||
// right now when window is resized, we will relocate the traffic light positions
|
// right now when window is resized, we will relocate the traffic light positions
|
||||||
if (isMacOS()) {
|
if (isMacOS()) {
|
||||||
const window = await getMainWindow();
|
const window = await getMainWindow();
|
||||||
const factor = window?.webContents.getZoomFactor() || 1;
|
const factor = webContents?.getZoomFactor() || 1;
|
||||||
window?.setWindowButtonPosition({ x: 20 * factor, y: 24 * factor - 6 });
|
window?.setWindowButtonPosition({ x: 16 * factor, y: 24 * factor - 6 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user