@bbearai/react-native 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +101 -5
- package/dist/index.mjs +106 -10
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11393,7 +11393,7 @@ function shouldShowDeprecationWarning() {
|
|
|
11393
11393
|
}
|
|
11394
11394
|
if (shouldShowDeprecationWarning()) console.warn("\u26A0\uFE0F Node.js 18 and below are deprecated and will no longer be supported in future versions of @supabase/supabase-js. Please upgrade to Node.js 20 or later. For more information, visit: https://github.com/orgs/supabase/discussions/37217");
|
|
11395
11395
|
|
|
11396
|
-
//
|
|
11396
|
+
// ../core/dist/index.mjs
|
|
11397
11397
|
var MAX_CONSOLE_LOGS = 50;
|
|
11398
11398
|
var MAX_NETWORK_REQUESTS = 20;
|
|
11399
11399
|
var MAX_NAVIGATION_HISTORY = 20;
|
|
@@ -11653,6 +11653,7 @@ var HOSTED_BUGBEAR_ANON_KEY = getEnvVar("BUGBEAR_ANON_KEY") || getEnvVar("NEXT_P
|
|
|
11653
11653
|
var BugBearClient = class {
|
|
11654
11654
|
constructor(config) {
|
|
11655
11655
|
this.navigationHistory = [];
|
|
11656
|
+
this.reportSubmitInFlight = false;
|
|
11656
11657
|
this.config = config;
|
|
11657
11658
|
this.supabase = createClient(
|
|
11658
11659
|
config.supabaseUrl || DEFAULT_SUPABASE_URL,
|
|
@@ -11713,6 +11714,10 @@ var BugBearClient = class {
|
|
|
11713
11714
|
* Submit a report
|
|
11714
11715
|
*/
|
|
11715
11716
|
async submitReport(report) {
|
|
11717
|
+
if (this.reportSubmitInFlight) {
|
|
11718
|
+
return { success: false, error: "A report is already being submitted" };
|
|
11719
|
+
}
|
|
11720
|
+
this.reportSubmitInFlight = true;
|
|
11716
11721
|
try {
|
|
11717
11722
|
const validationError = this.validateReport(report);
|
|
11718
11723
|
if (validationError) {
|
|
@@ -11764,6 +11769,8 @@ var BugBearClient = class {
|
|
|
11764
11769
|
} catch (err) {
|
|
11765
11770
|
const message = err instanceof Error ? err.message : "Unknown error";
|
|
11766
11771
|
return { success: false, error: message };
|
|
11772
|
+
} finally {
|
|
11773
|
+
this.reportSubmitInFlight = false;
|
|
11767
11774
|
}
|
|
11768
11775
|
}
|
|
11769
11776
|
/**
|
|
@@ -11804,6 +11811,14 @@ var BugBearClient = class {
|
|
|
11804
11811
|
name,
|
|
11805
11812
|
description,
|
|
11806
11813
|
sort_order
|
|
11814
|
+
),
|
|
11815
|
+
role:project_roles(
|
|
11816
|
+
id,
|
|
11817
|
+
name,
|
|
11818
|
+
slug,
|
|
11819
|
+
color,
|
|
11820
|
+
description,
|
|
11821
|
+
login_hint
|
|
11807
11822
|
)
|
|
11808
11823
|
)
|
|
11809
11824
|
`).eq("project_id", this.config.projectId).eq("tester_id", testerInfo.id).in("status", ["pending", "in_progress"]).order("created_at", { ascending: true }).limit(100);
|
|
@@ -11841,6 +11856,14 @@ var BugBearClient = class {
|
|
|
11841
11856
|
name: item.test_case.group.name,
|
|
11842
11857
|
description: item.test_case.group.description,
|
|
11843
11858
|
sortOrder: item.test_case.group.sort_order
|
|
11859
|
+
} : void 0,
|
|
11860
|
+
role: item.test_case.role ? {
|
|
11861
|
+
id: item.test_case.role.id,
|
|
11862
|
+
name: item.test_case.role.name,
|
|
11863
|
+
slug: item.test_case.role.slug,
|
|
11864
|
+
color: item.test_case.role.color,
|
|
11865
|
+
description: item.test_case.role.description,
|
|
11866
|
+
loginHint: item.test_case.role.login_hint
|
|
11844
11867
|
} : void 0
|
|
11845
11868
|
}
|
|
11846
11869
|
}));
|
|
@@ -12224,6 +12247,72 @@ var BugBearClient = class {
|
|
|
12224
12247
|
return null;
|
|
12225
12248
|
}
|
|
12226
12249
|
}
|
|
12250
|
+
/**
|
|
12251
|
+
* Get issue counts for the tester (Open, Done, Reopened)
|
|
12252
|
+
* Used by the widget HomeScreen cards
|
|
12253
|
+
*/
|
|
12254
|
+
async getIssueCounts() {
|
|
12255
|
+
try {
|
|
12256
|
+
const testerInfo = await this.getTesterInfo();
|
|
12257
|
+
if (!testerInfo) return { open: 0, done: 0, reopened: 0 };
|
|
12258
|
+
const { data, error } = await this.supabase.rpc("get_tester_issue_counts", {
|
|
12259
|
+
p_project_id: this.config.projectId,
|
|
12260
|
+
p_tester_id: testerInfo.id
|
|
12261
|
+
});
|
|
12262
|
+
if (error) {
|
|
12263
|
+
console.error("BugBear: Failed to fetch issue counts", formatPgError(error));
|
|
12264
|
+
return { open: 0, done: 0, reopened: 0 };
|
|
12265
|
+
}
|
|
12266
|
+
return {
|
|
12267
|
+
open: data?.open ?? 0,
|
|
12268
|
+
done: data?.done ?? 0,
|
|
12269
|
+
reopened: data?.reopened ?? 0
|
|
12270
|
+
};
|
|
12271
|
+
} catch (err) {
|
|
12272
|
+
console.error("BugBear: Error fetching issue counts", err);
|
|
12273
|
+
return { open: 0, done: 0, reopened: 0 };
|
|
12274
|
+
}
|
|
12275
|
+
}
|
|
12276
|
+
/**
|
|
12277
|
+
* Get issues for the tester by category.
|
|
12278
|
+
* Returns enriched data: done issues include verification proof,
|
|
12279
|
+
* reopened issues include original bug context.
|
|
12280
|
+
*/
|
|
12281
|
+
async getIssues(category) {
|
|
12282
|
+
try {
|
|
12283
|
+
const testerInfo = await this.getTesterInfo();
|
|
12284
|
+
if (!testerInfo) return [];
|
|
12285
|
+
const { data, error } = await this.supabase.rpc("get_tester_issues", {
|
|
12286
|
+
p_project_id: this.config.projectId,
|
|
12287
|
+
p_tester_id: testerInfo.id,
|
|
12288
|
+
p_category: category
|
|
12289
|
+
});
|
|
12290
|
+
if (error) {
|
|
12291
|
+
console.error("BugBear: Failed to fetch issues", formatPgError(error));
|
|
12292
|
+
return [];
|
|
12293
|
+
}
|
|
12294
|
+
return (data || []).map((row) => ({
|
|
12295
|
+
id: row.id,
|
|
12296
|
+
title: row.title || "Untitled",
|
|
12297
|
+
description: row.description,
|
|
12298
|
+
reportType: row.report_type,
|
|
12299
|
+
severity: row.severity || null,
|
|
12300
|
+
status: row.status,
|
|
12301
|
+
screenshotUrls: row.screenshot_urls || [],
|
|
12302
|
+
route: row.app_context?.currentRoute || void 0,
|
|
12303
|
+
reporterName: row.reporter_name || void 0,
|
|
12304
|
+
createdAt: row.created_at,
|
|
12305
|
+
updatedAt: row.updated_at,
|
|
12306
|
+
verifiedByName: row.verified_by_name || void 0,
|
|
12307
|
+
verifiedAt: row.verified_at || void 0,
|
|
12308
|
+
originalBugId: row.original_bug_id || void 0,
|
|
12309
|
+
originalBugTitle: row.original_bug_title || void 0
|
|
12310
|
+
}));
|
|
12311
|
+
} catch (err) {
|
|
12312
|
+
console.error("BugBear: Error fetching issues", err);
|
|
12313
|
+
return [];
|
|
12314
|
+
}
|
|
12315
|
+
}
|
|
12227
12316
|
/**
|
|
12228
12317
|
* Basic email format validation (defense in depth)
|
|
12229
12318
|
*/
|
|
@@ -12256,8 +12345,8 @@ var BugBearClient = class {
|
|
|
12256
12345
|
return "Maximum 10 screenshots allowed";
|
|
12257
12346
|
}
|
|
12258
12347
|
for (const url of report.screenshots) {
|
|
12259
|
-
if (typeof url !== "string" || url.length > 2e3) {
|
|
12260
|
-
return "Invalid screenshot URL";
|
|
12348
|
+
if (typeof url !== "string" || url.length > 2e3 || !/^https?:\/\//i.test(url)) {
|
|
12349
|
+
return "Invalid screenshot URL (must be an HTTP/HTTPS URL)";
|
|
12261
12350
|
}
|
|
12262
12351
|
}
|
|
12263
12352
|
}
|
|
@@ -12646,7 +12735,10 @@ var BugBearClient = class {
|
|
|
12646
12735
|
content
|
|
12647
12736
|
};
|
|
12648
12737
|
if (attachments && attachments.length > 0) {
|
|
12649
|
-
|
|
12738
|
+
const safeAttachments = attachments.filter((a) => /^https?:\/\//i.test(a.url));
|
|
12739
|
+
if (safeAttachments.length > 0) {
|
|
12740
|
+
insertData.attachments = safeAttachments;
|
|
12741
|
+
}
|
|
12650
12742
|
}
|
|
12651
12743
|
const { error } = await this.supabase.from("discussion_messages").insert(insertData);
|
|
12652
12744
|
if (error) {
|
|
@@ -14496,11 +14588,14 @@ function ReportScreen({ nav, prefill }) {
|
|
|
14496
14588
|
const [affectedScreen, setAffectedScreen] = (0, import_react10.useState)("");
|
|
14497
14589
|
const [submitting, setSubmitting] = (0, import_react10.useState)(false);
|
|
14498
14590
|
const [error, setError] = (0, import_react10.useState)(null);
|
|
14591
|
+
const submittingRef = (0, import_react10.useRef)(false);
|
|
14499
14592
|
const images = useImageAttachments(uploadImage, 5, "screenshots");
|
|
14500
14593
|
const isRetestFailure = prefill?.type === "test_fail";
|
|
14501
14594
|
const isBugType = reportType === "bug" || reportType === "test_fail";
|
|
14502
14595
|
const handleSubmit = async () => {
|
|
14503
14596
|
if (!client || !description.trim()) return;
|
|
14597
|
+
if (submittingRef.current) return;
|
|
14598
|
+
submittingRef.current = true;
|
|
14504
14599
|
setSubmitting(true);
|
|
14505
14600
|
setError(null);
|
|
14506
14601
|
try {
|
|
@@ -14524,17 +14619,18 @@ function ReportScreen({ nav, prefill }) {
|
|
|
14524
14619
|
console.error("BugBear: Report submission failed", result.error);
|
|
14525
14620
|
setError(result.error || "Failed to submit report. Please try again.");
|
|
14526
14621
|
setSubmitting(false);
|
|
14622
|
+
submittingRef.current = false;
|
|
14527
14623
|
return;
|
|
14528
14624
|
}
|
|
14529
14625
|
if (prefill?.assignmentId) {
|
|
14530
14626
|
await refreshAssignments();
|
|
14531
14627
|
}
|
|
14532
|
-
setSubmitting(false);
|
|
14533
14628
|
nav.replace({ name: "REPORT_SUCCESS" });
|
|
14534
14629
|
} catch (err) {
|
|
14535
14630
|
console.error("BugBear: Report submission error", err);
|
|
14536
14631
|
setError(err instanceof Error ? err.message : "An unexpected error occurred. Please try again.");
|
|
14537
14632
|
setSubmitting(false);
|
|
14633
|
+
submittingRef.current = false;
|
|
14538
14634
|
}
|
|
14539
14635
|
};
|
|
14540
14636
|
return /* @__PURE__ */ import_react10.default.createElement(import_react_native9.View, null, isRetestFailure ? /* @__PURE__ */ import_react10.default.createElement(import_react10.default.Fragment, null, /* @__PURE__ */ import_react10.default.createElement(import_react_native9.View, { style: styles7.retestBanner }, /* @__PURE__ */ import_react10.default.createElement(import_react_native9.Text, { style: styles7.retestIcon }, "\u{1F504}"), /* @__PURE__ */ import_react10.default.createElement(import_react_native9.View, null, /* @__PURE__ */ import_react10.default.createElement(import_react_native9.Text, { style: styles7.retestTitle }, "Bug Still Present"), /* @__PURE__ */ import_react10.default.createElement(import_react_native9.Text, { style: styles7.retestSubtitle }, "The fix did not resolve this issue"))), /* @__PURE__ */ import_react10.default.createElement(import_react_native9.View, { style: styles7.section }, /* @__PURE__ */ import_react10.default.createElement(import_react_native9.Text, { style: shared.label }, "Severity"), /* @__PURE__ */ import_react10.default.createElement(import_react_native9.View, { style: styles7.severityRow }, [
|
package/dist/index.mjs
CHANGED
|
@@ -11360,7 +11360,7 @@ function shouldShowDeprecationWarning() {
|
|
|
11360
11360
|
}
|
|
11361
11361
|
if (shouldShowDeprecationWarning()) console.warn("\u26A0\uFE0F Node.js 18 and below are deprecated and will no longer be supported in future versions of @supabase/supabase-js. Please upgrade to Node.js 20 or later. For more information, visit: https://github.com/orgs/supabase/discussions/37217");
|
|
11362
11362
|
|
|
11363
|
-
//
|
|
11363
|
+
// ../core/dist/index.mjs
|
|
11364
11364
|
var MAX_CONSOLE_LOGS = 50;
|
|
11365
11365
|
var MAX_NETWORK_REQUESTS = 20;
|
|
11366
11366
|
var MAX_NAVIGATION_HISTORY = 20;
|
|
@@ -11620,6 +11620,7 @@ var HOSTED_BUGBEAR_ANON_KEY = getEnvVar("BUGBEAR_ANON_KEY") || getEnvVar("NEXT_P
|
|
|
11620
11620
|
var BugBearClient = class {
|
|
11621
11621
|
constructor(config) {
|
|
11622
11622
|
this.navigationHistory = [];
|
|
11623
|
+
this.reportSubmitInFlight = false;
|
|
11623
11624
|
this.config = config;
|
|
11624
11625
|
this.supabase = createClient(
|
|
11625
11626
|
config.supabaseUrl || DEFAULT_SUPABASE_URL,
|
|
@@ -11680,6 +11681,10 @@ var BugBearClient = class {
|
|
|
11680
11681
|
* Submit a report
|
|
11681
11682
|
*/
|
|
11682
11683
|
async submitReport(report) {
|
|
11684
|
+
if (this.reportSubmitInFlight) {
|
|
11685
|
+
return { success: false, error: "A report is already being submitted" };
|
|
11686
|
+
}
|
|
11687
|
+
this.reportSubmitInFlight = true;
|
|
11683
11688
|
try {
|
|
11684
11689
|
const validationError = this.validateReport(report);
|
|
11685
11690
|
if (validationError) {
|
|
@@ -11731,6 +11736,8 @@ var BugBearClient = class {
|
|
|
11731
11736
|
} catch (err) {
|
|
11732
11737
|
const message = err instanceof Error ? err.message : "Unknown error";
|
|
11733
11738
|
return { success: false, error: message };
|
|
11739
|
+
} finally {
|
|
11740
|
+
this.reportSubmitInFlight = false;
|
|
11734
11741
|
}
|
|
11735
11742
|
}
|
|
11736
11743
|
/**
|
|
@@ -11771,6 +11778,14 @@ var BugBearClient = class {
|
|
|
11771
11778
|
name,
|
|
11772
11779
|
description,
|
|
11773
11780
|
sort_order
|
|
11781
|
+
),
|
|
11782
|
+
role:project_roles(
|
|
11783
|
+
id,
|
|
11784
|
+
name,
|
|
11785
|
+
slug,
|
|
11786
|
+
color,
|
|
11787
|
+
description,
|
|
11788
|
+
login_hint
|
|
11774
11789
|
)
|
|
11775
11790
|
)
|
|
11776
11791
|
`).eq("project_id", this.config.projectId).eq("tester_id", testerInfo.id).in("status", ["pending", "in_progress"]).order("created_at", { ascending: true }).limit(100);
|
|
@@ -11808,6 +11823,14 @@ var BugBearClient = class {
|
|
|
11808
11823
|
name: item.test_case.group.name,
|
|
11809
11824
|
description: item.test_case.group.description,
|
|
11810
11825
|
sortOrder: item.test_case.group.sort_order
|
|
11826
|
+
} : void 0,
|
|
11827
|
+
role: item.test_case.role ? {
|
|
11828
|
+
id: item.test_case.role.id,
|
|
11829
|
+
name: item.test_case.role.name,
|
|
11830
|
+
slug: item.test_case.role.slug,
|
|
11831
|
+
color: item.test_case.role.color,
|
|
11832
|
+
description: item.test_case.role.description,
|
|
11833
|
+
loginHint: item.test_case.role.login_hint
|
|
11811
11834
|
} : void 0
|
|
11812
11835
|
}
|
|
11813
11836
|
}));
|
|
@@ -12191,6 +12214,72 @@ var BugBearClient = class {
|
|
|
12191
12214
|
return null;
|
|
12192
12215
|
}
|
|
12193
12216
|
}
|
|
12217
|
+
/**
|
|
12218
|
+
* Get issue counts for the tester (Open, Done, Reopened)
|
|
12219
|
+
* Used by the widget HomeScreen cards
|
|
12220
|
+
*/
|
|
12221
|
+
async getIssueCounts() {
|
|
12222
|
+
try {
|
|
12223
|
+
const testerInfo = await this.getTesterInfo();
|
|
12224
|
+
if (!testerInfo) return { open: 0, done: 0, reopened: 0 };
|
|
12225
|
+
const { data, error } = await this.supabase.rpc("get_tester_issue_counts", {
|
|
12226
|
+
p_project_id: this.config.projectId,
|
|
12227
|
+
p_tester_id: testerInfo.id
|
|
12228
|
+
});
|
|
12229
|
+
if (error) {
|
|
12230
|
+
console.error("BugBear: Failed to fetch issue counts", formatPgError(error));
|
|
12231
|
+
return { open: 0, done: 0, reopened: 0 };
|
|
12232
|
+
}
|
|
12233
|
+
return {
|
|
12234
|
+
open: data?.open ?? 0,
|
|
12235
|
+
done: data?.done ?? 0,
|
|
12236
|
+
reopened: data?.reopened ?? 0
|
|
12237
|
+
};
|
|
12238
|
+
} catch (err) {
|
|
12239
|
+
console.error("BugBear: Error fetching issue counts", err);
|
|
12240
|
+
return { open: 0, done: 0, reopened: 0 };
|
|
12241
|
+
}
|
|
12242
|
+
}
|
|
12243
|
+
/**
|
|
12244
|
+
* Get issues for the tester by category.
|
|
12245
|
+
* Returns enriched data: done issues include verification proof,
|
|
12246
|
+
* reopened issues include original bug context.
|
|
12247
|
+
*/
|
|
12248
|
+
async getIssues(category) {
|
|
12249
|
+
try {
|
|
12250
|
+
const testerInfo = await this.getTesterInfo();
|
|
12251
|
+
if (!testerInfo) return [];
|
|
12252
|
+
const { data, error } = await this.supabase.rpc("get_tester_issues", {
|
|
12253
|
+
p_project_id: this.config.projectId,
|
|
12254
|
+
p_tester_id: testerInfo.id,
|
|
12255
|
+
p_category: category
|
|
12256
|
+
});
|
|
12257
|
+
if (error) {
|
|
12258
|
+
console.error("BugBear: Failed to fetch issues", formatPgError(error));
|
|
12259
|
+
return [];
|
|
12260
|
+
}
|
|
12261
|
+
return (data || []).map((row) => ({
|
|
12262
|
+
id: row.id,
|
|
12263
|
+
title: row.title || "Untitled",
|
|
12264
|
+
description: row.description,
|
|
12265
|
+
reportType: row.report_type,
|
|
12266
|
+
severity: row.severity || null,
|
|
12267
|
+
status: row.status,
|
|
12268
|
+
screenshotUrls: row.screenshot_urls || [],
|
|
12269
|
+
route: row.app_context?.currentRoute || void 0,
|
|
12270
|
+
reporterName: row.reporter_name || void 0,
|
|
12271
|
+
createdAt: row.created_at,
|
|
12272
|
+
updatedAt: row.updated_at,
|
|
12273
|
+
verifiedByName: row.verified_by_name || void 0,
|
|
12274
|
+
verifiedAt: row.verified_at || void 0,
|
|
12275
|
+
originalBugId: row.original_bug_id || void 0,
|
|
12276
|
+
originalBugTitle: row.original_bug_title || void 0
|
|
12277
|
+
}));
|
|
12278
|
+
} catch (err) {
|
|
12279
|
+
console.error("BugBear: Error fetching issues", err);
|
|
12280
|
+
return [];
|
|
12281
|
+
}
|
|
12282
|
+
}
|
|
12194
12283
|
/**
|
|
12195
12284
|
* Basic email format validation (defense in depth)
|
|
12196
12285
|
*/
|
|
@@ -12223,8 +12312,8 @@ var BugBearClient = class {
|
|
|
12223
12312
|
return "Maximum 10 screenshots allowed";
|
|
12224
12313
|
}
|
|
12225
12314
|
for (const url of report.screenshots) {
|
|
12226
|
-
if (typeof url !== "string" || url.length > 2e3) {
|
|
12227
|
-
return "Invalid screenshot URL";
|
|
12315
|
+
if (typeof url !== "string" || url.length > 2e3 || !/^https?:\/\//i.test(url)) {
|
|
12316
|
+
return "Invalid screenshot URL (must be an HTTP/HTTPS URL)";
|
|
12228
12317
|
}
|
|
12229
12318
|
}
|
|
12230
12319
|
}
|
|
@@ -12613,7 +12702,10 @@ var BugBearClient = class {
|
|
|
12613
12702
|
content
|
|
12614
12703
|
};
|
|
12615
12704
|
if (attachments && attachments.length > 0) {
|
|
12616
|
-
|
|
12705
|
+
const safeAttachments = attachments.filter((a) => /^https?:\/\//i.test(a.url));
|
|
12706
|
+
if (safeAttachments.length > 0) {
|
|
12707
|
+
insertData.attachments = safeAttachments;
|
|
12708
|
+
}
|
|
12617
12709
|
}
|
|
12618
12710
|
const { error } = await this.supabase.from("discussion_messages").insert(insertData);
|
|
12619
12711
|
if (error) {
|
|
@@ -13213,7 +13305,7 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
|
|
|
13213
13305
|
}
|
|
13214
13306
|
|
|
13215
13307
|
// src/BugBearButton.tsx
|
|
13216
|
-
import React14, { useState as useState10, useRef as
|
|
13308
|
+
import React14, { useState as useState10, useRef as useRef3 } from "react";
|
|
13217
13309
|
import {
|
|
13218
13310
|
View as View13,
|
|
13219
13311
|
Text as Text13,
|
|
@@ -14468,7 +14560,7 @@ var styles6 = StyleSheet7.create({
|
|
|
14468
14560
|
});
|
|
14469
14561
|
|
|
14470
14562
|
// src/widget/screens/ReportScreen.tsx
|
|
14471
|
-
import React8, { useState as useState6 } from "react";
|
|
14563
|
+
import React8, { useState as useState6, useRef as useRef2 } from "react";
|
|
14472
14564
|
import { View as View7, Text as Text7, TouchableOpacity as TouchableOpacity7, TextInput as TextInput3, StyleSheet as StyleSheet8 } from "react-native";
|
|
14473
14565
|
function ReportScreen({ nav, prefill }) {
|
|
14474
14566
|
const { client, getDeviceInfo, uploadImage, refreshAssignments } = useBugBear();
|
|
@@ -14478,11 +14570,14 @@ function ReportScreen({ nav, prefill }) {
|
|
|
14478
14570
|
const [affectedScreen, setAffectedScreen] = useState6("");
|
|
14479
14571
|
const [submitting, setSubmitting] = useState6(false);
|
|
14480
14572
|
const [error, setError] = useState6(null);
|
|
14573
|
+
const submittingRef = useRef2(false);
|
|
14481
14574
|
const images = useImageAttachments(uploadImage, 5, "screenshots");
|
|
14482
14575
|
const isRetestFailure = prefill?.type === "test_fail";
|
|
14483
14576
|
const isBugType = reportType === "bug" || reportType === "test_fail";
|
|
14484
14577
|
const handleSubmit = async () => {
|
|
14485
14578
|
if (!client || !description.trim()) return;
|
|
14579
|
+
if (submittingRef.current) return;
|
|
14580
|
+
submittingRef.current = true;
|
|
14486
14581
|
setSubmitting(true);
|
|
14487
14582
|
setError(null);
|
|
14488
14583
|
try {
|
|
@@ -14506,17 +14601,18 @@ function ReportScreen({ nav, prefill }) {
|
|
|
14506
14601
|
console.error("BugBear: Report submission failed", result.error);
|
|
14507
14602
|
setError(result.error || "Failed to submit report. Please try again.");
|
|
14508
14603
|
setSubmitting(false);
|
|
14604
|
+
submittingRef.current = false;
|
|
14509
14605
|
return;
|
|
14510
14606
|
}
|
|
14511
14607
|
if (prefill?.assignmentId) {
|
|
14512
14608
|
await refreshAssignments();
|
|
14513
14609
|
}
|
|
14514
|
-
setSubmitting(false);
|
|
14515
14610
|
nav.replace({ name: "REPORT_SUCCESS" });
|
|
14516
14611
|
} catch (err) {
|
|
14517
14612
|
console.error("BugBear: Report submission error", err);
|
|
14518
14613
|
setError(err instanceof Error ? err.message : "An unexpected error occurred. Please try again.");
|
|
14519
14614
|
setSubmitting(false);
|
|
14615
|
+
submittingRef.current = false;
|
|
14520
14616
|
}
|
|
14521
14617
|
};
|
|
14522
14618
|
return /* @__PURE__ */ React8.createElement(View7, null, isRetestFailure ? /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(View7, { style: styles7.retestBanner }, /* @__PURE__ */ React8.createElement(Text7, { style: styles7.retestIcon }, "\u{1F504}"), /* @__PURE__ */ React8.createElement(View7, null, /* @__PURE__ */ React8.createElement(Text7, { style: styles7.retestTitle }, "Bug Still Present"), /* @__PURE__ */ React8.createElement(Text7, { style: styles7.retestSubtitle }, "The fix did not resolve this issue"))), /* @__PURE__ */ React8.createElement(View7, { style: styles7.section }, /* @__PURE__ */ React8.createElement(Text7, { style: shared.label }, "Severity"), /* @__PURE__ */ React8.createElement(View7, { style: styles7.severityRow }, [
|
|
@@ -15046,9 +15142,9 @@ function BugBearButton({
|
|
|
15046
15142
|
return { x, y };
|
|
15047
15143
|
};
|
|
15048
15144
|
const initialPos = getInitialPosition();
|
|
15049
|
-
const pan =
|
|
15050
|
-
const isDragging =
|
|
15051
|
-
const panResponder =
|
|
15145
|
+
const pan = useRef3(new Animated.ValueXY(initialPos)).current;
|
|
15146
|
+
const isDragging = useRef3(false);
|
|
15147
|
+
const panResponder = useRef3(
|
|
15052
15148
|
PanResponder.create({
|
|
15053
15149
|
onStartShouldSetPanResponder: () => draggable,
|
|
15054
15150
|
onMoveShouldSetPanResponder: (_, gs) => draggable && (Math.abs(gs.dx) > 5 || Math.abs(gs.dy) > 5),
|