forked from akai/readest
This commit is contained in:
@@ -365,26 +365,26 @@ pub fn setup_traffic_light_positioner<R: Runtime>(window: Window<R>) {
|
||||
app_box: *mut c_void = app_box,
|
||||
toolbar: id = cocoa::base::nil,
|
||||
super_delegate: id = current_delegate,
|
||||
(windowShouldClose:) => on_window_should_close as extern fn(&Object, Sel, id) -> BOOL,
|
||||
(windowWillClose:) => on_window_will_close as extern fn(&Object, Sel, id),
|
||||
(windowDidResize:) => on_window_did_resize::<R> as extern fn(&Object, Sel, id),
|
||||
(windowDidMove:) => on_window_did_move as extern fn(&Object, Sel, id),
|
||||
(windowDidChangeBackingProperties:) => on_window_did_change_backing_properties as extern fn(&Object, Sel, id),
|
||||
(windowDidBecomeKey:) => on_window_did_become_key as extern fn(&Object, Sel, id),
|
||||
(windowDidResignKey:) => on_window_did_resign_key as extern fn(&Object, Sel, id),
|
||||
(draggingEntered:) => on_dragging_entered as extern fn(&Object, Sel, id) -> BOOL,
|
||||
(prepareForDragOperation:) => on_prepare_for_drag_operation as extern fn(&Object, Sel, id) -> BOOL,
|
||||
(performDragOperation:) => on_perform_drag_operation as extern fn(&Object, Sel, id) -> BOOL,
|
||||
(concludeDragOperation:) => on_conclude_drag_operation as extern fn(&Object, Sel, id),
|
||||
(draggingExited:) => on_dragging_exited as extern fn(&Object, Sel, id),
|
||||
(window:willUseFullScreenPresentationOptions:) => on_window_will_use_full_screen_presentation_options as extern fn(&Object, Sel, id, NSUInteger) -> NSUInteger,
|
||||
(windowDidEnterFullScreen:) => on_window_did_enter_full_screen::<R> as extern fn(&Object, Sel, id),
|
||||
(windowWillEnterFullScreen:) => on_window_will_enter_full_screen::<R> as extern fn(&Object, Sel, id),
|
||||
(windowDidExitFullScreen:) => on_window_did_exit_full_screen::<R> as extern fn(&Object, Sel, id),
|
||||
(windowWillExitFullScreen:) => on_window_will_exit_full_screen::<R> as extern fn(&Object, Sel, id),
|
||||
(windowDidFailToEnterFullScreen:) => on_window_did_fail_to_enter_full_screen as extern fn(&Object, Sel, id),
|
||||
(effectiveAppearanceDidChange:) => on_effective_appearance_did_change as extern fn(&Object, Sel, id),
|
||||
(effectiveAppearanceDidChangedOnMainThread:) => on_effective_appearance_did_changed_on_main_thread as extern fn(&Object, Sel, id)
|
||||
(windowShouldClose:) => on_window_should_close as extern "C" fn(&Object, Sel, id) -> BOOL,
|
||||
(windowWillClose:) => on_window_will_close as extern "C" fn(&Object, Sel, id),
|
||||
(windowDidResize:) => on_window_did_resize::<R> as extern "C" fn(&Object, Sel, id),
|
||||
(windowDidMove:) => on_window_did_move as extern "C" fn(&Object, Sel, id),
|
||||
(windowDidChangeBackingProperties:) => on_window_did_change_backing_properties as extern "C" fn(&Object, Sel, id),
|
||||
(windowDidBecomeKey:) => on_window_did_become_key as extern "C" fn(&Object, Sel, id),
|
||||
(windowDidResignKey:) => on_window_did_resign_key as extern "C" fn(&Object, Sel, id),
|
||||
(draggingEntered:) => on_dragging_entered as extern "C" fn(&Object, Sel, id) -> BOOL,
|
||||
(prepareForDragOperation:) => on_prepare_for_drag_operation as extern "C" fn(&Object, Sel, id) -> BOOL,
|
||||
(performDragOperation:) => on_perform_drag_operation as extern "C" fn(&Object, Sel, id) -> BOOL,
|
||||
(concludeDragOperation:) => on_conclude_drag_operation as extern "C" fn(&Object, Sel, id),
|
||||
(draggingExited:) => on_dragging_exited as extern "C" fn(&Object, Sel, id),
|
||||
(window:willUseFullScreenPresentationOptions:) => on_window_will_use_full_screen_presentation_options as extern "C" fn(&Object, Sel, id, NSUInteger) -> NSUInteger,
|
||||
(windowDidEnterFullScreen:) => on_window_did_enter_full_screen::<R> as extern "C" fn(&Object, Sel, id),
|
||||
(windowWillEnterFullScreen:) => on_window_will_enter_full_screen::<R> as extern "C" fn(&Object, Sel, id),
|
||||
(windowDidExitFullScreen:) => on_window_did_exit_full_screen::<R> as extern "C" fn(&Object, Sel, id),
|
||||
(windowWillExitFullScreen:) => on_window_will_exit_full_screen::<R> as extern "C" fn(&Object, Sel, id),
|
||||
(windowDidFailToEnterFullScreen:) => on_window_did_fail_to_enter_full_screen as extern "C" fn(&Object, Sel, id),
|
||||
(effectiveAppearanceDidChange:) => on_effective_appearance_did_change as extern "C" fn(&Object, Sel, id),
|
||||
(effectiveAppearanceDidChangedOnMainThread:) => on_effective_appearance_did_changed_on_main_thread as extern "C" fn(&Object, Sel, id)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,6 +158,7 @@ const BooksGrid: React.FC<BooksGridProps> = ({ bookKeys, onCloseBook }) => {
|
||||
)}
|
||||
{showHeader && (
|
||||
<SectionInfo
|
||||
bookKey={bookKey}
|
||||
section={sectionLabel}
|
||||
showDoubleBorder={viewSettings.vertical && viewSettings.doubleBorder}
|
||||
isScrolled={viewSettings.scrolled}
|
||||
|
||||
@@ -40,7 +40,7 @@ const HeaderBar: React.FC<HeaderBarProps> = ({
|
||||
const { appService } = useEnv();
|
||||
const headerRef = useRef<HTMLDivElement>(null);
|
||||
const {
|
||||
isTrafficLightVisible,
|
||||
trafficLightInFullscreen,
|
||||
setTrafficLightVisibility,
|
||||
initializeTrafficLightStore,
|
||||
initializeTrafficLightListeners,
|
||||
@@ -70,12 +70,19 @@ const HeaderBar: React.FC<HeaderBarProps> = ({
|
||||
|
||||
useEffect(() => {
|
||||
if (!appService?.hasTrafficLight) return;
|
||||
if (isSideBarVisible) return;
|
||||
|
||||
setTrafficLightVisibility(isSideBarVisible);
|
||||
if (hoveredBookKey === bookKey && isTopLeft) {
|
||||
setTrafficLightVisibility(true, { x: 10, y: 20 });
|
||||
} else if (!hoveredBookKey) {
|
||||
setTrafficLightVisibility(false);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [appService, isSideBarVisible]);
|
||||
}, [appService, isSideBarVisible, hoveredBookKey]);
|
||||
|
||||
const isVisible = hoveredBookKey === bookKey || isDropdownOpen;
|
||||
const isHeaderVisible = hoveredBookKey === bookKey || isDropdownOpen;
|
||||
const trafficLightInHeader =
|
||||
appService?.hasTrafficLight && !trafficLightInFullscreen && !isSideBarVisible && isTopLeft;
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -93,7 +100,7 @@ const HeaderBar: React.FC<HeaderBarProps> = ({
|
||||
className={clsx(
|
||||
'bg-base-100 absolute left-0 right-0 top-0 z-10',
|
||||
appService?.hasRoundedWindow && 'rounded-window-top-right',
|
||||
isVisible ? 'visible' : 'hidden',
|
||||
isHeaderVisible ? 'visible' : 'hidden',
|
||||
)}
|
||||
style={{
|
||||
height: systemUIVisible ? `${Math.max(gridInsets.top, statusBarHeight)}px` : '0px',
|
||||
@@ -104,11 +111,11 @@ const HeaderBar: React.FC<HeaderBarProps> = ({
|
||||
className={clsx(
|
||||
`header-bar bg-base-100 absolute top-0 z-10 flex h-11 w-full items-center pr-4`,
|
||||
`shadow-xs transition-[opacity,margin-top] duration-300`,
|
||||
isTrafficLightVisible && isTopLeft && !isSideBarVisible ? 'pl-16' : 'pl-4',
|
||||
trafficLightInHeader ? 'pl-20' : 'pl-4',
|
||||
appService?.hasRoundedWindow && 'rounded-window-top-right',
|
||||
!isSideBarVisible && appService?.hasRoundedWindow && 'rounded-window-top-left',
|
||||
isHoveredAnim && 'hover-bar-anim',
|
||||
isVisible ? 'pointer-events-auto visible' : 'pointer-events-none opacity-0',
|
||||
isHeaderVisible ? 'pointer-events-auto visible' : 'pointer-events-none opacity-0',
|
||||
isDropdownOpen && 'header-bar-pinned',
|
||||
)}
|
||||
style={{
|
||||
@@ -148,10 +155,14 @@ const HeaderBar: React.FC<HeaderBarProps> = ({
|
||||
className='window-buttons flex h-full items-center'
|
||||
headerRef={headerRef}
|
||||
showMinimize={
|
||||
bookKeys.length == 1 && !isTrafficLightVisible && appService?.appPlatform !== 'web'
|
||||
bookKeys.length == 1 &&
|
||||
!appService?.hasTrafficLight &&
|
||||
appService?.appPlatform !== 'web'
|
||||
}
|
||||
showMaximize={
|
||||
bookKeys.length == 1 && !isTrafficLightVisible && appService?.appPlatform !== 'web'
|
||||
bookKeys.length == 1 &&
|
||||
!appService?.hasTrafficLight &&
|
||||
appService?.appPlatform !== 'web'
|
||||
}
|
||||
onClose={() => {
|
||||
setHoveredBookKey(null);
|
||||
|
||||
@@ -3,8 +3,10 @@ import React from 'react';
|
||||
import { Insets } from '@/types/misc';
|
||||
import { useEnv } from '@/context/EnvContext';
|
||||
import { useThemeStore } from '@/store/themeStore';
|
||||
import { useReaderStore } from '@/store/readerStore';
|
||||
|
||||
interface SectionInfoProps {
|
||||
bookKey: string;
|
||||
section?: string;
|
||||
showDoubleBorder: boolean;
|
||||
isScrolled: boolean;
|
||||
@@ -15,6 +17,7 @@ interface SectionInfoProps {
|
||||
}
|
||||
|
||||
const SectionInfo: React.FC<SectionInfoProps> = ({
|
||||
bookKey,
|
||||
section,
|
||||
showDoubleBorder,
|
||||
isScrolled,
|
||||
@@ -24,6 +27,7 @@ const SectionInfo: React.FC<SectionInfoProps> = ({
|
||||
gridInsets,
|
||||
}) => {
|
||||
const { appService } = useEnv();
|
||||
const { hoveredBookKey } = useReaderStore();
|
||||
const { systemUIVisible, statusBarHeight } = useThemeStore();
|
||||
const topInset = Math.max(
|
||||
gridInsets.top,
|
||||
@@ -68,6 +72,7 @@ const SectionInfo: React.FC<SectionInfoProps> = ({
|
||||
className={clsx(
|
||||
'text-neutral-content text-center font-sans text-xs font-light',
|
||||
isVertical ? '' : 'line-clamp-1',
|
||||
!isVertical && hoveredBookKey == bookKey && 'hidden',
|
||||
)}
|
||||
>
|
||||
{section || ''}
|
||||
|
||||
@@ -9,8 +9,9 @@ interface TrafficLightState {
|
||||
appService?: AppService;
|
||||
isTrafficLightVisible: boolean;
|
||||
shouldShowTrafficLight: boolean;
|
||||
trafficLightInFullscreen: boolean;
|
||||
initializeTrafficLightStore: (appService: AppService) => void;
|
||||
setTrafficLightVisibility: (visible: boolean) => void;
|
||||
setTrafficLightVisibility: (visible: boolean, position?: { x: number; y: number }) => void;
|
||||
initializeTrafficLightListeners: () => Promise<void>;
|
||||
cleanupTrafficLightListeners: () => void;
|
||||
unlistenEnterFullScreen?: () => void;
|
||||
@@ -22,6 +23,7 @@ export const useTrafficLightStore = create<TrafficLightState>((set, get) => {
|
||||
appService: undefined,
|
||||
isTrafficLightVisible: false,
|
||||
shouldShowTrafficLight: false,
|
||||
trafficLightInFullscreen: false,
|
||||
|
||||
initializeTrafficLightStore: (appService: AppService) => {
|
||||
set({
|
||||
@@ -31,15 +33,19 @@ export const useTrafficLightStore = create<TrafficLightState>((set, get) => {
|
||||
});
|
||||
},
|
||||
|
||||
setTrafficLightVisibility: async (visible: boolean) => {
|
||||
setTrafficLightVisibility: async (visible: boolean, position?: { x: number; y: number }) => {
|
||||
const { getCurrentWindow } = await import('@tauri-apps/api/window');
|
||||
const currentWindow = getCurrentWindow();
|
||||
const isFullscreen = await currentWindow.isFullscreen();
|
||||
set({ isTrafficLightVisible: !isFullscreen && visible, shouldShowTrafficLight: visible });
|
||||
set({
|
||||
isTrafficLightVisible: !isFullscreen && visible,
|
||||
shouldShowTrafficLight: visible,
|
||||
trafficLightInFullscreen: isFullscreen,
|
||||
});
|
||||
invoke('set_traffic_lights', {
|
||||
visible: visible,
|
||||
x: WINDOW_CONTROL_PAD_X,
|
||||
y: WINDOW_CONTROL_PAD_Y,
|
||||
x: position?.x ?? WINDOW_CONTROL_PAD_X,
|
||||
y: position?.y ?? WINDOW_CONTROL_PAD_Y,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -48,12 +54,12 @@ export const useTrafficLightStore = create<TrafficLightState>((set, get) => {
|
||||
const currentWindow = getCurrentWindow();
|
||||
|
||||
const unlistenEnterFullScreen = await currentWindow.listen('will-enter-fullscreen', () => {
|
||||
set({ isTrafficLightVisible: false });
|
||||
set({ isTrafficLightVisible: false, trafficLightInFullscreen: true });
|
||||
});
|
||||
|
||||
const unlistenExitFullScreen = await currentWindow.listen('will-exit-fullscreen', () => {
|
||||
const { shouldShowTrafficLight } = get();
|
||||
set({ isTrafficLightVisible: shouldShowTrafficLight });
|
||||
set({ isTrafficLightVisible: shouldShowTrafficLight, trafficLightInFullscreen: false });
|
||||
});
|
||||
|
||||
set({ unlistenEnterFullScreen, unlistenExitFullScreen });
|
||||
|
||||
Reference in New Issue
Block a user