Add feedback button and dialog prominently dispayed in message list

This commit is contained in:
Kevin van Dijk
2026-03-09 23:36:05 +01:00
parent e8d0b12df2
commit 824f174f31
19 changed files with 216 additions and 0 deletions
@@ -0,0 +1,61 @@
import { Component, JSX } from "solid-js"
import { Dialog } from "@kilocode/kilo-ui/dialog"
import { Button } from "@kilocode/kilo-ui/button"
import { Icon } from "@kilocode/kilo-ui/icon"
import { useDialog } from "@kilocode/kilo-ui/context/dialog"
import { useVSCode } from "../../context/vscode"
import { useLanguage } from "../../context/language"
const GITHUB_ISSUES_URL = "https://github.com/Kilo-Org/kilocode/issues/new/choose"
const DISCORD_URL = "https://discord.gg/kilocode"
const SUPPORT_URL = "https://kilo.ai/support"
const KiloLogo = (): JSX.Element => {
const iconsBaseUri = (window as { ICONS_BASE_URI?: string }).ICONS_BASE_URI || ""
const isLight =
document.body.classList.contains("vscode-light") || document.body.classList.contains("vscode-high-contrast-light")
const iconFile = isLight ? "kilo-light.svg" : "kilo-dark.svg"
return (
<div class="feedback-dialog-logo">
<img src={`${iconsBaseUri}/${iconFile}`} alt="Kilo Code" />
</div>
)
}
export const FeedbackDialog: Component = () => {
const language = useLanguage()
const dialog = useDialog()
const vscode = useVSCode()
const open = (url: string) => {
vscode.postMessage({ type: "openExternal", url })
dialog.close()
}
return (
<Dialog title="" fit>
<div class="feedback-dialog">
<KiloLogo />
<p class="feedback-dialog-message">{language.t("feedback.dialog.message")}</p>
<div class="feedback-dialog-actions">
<Button variant="primary" size="large" data-full-width="true" onClick={() => open(GITHUB_ISSUES_URL)}>
<Icon name="github" size="small" />
{language.t("feedback.dialog.github")}
</Button>
<Button variant="secondary" size="large" data-full-width="true" onClick={() => open(DISCORD_URL)}>
<Icon name="discord" size="small" />
{language.t("feedback.dialog.discord")}
</Button>
<Button variant="secondary" size="large" data-full-width="true" onClick={() => open(SUPPORT_URL)}>
<Icon name="help" size="small" />
{language.t("feedback.dialog.support")}
</Button>
</div>
<Button variant="ghost" size="small" onClick={() => dialog.close()}>
{language.t("common.cancel")}
</Button>
</div>
</Dialog>
)
}
@@ -18,6 +18,7 @@ import { useServer } from "../../context/server"
import { useLanguage } from "../../context/language"
import { formatRelativeDate } from "../../utils/date"
import { CloudImportDialog } from "./CloudImportDialog"
import { FeedbackDialog } from "./FeedbackDialog"
import { VscodeSessionTurn } from "./VscodeSessionTurn"
import { WorkingIndicator } from "../shared/WorkingIndicator"
@@ -122,6 +123,10 @@ export const MessageList: Component<MessageListProps> = (props) => {
>
{language.t("session.cloud.import")}
</Button>
<button class="feedback-button" onClick={() => dialog.show(() => <FeedbackDialog />)}>
<Icon name="bubble-5" size="small" />
{language.t("feedback.button")}
</button>
</div>
</Show>
<Show when={!session.loading()}>
@@ -733,6 +733,11 @@ export const dict = {
"session.empty": "لا توجد جلسات بعد. انقر + لبدء محادثة جديدة.",
"session.cloud.repoOnly": "هذا المستودع فقط",
"session.cloud.import": "استيراد من السحابة",
"feedback.button": "التغذية الراجعة والدعم",
"feedback.dialog.message": "يسعدنا سماع تعليقاتك أو مساعدتك في حل أي مشكلات تواجهها.",
"feedback.dialog.github": "الإبلاغ عن مشكلة على GitHub",
"feedback.dialog.discord": "الانضمام إلى مجتمع Discord",
"feedback.dialog.support": "دعم العملاء",
"session.cloud.import.title": "استيراد من السحابة",
"session.cloud.import.placeholder": "معرّف الجلسة أو الرابط أو أمر kilo import",
"session.cloud.import.button": "استيراد",
@@ -740,6 +740,12 @@ export const dict = {
"session.empty": "Nenhuma sessão ainda. Clique + para iniciar uma nova conversa.",
"session.cloud.repoOnly": "Apenas este repositório",
"session.cloud.import": "Importar da nuvem",
"feedback.button": "Feedback e suporte",
"feedback.dialog.message":
"Adoraríamos ouvir seu feedback ou ajudar com quaisquer problemas que você esteja enfrentando.",
"feedback.dialog.github": "Reportar um problema no GitHub",
"feedback.dialog.discord": "Entrar na nossa comunidade Discord",
"feedback.dialog.support": "Suporte ao cliente",
"session.cloud.import.title": "Importar da nuvem",
"session.cloud.import.placeholder": "ID da sessão, URL ou comando kilo import",
"session.cloud.import.button": "Importar",
@@ -744,6 +744,11 @@ export const dict = {
"session.empty": "Još nema sesija. Kliknite + za početak novog razgovora.",
"session.cloud.repoOnly": "Samo ovaj repozitorij",
"session.cloud.import": "Uvezi iz oblaka",
"feedback.button": "Povratne informacije i podrška",
"feedback.dialog.message": "Voljeli bismo čuti vaše povratne informacije ili pomoći s problemima koje doživljavate.",
"feedback.dialog.github": "Prijavite problem na GitHubu",
"feedback.dialog.discord": "Pridružite se našoj Discord zajednici",
"feedback.dialog.support": "Korisnička podrška",
"session.cloud.import.title": "Uvezi iz oblaka",
"session.cloud.import.placeholder": "ID sesije, URL ili kilo import naredba",
"session.cloud.import.button": "Uvezi",
@@ -739,6 +739,11 @@ export const dict = {
"session.empty": "Ingen sessioner endnu. Klik + for at starte en ny samtale.",
"session.cloud.repoOnly": "Kun dette repository",
"session.cloud.import": "Importér fra skyen",
"feedback.button": "Feedback & support",
"feedback.dialog.message": "Vi vil gerne høre din feedback eller hjælpe med eventuelle problemer, du oplever.",
"feedback.dialog.github": "Rapportér et problem på GitHub",
"feedback.dialog.discord": "Deltag i vores Discord-fællesskab",
"feedback.dialog.support": "Kundesupport",
"session.cloud.import.title": "Importér fra skyen",
"session.cloud.import.placeholder": "Sessions-ID, URL eller kilo import-kommando",
"session.cloud.import.button": "Importér",
@@ -749,6 +749,11 @@ export const dict = {
"session.empty": "Noch keine Sitzungen. Klicke + um eine neue Unterhaltung zu starten.",
"session.cloud.repoOnly": "Nur dieses Repository",
"session.cloud.import": "Aus der Cloud importieren",
"feedback.button": "Feedback & Support",
"feedback.dialog.message": "Wir würden uns freuen, Ihr Feedback zu hören oder Ihnen bei Problemen zu helfen.",
"feedback.dialog.github": "Ein Problem auf GitHub melden",
"feedback.dialog.discord": "Unserer Discord-Community beitreten",
"feedback.dialog.support": "Kundensupport",
"session.cloud.import.title": "Aus der Cloud importieren",
"session.cloud.import.placeholder": "Sitzungs-ID, URL oder kilo import-Befehl",
"session.cloud.import.button": "Importieren",
@@ -744,6 +744,11 @@ export const dict = {
"session.empty": "No sessions yet. Click + to start a new conversation.",
"session.cloud.repoOnly": "Only this repository",
"session.cloud.import": "Import from cloud",
"feedback.button": "Feedback & Support",
"feedback.dialog.message": "We'd love to hear your feedback or help with any issues you're experiencing.",
"feedback.dialog.github": "Report an issue on GitHub",
"feedback.dialog.discord": "Join our Discord community",
"feedback.dialog.support": "Customer Support",
"session.cloud.import.title": "Import from cloud",
"session.cloud.import.placeholder": "Session ID, URL, or kilo import command",
"session.cloud.import.button": "Import",
@@ -745,6 +745,12 @@ export const dict = {
"session.empty": "Aún no hay sesiones. Haz clic en + para iniciar una nueva conversación.",
"session.cloud.repoOnly": "Solo este repositorio",
"session.cloud.import": "Importar desde la nube",
"feedback.button": "Comentarios y soporte",
"feedback.dialog.message":
"Nos encantaría escuchar tus comentarios o ayudarte con cualquier problema que estés experimentando.",
"feedback.dialog.github": "Reportar un problema en GitHub",
"feedback.dialog.discord": "Unirse a nuestra comunidad de Discord",
"feedback.dialog.support": "Atención al cliente",
"session.cloud.import.title": "Importar desde la nube",
"session.cloud.import.placeholder": "ID de sesión, URL o comando kilo import",
"session.cloud.import.button": "Importar",
@@ -750,6 +750,12 @@ export const dict = {
"session.empty": "Aucune session pour l'instant. Cliquez + pour démarrer une nouvelle conversation.",
"session.cloud.repoOnly": "Uniquement ce dépôt",
"session.cloud.import": "Importer depuis le cloud",
"feedback.button": "Commentaires & support",
"feedback.dialog.message":
"Nous aimerions recueillir vos commentaires ou vous aider avec les problèmes que vous rencontrez.",
"feedback.dialog.github": "Signaler un problème sur GitHub",
"feedback.dialog.discord": "Rejoindre notre communauté Discord",
"feedback.dialog.support": "Service client",
"session.cloud.import.title": "Importer depuis le cloud",
"session.cloud.import.placeholder": "ID de session, URL ou commande kilo import",
"session.cloud.import.button": "Importer",
@@ -737,6 +737,11 @@ export const dict = {
"session.empty": "セッションがありません。+ をクリックして新しい会話を始めましょう。",
"session.cloud.repoOnly": "このリポジトリのみ",
"session.cloud.import": "クラウドからインポート",
"feedback.button": "フィードバック & サポート",
"feedback.dialog.message": "フィードバックをお聞かせいただくか、問題がある場合はお気軽にご相談ください。",
"feedback.dialog.github": "GitHubで問題を報告する",
"feedback.dialog.discord": "Discordコミュニティに参加する",
"feedback.dialog.support": "カスタマーサポート",
"session.cloud.import.title": "クラウドからインポート",
"session.cloud.import.placeholder": "セッションID、URL、またはkilo importコマンド",
"session.cloud.import.button": "インポート",
@@ -738,6 +738,11 @@ export const dict = {
"session.empty": "아직 세션이 없습니다. +를 클릭하여 새 대화를 시작하세요.",
"session.cloud.repoOnly": "이 저장소만",
"session.cloud.import": "클라우드에서 가져오기",
"feedback.button": "피드백 & 지원",
"feedback.dialog.message": "피드백을 들려주시거나 겪고 계신 문제에 대해 도움을 드리고 싶습니다.",
"feedback.dialog.github": "GitHub에 이슈 보고하기",
"feedback.dialog.discord": "Discord 커뮤니티 참여하기",
"feedback.dialog.support": "고객 지원",
"session.cloud.import.title": "클라우드에서 가져오기",
"session.cloud.import.placeholder": "세션 ID, URL 또는 kilo import 명령어",
"session.cloud.import.button": "가져오기",
@@ -742,6 +742,11 @@ export const dict = {
"session.empty": "Ingen sesjoner ennå. Klikk + for å starte en ny samtale.",
"session.cloud.repoOnly": "Kun dette repositoriet",
"session.cloud.import": "Importer fra skyen",
"feedback.button": "Tilbakemelding & støtte",
"feedback.dialog.message": "Vi vil gjerne høre tilbakemeldingene dine eller hjelpe med problemer du opplever.",
"feedback.dialog.github": "Rapporter et problem på GitHub",
"feedback.dialog.discord": "Bli med i Discord-fellesskapet vårt",
"feedback.dialog.support": "Kundestøtte",
"session.cloud.import.title": "Importer fra skyen",
"session.cloud.import.placeholder": "Økt-ID, URL eller kilo import-kommando",
"session.cloud.import.button": "Importer",
@@ -741,6 +741,11 @@ export const dict = {
"session.empty": "Brak sesji. Kliknij + aby rozpocząć nową rozmowę.",
"session.cloud.repoOnly": "Tylko to repozytorium",
"session.cloud.import": "Importuj z chmury",
"feedback.button": "Opinie i wsparcie",
"feedback.dialog.message": "Chętnie poznamy Twoją opinię lub pomożemy w przypadku problemów.",
"feedback.dialog.github": "Zgłoś problem na GitHubie",
"feedback.dialog.discord": "Dołącz do naszej społeczności Discord",
"feedback.dialog.support": "Wsparcie klienta",
"session.cloud.import.title": "Importuj z chmury",
"session.cloud.import.placeholder": "ID sesji, URL lub polecenie kilo import",
"session.cloud.import.button": "Importuj",
@@ -745,6 +745,11 @@ export const dict = {
"session.empty": "Сессий пока нет. Нажмите + чтобы начать новый разговор.",
"session.cloud.repoOnly": "Только этот репозиторий",
"session.cloud.import": "Импорт из облака",
"feedback.button": "Отзывы и поддержка",
"feedback.dialog.message": "Мы будем рады услышать ваши отзывы или помочь с любыми возникающими проблемами.",
"feedback.dialog.github": "Сообщить о проблеме на GitHub",
"feedback.dialog.discord": "Присоединиться к нашему Discord",
"feedback.dialog.support": "Служба поддержки",
"session.cloud.import.title": "Импорт из облака",
"session.cloud.import.placeholder": "ID сессии, URL или команда kilo import",
"session.cloud.import.button": "Импортировать",
@@ -735,6 +735,11 @@ export const dict = {
"session.empty": "ยังไม่มีเซสชัน คลิก + เพื่อเริ่มการสนทนาใหม่",
"session.cloud.repoOnly": "เฉพาะรีโพซิทอรีนี้",
"session.cloud.import": "นำเข้าจากคลาวด์",
"feedback.button": "ข้อเสนอแนะและการสนับสนุน",
"feedback.dialog.message": "เรายินดีรับฟังข้อเสนอแนะของคุณหรือช่วยแก้ไขปัญหาที่คุณพบ",
"feedback.dialog.github": "รายงานปัญหาบน GitHub",
"feedback.dialog.discord": "เข้าร่วมชุมชน Discord ของเรา",
"feedback.dialog.support": "ฝ่ายสนับสนุนลูกค้า",
"session.cloud.import.title": "นำเข้าจากคลาวด์",
"session.cloud.import.placeholder": "ID เซสชัน, URL หรือคำสั่ง kilo import",
"session.cloud.import.button": "นำเข้า",
@@ -728,6 +728,11 @@ export const dict = {
"session.empty": "暂无会话。点击 + 开始新的对话。",
"session.cloud.repoOnly": "仅此仓库",
"session.cloud.import": "从云端导入",
"feedback.button": "反馈与支持",
"feedback.dialog.message": "我们很乐意听取您的反馈,或帮助解决您遇到的任何问题。",
"feedback.dialog.github": "在 GitHub 上报告问题",
"feedback.dialog.discord": "加入我们的 Discord 社区",
"feedback.dialog.support": "客户支持",
"session.cloud.import.title": "从云端导入",
"session.cloud.import.placeholder": "会话 ID、URL 或 kilo import 命令",
"session.cloud.import.button": "导入",
@@ -730,6 +730,11 @@ export const dict = {
"session.empty": "尚無工作階段。點選 + 以開始新的對話。",
"session.cloud.repoOnly": "僅此儲存庫",
"session.cloud.import": "從雲端匯入",
"feedback.button": "意見回饋與支援",
"feedback.dialog.message": "我們很樂意聆聽您的意見回饋,或協助解決您遇到的任何問題。",
"feedback.dialog.github": "在 GitHub 上回報問題",
"feedback.dialog.discord": "加入我們的 Discord 社群",
"feedback.dialog.support": "客戶支援",
"session.cloud.import.title": "從雲端匯入",
"session.cloud.import.placeholder": "工作階段 ID、URL 或 kilo import 指令",
"session.cloud.import.button": "匯入",
@@ -177,6 +177,73 @@
line-height: 1.4;
}
/* ============================================
Feedback Button (empty state)
============================================ */
.feedback-button {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 16px;
border: 1px dashed var(--vscode-button-background, #007acc);
border-radius: 6px;
background: transparent;
color: var(--vscode-button-background, #007acc);
font-family: inherit;
font-size: 12px;
font-weight: 500;
cursor: pointer;
transition:
background-color 0.15s,
color 0.15s,
border-color 0.15s;
}
.feedback-button:hover {
background: var(--vscode-button-background, #007acc);
color: var(--vscode-button-foreground, #fff);
border-style: solid;
}
/* Feedback Dialog */
.feedback-dialog {
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
padding: 8px 24px 16px;
text-align: center;
}
.feedback-dialog-logo {
width: 48px;
height: 48px;
}
.feedback-dialog-logo img {
width: 100%;
height: 100%;
object-fit: contain;
}
.feedback-dialog-message {
margin: 0;
font-size: 14px;
font-weight: 600;
line-height: 1.5;
color: var(--vscode-foreground);
max-width: 280px;
}
.feedback-dialog-actions {
display: flex;
flex-direction: column;
gap: 8px;
width: 100%;
}
/* ============================================
Recent Sessions (empty state)
============================================ */