Skip to content

feat: user feedback#8

Merged
bobbyg603 merged 6 commits intomainfrom
feature/user-feedback
Mar 27, 2026
Merged

feat: user feedback#8
bobbyg603 merged 6 commits intomainfrom
feature/user-feedback

Conversation

@bobbyg603
Copy link
Copy Markdown
Member

@bobbyg603 bobbyg603 commented Mar 10, 2026

Summary

  • Replaces 3-step presigned URL upload with a single multipart form POST to /post/feedback/
  • FeedbackClient now builds multipart form data with text fields and file attachments in one request
  • Treats any 2xx response as success
  • Adds "Send Feedback" button and AlertDialog to the example app demonstrating the API
  • Documents postFeedback, postFeedbackBlocking, and file attachments in README

Test plan

  • Call BugSplat.postFeedback(...) from the example app and verify the report appears in the BugSplat dashboard
  • Tap "Send Feedback" in the example app, fill in subject/description, and submit
  • Verify file attachments are included when passed
  • Verify empty title is rejected
  • Verify the dialog shows success/failure status

🤖 Generated with Claude Code

bobbyg603 and others added 3 commits March 10, 2026 17:28
Adds FeedbackClient implementing the 3-step presigned URL upload flow
(getCrashUploadUrl -> PUT to S3 -> commitS3CrashUpload) with crashTypeId=36.
Creates feedback.json with title and description, zips it, and uploads.
Exposes postFeedback and postFeedbackBlocking static methods on BugSplat.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds List<File> attachments parameter to postFeedback and
postFeedbackBlocking. Files are included in the zip alongside
feedback.json.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Passes appKey through to the commit API call for restricted databases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

This comment was marked as outdated.

Simplifies FeedbackClient to a single multipart form POST. Adds a
feedback dialog to the example app and documents the API in README.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bobbyg603 bobbyg603 changed the title Add postFeedback API for user feedback submission Add user feedback via direct POST to /post/feedback/ Mar 27, 2026
When checked, generates a sample log file and attaches it to the
feedback report via the postFeedbackBlocking attachments overload.
Checkbox is checked by default.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bobbyg603 bobbyg603 changed the title Add user feedback via direct POST to /post/feedback/ feat: user feedback Mar 27, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +82 to +90
.setPositiveButton("Submit", (dialog, which) -> {
String title = titleInput.getText().toString().trim();
String description = descriptionInput.getText().toString().trim();
boolean includeLogs = includeLogsCheckbox.isChecked();

if (title.isEmpty()) {
Toast.makeText(this, "Subject is required", Toast.LENGTH_SHORT).show();
return;
}
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

setPositiveButton always dismisses the dialog after the click handler runs. Returning early when the subject is empty still closes the dialog, so the user can't correct the input. Consider validating via an OnShowListener (override the positive button’s onClick) or disabling the submit button until the subject is non-empty so the dialog only dismisses on valid input.

Copilot uses AI. Check for mistakes.
Comment on lines +41 to +43
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);

Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

This builds the entire multipart payload (including file attachments) into a ByteArrayOutputStream before sending. Large attachments can cause high memory usage or OOMs. Prefer streaming the multipart body directly to conn.getOutputStream() (chunked or fixed-length streaming mode) instead of buffering the whole request in memory.

Copilot uses AI. Check for mistakes.
Comment on lines +36 to +40
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);

Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

HttpURLConnection is created without connect/read timeouts. A stalled network can hang the calling thread indefinitely (including the blocking API). Set reasonable setConnectTimeout and setReadTimeout values.

Copilot uses AI. Check for mistakes.
Comment on lines +79 to +86
byte[] payload = baos.toByteArray();
conn.setRequestProperty("Content-Length", String.valueOf(payload.length));
conn.getOutputStream().write(payload);
conn.getOutputStream().flush();

int status = conn.getResponseCode();
conn.disconnect();

Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

The request/response streams aren’t closed: conn.getOutputStream() is written/flushed but never closed, and no input/error stream is consumed/closed. This can leak sockets and prevent connection reuse. Use try-with-resources for the output stream and close the input/error stream (even if you ignore the body), and disconnect in a finally block.

Copilot uses AI. Check for mistakes.
…ding

- Add 30s connect/read timeouts to prevent hanging on stalled networks
- Wrap HttpURLConnection in try/finally to ensure disconnect on all paths
- Close output stream via try-with-resources
- Replace DataOutputStream.writeBytes with UTF-8 byte writes to prevent
  corruption of non-ASCII characters in multipart form fields

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bobbyg603 bobbyg603 merged commit 40f3206 into main Mar 27, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants