mirror of
https://github.com/infinilabs/coco-app.git
synced 2025-12-16 11:37:47 +01:00
feat: add window opacity configuration option (#963)
* feat: add window opacity configuration option * docs: update changelog
This commit is contained in:
@@ -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: allow navigate back when cursor is at the beginning #940
|
||||||
feat: add compact mode for window #947
|
feat: add compact mode for window #947
|
||||||
feat(extension compatibility): minimum_coco_version #946
|
feat(extension compatibility): minimum_coco_version #946
|
||||||
|
feat: add window opacity configuration option #963
|
||||||
|
|
||||||
### 🐛 Bug fix
|
### 🐛 Bug fix
|
||||||
|
|
||||||
|
|||||||
@@ -310,7 +310,6 @@ export default function ChatInput({
|
|||||||
<div className={`w-full relative`}>
|
<div className={`w-full relative`}>
|
||||||
<div
|
<div
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
id="search-bar"
|
|
||||||
className={`flex items-center dark:text-[#D8D8D8] rounded-md transition-all relative overflow-hidden`}
|
className={`flex items-center dark:text-[#D8D8D8] rounded-md transition-all relative overflow-hidden`}
|
||||||
>
|
>
|
||||||
{lineCount === 1 && renderSearchIcon()}
|
{lineCount === 1 && renderSearchIcon()}
|
||||||
|
|||||||
@@ -165,7 +165,6 @@ const InputControls = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
id="filter-bar"
|
|
||||||
data-tauri-drag-region
|
data-tauri-drag-region
|
||||||
className="flex justify-between items-center pt-2"
|
className="flex justify-between items-center pt-2"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -118,20 +118,11 @@ function SearchChat({
|
|||||||
const { windowMode } = useAppearanceStore.getState();
|
const { windowMode } = useAppearanceStore.getState();
|
||||||
|
|
||||||
if (windowMode === "compact") {
|
if (windowMode === "compact") {
|
||||||
const searchBar = document.querySelector("#search-bar");
|
height = 84;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setHideMiddleBorder(height < 590);
|
||||||
|
setSuppressErrors(height < 590);
|
||||||
} else {
|
} else {
|
||||||
setHideMiddleBorder(false);
|
setHideMiddleBorder(false);
|
||||||
setSuppressErrors(false);
|
setSuppressErrors(false);
|
||||||
@@ -293,7 +284,7 @@ function SearchChat({
|
|||||||
return state.defaultStartupWindow;
|
return state.defaultStartupWindow;
|
||||||
});
|
});
|
||||||
|
|
||||||
const opacity = useAppearanceStore((state) => state.opacity);
|
const { normalOpacity, blurOpacity } = useAppearanceStore();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isTauri) {
|
if (isTauri) {
|
||||||
@@ -327,7 +318,7 @@ function SearchChat({
|
|||||||
)}
|
)}
|
||||||
style={{
|
style={{
|
||||||
backgroundSize: "auto 590px",
|
backgroundSize: "auto 590px",
|
||||||
opacity: blurred ? (opacity ?? 30) / 100 : 1,
|
opacity: blurred ? blurOpacity / 100 : normalOpacity / 100,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import { useTranslation } from "react-i18next";
|
|||||||
|
|
||||||
const Appearance = () => {
|
const Appearance = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const opacity = useAppearanceStore((state) => state.opacity);
|
const { normalOpacity, setNormalOpacity, blurOpacity, setBlurOpacity } =
|
||||||
const setOpacity = useAppearanceStore((state) => state.setOpacity);
|
useAppearanceStore();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -17,16 +17,34 @@ const Appearance = () => {
|
|||||||
|
|
||||||
<SettingsItem
|
<SettingsItem
|
||||||
icon={AppWindowMac}
|
icon={AppWindowMac}
|
||||||
title={t("settings.advanced.appearance.opacity.title")}
|
title={t("settings.advanced.appearance.normalOpacity.title")}
|
||||||
description={t("settings.advanced.appearance.opacity.description")}
|
description={t(
|
||||||
|
"settings.advanced.appearance.normalOpacity.description"
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<SettingsInput
|
<SettingsInput
|
||||||
type="number"
|
type="number"
|
||||||
min={10}
|
min={10}
|
||||||
max={100}
|
max={100}
|
||||||
value={opacity}
|
value={normalOpacity}
|
||||||
onChange={(value) => {
|
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>
|
</SettingsItem>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export default function SettingsItem({
|
|||||||
children,
|
children,
|
||||||
}: SettingsItemProps) {
|
}: SettingsItemProps) {
|
||||||
return (
|
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">
|
<div className="flex items-center space-x-3">
|
||||||
<Icon className="h-5 min-w-5 text-gray-400 dark:text-gray-500" />
|
<Icon className="h-5 min-w-5 text-gray-400 dark:text-gray-500" />
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ export const useSyncStore = () => {
|
|||||||
const setQueryTimeout = useConnectStore((state) => {
|
const setQueryTimeout = useConnectStore((state) => {
|
||||||
return state.setQuerySourceTimeout;
|
return state.setQuerySourceTimeout;
|
||||||
});
|
});
|
||||||
const setOpacity = useAppearanceStore((state) => state.setOpacity);
|
const { setNormalOpacity, setBlurOpacity } = useAppearanceStore();
|
||||||
const setSnapshotUpdate = useAppearanceStore((state) => {
|
const setSnapshotUpdate = useAppearanceStore((state) => {
|
||||||
return state.setSnapshotUpdate;
|
return state.setSnapshotUpdate;
|
||||||
});
|
});
|
||||||
@@ -197,11 +197,11 @@ export const useSyncStore = () => {
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
platformAdapter.listenEvent("change-appearance-store", ({ payload }) => {
|
platformAdapter.listenEvent("change-appearance-store", ({ payload }) => {
|
||||||
const { opacity, snapshotUpdate, windowMode } = payload;
|
const { normalOpacity, blurOpacity, snapshotUpdate, windowMode } =
|
||||||
|
payload;
|
||||||
|
|
||||||
if (isNumber(opacity)) {
|
setNormalOpacity(normalOpacity);
|
||||||
setOpacity(opacity);
|
setBlurOpacity(blurOpacity);
|
||||||
}
|
|
||||||
setSnapshotUpdate(snapshotUpdate);
|
setSnapshotUpdate(snapshotUpdate);
|
||||||
setWindowMode(windowMode);
|
setWindowMode(windowMode);
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -181,7 +181,11 @@
|
|||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"title": "Appearance Settings",
|
"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",
|
"title": "Pinned Window Dimness Setting",
|
||||||
"description": "Adjusts the opacity level of the Coco AI window when it’s 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."
|
"description": "Adjusts the opacity level of the Coco AI window when it’s 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."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,7 +181,11 @@
|
|||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"title": "外观设置",
|
"title": "外观设置",
|
||||||
"opacity": {
|
"normalOpacity": {
|
||||||
|
"title": "窗口透明度",
|
||||||
|
"description": "调整 Coco AI 窗口在使用时的透明度。范围为10%到100%,其中100%表示完全不透明,较低的值会增加透明度,使底层内容能够透过窗口显示出来。"
|
||||||
|
},
|
||||||
|
"blurOpacity": {
|
||||||
"title": "置顶时失焦透明度",
|
"title": "置顶时失焦透明度",
|
||||||
"description": "设置 Coco AI 窗口在置顶且失去焦点时的不透明度(10%–100%,100% 表示完全不透明)。"
|
"description": "设置 Coco AI 窗口在置顶且失去焦点时的不透明度(10%–100%,100% 表示完全不透明)。"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ import { persist, subscribeWithSelector } from "zustand/middleware";
|
|||||||
export type WindowMode = "default" | "compact";
|
export type WindowMode = "default" | "compact";
|
||||||
|
|
||||||
export type IAppearanceStore = {
|
export type IAppearanceStore = {
|
||||||
opacity: number;
|
normalOpacity: number;
|
||||||
setOpacity: (opacity?: number) => void;
|
setNormalOpacity: (normalOpacity: number) => void;
|
||||||
|
blurOpacity: number;
|
||||||
|
setBlurOpacity: (blurOpacity: number) => void;
|
||||||
snapshotUpdate: boolean;
|
snapshotUpdate: boolean;
|
||||||
setSnapshotUpdate: (snapshotUpdate: boolean) => void;
|
setSnapshotUpdate: (snapshotUpdate: boolean) => void;
|
||||||
windowMode: WindowMode;
|
windowMode: WindowMode;
|
||||||
@@ -16,9 +18,13 @@ export const useAppearanceStore = create<IAppearanceStore>()(
|
|||||||
subscribeWithSelector(
|
subscribeWithSelector(
|
||||||
persist(
|
persist(
|
||||||
(set) => ({
|
(set) => ({
|
||||||
opacity: 30,
|
normalOpacity: 100,
|
||||||
setOpacity: (opacity) => {
|
setNormalOpacity(normalOpacity) {
|
||||||
return set({ opacity: opacity });
|
return set({ normalOpacity });
|
||||||
|
},
|
||||||
|
blurOpacity: 30,
|
||||||
|
setBlurOpacity(blurOpacity) {
|
||||||
|
return set({ blurOpacity });
|
||||||
},
|
},
|
||||||
snapshotUpdate: false,
|
snapshotUpdate: false,
|
||||||
setSnapshotUpdate: (snapshotUpdate) => {
|
setSnapshotUpdate: (snapshotUpdate) => {
|
||||||
@@ -32,7 +38,8 @@ export const useAppearanceStore = create<IAppearanceStore>()(
|
|||||||
{
|
{
|
||||||
name: "startup-store",
|
name: "startup-store",
|
||||||
partialize: (state) => ({
|
partialize: (state) => ({
|
||||||
opacity: state.opacity,
|
normalOpacity: state.normalOpacity,
|
||||||
|
blurOpacity: state.blurOpacity,
|
||||||
snapshotUpdate: state.snapshotUpdate,
|
snapshotUpdate: state.snapshotUpdate,
|
||||||
windowMode: state.windowMode,
|
windowMode: state.windowMode,
|
||||||
}),
|
}),
|
||||||
|
|||||||
Reference in New Issue
Block a user