feat: add window opacity configuration option (#963)

* feat: add window opacity configuration option

* docs: update changelog
This commit is contained in:
ayangweb
2025-11-04 14:52:01 +08:00
committed by GitHub
parent abac92d8d5
commit b5d3ce9910
10 changed files with 60 additions and 37 deletions

View File

@@ -24,6 +24,7 @@ feat: open quick ai with modifier key + enter #939
feat: allow navigate back when cursor is at the beginning #940
feat: add compact mode for window #947
feat(extension compatibility): minimum_coco_version #946
feat: add window opacity configuration option #963
### 🐛 Bug fix

View File

@@ -310,7 +310,6 @@ export default function ChatInput({
<div className={`w-full relative`}>
<div
ref={containerRef}
id="search-bar"
className={`flex items-center dark:text-[#D8D8D8] rounded-md transition-all relative overflow-hidden`}
>
{lineCount === 1 && renderSearchIcon()}

View File

@@ -165,7 +165,6 @@ const InputControls = ({
return (
<div
id="filter-bar"
data-tauri-drag-region
className="flex justify-between items-center pt-2"
>

View File

@@ -118,20 +118,11 @@ function SearchChat({
const { windowMode } = useAppearanceStore.getState();
if (windowMode === "compact") {
const searchBar = document.querySelector("#search-bar");
const filterBar = document.querySelector("#filter-bar");
if (searchBar && filterBar) {
height = searchBar.clientHeight + filterBar.clientHeight + 16;
} else {
height = 84;
}
height = Math.min(height, 88);
//
setHideMiddleBorder(height < 590);
setSuppressErrors(height < 590);
}
} else {
setHideMiddleBorder(false);
setSuppressErrors(false);
@@ -293,7 +284,7 @@ function SearchChat({
return state.defaultStartupWindow;
});
const opacity = useAppearanceStore((state) => state.opacity);
const { normalOpacity, blurOpacity } = useAppearanceStore();
useEffect(() => {
if (isTauri) {
@@ -327,7 +318,7 @@ function SearchChat({
)}
style={{
backgroundSize: "auto 590px",
opacity: blurred ? (opacity ?? 30) / 100 : 1,
opacity: blurred ? blurOpacity / 100 : normalOpacity / 100,
}}
>
<div

View File

@@ -6,8 +6,8 @@ import { useTranslation } from "react-i18next";
const Appearance = () => {
const { t } = useTranslation();
const opacity = useAppearanceStore((state) => state.opacity);
const setOpacity = useAppearanceStore((state) => state.setOpacity);
const { normalOpacity, setNormalOpacity, blurOpacity, setBlurOpacity } =
useAppearanceStore();
return (
<>
@@ -17,16 +17,34 @@ const Appearance = () => {
<SettingsItem
icon={AppWindowMac}
title={t("settings.advanced.appearance.opacity.title")}
description={t("settings.advanced.appearance.opacity.description")}
title={t("settings.advanced.appearance.normalOpacity.title")}
description={t(
"settings.advanced.appearance.normalOpacity.description"
)}
>
<SettingsInput
type="number"
min={10}
max={100}
value={opacity}
value={normalOpacity}
onChange={(value) => {
return setOpacity(!value ? void 0 : Number(value));
return setNormalOpacity(!value ? 100 : Number(value));
}}
/>
</SettingsItem>
<SettingsItem
icon={AppWindowMac}
title={t("settings.advanced.appearance.blurOpacity.title")}
description={t("settings.advanced.appearance.blurOpacity.description")}
>
<SettingsInput
type="number"
min={10}
max={100}
value={blurOpacity}
onChange={(value) => {
return setBlurOpacity(!value ? 30 : Number(value));
}}
/>
</SettingsItem>

View File

@@ -14,7 +14,7 @@ export default function SettingsItem({
children,
}: SettingsItemProps) {
return (
<div className="flex items-center justify-between">
<div className="flex items-center justify-between gap-6">
<div className="flex items-center space-x-3">
<Icon className="h-5 min-w-5 text-gray-400 dark:text-gray-500" />
<div>

View File

@@ -82,7 +82,7 @@ export const useSyncStore = () => {
const setQueryTimeout = useConnectStore((state) => {
return state.setQuerySourceTimeout;
});
const setOpacity = useAppearanceStore((state) => state.setOpacity);
const { setNormalOpacity, setBlurOpacity } = useAppearanceStore();
const setSnapshotUpdate = useAppearanceStore((state) => {
return state.setSnapshotUpdate;
});
@@ -197,11 +197,11 @@ export const useSyncStore = () => {
}),
platformAdapter.listenEvent("change-appearance-store", ({ payload }) => {
const { opacity, snapshotUpdate, windowMode } = payload;
const { normalOpacity, blurOpacity, snapshotUpdate, windowMode } =
payload;
if (isNumber(opacity)) {
setOpacity(opacity);
}
setNormalOpacity(normalOpacity);
setBlurOpacity(blurOpacity);
setSnapshotUpdate(snapshotUpdate);
setWindowMode(windowMode);
}),

View File

@@ -181,7 +181,11 @@
},
"appearance": {
"title": "Appearance Settings",
"opacity": {
"normalOpacity": {
"title": "Active Window Opacity",
"description": "Adjust the opacity of the Coco AI window while in use. The range is from 10% to 100%, where 100% means fully opaque, and lower values increase transparency, allowing the underlying content to show through."
},
"blurOpacity": {
"title": "Pinned Window Dimness Setting",
"description": "Adjusts the opacity level of the Coco AI window when its pinned and not in focus. Set a value between 10% and 100%, where 100% means fully opaque (no dimming), and lower values increase transparency, allowing underlying content to show through."
}

View File

@@ -181,7 +181,11 @@
},
"appearance": {
"title": "外观设置",
"opacity": {
"normalOpacity": {
"title": "窗口透明度",
"description": "调整 Coco AI 窗口在使用时的透明度。范围为10%到100%其中100%表示完全不透明,较低的值会增加透明度,使底层内容能够透过窗口显示出来。"
},
"blurOpacity": {
"title": "置顶时失焦透明度",
"description": "设置 Coco AI 窗口在置顶且失去焦点时的不透明度10%100%100% 表示完全不透明)。"
}

View File

@@ -4,8 +4,10 @@ import { persist, subscribeWithSelector } from "zustand/middleware";
export type WindowMode = "default" | "compact";
export type IAppearanceStore = {
opacity: number;
setOpacity: (opacity?: number) => void;
normalOpacity: number;
setNormalOpacity: (normalOpacity: number) => void;
blurOpacity: number;
setBlurOpacity: (blurOpacity: number) => void;
snapshotUpdate: boolean;
setSnapshotUpdate: (snapshotUpdate: boolean) => void;
windowMode: WindowMode;
@@ -16,9 +18,13 @@ export const useAppearanceStore = create<IAppearanceStore>()(
subscribeWithSelector(
persist(
(set) => ({
opacity: 30,
setOpacity: (opacity) => {
return set({ opacity: opacity });
normalOpacity: 100,
setNormalOpacity(normalOpacity) {
return set({ normalOpacity });
},
blurOpacity: 30,
setBlurOpacity(blurOpacity) {
return set({ blurOpacity });
},
snapshotUpdate: false,
setSnapshotUpdate: (snapshotUpdate) => {
@@ -32,7 +38,8 @@ export const useAppearanceStore = create<IAppearanceStore>()(
{
name: "startup-store",
partialize: (state) => ({
opacity: state.opacity,
normalOpacity: state.normalOpacity,
blurOpacity: state.blurOpacity,
snapshotUpdate: state.snapshotUpdate,
windowMode: state.windowMode,
}),