feat(feedback): 添加错误报告与邮件反馈入口
This commit is contained in:
1 parent
3c90b079d3
commit
3acc79472e
12 files changed
+132
-1
No files matched your search
@@ -0,0 +1,31 @@
|
||||
---
|
||||
name: 问题反馈 / Bug report
|
||||
about: 反馈 XStats 的故障或异常 / Report an XStats bug
|
||||
title: "[Bug] "
|
||||
---
|
||||
|
||||
## 问题描述 / Description
|
||||
|
||||
请简要描述遇到的问题。Describe the problem.
|
||||
|
||||
## 复现步骤 / Steps to reproduce
|
||||
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
## 预期结果 / Expected behavior
|
||||
|
||||
|
||||
## 实际结果 / Actual behavior
|
||||
|
||||
|
||||
## 环境 / Environment
|
||||
|
||||
- XStats 版本与构建号 / version and build:
|
||||
- macOS 版本 / version:
|
||||
|
||||
## 截图与日志 / Screenshots and logs
|
||||
|
||||
如有帮助,可在 XStats 的“设置 → 关于”中导出诊断信息并附上。请先检查附件,避免公开密码、令牌等敏感信息。
|
||||
If useful, export diagnostics from XStats Settings → About and attach them after reviewing the archive for sensitive information.
|
||||
@@ -397,6 +397,7 @@ uv 下载的 Python 包与构建缓存,由 uv 自行清理 ذاكرة حزم P
|
||||
发现问题:{} وُجدت مشكلة: {}
|
||||
发生这些状况时发送系统通知,点通知打开对应页面 إرسال إشعار عند حدوث هذه الحالات؛ انقر عليه لفتح الصفحة المعنية
|
||||
发送 إرسال
|
||||
发送反馈邮件 إرسال ملاحظات عبر البريد الإلكتروني
|
||||
发送测试通知 إرسال إشعار اختبار
|
||||
取消 إلغاء
|
||||
受保护 محمي
|
||||
@@ -467,6 +468,7 @@ uv 下载的 Python 包与构建缓存,由 uv 自行清理 ذاكرة حزم P
|
||||
图标 أيقونة
|
||||
圆环 حلقة
|
||||
圆环表示当前占用比例 تعرض الحلقة الاستخدام الحالي
|
||||
在 GitHub 提交问题 الإبلاغ عن مشكلة على GitHub
|
||||
在 cleanip.io 查看这个 IP 的完整报告 فتح التقرير الكامل لعنوان IP هذا في cleanip.io
|
||||
在主窗口打开“{}” فتح «{}» في النافذة الرئيسية
|
||||
在程序坞显示图标 عرض الرمز في Dock
|
||||
|
||||
|
@@ -397,6 +397,7 @@ uv 下载的 Python 包与构建缓存,由 uv 自行清理 Von uv geladener Py
|
||||
发现问题:{} Problem gefunden: {}
|
||||
发生这些状况时发送系统通知,点通知打开对应页面 Bei diesen Ereignissen eine Mitteilung senden; ein Klick öffnet die entsprechende Seite
|
||||
发送 Senden
|
||||
发送反馈邮件 Feedback per E-Mail senden
|
||||
发送测试通知 Testmitteilung senden
|
||||
取消 Abbrechen
|
||||
受保护 Geschützt
|
||||
@@ -467,6 +468,7 @@ uv 下载的 Python 包与构建缓存,由 uv 自行清理 Von uv geladener Py
|
||||
图标 Symbol
|
||||
圆环 Ring
|
||||
圆环表示当前占用比例 Ein Ring zeigt die aktuelle Auslastung
|
||||
在 GitHub 提交问题 Problem auf GitHub melden
|
||||
在 cleanip.io 查看这个 IP 的完整报告 Vollständigen Bericht zu dieser IP auf cleanip.io öffnen
|
||||
在主窗口打开“{}” „{}“ im Hauptfenster öffnen
|
||||
在程序坞显示图标 Symbol im Dock anzeigen
|
||||
|
||||
|
@@ -397,6 +397,7 @@ uv 下载的 Python 包与构建缓存,由 uv 自行清理 Cachés de paquetes
|
||||
发现问题:{} Problema encontrado: {}
|
||||
发生这些状况时发送系统通知,点通知打开对应页面 Enviar una notificación cuando ocurra; púlsala para abrir la página correspondiente
|
||||
发送 Enviar
|
||||
发送反馈邮件 Enviar correo de comentarios
|
||||
发送测试通知 Enviar notificación de prueba
|
||||
取消 Cancelar
|
||||
受保护 Protegido
|
||||
@@ -467,6 +468,7 @@ uv 下载的 Python 包与构建缓存,由 uv 自行清理 Cachés de paquetes
|
||||
图标 Icono
|
||||
圆环 Anillo
|
||||
圆环表示当前占用比例 Un anillo muestra el uso actual
|
||||
在 GitHub 提交问题 Informar de un problema en GitHub
|
||||
在 cleanip.io 查看这个 IP 的完整报告 Abrir el informe completo de esta IP en cleanip.io
|
||||
在主窗口打开“{}” Abrir «{}» en la ventana principal
|
||||
在程序坞显示图标 Mostrar icono en el Dock
|
||||
|
||||
|
@@ -397,6 +397,7 @@ uv 下载的 Python 包与构建缓存,由 uv 自行清理 Caches de paquets P
|
||||
发现问题:{} Problème détecté : {}
|
||||
发生这些状况时发送系统通知,点通知打开对应页面 Envoyer une notification lors de ces événements ; cliquer dessus ouvre la page correspondante
|
||||
发送 Envoyer
|
||||
发送反馈邮件 Envoyer un retour par e-mail
|
||||
发送测试通知 Envoyer une notification de test
|
||||
取消 Annuler
|
||||
受保护 Protégé
|
||||
@@ -467,6 +468,7 @@ uv 下载的 Python 包与构建缓存,由 uv 自行清理 Caches de paquets P
|
||||
图标 Icône
|
||||
圆环 Anneau
|
||||
圆环表示当前占用比例 Un anneau représente l’utilisation actuelle
|
||||
在 GitHub 提交问题 Signaler un problème sur GitHub
|
||||
在 cleanip.io 查看这个 IP 的完整报告 Ouvrir le rapport complet de cette IP sur cleanip.io
|
||||
在主窗口打开“{}” Ouvrir « {} » dans la fenêtre principale
|
||||
在程序坞显示图标 Afficher l’icône dans le Dock
|
||||
|
||||
|
@@ -397,6 +397,7 @@ uv 下载的 Python 包与构建缓存,由 uv 自行清理 uvのPythonパッ
|
||||
发现问题:{} 問題が見つかりました:{}
|
||||
发生这些状况时发送系统通知,点通知打开对应页面 これらの状態で通知を送信します。通知をクリックすると関連ページが開きます
|
||||
发送 送信
|
||||
发送反馈邮件 フィードバックをメールで送信
|
||||
发送测试通知 テスト通知を送信
|
||||
取消 キャンセル
|
||||
受保护 保護されています
|
||||
@@ -467,6 +468,7 @@ uv 下载的 Python 包与构建缓存,由 uv 自行清理 uvのPythonパッ
|
||||
图标 アイコン
|
||||
圆环 リング
|
||||
圆环表示当前占用比例 リングは現在の使用率を示します
|
||||
在 GitHub 提交问题 GitHubで問題を報告
|
||||
在 cleanip.io 查看这个 IP 的完整报告 cleanip.ioでこのIPの詳細レポートを開く
|
||||
在主窗口打开“{}” メインウインドウで「{}」を開く
|
||||
在程序坞显示图标 Dockにアイコンを表示
|
||||
|
||||
|
@@ -397,6 +397,7 @@ uv 下载的 Python 包与构建缓存,由 uv 自行清理 uv의 Python 패키
|
||||
发现问题:{} 문제 발견: {}
|
||||
发生这些状况时发送系统通知,点通知打开对应页面 이러한 상황에서 알림을 보냅니다. 알림을 클릭하면 관련 페이지가 열립니다
|
||||
发送 보내기
|
||||
发送反馈邮件 피드백 이메일 보내기
|
||||
发送测试通知 테스트 알림 보내기
|
||||
取消 취소
|
||||
受保护 보호됨
|
||||
@@ -467,6 +468,7 @@ uv 下载的 Python 包与构建缓存,由 uv 自行清理 uv의 Python 패키
|
||||
图标 아이콘
|
||||
圆环 링
|
||||
圆环表示当前占用比例 링은 현재 사용률을 표시합니다
|
||||
在 GitHub 提交问题 GitHub에 문제 신고
|
||||
在 cleanip.io 查看这个 IP 的完整报告 cleanip.io에서 이 IP의 전체 보고서 열기
|
||||
在主窗口打开“{}” 주 윈도우에서 “{}” 열기
|
||||
在程序坞显示图标 Dock에 아이콘 표시
|
||||
|
||||
|
@@ -398,6 +398,7 @@ uv 下载的 Python 包与构建缓存,由 uv 自行清理 uv 下載的 Python
|
||||
发现问题:{} 發現問題:{}
|
||||
发生这些状况时发送系统通知,点通知打开对应页面 發生這些狀況時發送系統通知,點通知打開對應頁面
|
||||
发送 發送
|
||||
发送反馈邮件 傳送回饋郵件
|
||||
发送测试通知 發送測試通知
|
||||
取消 取消
|
||||
受保护 受保護
|
||||
@@ -468,6 +469,7 @@ uv 下载的 Python 包与构建缓存,由 uv 自行清理 uv 下載的 Python
|
||||
图标 圖標
|
||||
圆环 圓環
|
||||
圆环表示当前占用比例 圓環表示當前佔用比例
|
||||
在 GitHub 提交问题 在 GitHub 提交問題
|
||||
在 cleanip.io 查看这个 IP 的完整报告 在 cleanip.io 查看這個 IP 的完整報告
|
||||
在主窗口打开“{}” 在主窗口打開“{}”
|
||||
在程序坞显示图标 在程序塢顯示圖標
|
||||
|
||||
|
@@ -518,6 +518,7 @@ uv 下载的 Python 包与构建缓存,由 uv 自行清理 Python package and
|
||||
发现问题:{} Problem found: {}
|
||||
发生这些状况时发送系统通知,点通知打开对应页面 Send a notification when these happen; click it to open the related page
|
||||
发送 Send
|
||||
发送反馈邮件 Send Feedback Email
|
||||
发送测试通知 Send Test Notification
|
||||
取消 Cancel
|
||||
受保护 Protected
|
||||
@@ -588,6 +589,7 @@ uv 下载的 Python 包与构建缓存,由 uv 自行清理 Python package and
|
||||
图标 Icon
|
||||
圆环 Ring
|
||||
圆环表示当前占用比例 A ring shows current usage
|
||||
在 GitHub 提交问题 Report a Problem on GitHub
|
||||
在 cleanip.io 查看这个 IP 的完整报告 Open this IP's full report on cleanip.io
|
||||
在主窗口打开“{}” Open “{}” in the main window
|
||||
在程序坞显示图标 Show Icon in Dock
|
||||
|
||||
@@ -477,7 +477,7 @@ private struct GlassButtonSurface: ViewModifier {
|
||||
}
|
||||
}
|
||||
|
||||
private struct IconButtonSurface: ViewModifier {
|
||||
struct IconButtonSurface: ViewModifier {
|
||||
let hovering: Bool
|
||||
let glass: Bool
|
||||
|
||||
|
||||
@@ -153,6 +153,7 @@ private struct MainSidebar: View {
|
||||
|
||||
HStack(spacing: DS.Space.s1) {
|
||||
ThemeToggle()
|
||||
FeedbackMenu()
|
||||
Spacer(minLength: 0)
|
||||
IconButton(systemName: "power", help: tr("退出 XStats")) { model.quit() }
|
||||
}
|
||||
@@ -208,6 +209,61 @@ private struct MainSidebar: View {
|
||||
}
|
||||
}
|
||||
|
||||
private struct FeedbackMenu: View {
|
||||
@Environment(\.isInsideGlass) private var isInsideGlass
|
||||
@State private var hovering = false
|
||||
|
||||
var body: some View {
|
||||
let glass = DS.Glass.isAvailable && !isInsideGlass
|
||||
Menu {
|
||||
Button {
|
||||
NSWorkspace.shared.open(FeedbackLinks.githubBugReport)
|
||||
} label: {
|
||||
Label(tr("在 GitHub 提交问题"), systemImage: "ladybug")
|
||||
}
|
||||
Button {
|
||||
let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? tr("开发版")
|
||||
let build = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as? String
|
||||
let systemVersion = ProcessInfo.processInfo.operatingSystemVersionString
|
||||
if let url = FeedbackLinks.email(version: version, build: build, systemVersion: systemVersion) {
|
||||
NSWorkspace.shared.open(url)
|
||||
}
|
||||
} label: {
|
||||
Label(tr("发送反馈邮件"), systemImage: "envelope")
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "ladybug")
|
||||
.font(.system(size: DS.TextSize.sm.rawValue, weight: .medium))
|
||||
.foregroundStyle(hovering ? DS.Palette.primary : glass ? DS.Palette.textPrimary : DS.Palette.textSecondary)
|
||||
.frame(width: DS.Size.controlHeight, height: DS.Size.controlHeight)
|
||||
.modifier(IconButtonSurface(hovering: hovering, glass: glass))
|
||||
.contentShape(Circle())
|
||||
}
|
||||
.menuStyle(.borderlessButton)
|
||||
.menuIndicator(.hidden)
|
||||
.frame(width: DS.Size.controlHeight)
|
||||
.onHover { hovering = $0 }
|
||||
.help(tr("反馈问题"))
|
||||
.accessibilityLabel(tr("反馈问题"))
|
||||
}
|
||||
}
|
||||
|
||||
enum FeedbackLinks {
|
||||
static let githubBugReport = URL(string: "https://github.com/ysicing/XStats/issues/new?template=bug_report.md")!
|
||||
|
||||
static func email(version: String, build: String?, systemVersion: String) -> URL? {
|
||||
let appVersion = build.map { "\(version) (\($0))" } ?? version
|
||||
var components = URLComponents()
|
||||
components.scheme = "mailto"
|
||||
components.path = "i@xiai.me"
|
||||
components.queryItems = [
|
||||
URLQueryItem(name: "subject", value: tr("反馈问题")),
|
||||
URLQueryItem(name: "body", value: "XStats \(appVersion)\nmacOS \(systemVersion)\n\n"),
|
||||
]
|
||||
return components.url
|
||||
}
|
||||
}
|
||||
|
||||
private struct PageHeader: View {
|
||||
@Environment(AppModel.self) private var model
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2026 ysicing
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import Foundation
|
||||
import Testing
|
||||
@testable import XStatsUI
|
||||
|
||||
@Suite struct FeedbackLinksTests {
|
||||
@Test func githubOpensTheBugReportTemplate() {
|
||||
let url = FeedbackLinks.githubBugReport
|
||||
let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
|
||||
#expect(url.scheme == "https")
|
||||
#expect(url.host == "github.com")
|
||||
#expect(url.path == "/ysicing/XStats/issues/new")
|
||||
#expect(components?.queryItems?.first(where: { $0.name == "template" })?.value == "bug_report.md")
|
||||
}
|
||||
|
||||
@Test func emailPrefillsAppBuildAndSystemVersion() throws {
|
||||
let url = try #require(FeedbackLinks.email(version: "0.10.0", build: "119",
|
||||
systemVersion: "Version 26.0 (Build 25A123)"))
|
||||
let components = try #require(URLComponents(url: url, resolvingAgainstBaseURL: false))
|
||||
#expect(components.scheme == "mailto")
|
||||
#expect(components.path == "i@xiai.me")
|
||||
#expect(components.queryItems?.first(where: { $0.name == "subject" })?.value?.isEmpty == false)
|
||||
#expect(components.queryItems?.first(where: { $0.name == "body" })?.value
|
||||
== "XStats 0.10.0 (119)\nmacOS Version 26.0 (Build 25A123)\n\n")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user