@bbearai/react-native 0.8.3 → 0.9.0
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 +438 -36
- package/dist/index.mjs +496 -94
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -12235,6 +12235,9 @@ var BugBearClient = class {
|
|
|
12235
12235
|
this.monitor = null;
|
|
12236
12236
|
this.initialized = false;
|
|
12237
12237
|
this.initError = null;
|
|
12238
|
+
this._presenceSessionId = null;
|
|
12239
|
+
this._presenceInterval = null;
|
|
12240
|
+
this._presencePaused = false;
|
|
12238
12241
|
this.config = config;
|
|
12239
12242
|
if (config.apiKey) {
|
|
12240
12243
|
this.pendingInit = this.resolveFromApiKey(config.apiKey);
|
|
@@ -12932,7 +12935,7 @@ var BugBearClient = class {
|
|
|
12932
12935
|
async updateAssignmentStatus(assignmentId, status, options) {
|
|
12933
12936
|
try {
|
|
12934
12937
|
await this.ensureReady();
|
|
12935
|
-
const { data: currentAssignment, error: fetchError } = await this.supabase.from("test_assignments").select("status, started_at").eq("id", assignmentId).single();
|
|
12938
|
+
const { data: currentAssignment, error: fetchError } = await this.supabase.from("test_assignments").select("status, started_at, tester_id, project_id").eq("id", assignmentId).single();
|
|
12936
12939
|
if (fetchError || !currentAssignment) {
|
|
12937
12940
|
console.error("BugBear: Assignment not found", {
|
|
12938
12941
|
message: fetchError?.message,
|
|
@@ -12953,6 +12956,19 @@ var BugBearClient = class {
|
|
|
12953
12956
|
const completedAt = /* @__PURE__ */ new Date();
|
|
12954
12957
|
durationSeconds = Math.round((completedAt.getTime() - startedAt.getTime()) / 1e3);
|
|
12955
12958
|
updateData.duration_seconds = durationSeconds;
|
|
12959
|
+
if (currentAssignment.tester_id && currentAssignment.project_id) {
|
|
12960
|
+
try {
|
|
12961
|
+
const { data: activeTime } = await this.supabase.rpc("compute_assignment_active_time", {
|
|
12962
|
+
p_tester_id: currentAssignment.tester_id,
|
|
12963
|
+
p_project_id: currentAssignment.project_id,
|
|
12964
|
+
p_started_at: currentAssignment.started_at,
|
|
12965
|
+
p_completed_at: updateData.completed_at
|
|
12966
|
+
});
|
|
12967
|
+
updateData.active_seconds = typeof activeTime === "number" ? activeTime : Math.min(durationSeconds, 1800);
|
|
12968
|
+
} catch {
|
|
12969
|
+
updateData.active_seconds = Math.min(durationSeconds, 1800);
|
|
12970
|
+
}
|
|
12971
|
+
}
|
|
12956
12972
|
}
|
|
12957
12973
|
}
|
|
12958
12974
|
if (options?.notes) {
|
|
@@ -13031,6 +13047,7 @@ var BugBearClient = class {
|
|
|
13031
13047
|
started_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13032
13048
|
completed_at: null,
|
|
13033
13049
|
duration_seconds: null,
|
|
13050
|
+
active_seconds: null,
|
|
13034
13051
|
skip_reason: null
|
|
13035
13052
|
}).eq("id", assignmentId).eq("status", current.status);
|
|
13036
13053
|
if (error) {
|
|
@@ -13880,6 +13897,7 @@ var BugBearClient = class {
|
|
|
13880
13897
|
lastMessageAt: row.last_message_at,
|
|
13881
13898
|
createdAt: row.created_at,
|
|
13882
13899
|
unreadCount: Number(row.unread_count) || 0,
|
|
13900
|
+
reporterName: row.reporter_name || void 0,
|
|
13883
13901
|
lastMessage: row.last_message_preview ? {
|
|
13884
13902
|
id: "",
|
|
13885
13903
|
threadId: row.thread_id,
|
|
@@ -14319,6 +14337,93 @@ var BugBearClient = class {
|
|
|
14319
14337
|
updatedAt: data.updated_at
|
|
14320
14338
|
};
|
|
14321
14339
|
}
|
|
14340
|
+
// ─── Passive Presence Tracking ──────────────────────────────
|
|
14341
|
+
/** Current presence session ID (null if not tracking). */
|
|
14342
|
+
get presenceSessionId() {
|
|
14343
|
+
return this._presenceSessionId;
|
|
14344
|
+
}
|
|
14345
|
+
/**
|
|
14346
|
+
* Start passive presence tracking for this tester.
|
|
14347
|
+
* Idempotent — reuses an existing active session if one exists.
|
|
14348
|
+
*/
|
|
14349
|
+
async startPresence(platform) {
|
|
14350
|
+
try {
|
|
14351
|
+
await this.ensureReady();
|
|
14352
|
+
const testerInfo = await this.getTesterInfo();
|
|
14353
|
+
if (!testerInfo) return null;
|
|
14354
|
+
const { data, error } = await this.supabase.rpc("upsert_tester_presence", {
|
|
14355
|
+
p_project_id: this.config.projectId,
|
|
14356
|
+
p_tester_id: testerInfo.id,
|
|
14357
|
+
p_platform: platform
|
|
14358
|
+
});
|
|
14359
|
+
if (error) {
|
|
14360
|
+
console.error("BugBear: Failed to start presence", formatPgError(error));
|
|
14361
|
+
return null;
|
|
14362
|
+
}
|
|
14363
|
+
this._presenceSessionId = data;
|
|
14364
|
+
this._presencePaused = false;
|
|
14365
|
+
this.startPresenceHeartbeat();
|
|
14366
|
+
return data;
|
|
14367
|
+
} catch (err) {
|
|
14368
|
+
console.error("BugBear: Error starting presence", err);
|
|
14369
|
+
return null;
|
|
14370
|
+
}
|
|
14371
|
+
}
|
|
14372
|
+
/** Gracefully end the current presence session. */
|
|
14373
|
+
async endPresence() {
|
|
14374
|
+
this.stopPresenceHeartbeat();
|
|
14375
|
+
if (!this._presenceSessionId) return;
|
|
14376
|
+
try {
|
|
14377
|
+
await this.supabase.rpc("end_tester_presence", {
|
|
14378
|
+
p_session_id: this._presenceSessionId
|
|
14379
|
+
});
|
|
14380
|
+
} catch {
|
|
14381
|
+
}
|
|
14382
|
+
this._presenceSessionId = null;
|
|
14383
|
+
}
|
|
14384
|
+
/** Pause heartbeat (tab hidden / app backgrounded). Sends one final beat. */
|
|
14385
|
+
pausePresence() {
|
|
14386
|
+
this._presencePaused = true;
|
|
14387
|
+
this.heartbeatPresence();
|
|
14388
|
+
}
|
|
14389
|
+
/** Resume heartbeat after pause. Restarts if session was cleaned up. */
|
|
14390
|
+
async resumePresence() {
|
|
14391
|
+
if (!this._presenceSessionId) return;
|
|
14392
|
+
this._presencePaused = false;
|
|
14393
|
+
try {
|
|
14394
|
+
const { data } = await this.supabase.rpc("heartbeat_tester_presence", {
|
|
14395
|
+
p_session_id: this._presenceSessionId
|
|
14396
|
+
});
|
|
14397
|
+
if (!data) {
|
|
14398
|
+
this._presenceSessionId = null;
|
|
14399
|
+
}
|
|
14400
|
+
} catch {
|
|
14401
|
+
this._presenceSessionId = null;
|
|
14402
|
+
}
|
|
14403
|
+
}
|
|
14404
|
+
async heartbeatPresence() {
|
|
14405
|
+
if (!this._presenceSessionId || this._presencePaused) return;
|
|
14406
|
+
try {
|
|
14407
|
+
const { data, error } = await this.supabase.rpc("heartbeat_tester_presence", {
|
|
14408
|
+
p_session_id: this._presenceSessionId
|
|
14409
|
+
});
|
|
14410
|
+
if (error || data === false) {
|
|
14411
|
+
this.stopPresenceHeartbeat();
|
|
14412
|
+
this._presenceSessionId = null;
|
|
14413
|
+
}
|
|
14414
|
+
} catch {
|
|
14415
|
+
}
|
|
14416
|
+
}
|
|
14417
|
+
startPresenceHeartbeat() {
|
|
14418
|
+
this.stopPresenceHeartbeat();
|
|
14419
|
+
this._presenceInterval = setInterval(() => this.heartbeatPresence(), 6e4);
|
|
14420
|
+
}
|
|
14421
|
+
stopPresenceHeartbeat() {
|
|
14422
|
+
if (this._presenceInterval) {
|
|
14423
|
+
clearInterval(this._presenceInterval);
|
|
14424
|
+
this._presenceInterval = null;
|
|
14425
|
+
}
|
|
14426
|
+
}
|
|
14322
14427
|
};
|
|
14323
14428
|
function createBugBear(config) {
|
|
14324
14429
|
return new BugBearClient(config);
|
|
@@ -14453,6 +14558,9 @@ function setActiveColors(palette) {
|
|
|
14453
14558
|
colors = palette;
|
|
14454
14559
|
shared = createSharedStyles();
|
|
14455
14560
|
}
|
|
14561
|
+
function withAlpha(hex, alpha) {
|
|
14562
|
+
return hex + Math.round(alpha * 255).toString(16).padStart(2, "0");
|
|
14563
|
+
}
|
|
14456
14564
|
function createSharedStyles() {
|
|
14457
14565
|
return import_react_native.StyleSheet.create({
|
|
14458
14566
|
card: {
|
|
@@ -14955,6 +15063,28 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
|
|
|
14955
15063
|
}
|
|
14956
15064
|
return () => subscription.remove();
|
|
14957
15065
|
}, [client]);
|
|
15066
|
+
(0, import_react.useEffect)(() => {
|
|
15067
|
+
if (!client || !isTester) return;
|
|
15068
|
+
let mounted = true;
|
|
15069
|
+
const platform = import_react_native2.Platform.OS === "ios" ? "ios" : "android";
|
|
15070
|
+
client.startPresence(platform);
|
|
15071
|
+
const subscription = import_react_native2.AppState.addEventListener("change", (nextState) => {
|
|
15072
|
+
if (nextState === "active") {
|
|
15073
|
+
client.resumePresence().then(() => {
|
|
15074
|
+
if (mounted && !client.presenceSessionId) {
|
|
15075
|
+
client.startPresence(platform);
|
|
15076
|
+
}
|
|
15077
|
+
});
|
|
15078
|
+
} else if (nextState === "background" || nextState === "inactive") {
|
|
15079
|
+
client.pausePresence();
|
|
15080
|
+
}
|
|
15081
|
+
});
|
|
15082
|
+
return () => {
|
|
15083
|
+
mounted = false;
|
|
15084
|
+
subscription.remove();
|
|
15085
|
+
client.endPresence();
|
|
15086
|
+
};
|
|
15087
|
+
}, [client, isTester]);
|
|
14958
15088
|
(0, import_react.useEffect)(() => {
|
|
14959
15089
|
if (!client || !isTester) return;
|
|
14960
15090
|
if (widgetMode === "qa" && !isQAEnabled) return;
|
|
@@ -16952,6 +17082,8 @@ function ReportScreen({ nav, prefill, autoCaptureUri, onAutoCaptureConsumed }) {
|
|
|
16952
17082
|
const [severity, setSeverity] = (0, import_react12.useState)("medium");
|
|
16953
17083
|
const [category, setCategory] = (0, import_react12.useState)(null);
|
|
16954
17084
|
const [description, setDescription] = (0, import_react12.useState)("");
|
|
17085
|
+
const [myIssues, setMyIssues] = (0, import_react12.useState)([]);
|
|
17086
|
+
const [similarReports, setSimilarReports] = (0, import_react12.useState)([]);
|
|
16955
17087
|
const [affectedScreen, setAffectedScreen] = (0, import_react12.useState)("");
|
|
16956
17088
|
const [submitting, setSubmitting] = (0, import_react12.useState)(false);
|
|
16957
17089
|
const [error, setError] = (0, import_react12.useState)(null);
|
|
@@ -16967,6 +17099,41 @@ function ReportScreen({ nav, prefill, autoCaptureUri, onAutoCaptureConsumed }) {
|
|
|
16967
17099
|
}, [autoCaptureUri, onAutoCaptureConsumed]);
|
|
16968
17100
|
const isRetestFailure = prefill?.type === "test_fail";
|
|
16969
17101
|
const isBugType = reportType === "bug" || reportType === "test_fail";
|
|
17102
|
+
(0, import_react12.useEffect)(() => {
|
|
17103
|
+
if (!client?.getIssues) return;
|
|
17104
|
+
let cancelled = false;
|
|
17105
|
+
const load = async () => {
|
|
17106
|
+
try {
|
|
17107
|
+
const [open, done] = await Promise.all([
|
|
17108
|
+
client.getIssues("open"),
|
|
17109
|
+
client.getIssues("done")
|
|
17110
|
+
]);
|
|
17111
|
+
if (!cancelled) setMyIssues([...open, ...done]);
|
|
17112
|
+
} catch {
|
|
17113
|
+
}
|
|
17114
|
+
};
|
|
17115
|
+
load();
|
|
17116
|
+
return () => {
|
|
17117
|
+
cancelled = true;
|
|
17118
|
+
};
|
|
17119
|
+
}, [client]);
|
|
17120
|
+
(0, import_react12.useEffect)(() => {
|
|
17121
|
+
if (description.length < 10 || myIssues.length === 0) {
|
|
17122
|
+
setSimilarReports([]);
|
|
17123
|
+
return;
|
|
17124
|
+
}
|
|
17125
|
+
const words = description.toLowerCase().split(/\s+/).filter((w) => w.length > 3);
|
|
17126
|
+
if (words.length === 0) {
|
|
17127
|
+
setSimilarReports([]);
|
|
17128
|
+
return;
|
|
17129
|
+
}
|
|
17130
|
+
const scored = myIssues.map((issue) => {
|
|
17131
|
+
const text = `${issue.title || ""} ${issue.description || ""}`.toLowerCase();
|
|
17132
|
+
const matches = words.filter((w) => text.includes(w)).length;
|
|
17133
|
+
return { issue, score: matches / words.length };
|
|
17134
|
+
}).filter((s2) => s2.score >= 0.3).sort((a, b) => b.score - a.score).slice(0, 3);
|
|
17135
|
+
setSimilarReports(scored.map((s2) => s2.issue));
|
|
17136
|
+
}, [description, myIssues]);
|
|
16970
17137
|
(0, import_react12.useEffect)(() => {
|
|
16971
17138
|
if (reportType === "feedback" || reportType === "suggestion") {
|
|
16972
17139
|
setCategory("other");
|
|
@@ -17041,7 +17208,41 @@ function ReportScreen({ nav, prefill, autoCaptureUri, onAutoCaptureConsumed }) {
|
|
|
17041
17208
|
numberOfLines: 4,
|
|
17042
17209
|
textAlignVertical: "top"
|
|
17043
17210
|
}
|
|
17044
|
-
)
|
|
17211
|
+
), similarReports.length > 0 && /* @__PURE__ */ import_react12.default.createElement(import_react_native11.View, { style: {
|
|
17212
|
+
marginTop: 8,
|
|
17213
|
+
padding: 12,
|
|
17214
|
+
borderRadius: 8,
|
|
17215
|
+
backgroundColor: withAlpha(colors.orange, 0.1),
|
|
17216
|
+
borderWidth: 1,
|
|
17217
|
+
borderColor: withAlpha(colors.orange, 0.3)
|
|
17218
|
+
} }, /* @__PURE__ */ import_react12.default.createElement(import_react_native11.Text, { style: { fontSize: 12, fontWeight: "600", color: colors.orange, marginBottom: 8 } }, "Similar reports you've already filed:"), similarReports.map((issue) => /* @__PURE__ */ import_react12.default.createElement(
|
|
17219
|
+
import_react_native11.TouchableOpacity,
|
|
17220
|
+
{
|
|
17221
|
+
key: issue.id,
|
|
17222
|
+
onPress: () => nav.push({ name: "ISSUE_DETAIL", issue }),
|
|
17223
|
+
style: {
|
|
17224
|
+
flexDirection: "row",
|
|
17225
|
+
alignItems: "center",
|
|
17226
|
+
gap: 8,
|
|
17227
|
+
paddingVertical: 6
|
|
17228
|
+
}
|
|
17229
|
+
},
|
|
17230
|
+
/* @__PURE__ */ import_react12.default.createElement(import_react_native11.View, { style: {
|
|
17231
|
+
width: 8,
|
|
17232
|
+
height: 8,
|
|
17233
|
+
borderRadius: 4,
|
|
17234
|
+
backgroundColor: issue.severity === "critical" ? colors.red : issue.severity === "high" ? colors.orange : colors.yellow
|
|
17235
|
+
} }),
|
|
17236
|
+
/* @__PURE__ */ import_react12.default.createElement(
|
|
17237
|
+
import_react_native11.Text,
|
|
17238
|
+
{
|
|
17239
|
+
numberOfLines: 1,
|
|
17240
|
+
style: { fontSize: 12, color: colors.textPrimary, flex: 1 }
|
|
17241
|
+
},
|
|
17242
|
+
issue.title
|
|
17243
|
+
),
|
|
17244
|
+
/* @__PURE__ */ import_react12.default.createElement(import_react_native11.Text, { style: { fontSize: 11, color: colors.textMuted } }, issue.status)
|
|
17245
|
+
)))), /* @__PURE__ */ import_react12.default.createElement(
|
|
17045
17246
|
ImagePickerButtons,
|
|
17046
17247
|
{
|
|
17047
17248
|
images: images.images,
|
|
@@ -17097,7 +17298,41 @@ function ReportScreen({ nav, prefill, autoCaptureUri, onAutoCaptureConsumed }) {
|
|
|
17097
17298
|
numberOfLines: 4,
|
|
17098
17299
|
textAlignVertical: "top"
|
|
17099
17300
|
}
|
|
17100
|
-
)
|
|
17301
|
+
), similarReports.length > 0 && /* @__PURE__ */ import_react12.default.createElement(import_react_native11.View, { style: {
|
|
17302
|
+
marginTop: 8,
|
|
17303
|
+
padding: 12,
|
|
17304
|
+
borderRadius: 8,
|
|
17305
|
+
backgroundColor: withAlpha(colors.orange, 0.1),
|
|
17306
|
+
borderWidth: 1,
|
|
17307
|
+
borderColor: withAlpha(colors.orange, 0.3)
|
|
17308
|
+
} }, /* @__PURE__ */ import_react12.default.createElement(import_react_native11.Text, { style: { fontSize: 12, fontWeight: "600", color: colors.orange, marginBottom: 8 } }, "Similar reports you've already filed:"), similarReports.map((issue) => /* @__PURE__ */ import_react12.default.createElement(
|
|
17309
|
+
import_react_native11.TouchableOpacity,
|
|
17310
|
+
{
|
|
17311
|
+
key: issue.id,
|
|
17312
|
+
onPress: () => nav.push({ name: "ISSUE_DETAIL", issue }),
|
|
17313
|
+
style: {
|
|
17314
|
+
flexDirection: "row",
|
|
17315
|
+
alignItems: "center",
|
|
17316
|
+
gap: 8,
|
|
17317
|
+
paddingVertical: 6
|
|
17318
|
+
}
|
|
17319
|
+
},
|
|
17320
|
+
/* @__PURE__ */ import_react12.default.createElement(import_react_native11.View, { style: {
|
|
17321
|
+
width: 8,
|
|
17322
|
+
height: 8,
|
|
17323
|
+
borderRadius: 4,
|
|
17324
|
+
backgroundColor: issue.severity === "critical" ? colors.red : issue.severity === "high" ? colors.orange : colors.yellow
|
|
17325
|
+
} }),
|
|
17326
|
+
/* @__PURE__ */ import_react12.default.createElement(
|
|
17327
|
+
import_react_native11.Text,
|
|
17328
|
+
{
|
|
17329
|
+
numberOfLines: 1,
|
|
17330
|
+
style: { fontSize: 12, color: colors.textPrimary, flex: 1 }
|
|
17331
|
+
},
|
|
17332
|
+
issue.title
|
|
17333
|
+
),
|
|
17334
|
+
/* @__PURE__ */ import_react12.default.createElement(import_react_native11.Text, { style: { fontSize: 11, color: colors.textMuted } }, issue.status)
|
|
17335
|
+
)))), isBugType && /* @__PURE__ */ import_react12.default.createElement(import_react_native11.View, { style: styles5.section }, /* @__PURE__ */ import_react12.default.createElement(import_react_native11.Text, { style: shared.label }, "Which screen?"), /* @__PURE__ */ import_react12.default.createElement(
|
|
17101
17336
|
import_react_native11.TextInput,
|
|
17102
17337
|
{
|
|
17103
17338
|
style: styles5.screenInput,
|
|
@@ -17178,6 +17413,19 @@ var import_react_native13 = require("react-native");
|
|
|
17178
17413
|
function MessageListScreen({ nav }) {
|
|
17179
17414
|
const { threads, unreadCount, refreshThreads, dashboardUrl, isLoading, widgetColorScheme } = useBugBear();
|
|
17180
17415
|
const styles5 = (0, import_react14.useMemo)(() => createStyles7(), [widgetColorScheme]);
|
|
17416
|
+
const [activeFilter, setActiveFilter] = (0, import_react14.useState)("all");
|
|
17417
|
+
const filteredThreads = threads.filter((thread) => {
|
|
17418
|
+
if (activeFilter === "all") return true;
|
|
17419
|
+
if (activeFilter === "unread") return thread.unreadCount > 0;
|
|
17420
|
+
return thread.threadType === activeFilter;
|
|
17421
|
+
});
|
|
17422
|
+
const filterChips = [
|
|
17423
|
+
{ key: "all", label: "All" },
|
|
17424
|
+
{ key: "report", label: "Bug Reports" },
|
|
17425
|
+
{ key: "direct", label: "Direct" },
|
|
17426
|
+
{ key: "announcement", label: "Announcements" },
|
|
17427
|
+
{ key: "unread", label: "Unread", count: threads.filter((t) => t.unreadCount > 0).length }
|
|
17428
|
+
];
|
|
17181
17429
|
if (isLoading) return /* @__PURE__ */ import_react14.default.createElement(MessageListScreenSkeleton, null);
|
|
17182
17430
|
return /* @__PURE__ */ import_react14.default.createElement(import_react_native13.View, null, /* @__PURE__ */ import_react14.default.createElement(
|
|
17183
17431
|
import_react_native13.TouchableOpacity,
|
|
@@ -17186,14 +17434,54 @@ function MessageListScreen({ nav }) {
|
|
|
17186
17434
|
onPress: () => nav.push({ name: "COMPOSE_MESSAGE" })
|
|
17187
17435
|
},
|
|
17188
17436
|
/* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: styles5.newMsgText }, "\u2709\uFE0F New Message")
|
|
17189
|
-
),
|
|
17437
|
+
), /* @__PURE__ */ import_react14.default.createElement(
|
|
17438
|
+
import_react_native13.ScrollView,
|
|
17439
|
+
{
|
|
17440
|
+
horizontal: true,
|
|
17441
|
+
showsHorizontalScrollIndicator: false,
|
|
17442
|
+
style: { paddingBottom: 12 },
|
|
17443
|
+
contentContainerStyle: { paddingHorizontal: 16, gap: 8 }
|
|
17444
|
+
},
|
|
17445
|
+
filterChips.map((chip) => /* @__PURE__ */ import_react14.default.createElement(
|
|
17446
|
+
import_react_native13.TouchableOpacity,
|
|
17447
|
+
{
|
|
17448
|
+
key: chip.key,
|
|
17449
|
+
onPress: () => setActiveFilter(chip.key),
|
|
17450
|
+
style: {
|
|
17451
|
+
paddingVertical: 6,
|
|
17452
|
+
paddingHorizontal: 12,
|
|
17453
|
+
borderRadius: 16,
|
|
17454
|
+
borderWidth: 1,
|
|
17455
|
+
borderColor: activeFilter === chip.key ? colors.blue : colors.border,
|
|
17456
|
+
backgroundColor: activeFilter === chip.key ? withAlpha(colors.blue, 0.15) : "transparent",
|
|
17457
|
+
flexDirection: "row",
|
|
17458
|
+
alignItems: "center",
|
|
17459
|
+
gap: 4
|
|
17460
|
+
}
|
|
17461
|
+
},
|
|
17462
|
+
/* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: {
|
|
17463
|
+
fontSize: 12,
|
|
17464
|
+
fontWeight: "500",
|
|
17465
|
+
color: activeFilter === chip.key ? colors.blue : colors.textSecondary
|
|
17466
|
+
} }, chip.label),
|
|
17467
|
+
chip.count !== void 0 && chip.count > 0 && /* @__PURE__ */ import_react14.default.createElement(import_react_native13.View, { style: {
|
|
17468
|
+
backgroundColor: colors.blue,
|
|
17469
|
+
borderRadius: 8,
|
|
17470
|
+
minWidth: 16,
|
|
17471
|
+
height: 16,
|
|
17472
|
+
justifyContent: "center",
|
|
17473
|
+
alignItems: "center",
|
|
17474
|
+
paddingHorizontal: 4
|
|
17475
|
+
} }, /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: { fontSize: 10, fontWeight: "bold", color: colors.onPrimary } }, chip.count))
|
|
17476
|
+
))
|
|
17477
|
+
), filteredThreads.length === 0 ? /* @__PURE__ */ import_react14.default.createElement(import_react_native13.View, { style: shared.emptyState }, /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: shared.emptyEmoji }, "\u{1F4AC}"), /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: shared.emptyTitle }, "No messages yet"), /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: shared.emptySubtitle }, "Start a conversation or wait for messages from admins")) : /* @__PURE__ */ import_react14.default.createElement(import_react_native13.View, null, filteredThreads.map((thread) => /* @__PURE__ */ import_react14.default.createElement(
|
|
17190
17478
|
import_react_native13.TouchableOpacity,
|
|
17191
17479
|
{
|
|
17192
17480
|
key: thread.id,
|
|
17193
17481
|
style: [styles5.threadItem, thread.unreadCount > 0 && styles5.threadItemUnread],
|
|
17194
17482
|
onPress: () => nav.push({ name: "THREAD_DETAIL", thread })
|
|
17195
17483
|
},
|
|
17196
|
-
/* @__PURE__ */ import_react14.default.createElement(import_react_native13.View, { style: styles5.threadLeft }, /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: styles5.threadIcon }, getThreadTypeIcon(thread.threadType)), /* @__PURE__ */ import_react14.default.createElement(import_react_native13.View, { style: styles5.threadInfo }, /* @__PURE__ */ import_react14.default.createElement(import_react_native13.View, { style: styles5.threadTitleRow }, thread.isPinned && /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: styles5.pinIcon }, "\u{1F4CC}"), /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: styles5.threadSubject, numberOfLines: 1 }, thread.subject || "No subject")), thread.lastMessage && /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: styles5.threadPreview, numberOfLines: 1 }, thread.lastMessage.senderName, ": ", thread.lastMessage.content))),
|
|
17484
|
+
/* @__PURE__ */ import_react14.default.createElement(import_react_native13.View, { style: styles5.threadLeft }, /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: styles5.threadIcon }, getThreadTypeIcon(thread.threadType)), /* @__PURE__ */ import_react14.default.createElement(import_react_native13.View, { style: styles5.threadInfo }, /* @__PURE__ */ import_react14.default.createElement(import_react_native13.View, { style: styles5.threadTitleRow }, thread.isPinned && /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: styles5.pinIcon }, "\u{1F4CC}"), /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: styles5.threadSubject, numberOfLines: 1 }, thread.subject || "No subject")), thread.threadType === "report" && thread.reporterName && /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: { fontSize: 11, color: colors.textMuted } }, "Reported by: ", thread.reporterName), thread.lastMessage && /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: styles5.threadPreview, numberOfLines: 1 }, thread.lastMessage.senderName, ": ", thread.lastMessage.content))),
|
|
17197
17485
|
/* @__PURE__ */ import_react14.default.createElement(import_react_native13.View, { style: styles5.threadRight }, /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: styles5.threadTime }, formatRelativeTime(thread.lastMessageAt)), thread.unreadCount > 0 && /* @__PURE__ */ import_react14.default.createElement(import_react_native13.View, { style: styles5.unreadBadge }, /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: styles5.unreadText }, thread.unreadCount)), thread.priority !== "normal" && /* @__PURE__ */ import_react14.default.createElement(import_react_native13.View, { style: [styles5.priorityDot, { backgroundColor: getPriorityColor(thread.priority) }] }))
|
|
17198
17486
|
))), dashboardUrl && /* @__PURE__ */ import_react14.default.createElement(
|
|
17199
17487
|
import_react_native13.TouchableOpacity,
|
|
@@ -17203,7 +17491,7 @@ function MessageListScreen({ nav }) {
|
|
|
17203
17491
|
activeOpacity: 0.7
|
|
17204
17492
|
},
|
|
17205
17493
|
/* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: styles5.dashboardLinkText }, "\u{1F310}", " View on Dashboard ", "\u2192")
|
|
17206
|
-
), /* @__PURE__ */ import_react14.default.createElement(import_react_native13.View, { style: styles5.footer }, /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: styles5.footerText },
|
|
17494
|
+
), /* @__PURE__ */ import_react14.default.createElement(import_react_native13.View, { style: styles5.footer }, /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: styles5.footerText }, filteredThreads.length, " thread", filteredThreads.length !== 1 ? "s" : "", " \xB7 ", unreadCount, " unread"), /* @__PURE__ */ import_react14.default.createElement(import_react_native13.TouchableOpacity, { onPress: refreshThreads }, /* @__PURE__ */ import_react14.default.createElement(import_react_native13.Text, { style: styles5.refreshText }, "\u21BB Refresh"))));
|
|
17207
17495
|
}
|
|
17208
17496
|
function createStyles7() {
|
|
17209
17497
|
return import_react_native13.StyleSheet.create({
|
|
@@ -17584,7 +17872,17 @@ function IssueListScreen({ nav, category }) {
|
|
|
17584
17872
|
const [loading, setLoading] = (0, import_react18.useState)(true);
|
|
17585
17873
|
const [counts, setCounts] = (0, import_react18.useState)(null);
|
|
17586
17874
|
const [sortMode, setSortMode] = (0, import_react18.useState)("severity");
|
|
17875
|
+
const [searchQuery, setSearchQuery] = (0, import_react18.useState)("");
|
|
17876
|
+
const [debouncedQuery, setDebouncedQuery] = (0, import_react18.useState)("");
|
|
17587
17877
|
const config = CATEGORY_CONFIG[activeCategory];
|
|
17878
|
+
(0, import_react18.useEffect)(() => {
|
|
17879
|
+
const timer = setTimeout(() => setDebouncedQuery(searchQuery), 300);
|
|
17880
|
+
return () => clearTimeout(timer);
|
|
17881
|
+
}, [searchQuery]);
|
|
17882
|
+
(0, import_react18.useEffect)(() => {
|
|
17883
|
+
setSearchQuery("");
|
|
17884
|
+
setDebouncedQuery("");
|
|
17885
|
+
}, [activeCategory]);
|
|
17588
17886
|
(0, import_react18.useEffect)(() => {
|
|
17589
17887
|
if (!client) return;
|
|
17590
17888
|
client.getIssueCounts().then(setCounts).catch(() => {
|
|
@@ -17624,6 +17922,9 @@ function IssueListScreen({ nav, category }) {
|
|
|
17624
17922
|
}
|
|
17625
17923
|
return sorted;
|
|
17626
17924
|
}, [issues, sortMode]);
|
|
17925
|
+
const searchFilteredIssues = debouncedQuery ? sortedIssues.filter(
|
|
17926
|
+
(issue) => (issue.title || "").toLowerCase().includes(debouncedQuery.toLowerCase()) || (issue.description || "").toLowerCase().includes(debouncedQuery.toLowerCase())
|
|
17927
|
+
) : sortedIssues;
|
|
17627
17928
|
return /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, null, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles5.tabBar }, CATEGORIES.map((cat) => {
|
|
17628
17929
|
const catConfig = CATEGORY_CONFIG[cat];
|
|
17629
17930
|
const isActive = activeCategory === cat;
|
|
@@ -17670,7 +17971,25 @@ function IssueListScreen({ nav, category }) {
|
|
|
17670
17971
|
styles5.sortBtnText,
|
|
17671
17972
|
sortMode === s2.key && styles5.sortBtnTextActive
|
|
17672
17973
|
] }, s2.label)
|
|
17673
|
-
))),
|
|
17974
|
+
))), /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: { paddingHorizontal: 16, paddingBottom: 12 } }, /* @__PURE__ */ import_react18.default.createElement(
|
|
17975
|
+
import_react_native17.TextInput,
|
|
17976
|
+
{
|
|
17977
|
+
value: searchQuery,
|
|
17978
|
+
onChangeText: setSearchQuery,
|
|
17979
|
+
placeholder: "Search my reports...",
|
|
17980
|
+
placeholderTextColor: colors.textMuted,
|
|
17981
|
+
style: {
|
|
17982
|
+
padding: 8,
|
|
17983
|
+
paddingHorizontal: 12,
|
|
17984
|
+
borderRadius: 8,
|
|
17985
|
+
borderWidth: 1,
|
|
17986
|
+
borderColor: colors.border,
|
|
17987
|
+
backgroundColor: colors.card,
|
|
17988
|
+
color: colors.textPrimary,
|
|
17989
|
+
fontSize: 13
|
|
17990
|
+
}
|
|
17991
|
+
}
|
|
17992
|
+
)), loading ? /* @__PURE__ */ import_react18.default.createElement(IssueListScreenSkeleton, null) : searchFilteredIssues.length === 0 ? /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles5.emptyContainer }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles5.emptyIcon }, debouncedQuery ? "\u{1F50D}" : config.emptyIcon), /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles5.emptyText }, debouncedQuery ? "No matching issues" : config.emptyText)) : searchFilteredIssues.map((issue) => /* @__PURE__ */ import_react18.default.createElement(
|
|
17674
17993
|
import_react_native17.TouchableOpacity,
|
|
17675
17994
|
{
|
|
17676
17995
|
key: issue.id,
|
|
@@ -18196,11 +18515,13 @@ function SessionStartScreen({ nav }) {
|
|
|
18196
18515
|
const styles5 = (0, import_react20.useMemo)(() => createStyles13(), [widgetColorScheme]);
|
|
18197
18516
|
const [focusArea, setFocusArea] = (0, import_react20.useState)("");
|
|
18198
18517
|
const [isStarting, setIsStarting] = (0, import_react20.useState)(false);
|
|
18518
|
+
const [error, setError] = (0, import_react20.useState)(null);
|
|
18199
18519
|
const trackNames = Array.from(new Set(
|
|
18200
18520
|
assignments.filter((a) => a.testCase.track?.name).map((a) => a.testCase.track.name)
|
|
18201
18521
|
)).slice(0, 6);
|
|
18202
18522
|
const handleStart = async () => {
|
|
18203
18523
|
if (isStarting) return;
|
|
18524
|
+
setError(null);
|
|
18204
18525
|
import_react_native19.Keyboard.dismiss();
|
|
18205
18526
|
setIsStarting(true);
|
|
18206
18527
|
try {
|
|
@@ -18209,6 +18530,10 @@ function SessionStartScreen({ nav }) {
|
|
|
18209
18530
|
});
|
|
18210
18531
|
if (result.success) {
|
|
18211
18532
|
nav.replace({ name: "SESSION_ACTIVE" });
|
|
18533
|
+
} else {
|
|
18534
|
+
const msg = result.error || "Failed to start session. Please try again.";
|
|
18535
|
+
console.warn("BugBear: Session start failed:", msg);
|
|
18536
|
+
setError(msg);
|
|
18212
18537
|
}
|
|
18213
18538
|
} finally {
|
|
18214
18539
|
setIsStarting(false);
|
|
@@ -18234,7 +18559,7 @@ function SessionStartScreen({ nav }) {
|
|
|
18234
18559
|
activeOpacity: 0.7
|
|
18235
18560
|
},
|
|
18236
18561
|
/* @__PURE__ */ import_react20.default.createElement(import_react_native19.Text, { style: [styles5.chipText, focusArea === name && styles5.chipTextActive] }, name)
|
|
18237
|
-
)))), /* @__PURE__ */ import_react20.default.createElement(
|
|
18562
|
+
)))), error && /* @__PURE__ */ import_react20.default.createElement(import_react_native19.View, { style: styles5.errorBox }, /* @__PURE__ */ import_react20.default.createElement(import_react_native19.Text, { style: styles5.errorText }, error)), /* @__PURE__ */ import_react20.default.createElement(
|
|
18238
18563
|
import_react_native19.TouchableOpacity,
|
|
18239
18564
|
{
|
|
18240
18565
|
style: [styles5.startBtn, isStarting && styles5.startBtnDisabled],
|
|
@@ -18313,6 +18638,20 @@ function createStyles13() {
|
|
|
18313
18638
|
chipTextActive: {
|
|
18314
18639
|
color: colors.blueLight
|
|
18315
18640
|
},
|
|
18641
|
+
errorBox: {
|
|
18642
|
+
marginBottom: 12,
|
|
18643
|
+
paddingVertical: 10,
|
|
18644
|
+
paddingHorizontal: 12,
|
|
18645
|
+
backgroundColor: "rgba(239, 68, 68, 0.1)",
|
|
18646
|
+
borderWidth: 1,
|
|
18647
|
+
borderColor: "rgba(239, 68, 68, 0.3)",
|
|
18648
|
+
borderRadius: 8
|
|
18649
|
+
},
|
|
18650
|
+
errorText: {
|
|
18651
|
+
fontSize: 13,
|
|
18652
|
+
color: "#f87171",
|
|
18653
|
+
lineHeight: 18
|
|
18654
|
+
},
|
|
18316
18655
|
startBtn: {
|
|
18317
18656
|
paddingVertical: 14,
|
|
18318
18657
|
backgroundColor: colors.blueSurface,
|
|
@@ -18790,14 +19129,31 @@ function BugBearButton({
|
|
|
18790
19129
|
}) {
|
|
18791
19130
|
const { shouldShowWidget, testerInfo, isLoading, unreadCount, assignments, widgetMode, widgetColorScheme } = useBugBear();
|
|
18792
19131
|
const { currentScreen, canGoBack, push, pop, replace, reset } = useNavigation();
|
|
18793
|
-
const [
|
|
19132
|
+
const [panelVisible, setPanelVisible] = (0, import_react23.useState)(false);
|
|
19133
|
+
const panelAnim = (0, import_react23.useRef)(new import_react_native22.Animated.Value(0)).current;
|
|
18794
19134
|
const styles5 = (0, import_react23.useMemo)(() => createStyles16(), [widgetColorScheme]);
|
|
18795
19135
|
const screenCaptureRef = (0, import_react23.useRef)(null);
|
|
18796
|
-
const
|
|
19136
|
+
const openPanel = () => {
|
|
18797
19137
|
captureAppScreen().then((uri) => {
|
|
18798
19138
|
screenCaptureRef.current = uri;
|
|
18799
19139
|
});
|
|
18800
|
-
|
|
19140
|
+
setPanelVisible(true);
|
|
19141
|
+
import_react_native22.Animated.spring(panelAnim, {
|
|
19142
|
+
toValue: 1,
|
|
19143
|
+
useNativeDriver: true,
|
|
19144
|
+
friction: 8,
|
|
19145
|
+
tension: 65
|
|
19146
|
+
}).start();
|
|
19147
|
+
};
|
|
19148
|
+
const closePanel = () => {
|
|
19149
|
+
import_react_native22.Keyboard.dismiss();
|
|
19150
|
+
import_react_native22.Animated.timing(panelAnim, {
|
|
19151
|
+
toValue: 0,
|
|
19152
|
+
duration: 250,
|
|
19153
|
+
useNativeDriver: true
|
|
19154
|
+
}).start(() => {
|
|
19155
|
+
setPanelVisible(false);
|
|
19156
|
+
});
|
|
18801
19157
|
};
|
|
18802
19158
|
const getInitialPosition = () => {
|
|
18803
19159
|
const buttonSize = 56;
|
|
@@ -18848,7 +19204,7 @@ function BugBearButton({
|
|
|
18848
19204
|
tension: 40
|
|
18849
19205
|
}).start();
|
|
18850
19206
|
if (!isDragging.current && Math.abs(gs.dx) < 5 && Math.abs(gs.dy) < 5) {
|
|
18851
|
-
|
|
19207
|
+
openPanel();
|
|
18852
19208
|
}
|
|
18853
19209
|
isDragging.current = false;
|
|
18854
19210
|
}
|
|
@@ -18856,6 +19212,19 @@ function BugBearButton({
|
|
|
18856
19212
|
).current;
|
|
18857
19213
|
const pendingTests = widgetMode === "qa" ? assignments.filter((a) => a.status === "pending" || a.status === "in_progress").length : 0;
|
|
18858
19214
|
const badgeCount = pendingTests + unreadCount;
|
|
19215
|
+
(0, import_react23.useEffect)(() => {
|
|
19216
|
+
if (!panelVisible || import_react_native22.Platform.OS !== "android") return;
|
|
19217
|
+
const handler = import_react_native22.BackHandler.addEventListener("hardwareBackPress", () => {
|
|
19218
|
+
if (canGoBack) {
|
|
19219
|
+
import_react_native22.Keyboard.dismiss();
|
|
19220
|
+
pop();
|
|
19221
|
+
} else {
|
|
19222
|
+
closePanel();
|
|
19223
|
+
}
|
|
19224
|
+
return true;
|
|
19225
|
+
});
|
|
19226
|
+
return () => handler.remove();
|
|
19227
|
+
}, [panelVisible, canGoBack]);
|
|
18859
19228
|
if (!shouldShowWidget) return null;
|
|
18860
19229
|
const getHeaderTitle = () => {
|
|
18861
19230
|
switch (currentScreen.name) {
|
|
@@ -18894,8 +19263,7 @@ function BugBearButton({
|
|
|
18894
19263
|
}
|
|
18895
19264
|
};
|
|
18896
19265
|
const handleClose = () => {
|
|
18897
|
-
|
|
18898
|
-
setModalVisible(false);
|
|
19266
|
+
closePanel();
|
|
18899
19267
|
};
|
|
18900
19268
|
const nav = {
|
|
18901
19269
|
push: (screen) => {
|
|
@@ -18967,7 +19335,7 @@ function BugBearButton({
|
|
|
18967
19335
|
return /* @__PURE__ */ import_react23.default.createElement(HomeScreen, { nav });
|
|
18968
19336
|
}
|
|
18969
19337
|
};
|
|
18970
|
-
return /* @__PURE__ */ import_react23.default.createElement(import_react23.default.Fragment, null, /* @__PURE__ */ import_react23.default.createElement(
|
|
19338
|
+
return /* @__PURE__ */ import_react23.default.createElement(import_react23.default.Fragment, null, !panelVisible && /* @__PURE__ */ import_react23.default.createElement(
|
|
18971
19339
|
import_react_native22.Animated.View,
|
|
18972
19340
|
{
|
|
18973
19341
|
style: [styles5.fabContainer, { transform: pan.getTranslateTransform() }, buttonStyle],
|
|
@@ -18977,27 +19345,37 @@ function BugBearButton({
|
|
|
18977
19345
|
import_react_native22.TouchableOpacity,
|
|
18978
19346
|
{
|
|
18979
19347
|
style: styles5.fab,
|
|
18980
|
-
onPress:
|
|
19348
|
+
onPress: openPanel,
|
|
18981
19349
|
activeOpacity: draggable ? 1 : 0.7
|
|
18982
19350
|
},
|
|
18983
19351
|
/* @__PURE__ */ import_react23.default.createElement(import_react_native22.Image, { source: { uri: BUGBEAR_LOGO_BASE64 }, style: styles5.fabIcon }),
|
|
18984
19352
|
badgeCount > 0 && /* @__PURE__ */ import_react23.default.createElement(import_react_native22.View, { style: styles5.badge }, /* @__PURE__ */ import_react23.default.createElement(import_react_native22.Text, { style: styles5.badgeText }, badgeCount > 9 ? "9+" : badgeCount))
|
|
18985
19353
|
)
|
|
18986
|
-
), /* @__PURE__ */ import_react23.default.createElement(
|
|
18987
|
-
import_react_native22.
|
|
19354
|
+
), panelVisible && /* @__PURE__ */ import_react23.default.createElement(import_react_native22.View, { style: styles5.panelWrapper, pointerEvents: "box-none" }, /* @__PURE__ */ import_react23.default.createElement(
|
|
19355
|
+
import_react_native22.KeyboardAvoidingView,
|
|
18988
19356
|
{
|
|
18989
|
-
|
|
18990
|
-
|
|
18991
|
-
|
|
18992
|
-
onRequestClose: handleClose
|
|
19357
|
+
behavior: import_react_native22.Platform.OS === "ios" ? "padding" : "height",
|
|
19358
|
+
style: styles5.panelKeyboardAvoid,
|
|
19359
|
+
pointerEvents: "box-none"
|
|
18993
19360
|
},
|
|
18994
19361
|
/* @__PURE__ */ import_react23.default.createElement(
|
|
18995
|
-
import_react_native22.
|
|
19362
|
+
import_react_native22.Animated.View,
|
|
18996
19363
|
{
|
|
18997
|
-
|
|
18998
|
-
|
|
19364
|
+
style: [
|
|
19365
|
+
styles5.panelContainer,
|
|
19366
|
+
{
|
|
19367
|
+
transform: [{
|
|
19368
|
+
translateY: panelAnim.interpolate({
|
|
19369
|
+
inputRange: [0, 1],
|
|
19370
|
+
outputRange: [screenHeight, 0]
|
|
19371
|
+
})
|
|
19372
|
+
}]
|
|
19373
|
+
}
|
|
19374
|
+
]
|
|
18999
19375
|
},
|
|
19000
|
-
/* @__PURE__ */ import_react23.default.createElement(import_react_native22.View, { style: styles5.
|
|
19376
|
+
/* @__PURE__ */ import_react23.default.createElement(import_react_native22.View, { style: styles5.panelHandle }, /* @__PURE__ */ import_react23.default.createElement(import_react_native22.View, { style: styles5.panelHandleBar })),
|
|
19377
|
+
/* @__PURE__ */ import_react23.default.createElement(import_react_native22.View, { style: styles5.header }, /* @__PURE__ */ import_react23.default.createElement(import_react_native22.View, { style: styles5.headerLeft }, canGoBack ? /* @__PURE__ */ import_react23.default.createElement(import_react_native22.TouchableOpacity, { onPress: () => nav.pop(), style: styles5.backButton }, /* @__PURE__ */ import_react23.default.createElement(import_react_native22.Text, { style: styles5.backText }, "\u2190 Back")) : /* @__PURE__ */ import_react23.default.createElement(import_react_native22.View, { style: styles5.headerTitleRow }, /* @__PURE__ */ import_react23.default.createElement(import_react_native22.Text, { style: styles5.headerTitle }, "BugBear"), testerInfo && /* @__PURE__ */ import_react23.default.createElement(import_react_native22.TouchableOpacity, { onPress: () => push({ name: "PROFILE" }) }, /* @__PURE__ */ import_react23.default.createElement(import_react_native22.Text, { style: styles5.headerName }, testerInfo.name, " \u270E")))), getHeaderTitle() ? /* @__PURE__ */ import_react23.default.createElement(import_react_native22.Text, { style: styles5.headerScreenTitle, numberOfLines: 1 }, getHeaderTitle()) : null, /* @__PURE__ */ import_react23.default.createElement(import_react_native22.View, { style: styles5.headerActions }, currentScreen.name !== "HOME" && /* @__PURE__ */ import_react23.default.createElement(import_react_native22.TouchableOpacity, { onPress: () => nav.reset(), style: styles5.homeButton }, /* @__PURE__ */ import_react23.default.createElement(import_react_native22.Text, { style: styles5.homeIcon }, "\u2302")), /* @__PURE__ */ import_react23.default.createElement(import_react_native22.TouchableOpacity, { onPress: handleClose, style: styles5.closeButton }, /* @__PURE__ */ import_react23.default.createElement(import_react_native22.Text, { style: styles5.closeText }, "\u2715")))),
|
|
19378
|
+
/* @__PURE__ */ import_react23.default.createElement(
|
|
19001
19379
|
import_react_native22.ScrollView,
|
|
19002
19380
|
{
|
|
19003
19381
|
style: styles5.content,
|
|
@@ -19006,9 +19384,9 @@ function BugBearButton({
|
|
|
19006
19384
|
showsVerticalScrollIndicator: false
|
|
19007
19385
|
},
|
|
19008
19386
|
isLoading ? /* @__PURE__ */ import_react23.default.createElement(import_react_native22.View, { style: styles5.loadingContainer }, /* @__PURE__ */ import_react23.default.createElement(import_react_native22.ActivityIndicator, { size: "large", color: colors.blue }), /* @__PURE__ */ import_react23.default.createElement(import_react_native22.Text, { style: styles5.loadingText }, "Loading...")) : renderScreen()
|
|
19009
|
-
)
|
|
19387
|
+
)
|
|
19010
19388
|
)
|
|
19011
|
-
));
|
|
19389
|
+
)));
|
|
19012
19390
|
}
|
|
19013
19391
|
function createStyles16() {
|
|
19014
19392
|
return import_react_native22.StyleSheet.create({
|
|
@@ -19052,18 +19430,42 @@ function createStyles16() {
|
|
|
19052
19430
|
fontSize: 11,
|
|
19053
19431
|
fontWeight: "700"
|
|
19054
19432
|
},
|
|
19055
|
-
// Modal
|
|
19056
|
-
|
|
19433
|
+
// Panel (replaces Modal — no backdrop, app stays interactive)
|
|
19434
|
+
panelWrapper: {
|
|
19435
|
+
position: "absolute",
|
|
19436
|
+
top: 0,
|
|
19437
|
+
left: 0,
|
|
19438
|
+
right: 0,
|
|
19439
|
+
bottom: 0,
|
|
19440
|
+
zIndex: 9998,
|
|
19441
|
+
justifyContent: "flex-end"
|
|
19442
|
+
},
|
|
19443
|
+
panelKeyboardAvoid: {
|
|
19057
19444
|
flex: 1,
|
|
19058
|
-
justifyContent: "flex-end"
|
|
19059
|
-
backgroundColor: "rgba(0,0,0,0.5)"
|
|
19445
|
+
justifyContent: "flex-end"
|
|
19060
19446
|
},
|
|
19061
|
-
|
|
19447
|
+
panelContainer: {
|
|
19062
19448
|
backgroundColor: colors.bg,
|
|
19063
19449
|
borderTopLeftRadius: 20,
|
|
19064
19450
|
borderTopRightRadius: 20,
|
|
19065
|
-
maxHeight: "
|
|
19066
|
-
minHeight: "
|
|
19451
|
+
maxHeight: "70%",
|
|
19452
|
+
minHeight: "40%",
|
|
19453
|
+
shadowColor: colors.onBright,
|
|
19454
|
+
shadowOffset: { width: 0, height: -4 },
|
|
19455
|
+
shadowOpacity: 0.25,
|
|
19456
|
+
shadowRadius: 12,
|
|
19457
|
+
elevation: 16
|
|
19458
|
+
},
|
|
19459
|
+
panelHandle: {
|
|
19460
|
+
alignItems: "center",
|
|
19461
|
+
paddingTop: 8,
|
|
19462
|
+
paddingBottom: 4
|
|
19463
|
+
},
|
|
19464
|
+
panelHandleBar: {
|
|
19465
|
+
width: 36,
|
|
19466
|
+
height: 4,
|
|
19467
|
+
borderRadius: 2,
|
|
19468
|
+
backgroundColor: colors.border
|
|
19067
19469
|
},
|
|
19068
19470
|
// Header
|
|
19069
19471
|
header: {
|
|
@@ -19146,7 +19548,7 @@ function createStyles16() {
|
|
|
19146
19548
|
},
|
|
19147
19549
|
contentContainer: {
|
|
19148
19550
|
padding: 16,
|
|
19149
|
-
paddingBottom:
|
|
19551
|
+
paddingBottom: import_react_native22.Platform.OS === "ios" ? 50 : 28
|
|
19150
19552
|
},
|
|
19151
19553
|
// Loading
|
|
19152
19554
|
loadingContainer: {
|