chore(react/collections): add date navigation buttons to calendar touchbar

This commit is contained in:
Elian Doran 2025-09-06 15:20:22 +03:00
parent 1917c04baf
commit 5966b9ff23
No known key found for this signature in database
3 changed files with 65 additions and 6 deletions

View File

@ -597,7 +597,8 @@
"year": "Year", "year": "Year",
"year_previous": "Previous year", "year_previous": "Previous year",
"year_next": "Next year", "year_next": "Next year",
"list": "List" "list": "List",
"today": "Today"
}, },
"close_pane_button": { "close_pane_button": {
"close_this_pane": "Close this pane" "close_this_pane": "Close this pane"

View File

@ -19,7 +19,7 @@ import FNote from "../../../entities/fnote";
import Button, { ButtonGroup } from "../../react/Button"; import Button, { ButtonGroup } from "../../react/Button";
import ActionButton from "../../react/ActionButton"; import ActionButton from "../../react/ActionButton";
import { RefObject } from "preact"; import { RefObject } from "preact";
import TouchBar, { TouchBarLabel, TouchBarSegmentedControl } from "../../react/TouchBar"; import TouchBar, { TouchBarButton, TouchBarLabel, TouchBarSegmentedControl } from "../../react/TouchBar";
interface CalendarViewData { interface CalendarViewData {
@ -164,7 +164,7 @@ function CalendarHeader({ calendarRef }: { calendarRef: RefObject<FullCalendar>
/> />
))} ))}
</ButtonGroup> </ButtonGroup>
<Button text="today" onClick={() => calendarRef.current?.today()} /> <Button text={t("calendar.today").toLocaleLowerCase()} onClick={() => calendarRef.current?.today()} />
<ButtonGroup> <ButtonGroup>
<ActionButton icon="bx bx-chevron-left" text={currentViewData?.previousText ?? ""} frame onClick={() => calendarRef.current?.prev()} /> <ActionButton icon="bx bx-chevron-left" text={currentViewData?.previousText ?? ""} frame onClick={() => calendarRef.current?.prev()} />
<ActionButton icon="bx bx-chevron-right" text={currentViewData?.nextText ?? ""} frame onClick={() => calendarRef.current?.next()} /> <ActionButton icon="bx bx-chevron-right" text={currentViewData?.nextText ?? ""} frame onClick={() => calendarRef.current?.next()} />
@ -336,6 +336,23 @@ function CalendarTouchBar({ calendarRef }: { calendarRef: RefObject<FullCalendar
selectedIndex={CALENDAR_VIEWS.findIndex(v => v.type === viewType) ?? 0} selectedIndex={CALENDAR_VIEWS.findIndex(v => v.type === viewType) ?? 0}
onChange={(selectedIndex) => calendarRef.current?.changeView(CALENDAR_VIEWS[selectedIndex].type)} onChange={(selectedIndex) => calendarRef.current?.changeView(CALENDAR_VIEWS[selectedIndex].type)}
/> />
<TouchBarButton
label={t("calendar.today")}
click={() => calendarRef.current?.today()}
/>
<TouchBarSegmentedControl
mode="buttons"
segments={[
{
icon: "NSImageNameTouchBarGoBackTemplate",
onClick: () => calendarRef.current?.prev()
},
{
icon: "NSImageNameTouchBarGoForwardTemplate",
onClick: () => calendarRef.current?.next()
}
]}
/>
</TouchBar> </TouchBar>
); );
} }

View File

@ -29,7 +29,9 @@ interface ButtonProps {
interface SegmentedControlProps { interface SegmentedControlProps {
mode: "single" | "buttons"; mode: "single" | "buttons";
segments: { segments: {
label: string; label?: string;
icon?: string;
onClick?: () => void;
}[]; }[];
selectedIndex?: number; selectedIndex?: number;
onChange?: (selectedIndex: number, isSelected: boolean) => void; onChange?: (selectedIndex: number, isSelected: boolean) => void;
@ -38,6 +40,7 @@ interface SegmentedControlProps {
interface TouchBarContextApi { interface TouchBarContextApi {
addItem(item: TouchBarItem): void; addItem(item: TouchBarItem): void;
TouchBar: typeof Electron.TouchBar; TouchBar: typeof Electron.TouchBar;
nativeImage: typeof Electron.nativeImage;
} }
const TouchBarContext = createContext<TouchBarContextApi | null>(null); const TouchBarContext = createContext<TouchBarContextApi | null>(null);
@ -50,6 +53,7 @@ export default function TouchBar({ children }: TouchBarProps) {
const api: TouchBarContextApi = { const api: TouchBarContextApi = {
TouchBar: remote.TouchBar, TouchBar: remote.TouchBar,
nativeImage: remote.nativeImage,
addItem: (item) => { addItem: (item) => {
items.push(item); items.push(item);
} }
@ -133,14 +137,51 @@ export function TouchBarButton({ label, click, enabled }: ButtonProps) {
export function TouchBarSegmentedControl({ mode, segments, selectedIndex, onChange }: SegmentedControlProps) { export function TouchBarSegmentedControl({ mode, segments, selectedIndex, onChange }: SegmentedControlProps) {
const api = useContext(TouchBarContext); const api = useContext(TouchBarContext);
const processedSegments = segments.map((segment) => {
if (segment.icon) {
if (!api) return undefined;
return {
...segment,
icon: buildIcon(api?.nativeImage, segment.icon)
}
} else {
return segment;
}
});
if (api) { if (api) {
const item = new api.TouchBar.TouchBarSegmentedControl({ const item = new api.TouchBar.TouchBarSegmentedControl({
mode, segments, selectedIndex, mode, selectedIndex,
change: onChange segments: processedSegments,
change: (selectedIndex, isSelected) => {
if (segments[selectedIndex].onClick) {
segments[selectedIndex].onClick();
} else if (onChange) {
onChange(selectedIndex, isSelected);
}
}
}); });
api.addItem(item); api.addItem(item);
} }
return <></>; return <></>;
} }
function buildIcon(nativeImage: typeof Electron.nativeImage, name: string) {
const sourceImage = nativeImage.createFromNamedImage(name, [-1, 0, 1]);
const { width, height } = sourceImage.getSize();
const newImage = nativeImage.createEmpty();
newImage.addRepresentation({
scaleFactor: 1,
width: width / 2,
height: height / 2,
buffer: sourceImage.resize({ height: height / 2 }).toBitmap()
});
newImage.addRepresentation({
scaleFactor: 2,
width: width,
height: height,
buffer: sourceImage.toBitmap()
});
return newImage;
}