Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Bug report
description: File a bug report.
title: "bug: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to report a bug! Please provide the details below.

- type: textarea
id: description
attributes:
label: Describe the bug
description: What happened?
placeholder: Tell us what you saw.
validations:
required: true

- type: textarea
id: reproduce
attributes:
label: How to reproduce
description: List the minimal steps to trigger the issue.
placeholder: |
1. …
2. …
3. …
validations:
required: true

- type: textarea
id: expected
attributes:
label: Expected behavior
description: What did you expect to happen instead?
placeholder: Tell us what you expected.

- type: input
id: os
attributes:
label: Operating system
description: Which OS are you using?
placeholder: e.g. Windows 11, macOS 14, Ubuntu 22.04
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My 2 cents, we do not support Ubuntu for the time being, so we could remove any noise.

Also, if we want this to be quite frictionless, we could even pre-populate fields with things we already know. For example I guess it would be fairly easy to get OS info from the app, to populate this field so filling bugs will have less friction.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thanks for the feedback. will add now

validations:
required: true

- type: textarea
id: attachments
attributes:
label: Attachments
description: Paste any relevant screenshots, error messages, or logs here.
placeholder: Drag & drop or paste text/images/logs.

118 changes: 30 additions & 88 deletions tauri/src/windows/main-window/report.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,18 @@
import { useEffect, useState } from "react";
import { invoke } from "@tauri-apps/api/core";
import { toast } from "react-hot-toast";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { FileInput } from "@/components/ui/file-input";
import * as Sentry from "@sentry/react";
import { readTextFile } from "@tauri-apps/plugin-fs";
import useStore from "@/store/store";
import { invoke } from "@tauri-apps/api/core";
import { open as openInBrowser } from "@tauri-apps/plugin-shell";

const getLogs = async () => {
const logs = await invoke<string | null>("get_logs");
return logs;
};
const OWNER = "gethopp";
const REPO = "hopp";
const TEMPLATE = "bug_report.yml";

const deactivateHiding = async (value: boolean) => {
await invoke("set_deactivate_hiding", { deactivate: value });
};

export function Report() {
const [description, setDescription] = useState("");
const [isSubmitting, setIsSubmitting] = useState(false);
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const user = useStore((state) => state.user);

useEffect(() => {
deactivateHiding(true);
Expand All @@ -30,89 +21,40 @@ export function Report() {
};
}, []);

const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();

if (!description.trim()) {
toast.error("Please provide a description of the issue");
return;
}

const handleOpenTemplate = async () => {
setIsSubmitting(true);
try {
let blob = await selectedFile?.arrayBuffer();

if (user?.email) {
Sentry.getCurrentScope().setUser({
email: user.email.trim(),
});
}
const base = `https://github.com/${OWNER}/${REPO}/issues/new`;
const url = `${base}?template=${encodeURIComponent(TEMPLATE)}`;

if (blob !== undefined) {
Sentry.getCurrentScope().addAttachment({
data: new Uint8Array(blob),
filename: selectedFile ? selectedFile.name : "screenshot.png",
});
try {
await openInBrowser(url);
} catch {
window.open(url, "_blank", "noopener");
}

Sentry.getCurrentScope().addAttachment({
data: description,
filename: "description.txt",
});

const logs = await getLogs();

if (logs !== null) {
const logs_content = await readTextFile(logs);
Sentry.getCurrentScope().addAttachment({
data: logs_content,
filename: "logs.txt",
});
}

const reportId = Math.random().toString(36).substring(7);
Sentry.captureMessage(`User reported an issue (${reportId})`);

Sentry.getCurrentScope().clearAttachments();
} catch (error) {
toast.error("Failed to submit report");
console.error(error);
return;
} finally {
setIsSubmitting(false);
}
setIsSubmitting(false);
toast.success("Report submitted successfully", {
duration: 5000,
});
};

return (
<div className="flex flex-col p-6 max-w-2xl mx-auto">
<h1 className="text-2xl font-semibold mb-4">Report an Issue</h1>
<form onSubmit={handleSubmit} className="space-y-4">
<div className="space-y-2">
<label htmlFor="description" className="block text-sm font-medium">
Description
</label>
<Textarea
id="description"
value={description}
onChange={(e) => setDescription(e.target.value)}
placeholder="Please describe the issue you're experiencing..."
className="min-h-[150px]"
required
/>
<FileInput
acceptedFileTypes="PNG, JPEG, JPG or MP4"
maxSize={15}
onFileSelect={(file) => {
setSelectedFile(file);
}}
/>
</div>
<Button type="submit" className="w-full" disabled={isSubmitting}>
{isSubmitting ? "Submitting..." : "Submit Report"}
</Button>
</form>
<h1 className="text-2xl font-semibold mb-2">Report an Issue</h1>
<p className="text-sm text-muted-foreground mb-6">
This opens a GitHub bug report form in your browser. Fill it out and attach any files there.
</p>

<Button onClick={handleOpenTemplate} className="w-full" disabled={isSubmitting}>
{isSubmitting ? "Opening GitHub…" : "Open Bug Report Form"}
</Button>

<div className="mt-4 text-xs text-muted-foreground">
Learn more in the official project{" "}
<a href="https://docs.gethopp.app/" target="_blank" rel="noreferrer" className="underline hover:no-underline">
documentation
</a>
.
</div>
</div>
);
}
Expand Down