-
-
+ {/* Section 1: Attachments bar */}
+
+
+ {attachments.map((name) => (
+ {
+ if (!plugin) return;
+ const files = plugin.app.vault.getMarkdownFiles();
+ const file = files.find((f) => f.basename === name);
+ if (file) {
+ openLinkedNote({
+ path: file.path,
+ filename: file.basename,
+ });
+ } else {
+ new Notice("File not found: " + name);
+ }
+ }}
+ >
+ {name}
+
+
+ ))}
+
+
+ {/* Section 2: Auto-sizing input box */}
+
+
+ {/* Section 3: Model selector and send button */}
+
+
diff --git a/src/copilot-chat/components/sections/MessageList.tsx b/src/copilot-chat/components/sections/MessageList.tsx
index ba79030..02fbd66 100644
--- a/src/copilot-chat/components/sections/MessageList.tsx
+++ b/src/copilot-chat/components/sections/MessageList.tsx
@@ -1,38 +1,87 @@
-import React, { useEffect, useRef } from "react";
-import ChatMessage, { MessageProps } from "../atoms/Message";
-import { concat, cx } from "../../../utils/style";
+import React, { useEffect, useLayoutEffect, useRef } from "react";
+import { CopilotMessage, UserMessage, MessageProps } from "../atoms/Message";
+import { concat } from "../../../utils/style";
const BASE_CLASSNAME = "copilot-chat-message-list";
interface MessageListProps {
messages: MessageProps[];
+ isLoading?: boolean;
+ onCopy?: (id?: string | number, content?: string) => void;
+ onDelete?: (id?: string | number) => void;
+ onRetry?: (id?: string | number) => void;
}
-const MessageList: React.FC
= ({ messages }) => {
+const MessageList: React.FC = ({
+ messages,
+ isLoading,
+ onCopy,
+ onDelete,
+ onRetry,
+}) => {
const endOfMessagesRef = useRef(null);
+ const containerRef = useRef(null);
- useEffect(() => {
- if (endOfMessagesRef.current) {
- endOfMessagesRef.current.scrollIntoView({ behavior: "smooth" });
+ const scrollToBottom = (behavior: ScrollBehavior = "smooth") => {
+ const container = containerRef.current;
+ if (container) {
+ container.scrollTo({ top: container.scrollHeight, behavior });
+ }
+ const endMarker = endOfMessagesRef.current;
+ if (endMarker) {
+ endMarker.scrollIntoView({ behavior });
}
+ };
+
+ useLayoutEffect(() => {
+ // After message changes, wait for layout to complete before scrolling, ensuring reliable history record switching
+ const timer = setTimeout(() => {
+ scrollToBottom("smooth");
+ }, 0);
+ return () => clearTimeout(timer);
}, [messages]);
+ // After first mount, delay scrolling once to avoid races during Obsidian startup rendering
+ useLayoutEffect(() => {
+ const timer = setTimeout(() => {
+ scrollToBottom("auto");
+ }, 30);
+ return () => clearTimeout(timer);
+ }, []);
+
+ useEffect(() => {
+ if (isLoading) {
+ scrollToBottom("smooth");
+ }
+ }, [isLoading]);
+
+ // When history finishes loading (isLoading -> false), scroll to bottom
+ useEffect(() => {
+ if (!isLoading) {
+ scrollToBottom("smooth");
+ }
+ }, [isLoading, messages]);
+
return (
-
- {messages.map((message, index) => (
-
- ))}
+
+ {messages.map((message, index) => {
+ const isCopilot = message.name === "GitHub Copilot";
+ const Comp = isCopilot ? CopilotMessage : UserMessage;
+ return (
+
+ );
+ })}
);
diff --git a/src/copilot-chat/components/sections/ModelSelector.tsx b/src/copilot-chat/components/sections/ModelSelector.tsx
index ad49db9..0e00de4 100644
--- a/src/copilot-chat/components/sections/ModelSelector.tsx
+++ b/src/copilot-chat/components/sections/ModelSelector.tsx
@@ -1,7 +1,8 @@
-import React from "react";
+import React, { useEffect, useRef, useState } from "react";
import { concat, cx } from "../../../utils/style";
import { useCopilotStore } from "../../store/store";
import { usePlugin } from "../../hooks/usePlugin";
+import { ObsidianIcon } from "../atoms/ObsidianIcon";
const BASE_CLASSNAME = "copilot-chat-model-selector";
@@ -14,31 +15,75 @@ const ModelSelector: React.FC
= ({ isAuthenticated }) => {
const { selectedModel, availableModels, setSelectedModel } =
useCopilotStore();
- const handleModelChange = (e: React.ChangeEvent) => {
- const modelValue = e.target.value;
+ const [open, setOpen] = useState(false);
+ const containerRef = useRef(null);
+
+ useEffect(() => {
+ const handleClickOutside = (e: MouseEvent) => {
+ if (
+ containerRef.current &&
+ !containerRef.current.contains(e.target as Node)
+ ) {
+ setOpen(false);
+ }
+ };
+ document.addEventListener("mousedown", handleClickOutside);
+ return () =>
+ document.removeEventListener("mousedown", handleClickOutside);
+ }, []);
+
+ const handleSelect = (value: string) => {
const selectedModelOption = availableModels.find(
- (model) => model.value === modelValue,
+ (model) => model.value === value,
);
-
if (selectedModelOption) {
setSelectedModel(plugin, selectedModelOption);
+ setOpen(false);
}
};
return (
-
-
+
+ {selectedModel.label}
+
+
+
+
+ {open && (
+
+ {availableModels.map((model) => (
+
+ ))}
+
+ )}
);
};
diff --git a/src/copilot-chat/store/slices/message.tsx b/src/copilot-chat/store/slices/message.tsx
index a2ff765..c3e440e 100644
--- a/src/copilot-chat/store/slices/message.tsx
+++ b/src/copilot-chat/store/slices/message.tsx
@@ -39,6 +39,16 @@ export interface MessageSlice {
plugin: CopilotPlugin | undefined,
model: ModelOption,
) => void;
+
+ // New actions for UI callbacks
+ deleteMessage: (
+ plugin: CopilotPlugin | undefined,
+ messageId: string,
+ ) => void;
+ retryMessage: (
+ plugin: CopilotPlugin | undefined,
+ messageId: string,
+ ) => Promise;
}
export const defaultModels: ModelOption[] = [
@@ -245,4 +255,73 @@ export const createMessageSlice: StateCreator<
});
}
},
+
+ deleteMessage: (plugin: CopilotPlugin | undefined, messageId: string) => {
+ // Remove from flat messages
+ set((state: MessageSlice) => ({
+ messages: state.messages.filter((m) => m.id !== messageId),
+ }));
+
+ // Remove from active conversation
+ const activeId = get().activeConversationId;
+ if (activeId) {
+ set((state: any) => ({
+ conversations: state.conversations.map((conv: any) =>
+ conv.id === activeId
+ ? {
+ ...conv,
+ messages: conv.messages.filter(
+ (m: MessageData) => m.id !== messageId,
+ ),
+ updatedAt: Date.now(),
+ }
+ : conv,
+ ),
+ }));
+ }
+
+ if (plugin) {
+ get().saveConversations(plugin);
+ }
+ },
+
+ retryMessage: async (
+ plugin: CopilotPlugin | undefined,
+ messageId: string,
+ ) => {
+ if (!plugin) {
+ new Notice("Plugin not initialized");
+ return;
+ }
+
+ const activeId = get().activeConversationId;
+ const conversation = activeId
+ ? get().conversations.find((c: any) => c.id === activeId)
+ : undefined;
+
+ const messages = conversation ? conversation.messages : get().messages;
+ // Find nearest previous user message before the target assistant message
+ const index = messages.findIndex(
+ (m: MessageData) => m.id === messageId,
+ );
+ let userMsg: MessageData | undefined;
+ for (let i = index - 1; i >= 0; i--) {
+ if (messages[i].role === "user") {
+ userMsg = messages[i];
+ break;
+ }
+ }
+
+ if (!userMsg) {
+ new Notice("No user prompt found to retry");
+ return;
+ }
+
+ await get().sendMessage(
+ plugin,
+ userMsg.content,
+ undefined,
+ userMsg.linkedNotes,
+ );
+ },
});
diff --git a/styles.css b/styles.css
index ec15f3f..5620378 100644
--- a/styles.css
+++ b/styles.css
@@ -220,6 +220,7 @@
.copilot-chat-message-list-container {
flex: 1;
+ overflow-x: hidden;
overflow-y: auto;
padding: 10px 0;
display: flex;
@@ -233,7 +234,7 @@
gap: 5px;
}
-.copilot-chat-message-info {
+.copilot-chat-message-actions {
display: flex;
align-items: center;
gap: 5px;
@@ -256,8 +257,69 @@
.copilot-chat-input-container {
display: flex;
flex-direction: column;
- gap: 5px;
+ gap: 1px;
width: 100%;
+ background: var(--background-modifier-form-field);
+ border: 1px solid var(--background-modifier-border);
+ border-radius: 8px;
+ padding: 5px 10px;
+ margin-top: 8px;
+}
+
+.copilot-chat-input-attachments-bar {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 5px;
+ margin-bottom: 5px;
+}
+
+.copilot-chat-input-attach-button {
+ --icon-size: 1.2em;
+ aspect-ratio: 1 / 1;
+ height: 1.6em;
+ border: 1px solid var(--background-modifier-border);
+ box-shadow: none;
+ cursor: pointer;
+}
+
+.copilot-chat-input-attachment-tag {
+ border: 1px solid var(--background-modifier-border);
+ border-radius: 4px;
+ padding: 2px 6px;
+ font-size: 0.85em;
+ transition:
+ background-color 0.15s ease,
+ color 0.15s ease,
+ border-color 0.15s ease;
+ display: flex;
+ align-items: center;
+ gap: 2px;
+ cursor: pointer;
+ user-select: none;
+}
+
+.copilot-chat-input-attachment-tag:hover {
+ background-color: var(--background-modifier-hover);
+ border-color: var(--interactive-accent);
+ color: var(--text-accent);
+}
+
+.copilot-chat-input-attachment-tag:hover svg {
+ color: var(--text-accent);
+}
+
+button.copilot-chat-input-attachment-remove {
+ height: 1.2em;
+ aspect-ratio: 1 / 1;
+ padding: 0;
+ box-shadow: none;
+ cursor: pointer;
+}
+
+button.copilot-chat-input-attachment-remove:not(:hover) {
+ background: transparent;
}
.copilot-chat-input-input-container {
@@ -269,10 +331,23 @@
.copilot-chat-input-input {
width: 100%;
+ padding: 0;
+ border: none !important;
+ background: transparent !important;
+ outline: none !important;
+ box-shadow: none !important;
+}
+
+.copilot-chat-input-actions-bar {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
}
-.copilot-chat-input-button {
- height: 60px;
+.copilot-chat-input-send-button {
+ box-shadow: none;
+ padding: 4px;
}
.copilot-chat-header-container {
@@ -280,6 +355,7 @@
display: flex;
justify-content: space-between;
align-items: center;
+ padding-bottom: 5px;
}
.copilot-chat-header-title {
@@ -288,7 +364,7 @@
.copilot-chat-header-actions {
display: flex;
- gap: 8px;
+ gap: 1px;
}
.copilot-chat-header-action-button {
@@ -297,7 +373,6 @@
color: var(--text-muted);
cursor: pointer;
padding: 4px;
- border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
@@ -312,328 +387,500 @@
* Model Selector Styles
***********************/
.copilot-chat-model-selector-container {
- display: flex;
- align-items: center;
- margin-bottom: 8px;
position: relative;
- width: 100%;
+ display: inline-block;
}
-.copilot-chat-model-selector-select {
- width: 100%;
- background-color: var(--background-secondary);
- border-radius: 4px;
- cursor: pointer;
- font-size: 0.9rem;
- border: 1px solid var(--background-modifier-border);
- color: var(--text-normal);
- transition: border-color 0.2s ease;
- appearance: auto;
- -webkit-appearance: listbox;
- padding: 0 0 0 4px;
+.copilot-chat-model-selector-button:not(.clickable-icon) {
+ width: auto;
+ height: 2em;
+ max-width: 300px;
+ padding: 0px 5px;
+ display: inline-flex;
+ align-items: center;
+ gap: 2px;
+ box-shadow: none;
}
-.copilot-chat-model-selector-select:focus {
- outline: none;
- border-color: var(--interactive-accent);
+.copilot-chat-model-selector-menu {
+ position: absolute;
+ bottom: 100%;
+ left: -5px;
+ min-width: 100%;
+ z-index: 1000;
+ background: var(--background-primary);
+ border: 1px solid var(--background-modifier-border);
+ border-radius: 4px;
+ box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 8px;
+ overflow: hidden;
}
-.copilot-chat-model-selector-select:hover {
- background-color: var(--background-modifier-hover);
+.copilot-chat-model-selector-menu-item:not(.clickable-icon) {
+ display: block;
+ width: 100%;
+ text-align: left;
+ padding: 6px 8px;
+ border-radius: 0;
+ background: transparent;
+ cursor: pointer;
+ box-shadow: none;
}
-.copilot-chat-model-selector-disabled {
- opacity: 0.6;
- cursor: not-allowed;
+.copilot-chat-model-selector-menu-item-selected:not(.clickable-icon) {
+ background: var(--background-secondary);
}
-.copilot-chat-model-selector-select option {
- background-color: var(--background-primary);
- color: var(--text-normal);
+.copilot-chat-model-selector-menu-item:not(.clickable-icon):hover {
+ background: var(--background-modifier-hover);
}
/***********************
* Conversation Selector Styles
***********************/
.copilot-chat-conversation-selector-overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: rgba(0, 0, 0, 0.4);
- z-index: 1000;
- display: flex;
- justify-content: center;
- align-items: center;
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.4);
+ z-index: 1000;
+ display: flex;
+ justify-content: center;
+ align-items: center;
}
.copilot-chat-conversation-selector-container {
- background-color: var(--background-primary);
- border-radius: 8px;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
- width: 90%;
- max-width: 500px;
- max-height: 80vh;
- display: flex;
- flex-direction: column;
- overflow: hidden;
+ background-color: var(--background-primary);
+ border-radius: 8px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ width: 90%;
+ max-width: 500px;
+ max-height: 80vh;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
}
.copilot-chat-conversation-selector-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 12px 16px;
- border-bottom: 1px solid var(--background-modifier-border);
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 12px 16px;
+ border-bottom: 1px solid var(--background-modifier-border);
}
.copilot-chat-conversation-selector-title {
- margin: 0;
- font-size: 1.2rem;
+ margin: 0;
+ font-size: 1.2rem;
}
.copilot-chat-conversation-selector-close-button {
- background: none;
- border: none;
- color: var(--text-muted);
- font-size: 1.5rem;
- cursor: pointer;
- padding: 0 0 4px 0;
- display: flex;
- align-items: center;
- justify-content: center;
- width: 24px;
- height: 24px;
+ background: none;
+ border: none;
+ color: var(--text-muted);
+ font-size: 1.5rem;
+ cursor: pointer;
+ padding: 0 0 4px 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 24px;
+ height: 24px;
}
.copilot-chat-conversation-selector-close-button:hover {
- color: var(--text-normal);
+ color: var(--text-normal);
}
.copilot-chat-conversation-selector-list {
- overflow-y: auto;
- padding: 8px;
- max-height: 60vh;
+ overflow-y: auto;
+ padding: 8px;
+ max-height: 60vh;
}
.copilot-chat-conversation-selector-item:hover {
- background-color: var(--background-modifier-hover);
+ background-color: var(--background-modifier-hover);
}
.copilot-chat-conversation-selector-item-active {
- background-color: var(--background-secondary);
- border-color: var(--interactive-accent);
+ background-color: var(--background-secondary);
+ border-color: var(--interactive-accent);
}
.copilot-chat-conversation-selector-item-title {
- font-weight: 500;
- margin-bottom: 6px;
- word-break: break-word;
+ font-weight: 500;
+ margin-bottom: 6px;
+ word-break: break-word;
}
.copilot-chat-conversation-selector-item-meta {
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-size: 0.8rem;
- color: var(--text-muted);
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ font-size: 0.8rem;
+ color: var(--text-muted);
}
.copilot-chat-conversation-selector-item-model {
- background-color: var(--background-secondary);
- padding: 2px 6px;
- border-radius: 4px;
+ background-color: var(--background-secondary);
+ padding: 2px 6px;
+ border-radius: 4px;
}
.copilot-chat-conversation-selector-empty {
- padding: 24px;
- text-align: center;
- color: var(--text-muted);
+ padding: 24px;
+ text-align: center;
+ color: var(--text-muted);
}
.copilot-chat-conversation-selector-header-actions {
- display: flex;
- align-items: center;
- gap: 8px;
+ display: flex;
+ align-items: center;
+ gap: 8px;
}
.copilot-chat-conversation-selector-delete-all-button {
- background: none;
- border: 1px solid var(--background-modifier-border);
- color: var(--text-muted);
- cursor: pointer;
- padding: 4px 8px;
- border-radius: 4px;
- font-size: 0.8rem;
- transition: all 0.2s ease;
+ background: none;
+ border: 1px solid var(--background-modifier-border);
+ color: var(--text-muted);
+ cursor: pointer;
+ padding: 4px 8px;
+ border-radius: 4px;
+ font-size: 0.8rem;
+ transition: all 0.2s ease;
}
.copilot-chat-conversation-selector-delete-all-button:hover {
- color: var(--text-accent-hover);
- border-color: var(--text-accent-hover);
- background-color: var(--background-modifier-hover);
+ color: var(--text-accent-hover);
+ border-color: var(--text-accent-hover);
+ background-color: var(--background-modifier-hover);
}
.copilot-chat-conversation-selector-item {
- padding: 12px;
- border-radius: 4px;
- margin-bottom: 8px;
- border: 1px solid transparent;
- cursor: pointer;
- transition: background-color 0.2s ease;
- display: flex;
- align-items: center;
- justify-content: space-between;
+ padding: 12px;
+ border-radius: 4px;
+ margin-bottom: 8px;
+ border: 1px solid transparent;
+ cursor: pointer;
+ transition: background-color 0.2s ease;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
}
.copilot-chat-conversation-selector-item-content {
- flex: 1;
- min-width: 0;
+ flex: 1;
+ min-width: 0;
}
.copilot-chat-conversation-selector-delete-button {
- background: none;
- border: none;
- color: var(--text-muted);
- cursor: pointer;
- padding: 6px;
- border-radius: 4px;
- display: flex;
- align-items: center;
- justify-content: center;
- opacity: 0;
- transition: all 0.2s ease;
- flex-shrink: 0;
- margin-left: 8px;
+ background: none;
+ border: none;
+ color: var(--text-muted);
+ cursor: pointer;
+ padding: 6px;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ opacity: 0;
+ transition: all 0.2s ease;
+ flex-shrink: 0;
+ margin-left: 8px;
}
-.copilot-chat-conversation-selector-item:hover .copilot-chat-conversation-selector-delete-button {
- opacity: 1;
+.copilot-chat-conversation-selector-item:hover
+ .copilot-chat-conversation-selector-delete-button {
+ opacity: 1;
}
.copilot-chat-conversation-selector-delete-button:hover {
- color: var(--text-accent-hover);
- background-color: var(--background-modifier-hover);
+ color: var(--text-accent-hover);
+ background-color: var(--background-modifier-hover);
}
/***********************
* File Suggestion Styles
***********************/
.copilot-chat-file-suggestion-container {
- background-color: var(--background-primary);
- border: 1px solid var(--background-modifier-border);
- border-radius: 4px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
- max-height: 200px;
- width: 250px;
- overflow-y: auto;
- z-index: 1000;
-}
-
-.copilot-chat-file-suggestion-list {
- padding: 5px 0;
+ position: absolute;
+ bottom: 100%;
+ background-color: var(--background-primary);
+ border: 1px solid var(--background-modifier-border);
+ border-radius: 4px;
+ box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.1);
+ max-height: 300px;
+ width: calc(100% - 20px);
+ overflow-y: auto;
+ z-index: 1000;
}
.copilot-chat-file-suggestion-item {
- padding: 5px 10px;
- cursor: pointer;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 3px;
+ padding: 8px 10px;
+ cursor: pointer;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ background-color: transparent;
+ border-top: 0.5px solid var(--background-modifier-border);
+ border-bottom: 0.5px solid var(--background-modifier-border);
}
.copilot-chat-file-suggestion-item:hover {
- background-color: var(--background-modifier-hover);
+ background-color: var(--background-modifier-hover);
}
.copilot-chat-file-suggestion-item-selected {
- background-color: var(--background-secondary);
+ background-color: var(--background-secondary);
+}
+
+.copilot-chat-file-suggestion-item-name {
+ font-weight: 500;
+ flex-shrink: 1;
+}
+
+.copilot-chat-file-suggestion-item-path {
+ font-size: 0.8em;
+ color: var(--text-muted);
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
}
.copilot-chat-file-suggestion-no-results {
- padding: 10px;
- text-align: center;
- color: var(--text-muted);
+ padding: 10px;
+ text-align: center;
+ color: var(--text-muted);
}
/***********************
* Message Styles
***********************/
-.copilot-chat-message-info {
- display: flex;
- align-items: center;
- gap: 5px;
- position: relative;
+.copilot-chat-message-container .copilot-chat-message-message {
+ word-break: break-word;
}
-.copilot-chat-message-icon {
- margin-right: 5px;
+.copilot-chat-message-container .copilot-chat-message-message p {
+ white-space: pre-wrap;
}
-.copilot-chat-message-name {
- flex-grow: 1;
+.copilot-chat-message-user {
+ position: relative;
+ margin-top: 10px;
+}
+
+.copilot-chat-message-user .copilot-chat-message-message {
+ position: relative;
+ background: var(--background-secondary);
+ border: 1px solid var(--background-modifier-border);
+ border-radius: 8px;
+ padding: 0 14px;
+ width: 90%;
+ margin-left: auto;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ overflow-x: auto;
+ overflow-y: hidden;
+ transition:
+ background-color 0.15s ease,
+ box-shadow 0.15s ease,
+ height 200ms ease;
+}
+
+.theme-dark .copilot-chat-message-user .copilot-chat-message-message {
+ background: var(--background-primary-alt, var(--background-secondary));
+}
+
+.copilot-chat-message-user.copilot-chat-message-collapsed
+ .copilot-chat-message-message {
+ overflow-x: hidden;
+}
+
+.copilot-chat-message-toggle-button.copilot-chat-message-expand-collapse-button,
+.copilot-chat-message-toggle-button.copilot-chat-message-expand-collapse-button:hover {
+ background: transparent;
+ border: none;
+ box-shadow: none;
+ transform: rotate(180deg);
+ transition: transform 0.2s ease;
+}
+
+.copilot-chat-message-expand-collapse-button.copilot-chat-message-collapsed,
+.copilot-chat-message-expand-collapse-button.copilot-chat-message-collapsed:hover {
+ transform: rotate(0deg);
+}
+
+.copilot-chat-message-collapsed .copilot-chat-message-message:after {
+ content: "";
+ position: absolute;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ height: 2.2em;
+ background: linear-gradient(
+ to bottom,
+ rgba(0, 0, 0, 0),
+ var(--background-secondary)
+ );
+ pointer-events: none;
+}
+
+/* Collapsed message hover highlight + pointer */
+.copilot-chat-message-collapsed .copilot-chat-message-message {
+ cursor: pointer;
+}
+
+.copilot-chat-message-collapsed .copilot-chat-message-message:hover {
+ background: var(--background-modifier-hover);
+}
+
+.theme-dark
+ .copilot-chat-message-collapsed
+ .copilot-chat-message-message:after {
+ background: linear-gradient(
+ to bottom,
+ rgba(0, 0, 0, 0),
+ var(--background-primary-alt, var(--background-secondary))
+ );
+}
+
+/* Toggle button (collapse/expand arrow) */
+.copilot-chat-message-toggle-button {
+ position: absolute;
+ top: 4px;
+ right: 4px;
+ background: none;
+ border: none;
+ color: var(--text-muted);
+ padding: 2px;
+ border-radius: 4px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition:
+ background-color 0.15s ease,
+ color 0.15s ease,
+ opacity 0.15s ease;
+ opacity: 0.7;
+}
+
+.copilot-chat-message-toggle-button:hover {
+ background: var(--background-modifier-hover);
+ color: var(--text-normal);
+ opacity: 1;
+}
+
+/* Actions row at bottom */
+.copilot-chat-message-actions {
+ margin-top: 4px;
+ display: flex;
+ gap: 6px;
+ flex-direction: row;
+ justify-content: flex-start;
+}
+
+.copilot-chat-message-user .copilot-chat-message-actions {
+ justify-content: flex-end;
+}
+
+.copilot-chat-message-container
+ .copilot-chat-message-actions
+ button:not(.clickable-icon) {
+ background: none;
+ border: none;
+ box-shadow: none;
+ color: var(--text-muted);
+ padding: 4px;
+ border-radius: 4px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.copilot-chat-message-container
+ .copilot-chat-message-actions
+ button:not(.clickable-icon):hover {
+ color: var(--text-normal);
+ background: var(--background-modifier-hover);
}
-.copilot-chat-message-copy-button {
- background: none;
- border: none;
- color: var(--text-muted);
- cursor: pointer;
- padding: 4px;
- border-radius: 4px;
- display: flex;
- align-items: center;
- justify-content: center;
- opacity: 0.6;
- transition: opacity 0.2s ease, background-color 0.2s ease;
- margin-left: auto;
+.copilot-chat-message-copy-button[title="Copied!"] {
+ color: var(--text-accent);
+ background: var(
+ --background-modifier-success-hover,
+ var(--background-modifier-hover)
+ );
+}
+
+.copilot-chat-message-actions {
+ display: flex;
+ align-items: center;
+ gap: 5px;
+ position: relative;
+}
+
+.copilot-chat-message-icon {
+ margin-right: 5px;
+}
+
+.copilot-chat-message-name {
+ flex-grow: 1;
}
.copilot-chat-message-copy-button:hover {
- opacity: 1;
- background-color: var(--background-modifier-hover);
- color: var(--text-normal);
+ opacity: 1;
+ background-color: var(--background-modifier-hover);
+ color: var(--text-normal);
}
.copilot-chat-message-copy-button[title="Copied!"] {
- opacity: 1;
- color: var(--text-accent);
- background-color: var(--background-modifier-success-hover);
+ opacity: 1;
+ color: var(--text-accent);
+ background-color: var(--background-modifier-success-hover);
}
/***********************
* Linked Notes Styles
***********************/
-.copilot-chat-message-linked-notes {
- margin-top: 10px;
- padding-top: 5px;
- border-top: 1px solid var(--background-modifier-border);
-}
-
-.copilot-chat-message-linked-notes-title {
- font-weight: 600;
- margin-bottom: 5px;
- color: var(--text-muted);
- font-size: 0.9em;
+.copilot-chat-message-linked-notes-list {
+ margin-top: 4px;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: flex-start;
+ gap: 5px;
}
-.copilot-chat-message-linked-notes-list {
- display: flex;
- flex-wrap: wrap;
- gap: 5px;
+.copilot-chat-message-user .copilot-chat-message-linked-notes-list {
+ margin-left: auto;
+ justify-content: flex-end;
}
.copilot-chat-message-linked-note {
- background-color: var(--background-secondary);
- border: 1px solid var(--background-modifier-border);
- border-radius: 4px;
- padding: 2px 6px;
- font-size: 0.85em;
+ color: var(--text-accent);
+ background-color: var(--background-secondary);
+ border: 1px solid var(--background-modifier-border);
+ border-radius: 4px;
+ padding: 2px 6px;
+ font-size: 0.85em;
+ cursor: pointer;
+ transition:
+ background-color 0.15s ease,
+ color 0.15s ease,
+ border-color 0.15s ease;
}
-.copilot-chat-message-linked-note-filename {
- color: var(--text-accent);
+.copilot-chat-message-linked-note.tag:hover {
+ background-color: var(--background-modifier-hover);
+ border-color: var(--interactive-accent);
}
/***********************
@@ -771,4 +1018,4 @@
.copilot-chat-message table th {
background-color: var(--background-secondary);
-}
\ No newline at end of file
+}