@bbearai/react-native 0.9.3 → 0.10.1
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 +918 -382
- package/dist/index.mjs +933 -386
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -14085,7 +14085,9 @@ var BugBearClient = class {
|
|
|
14085
14085
|
p_tester_id: testerInfo.id,
|
|
14086
14086
|
p_focus_area: options.focusArea || null,
|
|
14087
14087
|
p_track: options.track || null,
|
|
14088
|
-
p_platform: options.platform || null
|
|
14088
|
+
p_platform: options.platform || null,
|
|
14089
|
+
p_session_type: options.sessionType || "exploratory",
|
|
14090
|
+
p_task_id: options.taskId || null
|
|
14089
14091
|
});
|
|
14090
14092
|
if (error) {
|
|
14091
14093
|
console.error("BugBear: Failed to start session", formatPgError(error));
|
|
@@ -14269,6 +14271,45 @@ var BugBearClient = class {
|
|
|
14269
14271
|
return { success: false, error: message };
|
|
14270
14272
|
}
|
|
14271
14273
|
}
|
|
14274
|
+
// ============================================
|
|
14275
|
+
// QA Tasks (Ad Hoc Testing)
|
|
14276
|
+
// ============================================
|
|
14277
|
+
/**
|
|
14278
|
+
* Get active QA tasks for the project
|
|
14279
|
+
*/
|
|
14280
|
+
async getTasks(status = "active") {
|
|
14281
|
+
try {
|
|
14282
|
+
await this.ensureReady();
|
|
14283
|
+
const { data, error } = await this.supabase.rpc("list_qa_tasks", {
|
|
14284
|
+
p_project_id: this.config.projectId,
|
|
14285
|
+
p_status: status
|
|
14286
|
+
});
|
|
14287
|
+
if (error) {
|
|
14288
|
+
console.error("BugBear: Failed to fetch tasks", formatPgError(error));
|
|
14289
|
+
return [];
|
|
14290
|
+
}
|
|
14291
|
+
return (data || []).map((t) => this.transformTask(t));
|
|
14292
|
+
} catch (err) {
|
|
14293
|
+
console.error("BugBear: Error fetching tasks", err);
|
|
14294
|
+
return [];
|
|
14295
|
+
}
|
|
14296
|
+
}
|
|
14297
|
+
/**
|
|
14298
|
+
* Transform database task to QATask type
|
|
14299
|
+
*/
|
|
14300
|
+
transformTask(data) {
|
|
14301
|
+
return {
|
|
14302
|
+
id: data.id,
|
|
14303
|
+
projectId: data.project_id,
|
|
14304
|
+
title: data.title,
|
|
14305
|
+
description: data.description || void 0,
|
|
14306
|
+
trackId: data.track_id || void 0,
|
|
14307
|
+
priority: data.priority,
|
|
14308
|
+
status: data.status,
|
|
14309
|
+
createdAt: data.created_at,
|
|
14310
|
+
updatedAt: data.updated_at
|
|
14311
|
+
};
|
|
14312
|
+
}
|
|
14272
14313
|
/**
|
|
14273
14314
|
* Transform database session to QASession type
|
|
14274
14315
|
*/
|
|
@@ -14280,6 +14321,8 @@ var BugBearClient = class {
|
|
|
14280
14321
|
focusArea: data.focus_area,
|
|
14281
14322
|
track: data.track,
|
|
14282
14323
|
platform: data.platform,
|
|
14324
|
+
sessionType: data.session_type || "exploratory",
|
|
14325
|
+
taskId: data.task_id || void 0,
|
|
14283
14326
|
startedAt: data.started_at,
|
|
14284
14327
|
endedAt: data.ended_at,
|
|
14285
14328
|
notes: data.notes,
|
|
@@ -14861,7 +14904,13 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
|
|
|
14861
14904
|
}, [client, activeSession]);
|
|
14862
14905
|
const addFinding = useCallback(async (options) => {
|
|
14863
14906
|
if (!client || !activeSession) return { success: false, error: "No active session" };
|
|
14864
|
-
const
|
|
14907
|
+
const enhanced = contextCapture.getEnhancedContext();
|
|
14908
|
+
const enriched = {
|
|
14909
|
+
...options,
|
|
14910
|
+
consoleLogs: options.consoleLogs ?? enhanced.consoleLogs,
|
|
14911
|
+
networkSnapshot: options.networkSnapshot ?? enhanced.networkRequests
|
|
14912
|
+
};
|
|
14913
|
+
const result = await client.addFinding(activeSession.id, enriched);
|
|
14865
14914
|
if (result.success && result.finding) {
|
|
14866
14915
|
setSessionFindings((prev) => [...prev, result.finding]);
|
|
14867
14916
|
setActiveSession((prev) => prev ? { ...prev, findingsCount: prev.findingsCount + 1 } : null);
|
|
@@ -15162,21 +15211,21 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
|
|
|
15162
15211
|
}
|
|
15163
15212
|
|
|
15164
15213
|
// src/BugBearButton.tsx
|
|
15165
|
-
import
|
|
15214
|
+
import React23, { useState as useState20, useRef as useRef9, useEffect as useEffect14, useMemo as useMemo16, useCallback as useCallback8 } from "react";
|
|
15166
15215
|
import {
|
|
15167
|
-
View as
|
|
15168
|
-
Text as
|
|
15216
|
+
View as View23,
|
|
15217
|
+
Text as Text21,
|
|
15169
15218
|
Image as Image4,
|
|
15170
|
-
TouchableOpacity as
|
|
15219
|
+
TouchableOpacity as TouchableOpacity20,
|
|
15171
15220
|
ScrollView as ScrollView4,
|
|
15172
|
-
StyleSheet as
|
|
15173
|
-
Dimensions as
|
|
15221
|
+
StyleSheet as StyleSheet23,
|
|
15222
|
+
Dimensions as Dimensions4,
|
|
15174
15223
|
KeyboardAvoidingView,
|
|
15175
|
-
Platform as
|
|
15176
|
-
PanResponder as
|
|
15177
|
-
Animated as
|
|
15224
|
+
Platform as Platform7,
|
|
15225
|
+
PanResponder as PanResponder3,
|
|
15226
|
+
Animated as Animated5,
|
|
15178
15227
|
ActivityIndicator as ActivityIndicator3,
|
|
15179
|
-
Keyboard as
|
|
15228
|
+
Keyboard as Keyboard5,
|
|
15180
15229
|
BackHandler
|
|
15181
15230
|
} from "react-native";
|
|
15182
15231
|
|
|
@@ -15321,8 +15370,9 @@ var s = StyleSheet2.create({
|
|
|
15321
15370
|
|
|
15322
15371
|
// src/widget/screens/HomeScreen.tsx
|
|
15323
15372
|
function HomeScreen({ nav }) {
|
|
15324
|
-
const { assignments, unreadCount, threads, refreshAssignments, refreshThreads, issueCounts, refreshIssueCounts, dashboardUrl, isLoading, activeSession, sessionFindings, refreshSession, widgetMode, widgetColorScheme } = useBugBear();
|
|
15325
|
-
const
|
|
15373
|
+
const { client, assignments, unreadCount, threads, refreshAssignments, refreshThreads, issueCounts, refreshIssueCounts, dashboardUrl, isLoading, activeSession, sessionFindings, refreshSession, widgetMode, widgetColorScheme } = useBugBear();
|
|
15374
|
+
const [tasks, setTasks] = useState2([]);
|
|
15375
|
+
const styles7 = useMemo(() => createStyles(), [widgetColorScheme]);
|
|
15326
15376
|
const [sessionElapsed, setSessionElapsed] = useState2(0);
|
|
15327
15377
|
const timerRef = useRef3(null);
|
|
15328
15378
|
useEffect3(() => {
|
|
@@ -15342,6 +15392,10 @@ function HomeScreen({ nav }) {
|
|
|
15342
15392
|
if (widgetMode === "qa") {
|
|
15343
15393
|
refreshAssignments();
|
|
15344
15394
|
refreshSession();
|
|
15395
|
+
if (client?.getTasks) {
|
|
15396
|
+
client.getTasks().then(setTasks).catch(() => {
|
|
15397
|
+
});
|
|
15398
|
+
}
|
|
15345
15399
|
}
|
|
15346
15400
|
refreshThreads();
|
|
15347
15401
|
refreshIssueCounts();
|
|
@@ -15351,98 +15405,98 @@ function HomeScreen({ nav }) {
|
|
|
15351
15405
|
return /* @__PURE__ */ React3.createElement(View3, null, unreadCount > 0 ? /* @__PURE__ */ React3.createElement(
|
|
15352
15406
|
TouchableOpacity,
|
|
15353
15407
|
{
|
|
15354
|
-
style: [
|
|
15408
|
+
style: [styles7.heroBanner, styles7.heroBannerMessages],
|
|
15355
15409
|
onPress: () => nav.push({ name: "MESSAGE_LIST" }),
|
|
15356
15410
|
activeOpacity: 0.8
|
|
15357
15411
|
},
|
|
15358
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15359
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15360
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15361
|
-
) : /* @__PURE__ */ React3.createElement(View3, { style: [
|
|
15412
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.heroCount }, unreadCount),
|
|
15413
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.heroLabel }, "unread message", unreadCount !== 1 ? "s" : ""),
|
|
15414
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.heroAction }, "View Messages \u2192")
|
|
15415
|
+
) : /* @__PURE__ */ React3.createElement(View3, { style: [styles7.heroBanner, styles7.heroBannerClear] }, /* @__PURE__ */ React3.createElement(Text, { style: styles7.heroClearEmoji }, "\u{1F4AC}"), /* @__PURE__ */ React3.createElement(Text, { style: styles7.heroClearTitle }, "Help us improve"), /* @__PURE__ */ React3.createElement(Text, { style: styles7.heroClearSub }, "Report bugs, share ideas, and track your submissions")), /* @__PURE__ */ React3.createElement(View3, { style: styles7.actionGrid }, /* @__PURE__ */ React3.createElement(
|
|
15362
15416
|
TouchableOpacity,
|
|
15363
15417
|
{
|
|
15364
|
-
style:
|
|
15418
|
+
style: styles7.actionCard,
|
|
15365
15419
|
onPress: () => nav.push({ name: "REPORT", prefill: { type: "bug" } }),
|
|
15366
15420
|
activeOpacity: 0.7
|
|
15367
15421
|
},
|
|
15368
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15369
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15422
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.actionIcon }, "\u{1F41B}"),
|
|
15423
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.actionLabel }, "Report Bug")
|
|
15370
15424
|
), /* @__PURE__ */ React3.createElement(
|
|
15371
15425
|
TouchableOpacity,
|
|
15372
15426
|
{
|
|
15373
|
-
style:
|
|
15427
|
+
style: styles7.actionCard,
|
|
15374
15428
|
onPress: () => nav.push({ name: "REPORT", prefill: { type: "feedback" } }),
|
|
15375
15429
|
activeOpacity: 0.7
|
|
15376
15430
|
},
|
|
15377
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15378
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15431
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.actionIcon }, "\u{1F4A1}"),
|
|
15432
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.actionLabel }, "Share Feedback")
|
|
15379
15433
|
), /* @__PURE__ */ React3.createElement(
|
|
15380
15434
|
TouchableOpacity,
|
|
15381
15435
|
{
|
|
15382
|
-
style:
|
|
15436
|
+
style: styles7.actionCard,
|
|
15383
15437
|
onPress: () => nav.push({ name: "MESSAGE_LIST" }),
|
|
15384
15438
|
activeOpacity: 0.7
|
|
15385
15439
|
},
|
|
15386
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15387
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15388
|
-
unreadCount > 0 && /* @__PURE__ */ React3.createElement(View3, { style: [
|
|
15440
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.actionIcon }, "\u{1F4AC}"),
|
|
15441
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.actionLabel }, "Messages"),
|
|
15442
|
+
unreadCount > 0 && /* @__PURE__ */ React3.createElement(View3, { style: [styles7.actionBadge, styles7.actionBadgeMsg] }, /* @__PURE__ */ React3.createElement(Text, { style: styles7.actionBadgeText }, unreadCount))
|
|
15389
15443
|
), /* @__PURE__ */ React3.createElement(
|
|
15390
15444
|
TouchableOpacity,
|
|
15391
15445
|
{
|
|
15392
|
-
style:
|
|
15446
|
+
style: styles7.actionCard,
|
|
15393
15447
|
onPress: () => nav.push({ name: "ISSUE_LIST", category: "open" }),
|
|
15394
15448
|
activeOpacity: 0.7
|
|
15395
15449
|
},
|
|
15396
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15397
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15398
|
-
issueCounts.open > 0 && /* @__PURE__ */ React3.createElement(View3, { style: [
|
|
15399
|
-
)), /* @__PURE__ */ React3.createElement(View3, { style:
|
|
15450
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.actionIcon }, "\u{1F4CB}"),
|
|
15451
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.actionLabel }, "My Issues"),
|
|
15452
|
+
issueCounts.open > 0 && /* @__PURE__ */ React3.createElement(View3, { style: [styles7.actionBadge, styles7.actionBadgeIssue] }, /* @__PURE__ */ React3.createElement(Text, { style: styles7.actionBadgeText }, issueCounts.open))
|
|
15453
|
+
)), /* @__PURE__ */ React3.createElement(View3, { style: styles7.issueGrid }, /* @__PURE__ */ React3.createElement(
|
|
15400
15454
|
TouchableOpacity,
|
|
15401
15455
|
{
|
|
15402
|
-
style: [
|
|
15456
|
+
style: [styles7.issueCard, styles7.issueCardOpen],
|
|
15403
15457
|
onPress: () => nav.push({ name: "ISSUE_LIST", category: "open" }),
|
|
15404
15458
|
activeOpacity: 0.7
|
|
15405
15459
|
},
|
|
15406
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15407
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15460
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.issueCountOpen }, issueCounts.open),
|
|
15461
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.issueLabel }, "Open")
|
|
15408
15462
|
), /* @__PURE__ */ React3.createElement(
|
|
15409
15463
|
TouchableOpacity,
|
|
15410
15464
|
{
|
|
15411
|
-
style: [
|
|
15465
|
+
style: [styles7.issueCard, styles7.issueCardDone],
|
|
15412
15466
|
onPress: () => nav.push({ name: "ISSUE_LIST", category: "done" }),
|
|
15413
15467
|
activeOpacity: 0.7
|
|
15414
15468
|
},
|
|
15415
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15416
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15469
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.issueCountDone }, issueCounts.done),
|
|
15470
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.issueLabel }, "Done")
|
|
15417
15471
|
), /* @__PURE__ */ React3.createElement(
|
|
15418
15472
|
TouchableOpacity,
|
|
15419
15473
|
{
|
|
15420
|
-
style: [
|
|
15474
|
+
style: [styles7.issueCard, styles7.issueCardReopened],
|
|
15421
15475
|
onPress: () => nav.push({ name: "ISSUE_LIST", category: "reopened" }),
|
|
15422
15476
|
activeOpacity: 0.7
|
|
15423
15477
|
},
|
|
15424
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15425
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15478
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.issueCountReopened }, issueCounts.reopened),
|
|
15479
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.issueLabel }, "Reopened")
|
|
15426
15480
|
)), dashboardUrl && /* @__PURE__ */ React3.createElement(
|
|
15427
15481
|
TouchableOpacity,
|
|
15428
15482
|
{
|
|
15429
|
-
style:
|
|
15483
|
+
style: styles7.webAppLink,
|
|
15430
15484
|
onPress: () => Linking.openURL(dashboardUrl),
|
|
15431
15485
|
activeOpacity: 0.7
|
|
15432
15486
|
},
|
|
15433
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15434
|
-
/* @__PURE__ */ React3.createElement(View3, { style:
|
|
15435
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15487
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.webAppIcon }, "\u{1F310}"),
|
|
15488
|
+
/* @__PURE__ */ React3.createElement(View3, { style: styles7.webAppTextWrap }, /* @__PURE__ */ React3.createElement(Text, { style: styles7.webAppTitle }, "Open Web Dashboard"), /* @__PURE__ */ React3.createElement(Text, { style: styles7.webAppSub }, "View your submissions & updates")),
|
|
15489
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.webAppArrow }, "\u2192")
|
|
15436
15490
|
), /* @__PURE__ */ React3.createElement(
|
|
15437
15491
|
TouchableOpacity,
|
|
15438
15492
|
{
|
|
15439
|
-
style:
|
|
15493
|
+
style: styles7.refreshButton,
|
|
15440
15494
|
onPress: () => {
|
|
15441
15495
|
refreshThreads();
|
|
15442
15496
|
refreshIssueCounts();
|
|
15443
15497
|
}
|
|
15444
15498
|
},
|
|
15445
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15499
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.refreshText }, "\u21BB Refresh")
|
|
15446
15500
|
));
|
|
15447
15501
|
}
|
|
15448
15502
|
const formatTimer = (s2) => {
|
|
@@ -15459,130 +15513,151 @@ function HomeScreen({ nav }) {
|
|
|
15459
15513
|
return /* @__PURE__ */ React3.createElement(View3, null, pendingCount > 0 ? /* @__PURE__ */ React3.createElement(
|
|
15460
15514
|
TouchableOpacity,
|
|
15461
15515
|
{
|
|
15462
|
-
style: [
|
|
15516
|
+
style: [styles7.heroBanner, styles7.heroBannerTests],
|
|
15463
15517
|
onPress: () => nav.push({ name: "TEST_DETAIL" }),
|
|
15464
15518
|
activeOpacity: 0.8
|
|
15465
15519
|
},
|
|
15466
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15467
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15468
|
-
retestCount > 0 && /* @__PURE__ */ React3.createElement(View3, { style:
|
|
15469
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15520
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.heroCount }, pendingCount),
|
|
15521
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.heroLabel }, "test", pendingCount !== 1 ? "s" : "", " waiting"),
|
|
15522
|
+
retestCount > 0 && /* @__PURE__ */ React3.createElement(View3, { style: styles7.retestPill }, /* @__PURE__ */ React3.createElement(Text, { style: styles7.retestPillText }, "\u{1F504} ", retestCount, " retest", retestCount !== 1 ? "s" : "")),
|
|
15523
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.heroAction }, "Start Testing \u2192")
|
|
15470
15524
|
) : unreadCount > 0 ? /* @__PURE__ */ React3.createElement(
|
|
15471
15525
|
TouchableOpacity,
|
|
15472
15526
|
{
|
|
15473
|
-
style: [
|
|
15527
|
+
style: [styles7.heroBanner, styles7.heroBannerMessages],
|
|
15474
15528
|
onPress: () => nav.push({ name: "MESSAGE_LIST" }),
|
|
15475
15529
|
activeOpacity: 0.8
|
|
15476
15530
|
},
|
|
15477
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15478
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15479
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15480
|
-
) : /* @__PURE__ */ React3.createElement(View3, { style: [
|
|
15531
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.heroCount }, unreadCount),
|
|
15532
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.heroLabel }, "unread message", unreadCount !== 1 ? "s" : ""),
|
|
15533
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.heroAction }, "View Messages \u2192")
|
|
15534
|
+
) : /* @__PURE__ */ React3.createElement(View3, { style: [styles7.heroBanner, styles7.heroBannerClear] }, /* @__PURE__ */ React3.createElement(Text, { style: styles7.heroClearEmoji }, "\u2705"), /* @__PURE__ */ React3.createElement(Text, { style: styles7.heroClearTitle }, "All caught up!"), totalTests > 0 && /* @__PURE__ */ React3.createElement(Text, { style: styles7.heroClearSub }, completedCount, "/", totalTests, " tests completed")), activeSession && activeSession.status === "active" ? /* @__PURE__ */ React3.createElement(
|
|
15481
15535
|
TouchableOpacity,
|
|
15482
15536
|
{
|
|
15483
|
-
style:
|
|
15537
|
+
style: styles7.sessionCardActive,
|
|
15484
15538
|
onPress: () => nav.push({ name: "SESSION_ACTIVE" }),
|
|
15485
15539
|
activeOpacity: 0.8
|
|
15486
15540
|
},
|
|
15487
|
-
/* @__PURE__ */ React3.createElement(View3, { style:
|
|
15488
|
-
/* @__PURE__ */ React3.createElement(View3, { style:
|
|
15489
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15541
|
+
/* @__PURE__ */ React3.createElement(View3, { style: styles7.sessionDot }),
|
|
15542
|
+
/* @__PURE__ */ React3.createElement(View3, { style: styles7.sessionCardContent }, /* @__PURE__ */ React3.createElement(Text, { style: styles7.sessionCardTitle, numberOfLines: 1 }, activeSession.focusArea || "QA Session"), /* @__PURE__ */ React3.createElement(Text, { style: styles7.sessionCardMeta }, formatTimer(sessionElapsed), " \xB7 ", sessionFindings.length, " finding", sessionFindings.length !== 1 ? "s" : "")),
|
|
15543
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.sessionCardAction }, "Resume \u2192")
|
|
15490
15544
|
) : /* @__PURE__ */ React3.createElement(
|
|
15491
15545
|
TouchableOpacity,
|
|
15492
15546
|
{
|
|
15493
|
-
style:
|
|
15547
|
+
style: styles7.sessionCardInactive,
|
|
15494
15548
|
onPress: () => nav.push({ name: "SESSION_START" }),
|
|
15495
15549
|
activeOpacity: 0.7
|
|
15496
15550
|
},
|
|
15497
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15498
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15499
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15500
|
-
),
|
|
15551
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.sessionCardIcon }, "\u{1F50D}"),
|
|
15552
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.sessionCardLabel }, "Start QA Session"),
|
|
15553
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.sessionCardArrow }, "\u2192")
|
|
15554
|
+
), !activeSession && nav.startAdHoc && /* @__PURE__ */ React3.createElement(
|
|
15555
|
+
TouchableOpacity,
|
|
15556
|
+
{
|
|
15557
|
+
style: styles7.quickTestCard,
|
|
15558
|
+
onPress: () => nav.startAdHoc?.(),
|
|
15559
|
+
activeOpacity: 0.7
|
|
15560
|
+
},
|
|
15561
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.quickTestIcon }, "\u26A1"),
|
|
15562
|
+
/* @__PURE__ */ React3.createElement(View3, { style: styles7.quickTestContent }, /* @__PURE__ */ React3.createElement(Text, { style: styles7.quickTestTitle }, "Quick Test"), /* @__PURE__ */ React3.createElement(Text, { style: styles7.quickTestSub }, "Ad hoc explore & report")),
|
|
15563
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.sessionCardArrow }, "\u2192")
|
|
15564
|
+
), !activeSession && tasks.length > 0 && /* @__PURE__ */ React3.createElement(View3, { style: { marginBottom: 20 } }, /* @__PURE__ */ React3.createElement(Text, { style: { fontSize: 12, fontWeight: "600", color: colors.textSecondary, textTransform: "uppercase", letterSpacing: 0.5, marginBottom: 8 } }, "Task Checklist"), tasks.map((task) => /* @__PURE__ */ React3.createElement(
|
|
15501
15565
|
TouchableOpacity,
|
|
15502
15566
|
{
|
|
15503
|
-
|
|
15567
|
+
key: task.id,
|
|
15568
|
+
style: { backgroundColor: colors.card, borderWidth: 1, borderColor: colors.border, borderRadius: 10, padding: 12, paddingHorizontal: 14, flexDirection: "row", alignItems: "center", gap: 10, marginBottom: 4 },
|
|
15569
|
+
onPress: () => nav.startAdHoc?.(task.id, task.title),
|
|
15570
|
+
activeOpacity: 0.7
|
|
15571
|
+
},
|
|
15572
|
+
task.priority === "high" && /* @__PURE__ */ React3.createElement(View3, { style: { width: 6, height: 6, borderRadius: 3, backgroundColor: colors.red } }),
|
|
15573
|
+
/* @__PURE__ */ React3.createElement(View3, { style: { flex: 1 } }, /* @__PURE__ */ React3.createElement(Text, { style: { fontSize: 13, fontWeight: "500", color: colors.textPrimary }, numberOfLines: 1 }, task.title), task.description ? /* @__PURE__ */ React3.createElement(Text, { style: { fontSize: 11, color: colors.textMuted, marginTop: 2 }, numberOfLines: 1 }, task.description) : null),
|
|
15574
|
+
/* @__PURE__ */ React3.createElement(Text, { style: { fontSize: 11, fontWeight: "600", color: colors.blue } }, "Go")
|
|
15575
|
+
))), /* @__PURE__ */ React3.createElement(View3, { style: styles7.actionGrid }, /* @__PURE__ */ React3.createElement(
|
|
15576
|
+
TouchableOpacity,
|
|
15577
|
+
{
|
|
15578
|
+
style: styles7.actionCard,
|
|
15504
15579
|
onPress: () => nav.push({ name: "TEST_LIST" }),
|
|
15505
15580
|
activeOpacity: 0.7
|
|
15506
15581
|
},
|
|
15507
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15508
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15509
|
-
pendingCount > 0 && /* @__PURE__ */ React3.createElement(View3, { style:
|
|
15582
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.actionIcon }, "\u2705"),
|
|
15583
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.actionLabel }, "Tests"),
|
|
15584
|
+
pendingCount > 0 && /* @__PURE__ */ React3.createElement(View3, { style: styles7.actionBadge }, /* @__PURE__ */ React3.createElement(Text, { style: styles7.actionBadgeText }, pendingCount))
|
|
15510
15585
|
), /* @__PURE__ */ React3.createElement(
|
|
15511
15586
|
TouchableOpacity,
|
|
15512
15587
|
{
|
|
15513
|
-
style:
|
|
15588
|
+
style: styles7.actionCard,
|
|
15514
15589
|
onPress: () => nav.push({ name: "REPORT", prefill: { type: "bug" } }),
|
|
15515
15590
|
activeOpacity: 0.7
|
|
15516
15591
|
},
|
|
15517
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15518
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15592
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.actionIcon }, "\u{1F41B}"),
|
|
15593
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.actionLabel }, "Report Bug")
|
|
15519
15594
|
), /* @__PURE__ */ React3.createElement(
|
|
15520
15595
|
TouchableOpacity,
|
|
15521
15596
|
{
|
|
15522
|
-
style:
|
|
15597
|
+
style: styles7.actionCard,
|
|
15523
15598
|
onPress: () => nav.push({ name: "REPORT", prefill: { type: "feedback" } }),
|
|
15524
15599
|
activeOpacity: 0.7
|
|
15525
15600
|
},
|
|
15526
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15527
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15601
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.actionIcon }, "\u{1F4A1}"),
|
|
15602
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.actionLabel }, "Feedback")
|
|
15528
15603
|
), /* @__PURE__ */ React3.createElement(
|
|
15529
15604
|
TouchableOpacity,
|
|
15530
15605
|
{
|
|
15531
|
-
style:
|
|
15606
|
+
style: styles7.actionCard,
|
|
15532
15607
|
onPress: () => nav.push({ name: "MESSAGE_LIST" }),
|
|
15533
15608
|
activeOpacity: 0.7
|
|
15534
15609
|
},
|
|
15535
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15536
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15537
|
-
unreadCount > 0 && /* @__PURE__ */ React3.createElement(View3, { style: [
|
|
15538
|
-
)), /* @__PURE__ */ React3.createElement(View3, { style:
|
|
15610
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.actionIcon }, "\u{1F4AC}"),
|
|
15611
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.actionLabel }, "Messages"),
|
|
15612
|
+
unreadCount > 0 && /* @__PURE__ */ React3.createElement(View3, { style: [styles7.actionBadge, styles7.actionBadgeMsg] }, /* @__PURE__ */ React3.createElement(Text, { style: styles7.actionBadgeText }, unreadCount))
|
|
15613
|
+
)), /* @__PURE__ */ React3.createElement(View3, { style: styles7.issueGrid }, /* @__PURE__ */ React3.createElement(
|
|
15539
15614
|
TouchableOpacity,
|
|
15540
15615
|
{
|
|
15541
|
-
style: [
|
|
15616
|
+
style: [styles7.issueCard, styles7.issueCardOpen],
|
|
15542
15617
|
onPress: () => nav.push({ name: "ISSUE_LIST", category: "open" }),
|
|
15543
15618
|
activeOpacity: 0.7
|
|
15544
15619
|
},
|
|
15545
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15546
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15620
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.issueCountOpen }, issueCounts.open),
|
|
15621
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.issueLabel }, "Open")
|
|
15547
15622
|
), /* @__PURE__ */ React3.createElement(
|
|
15548
15623
|
TouchableOpacity,
|
|
15549
15624
|
{
|
|
15550
|
-
style: [
|
|
15625
|
+
style: [styles7.issueCard, styles7.issueCardDone],
|
|
15551
15626
|
onPress: () => nav.push({ name: "ISSUE_LIST", category: "done" }),
|
|
15552
15627
|
activeOpacity: 0.7
|
|
15553
15628
|
},
|
|
15554
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15555
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15629
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.issueCountDone }, issueCounts.done),
|
|
15630
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.issueLabel }, "Done")
|
|
15556
15631
|
), /* @__PURE__ */ React3.createElement(
|
|
15557
15632
|
TouchableOpacity,
|
|
15558
15633
|
{
|
|
15559
|
-
style: [
|
|
15634
|
+
style: [styles7.issueCard, styles7.issueCardReopened],
|
|
15560
15635
|
onPress: () => nav.push({ name: "ISSUE_LIST", category: "reopened" }),
|
|
15561
15636
|
activeOpacity: 0.7
|
|
15562
15637
|
},
|
|
15563
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15564
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15565
|
-
)), totalTests > 0 && /* @__PURE__ */ React3.createElement(View3, { style:
|
|
15638
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.issueCountReopened }, issueCounts.reopened),
|
|
15639
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.issueLabel }, "Reopened")
|
|
15640
|
+
)), totalTests > 0 && /* @__PURE__ */ React3.createElement(View3, { style: styles7.progressSection }, /* @__PURE__ */ React3.createElement(View3, { style: styles7.progressBar }, /* @__PURE__ */ React3.createElement(View3, { style: [styles7.progressFill, { width: `${Math.round(completedCount / totalTests * 100)}%` }] })), /* @__PURE__ */ React3.createElement(Text, { style: styles7.progressText }, completedCount, "/", totalTests, " tests completed")), dashboardUrl && /* @__PURE__ */ React3.createElement(
|
|
15566
15641
|
TouchableOpacity,
|
|
15567
15642
|
{
|
|
15568
|
-
style:
|
|
15643
|
+
style: styles7.webAppLink,
|
|
15569
15644
|
onPress: () => Linking.openURL(dashboardUrl),
|
|
15570
15645
|
activeOpacity: 0.7
|
|
15571
15646
|
},
|
|
15572
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15573
|
-
/* @__PURE__ */ React3.createElement(View3, { style:
|
|
15574
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15647
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.webAppIcon }, "\u{1F310}"),
|
|
15648
|
+
/* @__PURE__ */ React3.createElement(View3, { style: styles7.webAppTextWrap }, /* @__PURE__ */ React3.createElement(Text, { style: styles7.webAppTitle }, "Open Web Dashboard"), /* @__PURE__ */ React3.createElement(Text, { style: styles7.webAppSub }, "View analytics, history & more")),
|
|
15649
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.webAppArrow }, "\u2192")
|
|
15575
15650
|
), /* @__PURE__ */ React3.createElement(
|
|
15576
15651
|
TouchableOpacity,
|
|
15577
15652
|
{
|
|
15578
|
-
style:
|
|
15653
|
+
style: styles7.refreshButton,
|
|
15579
15654
|
onPress: () => {
|
|
15580
15655
|
refreshAssignments();
|
|
15581
15656
|
refreshThreads();
|
|
15582
15657
|
refreshIssueCounts();
|
|
15583
15658
|
}
|
|
15584
15659
|
},
|
|
15585
|
-
/* @__PURE__ */ React3.createElement(Text, { style:
|
|
15660
|
+
/* @__PURE__ */ React3.createElement(Text, { style: styles7.refreshText }, "\u21BB Refresh")
|
|
15586
15661
|
));
|
|
15587
15662
|
}
|
|
15588
15663
|
function createStyles() {
|
|
@@ -15871,6 +15946,35 @@ function createStyles() {
|
|
|
15871
15946
|
sessionCardArrow: {
|
|
15872
15947
|
fontSize: 13,
|
|
15873
15948
|
color: colors.textMuted
|
|
15949
|
+
},
|
|
15950
|
+
// Quick Test card
|
|
15951
|
+
quickTestCard: {
|
|
15952
|
+
flexDirection: "row",
|
|
15953
|
+
alignItems: "center",
|
|
15954
|
+
backgroundColor: colors.card,
|
|
15955
|
+
borderWidth: 1,
|
|
15956
|
+
borderColor: colors.border,
|
|
15957
|
+
borderRadius: 12,
|
|
15958
|
+
padding: 12,
|
|
15959
|
+
paddingHorizontal: 16,
|
|
15960
|
+
gap: 12,
|
|
15961
|
+
marginBottom: 16
|
|
15962
|
+
},
|
|
15963
|
+
quickTestIcon: {
|
|
15964
|
+
fontSize: 22
|
|
15965
|
+
},
|
|
15966
|
+
quickTestContent: {
|
|
15967
|
+
flex: 1
|
|
15968
|
+
},
|
|
15969
|
+
quickTestTitle: {
|
|
15970
|
+
fontSize: 14,
|
|
15971
|
+
fontWeight: "600",
|
|
15972
|
+
color: colors.textPrimary
|
|
15973
|
+
},
|
|
15974
|
+
quickTestSub: {
|
|
15975
|
+
fontSize: 12,
|
|
15976
|
+
color: colors.textMuted,
|
|
15977
|
+
marginTop: 2
|
|
15874
15978
|
}
|
|
15875
15979
|
});
|
|
15876
15980
|
}
|
|
@@ -15880,7 +15984,7 @@ import React4, { useState as useState3, useEffect as useEffect4, useCallback as
|
|
|
15880
15984
|
import { View as View4, Text as Text2, TouchableOpacity as TouchableOpacity2, StyleSheet as StyleSheet4, Modal, TextInput, Keyboard, Animated as Animated2 } from "react-native";
|
|
15881
15985
|
function TestDetailScreen({ testId, nav }) {
|
|
15882
15986
|
const { client, assignments, currentAssignment, refreshAssignments, getDeviceInfo, onNavigate, widgetColorScheme } = useBugBear();
|
|
15883
|
-
const
|
|
15987
|
+
const styles7 = useMemo2(() => createStyles2(), [widgetColorScheme]);
|
|
15884
15988
|
const displayedAssignment = testId ? assignments.find((a) => a.id === testId) || currentAssignment : currentAssignment;
|
|
15885
15989
|
const [showSteps, setShowSteps] = useState3(true);
|
|
15886
15990
|
const [showDetails, setShowDetails] = useState3(false);
|
|
@@ -16058,7 +16162,7 @@ function TestDetailScreen({ testId, nav }) {
|
|
|
16058
16162
|
const steps = testCase.steps;
|
|
16059
16163
|
const info = templateInfo[template] || templateInfo.steps;
|
|
16060
16164
|
const rubricMode = testCase.track?.rubricMode || "pass_fail";
|
|
16061
|
-
return /* @__PURE__ */ React4.createElement(View4, { style:
|
|
16165
|
+
return /* @__PURE__ */ React4.createElement(View4, { style: styles7.container }, /* @__PURE__ */ React4.createElement(View4, { style: styles7.topRow }, /* @__PURE__ */ React4.createElement(View4, { style: styles7.positionInfo }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.positionText }, "Test ", currentIndex + 1, " of ", allTests.length), displayedAssignment.status === "in_progress" && assignmentElapsedTime > 0 && /* @__PURE__ */ React4.createElement(View4, { style: styles7.timerBadge }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.timerText }, formatElapsedTime(assignmentElapsedTime)))), /* @__PURE__ */ React4.createElement(TouchableOpacity2, { onPress: () => nav.push({ name: "TEST_LIST" }) }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.viewAllLink }, "View All \u2192"))), displayedAssignment.isVerification && /* @__PURE__ */ React4.createElement(View4, { style: styles7.retestBanner }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.retestIcon }, "\u{1F504}"), /* @__PURE__ */ React4.createElement(Text2, { style: styles7.retestLabel }, "Retest"), /* @__PURE__ */ React4.createElement(Text2, { style: styles7.retestSub }, "\u2014 Verify bug fix")), /* @__PURE__ */ React4.createElement(Text2, { style: styles7.testTitle }, testCase.title), testCase.key && /* @__PURE__ */ React4.createElement(Text2, { style: styles7.testKey }, testCase.key), /* @__PURE__ */ React4.createElement(TouchableOpacity2, { onPress: () => setShowSteps(!showSteps), style: styles7.sectionHeader }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.sectionHeaderText }, showSteps ? "\u25BC" : "\u25B6", " ", info.icon, " ", template === "freeform" ? "Instructions" : `${steps.length} ${template === "checklist" ? "items" : template === "rubric" ? "criteria" : "steps"}`)), showSteps && /* @__PURE__ */ React4.createElement(View4, { style: styles7.templateContent }, template === "steps" && steps.map((step, idx) => /* @__PURE__ */ React4.createElement(View4, { key: idx, style: styles7.step }, /* @__PURE__ */ React4.createElement(View4, { style: styles7.stepNumber }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.stepNumberText }, step.stepNumber)), /* @__PURE__ */ React4.createElement(View4, { style: styles7.stepBody }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.stepAction }, step.action), step.expectedResult && /* @__PURE__ */ React4.createElement(Text2, { style: styles7.stepExpected }, "\u2192 ", step.expectedResult)))), template === "checklist" && /* @__PURE__ */ React4.createElement(React4.Fragment, null, steps.map((step, idx) => /* @__PURE__ */ React4.createElement(
|
|
16062
16166
|
TouchableOpacity2,
|
|
16063
16167
|
{
|
|
16064
16168
|
key: idx,
|
|
@@ -16068,86 +16172,86 @@ function TestDetailScreen({ testId, nav }) {
|
|
|
16068
16172
|
else next[idx] = true;
|
|
16069
16173
|
return next;
|
|
16070
16174
|
}),
|
|
16071
|
-
style: [
|
|
16175
|
+
style: [styles7.checklistItem, criteriaResults[idx] === true && styles7.checklistItemChecked]
|
|
16072
16176
|
},
|
|
16073
|
-
/* @__PURE__ */ React4.createElement(View4, { style: [
|
|
16074
|
-
/* @__PURE__ */ React4.createElement(Text2, { style: [
|
|
16075
|
-
)), Object.keys(criteriaResults).length > 0 && /* @__PURE__ */ React4.createElement(TouchableOpacity2, { onPress: () => setCriteriaResults({}), style:
|
|
16177
|
+
/* @__PURE__ */ React4.createElement(View4, { style: [styles7.checkbox, criteriaResults[idx] === true && styles7.checkboxChecked] }, criteriaResults[idx] === true && /* @__PURE__ */ React4.createElement(Text2, { style: styles7.checkmark }, "\u2713")),
|
|
16178
|
+
/* @__PURE__ */ React4.createElement(Text2, { style: [styles7.checklistText, criteriaResults[idx] === true && styles7.checklistTextDone] }, step.action)
|
|
16179
|
+
)), Object.keys(criteriaResults).length > 0 && /* @__PURE__ */ React4.createElement(TouchableOpacity2, { onPress: () => setCriteriaResults({}), style: styles7.resetRow }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.resetText }, "\u21BA Reset"))), template === "rubric" && steps.map((step, idx) => /* @__PURE__ */ React4.createElement(View4, { key: idx, style: styles7.rubricItem }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.rubricTitle }, idx + 1, ". ", step.action), step.expectedResult && /* @__PURE__ */ React4.createElement(Text2, { style: styles7.rubricExpected }, step.expectedResult), rubricMode === "pass_fail" ? /* @__PURE__ */ React4.createElement(View4, { style: styles7.passFailRow }, /* @__PURE__ */ React4.createElement(
|
|
16076
16180
|
TouchableOpacity2,
|
|
16077
16181
|
{
|
|
16078
16182
|
onPress: () => setCriteriaResults((prev) => ({ ...prev, [idx]: true })),
|
|
16079
|
-
style: [
|
|
16183
|
+
style: [styles7.pfButton, criteriaResults[idx] === true && styles7.pfButtonPass]
|
|
16080
16184
|
},
|
|
16081
|
-
/* @__PURE__ */ React4.createElement(Text2, { style: [
|
|
16185
|
+
/* @__PURE__ */ React4.createElement(Text2, { style: [styles7.pfButtonText, criteriaResults[idx] === true && styles7.pfButtonTextActive] }, "\u2713 Pass")
|
|
16082
16186
|
), /* @__PURE__ */ React4.createElement(
|
|
16083
16187
|
TouchableOpacity2,
|
|
16084
16188
|
{
|
|
16085
16189
|
onPress: () => setCriteriaResults((prev) => ({ ...prev, [idx]: false })),
|
|
16086
|
-
style: [
|
|
16190
|
+
style: [styles7.pfButton, criteriaResults[idx] === false && styles7.pfButtonFail]
|
|
16087
16191
|
},
|
|
16088
|
-
/* @__PURE__ */ React4.createElement(Text2, { style: [
|
|
16089
|
-
)) : /* @__PURE__ */ React4.createElement(View4, { style:
|
|
16192
|
+
/* @__PURE__ */ React4.createElement(Text2, { style: [styles7.pfButtonText, criteriaResults[idx] === false && styles7.pfButtonTextActive] }, "\u2717 Fail")
|
|
16193
|
+
)) : /* @__PURE__ */ React4.createElement(View4, { style: styles7.ratingRow }, [1, 2, 3, 4, 5].map((n) => /* @__PURE__ */ React4.createElement(
|
|
16090
16194
|
TouchableOpacity2,
|
|
16091
16195
|
{
|
|
16092
16196
|
key: n,
|
|
16093
16197
|
onPress: () => setCriteriaResults((prev) => ({ ...prev, [idx]: n })),
|
|
16094
|
-
style: [
|
|
16198
|
+
style: [styles7.ratingBtn, criteriaResults[idx] === n && styles7.ratingBtnActive]
|
|
16095
16199
|
},
|
|
16096
|
-
/* @__PURE__ */ React4.createElement(Text2, { style: [
|
|
16097
|
-
))))), template === "freeform" && /* @__PURE__ */ React4.createElement(View4, { style:
|
|
16200
|
+
/* @__PURE__ */ React4.createElement(Text2, { style: [styles7.ratingBtnText, criteriaResults[idx] === n && styles7.ratingBtnTextActive] }, n)
|
|
16201
|
+
))))), template === "freeform" && /* @__PURE__ */ React4.createElement(View4, { style: styles7.freeformBox }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.freeformText }, "Review the area and note:"), /* @__PURE__ */ React4.createElement(Text2, { style: styles7.freeformBullet }, "\u2022 What works well"), /* @__PURE__ */ React4.createElement(Text2, { style: styles7.freeformBullet }, "\u2022 Issues or concerns"), /* @__PURE__ */ React4.createElement(Text2, { style: styles7.freeformBullet }, "\u2022 Suggestions"))), testCase.expectedResult && /* @__PURE__ */ React4.createElement(View4, { style: styles7.expectedBox }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.expectedLabel }, "\u2705 Expected Result"), /* @__PURE__ */ React4.createElement(Text2, { style: styles7.expectedText }, testCase.expectedResult)), testCase.targetRoute && onNavigate && /* @__PURE__ */ React4.createElement(
|
|
16098
16202
|
TouchableOpacity2,
|
|
16099
16203
|
{
|
|
16100
|
-
style:
|
|
16204
|
+
style: styles7.navigateButton,
|
|
16101
16205
|
onPress: () => {
|
|
16102
16206
|
Keyboard.dismiss();
|
|
16103
16207
|
onNavigate(testCase.targetRoute);
|
|
16104
16208
|
nav.closeWidget?.();
|
|
16105
16209
|
}
|
|
16106
16210
|
},
|
|
16107
|
-
/* @__PURE__ */ React4.createElement(Text2, { style:
|
|
16108
|
-
), /* @__PURE__ */ React4.createElement(TouchableOpacity2, { onPress: () => setShowDetails(!showDetails), style:
|
|
16211
|
+
/* @__PURE__ */ React4.createElement(Text2, { style: styles7.navigateText }, "\u{1F9ED} Go to test location")
|
|
16212
|
+
), /* @__PURE__ */ React4.createElement(TouchableOpacity2, { onPress: () => setShowDetails(!showDetails), style: styles7.detailsToggle }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.detailsToggleText }, showDetails ? "\u25BC" : "\u25B6", " Details")), showDetails && /* @__PURE__ */ React4.createElement(View4, { style: styles7.detailsSection }, testCase.key && /* @__PURE__ */ React4.createElement(Text2, { style: styles7.detailMeta }, testCase.key, " \xB7 ", testCase.priority, " \xB7 ", info.name), testCase.track && /* @__PURE__ */ React4.createElement(Text2, { style: styles7.detailMeta }, testCase.track.icon, " ", testCase.track.name), testCase.description && /* @__PURE__ */ React4.createElement(Text2, { style: styles7.detailDesc }, testCase.description), testCase.group && /* @__PURE__ */ React4.createElement(View4, { style: styles7.folderProgress }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.folderName }, "\u{1F4C1} ", testCase.group.name))), displayedAssignment.status === "in_progress" && nav.startMiniRunner && /* @__PURE__ */ React4.createElement(
|
|
16109
16213
|
TouchableOpacity2,
|
|
16110
16214
|
{
|
|
16111
|
-
style:
|
|
16215
|
+
style: styles7.startTestBtn,
|
|
16112
16216
|
onPress: () => nav.startMiniRunner(displayedAssignment.id)
|
|
16113
16217
|
},
|
|
16114
|
-
/* @__PURE__ */ React4.createElement(Text2, { style:
|
|
16218
|
+
/* @__PURE__ */ React4.createElement(Text2, { style: styles7.startTestText }, "\u25B6 Start Test")
|
|
16115
16219
|
), displayedAssignment.status === "passed" || displayedAssignment.status === "failed" || displayedAssignment.status === "skipped" || displayedAssignment.status === "blocked" ? /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(View4, { style: [
|
|
16116
|
-
|
|
16117
|
-
displayedAssignment.status === "passed" &&
|
|
16118
|
-
displayedAssignment.status === "failed" &&
|
|
16119
|
-
] }, /* @__PURE__ */ React4.createElement(Text2, { style:
|
|
16120
|
-
|
|
16220
|
+
styles7.completedBanner,
|
|
16221
|
+
displayedAssignment.status === "passed" && styles7.completedBannerPass,
|
|
16222
|
+
displayedAssignment.status === "failed" && styles7.completedBannerFail
|
|
16223
|
+
] }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.completedIcon }, displayedAssignment.status === "passed" ? "\u2705" : displayedAssignment.status === "failed" ? "\u274C" : displayedAssignment.status === "skipped" ? "\u23ED" : "\u{1F6AB}"), /* @__PURE__ */ React4.createElement(Text2, { style: [
|
|
16224
|
+
styles7.completedLabel,
|
|
16121
16225
|
displayedAssignment.status === "passed" && { color: colors.green },
|
|
16122
16226
|
displayedAssignment.status === "failed" && { color: colors.redLight }
|
|
16123
|
-
] }, "Marked as ", displayedAssignment.status.charAt(0).toUpperCase() + displayedAssignment.status.slice(1))), !(displayedAssignment.isVerification && (displayedAssignment.status === "passed" || displayedAssignment.status === "failed")) && /* @__PURE__ */ React4.createElement(View4, { style: [
|
|
16227
|
+
] }, "Marked as ", displayedAssignment.status.charAt(0).toUpperCase() + displayedAssignment.status.slice(1))), !(displayedAssignment.isVerification && (displayedAssignment.status === "passed" || displayedAssignment.status === "failed")) && /* @__PURE__ */ React4.createElement(View4, { style: [styles7.actionButtons, { marginTop: 4 }] }, /* @__PURE__ */ React4.createElement(
|
|
16124
16228
|
TouchableOpacity2,
|
|
16125
16229
|
{
|
|
16126
|
-
style: [
|
|
16230
|
+
style: [styles7.actionBtn, styles7.reopenBtn, isSubmitting && { opacity: 0.5 }],
|
|
16127
16231
|
onPress: handleReopen,
|
|
16128
16232
|
disabled: isSubmitting
|
|
16129
16233
|
},
|
|
16130
|
-
/* @__PURE__ */ React4.createElement(Text2, { style:
|
|
16234
|
+
/* @__PURE__ */ React4.createElement(Text2, { style: styles7.reopenBtnText }, isSubmitting ? "Reopening..." : "\u{1F504} Reopen Test")
|
|
16131
16235
|
), displayedAssignment.status === "passed" && /* @__PURE__ */ React4.createElement(
|
|
16132
16236
|
TouchableOpacity2,
|
|
16133
16237
|
{
|
|
16134
|
-
style: [
|
|
16238
|
+
style: [styles7.actionBtn, styles7.failBtn, isSubmitting && { opacity: 0.5 }],
|
|
16135
16239
|
onPress: () => handleChangeResult("failed"),
|
|
16136
16240
|
disabled: isSubmitting
|
|
16137
16241
|
},
|
|
16138
|
-
/* @__PURE__ */ React4.createElement(Text2, { style:
|
|
16242
|
+
/* @__PURE__ */ React4.createElement(Text2, { style: styles7.failBtnText }, "Change to Fail")
|
|
16139
16243
|
), displayedAssignment.status === "failed" && /* @__PURE__ */ React4.createElement(
|
|
16140
16244
|
TouchableOpacity2,
|
|
16141
16245
|
{
|
|
16142
|
-
style: [
|
|
16246
|
+
style: [styles7.actionBtn, styles7.passBtn, isSubmitting && { opacity: 0.5 }],
|
|
16143
16247
|
onPress: () => handleChangeResult("passed"),
|
|
16144
16248
|
disabled: isSubmitting
|
|
16145
16249
|
},
|
|
16146
|
-
/* @__PURE__ */ React4.createElement(Text2, { style:
|
|
16147
|
-
))) : /* @__PURE__ */ React4.createElement(View4, { style:
|
|
16250
|
+
/* @__PURE__ */ React4.createElement(Text2, { style: styles7.passBtnText }, "Change to Pass")
|
|
16251
|
+
))) : /* @__PURE__ */ React4.createElement(View4, { style: styles7.actionButtons }, /* @__PURE__ */ React4.createElement(TouchableOpacity2, { style: [styles7.actionBtn, styles7.failBtn, isSubmitting && { opacity: 0.5 }], onPress: handleFail, disabled: isSubmitting }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.failBtnText }, isSubmitting ? displayedAssignment.isVerification ? "Reporting..." : "Failing..." : displayedAssignment.isVerification ? "\u2717 Still Broken" : "Fail")), /* @__PURE__ */ React4.createElement(TouchableOpacity2, { style: [styles7.actionBtn, styles7.skipBtn, isSubmitting && { opacity: 0.5 }], onPress: () => setShowSkipModal(true), disabled: isSubmitting }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.skipBtnText }, "Skip")), /* @__PURE__ */ React4.createElement(TouchableOpacity2, { style: [styles7.actionBtn, styles7.passBtn, isSubmitting && { opacity: 0.5 }], onPress: handlePass, disabled: isSubmitting }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.passBtnText }, isSubmitting ? displayedAssignment.isVerification ? "Verifying..." : "Passing..." : displayedAssignment.isVerification ? "\u2713 Fix Verified" : "Pass"))), feedbackToastAssignmentId && /* @__PURE__ */ React4.createElement(Animated2.View, { style: [styles7.passToast, { transform: [{ translateY: toastSlideAnim }] }] }, /* @__PURE__ */ React4.createElement(View4, { style: styles7.passToastContent }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.passToastIcon }, "\u2705"), /* @__PURE__ */ React4.createElement(Text2, { style: styles7.passToastText }, "Test passed!")), /* @__PURE__ */ React4.createElement(
|
|
16148
16252
|
TouchableOpacity2,
|
|
16149
16253
|
{
|
|
16150
|
-
style:
|
|
16254
|
+
style: styles7.passToastButton,
|
|
16151
16255
|
onPress: () => {
|
|
16152
16256
|
if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
|
|
16153
16257
|
const toastId = feedbackToastAssignmentId;
|
|
@@ -16155,8 +16259,8 @@ function TestDetailScreen({ testId, nav }) {
|
|
|
16155
16259
|
nav.push({ name: "TEST_FEEDBACK", status: "passed", assignmentId: toastId });
|
|
16156
16260
|
}
|
|
16157
16261
|
},
|
|
16158
|
-
/* @__PURE__ */ React4.createElement(Text2, { style:
|
|
16159
|
-
)), /* @__PURE__ */ React4.createElement(Modal, { visible: showSkipModal, transparent: true, animationType: "fade" }, /* @__PURE__ */ React4.createElement(View4, { style:
|
|
16262
|
+
/* @__PURE__ */ React4.createElement(Text2, { style: styles7.passToastButtonText }, "Rate this test")
|
|
16263
|
+
)), /* @__PURE__ */ React4.createElement(Modal, { visible: showSkipModal, transparent: true, animationType: "fade" }, /* @__PURE__ */ React4.createElement(View4, { style: styles7.modalOverlay }, /* @__PURE__ */ React4.createElement(View4, { style: styles7.modalContent }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.modalTitle }, "Skip this test?"), /* @__PURE__ */ React4.createElement(Text2, { style: styles7.modalSubtitle }, "Select a reason:"), [
|
|
16160
16264
|
{ reason: "blocked", label: "\u{1F6AB} Blocked by a bug" },
|
|
16161
16265
|
{ reason: "not_ready", label: "\u{1F6A7} Feature not ready" },
|
|
16162
16266
|
{ reason: "dependency", label: "\u{1F517} Needs another test first" },
|
|
@@ -16165,32 +16269,32 @@ function TestDetailScreen({ testId, nav }) {
|
|
|
16165
16269
|
TouchableOpacity2,
|
|
16166
16270
|
{
|
|
16167
16271
|
key: reason,
|
|
16168
|
-
style: [
|
|
16272
|
+
style: [styles7.skipOption, selectedSkipReason === reason && styles7.skipOptionActive],
|
|
16169
16273
|
onPress: () => setSelectedSkipReason(reason)
|
|
16170
16274
|
},
|
|
16171
|
-
/* @__PURE__ */ React4.createElement(Text2, { style: [
|
|
16275
|
+
/* @__PURE__ */ React4.createElement(Text2, { style: [styles7.skipOptionText, selectedSkipReason === reason && styles7.skipOptionTextActive] }, label)
|
|
16172
16276
|
)), /* @__PURE__ */ React4.createElement(
|
|
16173
16277
|
TextInput,
|
|
16174
16278
|
{
|
|
16175
|
-
style:
|
|
16279
|
+
style: styles7.skipNotes,
|
|
16176
16280
|
value: skipNotes,
|
|
16177
16281
|
onChangeText: setSkipNotes,
|
|
16178
16282
|
placeholder: "Additional notes (optional)",
|
|
16179
16283
|
placeholderTextColor: colors.textMuted,
|
|
16180
16284
|
multiline: true
|
|
16181
16285
|
}
|
|
16182
|
-
), /* @__PURE__ */ React4.createElement(View4, { style:
|
|
16286
|
+
), /* @__PURE__ */ React4.createElement(View4, { style: styles7.skipActions }, /* @__PURE__ */ React4.createElement(TouchableOpacity2, { style: styles7.skipCancel, onPress: () => {
|
|
16183
16287
|
setShowSkipModal(false);
|
|
16184
16288
|
setSelectedSkipReason(null);
|
|
16185
16289
|
setSkipNotes("");
|
|
16186
|
-
} }, /* @__PURE__ */ React4.createElement(Text2, { style:
|
|
16290
|
+
} }, /* @__PURE__ */ React4.createElement(Text2, { style: styles7.skipCancelText }, "Cancel")), /* @__PURE__ */ React4.createElement(
|
|
16187
16291
|
TouchableOpacity2,
|
|
16188
16292
|
{
|
|
16189
|
-
style: [
|
|
16293
|
+
style: [styles7.skipConfirm, !selectedSkipReason && { opacity: 0.4 }],
|
|
16190
16294
|
onPress: handleSkip,
|
|
16191
16295
|
disabled: !selectedSkipReason || skipping
|
|
16192
16296
|
},
|
|
16193
|
-
/* @__PURE__ */ React4.createElement(Text2, { style:
|
|
16297
|
+
/* @__PURE__ */ React4.createElement(Text2, { style: styles7.skipConfirmText }, skipping ? "Skipping..." : "Skip Test")
|
|
16194
16298
|
))))));
|
|
16195
16299
|
}
|
|
16196
16300
|
function createStyles2() {
|
|
@@ -16312,7 +16416,7 @@ import React5, { useState as useState4, useMemo as useMemo3, useCallback as useC
|
|
|
16312
16416
|
import { View as View5, Text as Text3, TouchableOpacity as TouchableOpacity3, StyleSheet as StyleSheet5, ScrollView, TextInput as TextInput2, Platform as Platform3, Linking as Linking2 } from "react-native";
|
|
16313
16417
|
function TestListScreen({ nav }) {
|
|
16314
16418
|
const { assignments, currentAssignment, refreshAssignments, dashboardUrl, isLoading, widgetColorScheme } = useBugBear();
|
|
16315
|
-
const
|
|
16419
|
+
const styles7 = useMemo3(() => createStyles3(), [widgetColorScheme]);
|
|
16316
16420
|
const [filter, setFilter] = useState4("all");
|
|
16317
16421
|
const [roleFilter, setRoleFilter] = useState4(null);
|
|
16318
16422
|
const [trackFilter, setTrackFilter] = useState4(null);
|
|
@@ -16404,18 +16508,18 @@ function TestListScreen({ nav }) {
|
|
|
16404
16508
|
return true;
|
|
16405
16509
|
}, [platformFilter, roleFilter, trackFilter, searchQuery, filter]);
|
|
16406
16510
|
if (isLoading) return /* @__PURE__ */ React5.createElement(TestListScreenSkeleton, null);
|
|
16407
|
-
return /* @__PURE__ */ React5.createElement(View5, null, /* @__PURE__ */ React5.createElement(View5, { style:
|
|
16511
|
+
return /* @__PURE__ */ React5.createElement(View5, null, /* @__PURE__ */ React5.createElement(View5, { style: styles7.filterBar }, [
|
|
16408
16512
|
{ key: "all", label: "All", count: assignments.length },
|
|
16409
16513
|
{ key: "todo", label: "To Do", count: assignments.filter((a) => !a.isVerification && (a.status === "pending" || a.status === "in_progress" || a.status === "failed")).length },
|
|
16410
16514
|
{ key: "retest", label: "Retest", count: assignments.filter((a) => !!a.isVerification && (a.status === "pending" || a.status === "in_progress")).length },
|
|
16411
16515
|
{ key: "done", label: "Done", count: assignments.filter((a) => a.status === "passed" || a.status === "skipped" || a.status === "blocked").length }
|
|
16412
|
-
].map((f) => /* @__PURE__ */ React5.createElement(TouchableOpacity3, { key: f.key, style: [
|
|
16516
|
+
].map((f) => /* @__PURE__ */ React5.createElement(TouchableOpacity3, { key: f.key, style: [styles7.filterBtn, filter === f.key && styles7.filterBtnActive], onPress: () => setFilter(f.key) }, /* @__PURE__ */ React5.createElement(Text3, { style: [styles7.filterBtnText, filter === f.key && styles7.filterBtnTextActive] }, f.label, " (", f.count, ")")))), availableRoles.length >= 2 && /* @__PURE__ */ React5.createElement(View5, { style: styles7.roleSection }, /* @__PURE__ */ React5.createElement(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, style: styles7.roleBar }, /* @__PURE__ */ React5.createElement(
|
|
16413
16517
|
TouchableOpacity3,
|
|
16414
16518
|
{
|
|
16415
|
-
style: [
|
|
16519
|
+
style: [styles7.roleBtn, !roleFilter && styles7.roleBtnActive],
|
|
16416
16520
|
onPress: () => setRoleFilter(null)
|
|
16417
16521
|
},
|
|
16418
|
-
/* @__PURE__ */ React5.createElement(Text3, { style: [
|
|
16522
|
+
/* @__PURE__ */ React5.createElement(Text3, { style: [styles7.roleBtnText, !roleFilter && styles7.roleBtnTextActive] }, "All Roles")
|
|
16419
16523
|
), availableRoles.map((role) => {
|
|
16420
16524
|
const isActive = roleFilter === role.id;
|
|
16421
16525
|
return /* @__PURE__ */ React5.createElement(
|
|
@@ -16423,30 +16527,30 @@ function TestListScreen({ nav }) {
|
|
|
16423
16527
|
{
|
|
16424
16528
|
key: role.id,
|
|
16425
16529
|
style: [
|
|
16426
|
-
|
|
16530
|
+
styles7.roleBtn,
|
|
16427
16531
|
isActive && { backgroundColor: role.color + "20", borderColor: role.color + "60", borderWidth: 1 }
|
|
16428
16532
|
],
|
|
16429
16533
|
onPress: () => setRoleFilter(isActive ? null : role.id)
|
|
16430
16534
|
},
|
|
16431
|
-
/* @__PURE__ */ React5.createElement(View5, { style: [
|
|
16432
|
-
/* @__PURE__ */ React5.createElement(Text3, { style: [
|
|
16535
|
+
/* @__PURE__ */ React5.createElement(View5, { style: [styles7.roleDot, { backgroundColor: role.color }] }),
|
|
16536
|
+
/* @__PURE__ */ React5.createElement(Text3, { style: [styles7.roleBtnText, isActive && { color: role.color, fontWeight: "600" }] }, role.name)
|
|
16433
16537
|
);
|
|
16434
|
-
})), selectedRole?.loginHint && /* @__PURE__ */ React5.createElement(View5, { style: [
|
|
16538
|
+
})), selectedRole?.loginHint && /* @__PURE__ */ React5.createElement(View5, { style: [styles7.loginHint, { backgroundColor: selectedRole.color + "10", borderColor: selectedRole.color + "30" }] }, /* @__PURE__ */ React5.createElement(Text3, { style: styles7.loginHintText }, "Log in as: ", selectedRole.loginHint))), /* @__PURE__ */ React5.createElement(View5, { style: styles7.searchContainer }, /* @__PURE__ */ React5.createElement(
|
|
16435
16539
|
TextInput2,
|
|
16436
16540
|
{
|
|
16437
16541
|
value: searchQuery,
|
|
16438
16542
|
onChangeText: setSearchQuery,
|
|
16439
16543
|
placeholder: "Search tests...",
|
|
16440
16544
|
placeholderTextColor: colors.textMuted,
|
|
16441
|
-
style:
|
|
16545
|
+
style: styles7.searchInput
|
|
16442
16546
|
}
|
|
16443
|
-
)), /* @__PURE__ */ React5.createElement(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, style:
|
|
16547
|
+
)), /* @__PURE__ */ React5.createElement(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, style: styles7.platformBar }, /* @__PURE__ */ React5.createElement(
|
|
16444
16548
|
TouchableOpacity3,
|
|
16445
16549
|
{
|
|
16446
|
-
style: [
|
|
16550
|
+
style: [styles7.platformBtn, !platformFilter && styles7.platformBtnActive],
|
|
16447
16551
|
onPress: () => setPlatformFilter(null)
|
|
16448
16552
|
},
|
|
16449
|
-
/* @__PURE__ */ React5.createElement(Text3, { style: [
|
|
16553
|
+
/* @__PURE__ */ React5.createElement(Text3, { style: [styles7.platformBtnText, !platformFilter && styles7.platformBtnTextActive] }, "All")
|
|
16450
16554
|
), [
|
|
16451
16555
|
{ key: "web", label: "Web", icon: "\u{1F310}" },
|
|
16452
16556
|
{ key: "ios", label: "iOS", icon: "\u{1F4F1}" },
|
|
@@ -16458,32 +16562,32 @@ function TestListScreen({ nav }) {
|
|
|
16458
16562
|
{
|
|
16459
16563
|
key: p.key,
|
|
16460
16564
|
style: [
|
|
16461
|
-
|
|
16565
|
+
styles7.platformBtn,
|
|
16462
16566
|
isActive && { backgroundColor: colors.blue + "20", borderColor: colors.blue + "60", borderWidth: 1 }
|
|
16463
16567
|
],
|
|
16464
16568
|
onPress: () => setPlatformFilter(isActive ? null : p.key)
|
|
16465
16569
|
},
|
|
16466
|
-
/* @__PURE__ */ React5.createElement(Text3, { style: [
|
|
16570
|
+
/* @__PURE__ */ React5.createElement(Text3, { style: [styles7.platformBtnText, isActive && { color: colors.blue, fontWeight: "600" }] }, p.icon, " ", p.label)
|
|
16467
16571
|
);
|
|
16468
|
-
})), /* @__PURE__ */ React5.createElement(View5, { style:
|
|
16572
|
+
})), /* @__PURE__ */ React5.createElement(View5, { style: styles7.trackSortRow }, availableTracks.length >= 2 && /* @__PURE__ */ React5.createElement(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, style: { flex: 1 } }, /* @__PURE__ */ React5.createElement(
|
|
16469
16573
|
TouchableOpacity3,
|
|
16470
16574
|
{
|
|
16471
|
-
style: [
|
|
16575
|
+
style: [styles7.trackBtn, !trackFilter && styles7.trackBtnActive],
|
|
16472
16576
|
onPress: () => setTrackFilter(null)
|
|
16473
16577
|
},
|
|
16474
|
-
/* @__PURE__ */ React5.createElement(Text3, { style: [
|
|
16578
|
+
/* @__PURE__ */ React5.createElement(Text3, { style: [styles7.trackBtnText, !trackFilter && styles7.trackBtnTextActive] }, "All Tracks")
|
|
16475
16579
|
), availableTracks.map((track) => {
|
|
16476
16580
|
const isActive = trackFilter === track.id;
|
|
16477
16581
|
return /* @__PURE__ */ React5.createElement(
|
|
16478
16582
|
TouchableOpacity3,
|
|
16479
16583
|
{
|
|
16480
16584
|
key: track.id,
|
|
16481
|
-
style: [
|
|
16585
|
+
style: [styles7.trackBtn, isActive && { backgroundColor: track.color + "20", borderColor: track.color + "60", borderWidth: 1 }],
|
|
16482
16586
|
onPress: () => setTrackFilter(isActive ? null : track.id)
|
|
16483
16587
|
},
|
|
16484
|
-
/* @__PURE__ */ React5.createElement(Text3, { style: [
|
|
16588
|
+
/* @__PURE__ */ React5.createElement(Text3, { style: [styles7.trackBtnText, isActive && { color: track.color, fontWeight: "600" }] }, track.icon, " ", track.name)
|
|
16485
16589
|
);
|
|
16486
|
-
})), /* @__PURE__ */ React5.createElement(View5, { style:
|
|
16590
|
+
})), /* @__PURE__ */ React5.createElement(View5, { style: styles7.sortGroup }, [
|
|
16487
16591
|
{ key: "priority", label: "\u2195 Priority" },
|
|
16488
16592
|
{ key: "recent", label: "\u{1F550} Recent" },
|
|
16489
16593
|
{ key: "alpha", label: "A-Z" }
|
|
@@ -16491,41 +16595,41 @@ function TestListScreen({ nav }) {
|
|
|
16491
16595
|
TouchableOpacity3,
|
|
16492
16596
|
{
|
|
16493
16597
|
key: s2.key,
|
|
16494
|
-
style: [
|
|
16598
|
+
style: [styles7.sortBtn, sortMode === s2.key && styles7.sortBtnActive],
|
|
16495
16599
|
onPress: () => setSortMode(s2.key)
|
|
16496
16600
|
},
|
|
16497
|
-
/* @__PURE__ */ React5.createElement(Text3, { style: [
|
|
16601
|
+
/* @__PURE__ */ React5.createElement(Text3, { style: [styles7.sortBtnText, sortMode === s2.key && styles7.sortBtnTextActive] }, s2.label)
|
|
16498
16602
|
)))), groupedAssignments.map((folder) => {
|
|
16499
16603
|
const folderId = folder.group?.id || "ungrouped";
|
|
16500
16604
|
const isCollapsed = collapsedFolders.has(folderId);
|
|
16501
16605
|
const filtered = folder.assignments.filter(filterAssignment);
|
|
16502
16606
|
if (filtered.length === 0 && filter !== "all") return null;
|
|
16503
|
-
return /* @__PURE__ */ React5.createElement(View5, { key: folderId, style:
|
|
16607
|
+
return /* @__PURE__ */ React5.createElement(View5, { key: folderId, style: styles7.folder }, /* @__PURE__ */ React5.createElement(TouchableOpacity3, { style: styles7.folderHeader, onPress: () => toggleFolder(folderId) }, /* @__PURE__ */ React5.createElement(Text3, { style: styles7.folderToggle }, isCollapsed ? "\u25B6" : "\u25BC"), /* @__PURE__ */ React5.createElement(Text3, { style: styles7.folderName, numberOfLines: 1 }, folder.group?.name || "Ungrouped"), /* @__PURE__ */ React5.createElement(View5, { style: styles7.folderProgress }, /* @__PURE__ */ React5.createElement(View5, { style: [styles7.folderProgressFill, { width: `${folder.stats.total > 0 ? Math.round((folder.stats.passed + folder.stats.failed) / folder.stats.total * 100) : 0}%` }] })), /* @__PURE__ */ React5.createElement(Text3, { style: styles7.folderCount }, folder.stats.passed + folder.stats.failed, "/", folder.stats.total)), !isCollapsed && filtered.map((assignment) => {
|
|
16504
16608
|
const badge = getStatusBadge(assignment.status);
|
|
16505
16609
|
const isCurrent = currentAssignment?.id === assignment.id;
|
|
16506
16610
|
return /* @__PURE__ */ React5.createElement(
|
|
16507
16611
|
TouchableOpacity3,
|
|
16508
16612
|
{
|
|
16509
16613
|
key: assignment.id,
|
|
16510
|
-
style: [
|
|
16614
|
+
style: [styles7.testItem, isCurrent && styles7.testItemCurrent],
|
|
16511
16615
|
onPress: () => nav.push({ name: "TEST_DETAIL", testId: assignment.id })
|
|
16512
16616
|
},
|
|
16513
|
-
/* @__PURE__ */ React5.createElement(Text3, { style:
|
|
16514
|
-
/* @__PURE__ */ React5.createElement(View5, { style:
|
|
16515
|
-
|
|
16617
|
+
/* @__PURE__ */ React5.createElement(Text3, { style: styles7.testBadge }, badge.icon),
|
|
16618
|
+
/* @__PURE__ */ React5.createElement(View5, { style: styles7.testInfo }, /* @__PURE__ */ React5.createElement(Text3, { style: styles7.testTitle, numberOfLines: 1 }, assignment.testCase.title), /* @__PURE__ */ React5.createElement(View5, { style: styles7.testMetaRow }, assignment.isVerification && /* @__PURE__ */ React5.createElement(View5, { style: [
|
|
16619
|
+
styles7.retestTag,
|
|
16516
16620
|
assignment.status === "passed" && { backgroundColor: colors.greenDark, borderColor: colors.greenBorder }
|
|
16517
16621
|
] }, /* @__PURE__ */ React5.createElement(Text3, { style: [
|
|
16518
|
-
|
|
16622
|
+
styles7.retestTagText,
|
|
16519
16623
|
assignment.status === "passed" && { color: colors.greenLight }
|
|
16520
|
-
] }, assignment.status === "passed" ? "Verified" : "Retest")), /* @__PURE__ */ React5.createElement(Text3, { style:
|
|
16624
|
+
] }, assignment.status === "passed" ? "Verified" : "Retest")), /* @__PURE__ */ React5.createElement(Text3, { style: styles7.testMeta }, assignment.testCase.testKey, " \xB7 ", assignment.testCase.priority), assignment.testCase.role && /* @__PURE__ */ React5.createElement(View5, { style: styles7.roleBadgeRow }, /* @__PURE__ */ React5.createElement(Text3, { style: styles7.testMeta }, " \xB7 "), /* @__PURE__ */ React5.createElement(View5, { style: [styles7.roleBadgeDot, { backgroundColor: assignment.testCase.role.color }] }), /* @__PURE__ */ React5.createElement(Text3, { style: [styles7.testMeta, { color: assignment.testCase.role.color, fontWeight: "500" }] }, assignment.testCase.role.name)))),
|
|
16521
16625
|
/* @__PURE__ */ React5.createElement(View5, { style: [
|
|
16522
|
-
|
|
16626
|
+
styles7.statusPill,
|
|
16523
16627
|
{
|
|
16524
16628
|
backgroundColor: assignment.status === "passed" ? colors.greenDark : assignment.status === "failed" ? colors.redSurface : assignment.status === "in_progress" ? colors.blueSurface : colors.card,
|
|
16525
16629
|
borderColor: assignment.status === "passed" ? colors.greenBorder : assignment.status === "failed" ? colors.redDark : assignment.status === "in_progress" ? colors.blueDark : colors.border
|
|
16526
16630
|
}
|
|
16527
16631
|
] }, /* @__PURE__ */ React5.createElement(Text3, { style: [
|
|
16528
|
-
|
|
16632
|
+
styles7.statusPillText,
|
|
16529
16633
|
{
|
|
16530
16634
|
color: assignment.status === "passed" ? colors.greenMed : assignment.status === "failed" ? colors.redMed : assignment.status === "in_progress" ? colors.blueLight : colors.zincLight
|
|
16531
16635
|
}
|
|
@@ -16535,12 +16639,12 @@ function TestListScreen({ nav }) {
|
|
|
16535
16639
|
}), dashboardUrl && /* @__PURE__ */ React5.createElement(
|
|
16536
16640
|
TouchableOpacity3,
|
|
16537
16641
|
{
|
|
16538
|
-
style:
|
|
16642
|
+
style: styles7.dashboardLink,
|
|
16539
16643
|
onPress: () => Linking2.openURL(`${dashboardUrl}/test-cases`),
|
|
16540
16644
|
activeOpacity: 0.7
|
|
16541
16645
|
},
|
|
16542
|
-
/* @__PURE__ */ React5.createElement(Text3, { style:
|
|
16543
|
-
), /* @__PURE__ */ React5.createElement(TouchableOpacity3, { style:
|
|
16646
|
+
/* @__PURE__ */ React5.createElement(Text3, { style: styles7.dashboardLinkText }, "\u{1F310}", " Manage on Dashboard ", "\u2192")
|
|
16647
|
+
), /* @__PURE__ */ React5.createElement(TouchableOpacity3, { style: styles7.refreshBtn, onPress: refreshAssignments }, /* @__PURE__ */ React5.createElement(Text3, { style: styles7.refreshText }, "\u21BB", " Refresh")));
|
|
16544
16648
|
}
|
|
16545
16649
|
function createStyles3() {
|
|
16546
16650
|
return StyleSheet5.create({
|
|
@@ -16860,7 +16964,7 @@ var styles2 = StyleSheet7.create({
|
|
|
16860
16964
|
// src/widget/screens/TestFeedbackScreen.tsx
|
|
16861
16965
|
function TestFeedbackScreen({ status, assignmentId, nav }) {
|
|
16862
16966
|
const { client, assignments, refreshAssignments, uploadImage, widgetColorScheme } = useBugBear();
|
|
16863
|
-
const
|
|
16967
|
+
const styles7 = useMemo4(() => createStyles4(), [widgetColorScheme]);
|
|
16864
16968
|
const images = useImageAttachments(uploadImage, 3, "screenshots");
|
|
16865
16969
|
const [rating, setRating] = useState6(5);
|
|
16866
16970
|
const [note, setNote] = useState6("");
|
|
@@ -16920,7 +17024,7 @@ function TestFeedbackScreen({ status, assignmentId, nav }) {
|
|
|
16920
17024
|
}
|
|
16921
17025
|
}
|
|
16922
17026
|
};
|
|
16923
|
-
return /* @__PURE__ */ React8.createElement(View8, { style:
|
|
17027
|
+
return /* @__PURE__ */ React8.createElement(View8, { style: styles7.container }, /* @__PURE__ */ React8.createElement(Text6, { style: styles7.header }, status === "passed" ? "\u2705 Test Passed!" : "\u274C Test Failed"), /* @__PURE__ */ React8.createElement(Text6, { style: styles7.subheader }, "Rate this test case"), /* @__PURE__ */ React8.createElement(View8, { style: styles7.starRow }, [1, 2, 3, 4, 5].map((n) => /* @__PURE__ */ React8.createElement(TouchableOpacity6, { key: n, onPress: () => setRating(n), style: styles7.starButton }, /* @__PURE__ */ React8.createElement(Text6, { style: [styles7.star, n <= rating && styles7.starActive] }, n <= rating ? "\u2605" : "\u2606")))), showFlags && /* @__PURE__ */ React8.createElement(View8, { style: styles7.flagsSection }, /* @__PURE__ */ React8.createElement(Text6, { style: styles7.flagsLabel }, "What could be improved?"), [
|
|
16924
17028
|
{ key: "isOutdated", label: "Test is outdated" },
|
|
16925
17029
|
{ key: "needsMoreDetail", label: "Needs more detail" },
|
|
16926
17030
|
{ key: "stepsUnclear", label: "Steps are unclear" },
|
|
@@ -16929,15 +17033,15 @@ function TestFeedbackScreen({ status, assignmentId, nav }) {
|
|
|
16929
17033
|
TouchableOpacity6,
|
|
16930
17034
|
{
|
|
16931
17035
|
key,
|
|
16932
|
-
style: [
|
|
17036
|
+
style: [styles7.flagItem, flags[key] && styles7.flagItemActive],
|
|
16933
17037
|
onPress: () => setFlags((prev) => ({ ...prev, [key]: !prev[key] }))
|
|
16934
17038
|
},
|
|
16935
|
-
/* @__PURE__ */ React8.createElement(View8, { style: [
|
|
16936
|
-
/* @__PURE__ */ React8.createElement(Text6, { style: [
|
|
17039
|
+
/* @__PURE__ */ React8.createElement(View8, { style: [styles7.flagCheck, flags[key] && styles7.flagCheckActive] }, flags[key] && /* @__PURE__ */ React8.createElement(Text6, { style: styles7.flagCheckmark }, "\u2713")),
|
|
17040
|
+
/* @__PURE__ */ React8.createElement(Text6, { style: [styles7.flagText, flags[key] && styles7.flagTextActive] }, label)
|
|
16937
17041
|
))), /* @__PURE__ */ React8.createElement(
|
|
16938
17042
|
TextInput3,
|
|
16939
17043
|
{
|
|
16940
|
-
style:
|
|
17044
|
+
style: styles7.noteInput,
|
|
16941
17045
|
value: note,
|
|
16942
17046
|
onChangeText: setNote,
|
|
16943
17047
|
placeholder: "Add a note (optional)",
|
|
@@ -16954,7 +17058,7 @@ function TestFeedbackScreen({ status, assignmentId, nav }) {
|
|
|
16954
17058
|
onRemove: images.removeImage,
|
|
16955
17059
|
label: "Screenshots (optional)"
|
|
16956
17060
|
}
|
|
16957
|
-
), /* @__PURE__ */ React8.createElement(View8, { style:
|
|
17061
|
+
), /* @__PURE__ */ React8.createElement(View8, { style: styles7.actions }, /* @__PURE__ */ React8.createElement(TouchableOpacity6, { style: styles7.skipButton, onPress: handleSkip }, /* @__PURE__ */ React8.createElement(Text6, { style: styles7.skipText }, "Skip")), /* @__PURE__ */ React8.createElement(TouchableOpacity6, { style: [shared.primaryButton, { flex: 2, opacity: submitting || images.isUploading ? 0.5 : 1 }], onPress: handleSubmit, disabled: submitting || images.isUploading }, /* @__PURE__ */ React8.createElement(Text6, { style: shared.primaryButtonText }, images.isUploading ? "Uploading..." : submitting ? "Submitting..." : "Submit"))));
|
|
16958
17062
|
}
|
|
16959
17063
|
function createStyles4() {
|
|
16960
17064
|
return StyleSheet8.create({
|
|
@@ -17143,7 +17247,7 @@ var styles3 = StyleSheet9.create({
|
|
|
17143
17247
|
// src/widget/screens/ReportScreen.tsx
|
|
17144
17248
|
function ReportScreen({ nav, prefill, autoCaptureUri, onAutoCaptureConsumed }) {
|
|
17145
17249
|
const { client, getDeviceInfo, uploadImage, refreshAssignments, widgetColorScheme } = useBugBear();
|
|
17146
|
-
const
|
|
17250
|
+
const styles7 = useMemo5(() => createStyles5(), [widgetColorScheme]);
|
|
17147
17251
|
const [reportType, setReportType] = useState8(prefill?.type || "bug");
|
|
17148
17252
|
const [severity, setSeverity] = useState8("medium");
|
|
17149
17253
|
const [category, setCategory] = useState8(null);
|
|
@@ -17249,7 +17353,7 @@ function ReportScreen({ nav, prefill, autoCaptureUri, onAutoCaptureConsumed }) {
|
|
|
17249
17353
|
submittingRef.current = false;
|
|
17250
17354
|
}
|
|
17251
17355
|
};
|
|
17252
|
-
return /* @__PURE__ */ React10.createElement(View10, null, isRetestFailure ? /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(View10, { style:
|
|
17356
|
+
return /* @__PURE__ */ React10.createElement(View10, null, isRetestFailure ? /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(View10, { style: styles7.retestBanner }, /* @__PURE__ */ React10.createElement(Text8, { style: styles7.retestIcon }, "\u{1F504}"), /* @__PURE__ */ React10.createElement(View10, null, /* @__PURE__ */ React10.createElement(Text8, { style: styles7.retestTitle }, "Bug Still Present"), /* @__PURE__ */ React10.createElement(Text8, { style: styles7.retestSubtitle }, "The fix did not resolve this issue"))), /* @__PURE__ */ React10.createElement(View10, { style: styles7.section }, /* @__PURE__ */ React10.createElement(Text8, { style: shared.label }, "Severity"), /* @__PURE__ */ React10.createElement(View10, { style: styles7.severityRow }, [
|
|
17253
17357
|
{ sev: "critical", color: colors.red },
|
|
17254
17358
|
{ sev: "high", color: colors.orange },
|
|
17255
17359
|
{ sev: "medium", color: colors.yellow },
|
|
@@ -17258,14 +17362,14 @@ function ReportScreen({ nav, prefill, autoCaptureUri, onAutoCaptureConsumed }) {
|
|
|
17258
17362
|
TouchableOpacity8,
|
|
17259
17363
|
{
|
|
17260
17364
|
key: sev,
|
|
17261
|
-
style: [
|
|
17365
|
+
style: [styles7.sevButton, severity === sev && { backgroundColor: `${color}30`, borderColor: color }],
|
|
17262
17366
|
onPress: () => setSeverity(sev)
|
|
17263
17367
|
},
|
|
17264
|
-
/* @__PURE__ */ React10.createElement(Text8, { style: [
|
|
17265
|
-
)))), /* @__PURE__ */ React10.createElement(View10, { style:
|
|
17368
|
+
/* @__PURE__ */ React10.createElement(Text8, { style: [styles7.sevText, severity === sev && { color }] }, sev)
|
|
17369
|
+
)))), /* @__PURE__ */ React10.createElement(View10, { style: styles7.section }, /* @__PURE__ */ React10.createElement(Text8, { style: shared.label }, "Category (optional)"), /* @__PURE__ */ React10.createElement(CategoryPicker, { value: category, onChange: setCategory, optional: true })), /* @__PURE__ */ React10.createElement(View10, { style: styles7.section }, /* @__PURE__ */ React10.createElement(Text8, { style: shared.label }, "What went wrong?"), /* @__PURE__ */ React10.createElement(
|
|
17266
17370
|
TextInput4,
|
|
17267
17371
|
{
|
|
17268
|
-
style:
|
|
17372
|
+
style: styles7.descInput,
|
|
17269
17373
|
value: description,
|
|
17270
17374
|
onChangeText: setDescription,
|
|
17271
17375
|
placeholder: "Describe what you observed. What still doesn't work?",
|
|
@@ -17318,15 +17422,15 @@ function ReportScreen({ nav, prefill, autoCaptureUri, onAutoCaptureConsumed }) {
|
|
|
17318
17422
|
onRemove: images.removeImage,
|
|
17319
17423
|
label: "Attachments (optional)"
|
|
17320
17424
|
}
|
|
17321
|
-
), error && /* @__PURE__ */ React10.createElement(View10, { style:
|
|
17425
|
+
), error && /* @__PURE__ */ React10.createElement(View10, { style: styles7.errorBanner }, /* @__PURE__ */ React10.createElement(Text8, { style: styles7.errorText }, error)), /* @__PURE__ */ React10.createElement(
|
|
17322
17426
|
TouchableOpacity8,
|
|
17323
17427
|
{
|
|
17324
|
-
style: [shared.primaryButton,
|
|
17428
|
+
style: [shared.primaryButton, styles7.retestSubmitButton, (!description.trim() || submitting || images.isUploading) && shared.primaryButtonDisabled, { marginTop: 20 }],
|
|
17325
17429
|
onPress: handleSubmit,
|
|
17326
17430
|
disabled: !description.trim() || submitting || images.isUploading
|
|
17327
17431
|
},
|
|
17328
17432
|
/* @__PURE__ */ React10.createElement(Text8, { style: shared.primaryButtonText }, images.isUploading ? "Uploading images..." : submitting ? "Submitting..." : error ? "Retry" : "Submit Failed Retest")
|
|
17329
|
-
)) : /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(Text8, { style: shared.label }, "What are you reporting?"), /* @__PURE__ */ React10.createElement(View10, { style:
|
|
17433
|
+
)) : /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(Text8, { style: shared.label }, "What are you reporting?"), /* @__PURE__ */ React10.createElement(View10, { style: styles7.typeRow }, [
|
|
17330
17434
|
{ type: "bug", label: "Bug", icon: "\u{1F41B}" },
|
|
17331
17435
|
{ type: "feedback", label: "Feedback", icon: "\u{1F4A1}" },
|
|
17332
17436
|
{ type: "suggestion", label: "Idea", icon: "\u2728" }
|
|
@@ -17334,12 +17438,12 @@ function ReportScreen({ nav, prefill, autoCaptureUri, onAutoCaptureConsumed }) {
|
|
|
17334
17438
|
TouchableOpacity8,
|
|
17335
17439
|
{
|
|
17336
17440
|
key: type,
|
|
17337
|
-
style: [
|
|
17441
|
+
style: [styles7.typeCard, reportType === type && styles7.typeCardActive],
|
|
17338
17442
|
onPress: () => setReportType(type)
|
|
17339
17443
|
},
|
|
17340
|
-
/* @__PURE__ */ React10.createElement(Text8, { style:
|
|
17341
|
-
/* @__PURE__ */ React10.createElement(Text8, { style: [
|
|
17342
|
-
))), isBugType && /* @__PURE__ */ React10.createElement(View10, { style:
|
|
17444
|
+
/* @__PURE__ */ React10.createElement(Text8, { style: styles7.typeIcon }, icon),
|
|
17445
|
+
/* @__PURE__ */ React10.createElement(Text8, { style: [styles7.typeLabel, reportType === type && styles7.typeLabelActive] }, label)
|
|
17446
|
+
))), isBugType && /* @__PURE__ */ React10.createElement(View10, { style: styles7.section }, /* @__PURE__ */ React10.createElement(Text8, { style: shared.label }, "Severity"), /* @__PURE__ */ React10.createElement(View10, { style: styles7.severityRow }, [
|
|
17343
17447
|
{ sev: "critical", color: colors.red },
|
|
17344
17448
|
{ sev: "high", color: colors.orange },
|
|
17345
17449
|
{ sev: "medium", color: colors.yellow },
|
|
@@ -17348,14 +17452,14 @@ function ReportScreen({ nav, prefill, autoCaptureUri, onAutoCaptureConsumed }) {
|
|
|
17348
17452
|
TouchableOpacity8,
|
|
17349
17453
|
{
|
|
17350
17454
|
key: sev,
|
|
17351
|
-
style: [
|
|
17455
|
+
style: [styles7.sevButton, severity === sev && { backgroundColor: `${color}30`, borderColor: color }],
|
|
17352
17456
|
onPress: () => setSeverity(sev)
|
|
17353
17457
|
},
|
|
17354
|
-
/* @__PURE__ */ React10.createElement(Text8, { style: [
|
|
17355
|
-
)))), isBugType && /* @__PURE__ */ React10.createElement(View10, { style:
|
|
17458
|
+
/* @__PURE__ */ React10.createElement(Text8, { style: [styles7.sevText, severity === sev && { color }] }, sev)
|
|
17459
|
+
)))), isBugType && /* @__PURE__ */ React10.createElement(View10, { style: styles7.section }, /* @__PURE__ */ React10.createElement(Text8, { style: shared.label }, "Category (optional)"), /* @__PURE__ */ React10.createElement(CategoryPicker, { value: category, onChange: setCategory, optional: true })), /* @__PURE__ */ React10.createElement(View10, { style: styles7.section }, /* @__PURE__ */ React10.createElement(Text8, { style: shared.label }, "What happened?"), /* @__PURE__ */ React10.createElement(
|
|
17356
17460
|
TextInput4,
|
|
17357
17461
|
{
|
|
17358
|
-
style:
|
|
17462
|
+
style: styles7.descInput,
|
|
17359
17463
|
value: description,
|
|
17360
17464
|
onChangeText: setDescription,
|
|
17361
17465
|
placeholder: "Describe the issue...",
|
|
@@ -17398,16 +17502,16 @@ function ReportScreen({ nav, prefill, autoCaptureUri, onAutoCaptureConsumed }) {
|
|
|
17398
17502
|
issue.title
|
|
17399
17503
|
),
|
|
17400
17504
|
/* @__PURE__ */ React10.createElement(Text8, { style: { fontSize: 11, color: colors.textMuted } }, issue.status)
|
|
17401
|
-
)))), isBugType && /* @__PURE__ */ React10.createElement(View10, { style:
|
|
17505
|
+
)))), isBugType && /* @__PURE__ */ React10.createElement(View10, { style: styles7.section }, /* @__PURE__ */ React10.createElement(Text8, { style: shared.label }, "Which screen?"), /* @__PURE__ */ React10.createElement(
|
|
17402
17506
|
TextInput4,
|
|
17403
17507
|
{
|
|
17404
|
-
style:
|
|
17508
|
+
style: styles7.screenInput,
|
|
17405
17509
|
value: affectedScreen,
|
|
17406
17510
|
onChangeText: setAffectedScreen,
|
|
17407
17511
|
placeholder: "e.g. Reservations, Settings...",
|
|
17408
17512
|
placeholderTextColor: colors.textMuted
|
|
17409
17513
|
}
|
|
17410
|
-
), /* @__PURE__ */ React10.createElement(Text8, { style:
|
|
17514
|
+
), /* @__PURE__ */ React10.createElement(Text8, { style: styles7.screenHint }, "Which screen or area was the bug on? (optional)")), /* @__PURE__ */ React10.createElement(
|
|
17411
17515
|
ImagePickerButtons,
|
|
17412
17516
|
{
|
|
17413
17517
|
images: images.images,
|
|
@@ -17417,7 +17521,7 @@ function ReportScreen({ nav, prefill, autoCaptureUri, onAutoCaptureConsumed }) {
|
|
|
17417
17521
|
onRemove: images.removeImage,
|
|
17418
17522
|
label: "Screenshots (optional)"
|
|
17419
17523
|
}
|
|
17420
|
-
), error && /* @__PURE__ */ React10.createElement(View10, { style:
|
|
17524
|
+
), error && /* @__PURE__ */ React10.createElement(View10, { style: styles7.errorBanner }, /* @__PURE__ */ React10.createElement(Text8, { style: styles7.errorText }, error)), /* @__PURE__ */ React10.createElement(
|
|
17421
17525
|
TouchableOpacity8,
|
|
17422
17526
|
{
|
|
17423
17527
|
style: [shared.primaryButton, (!description.trim() || submitting || images.isUploading) && shared.primaryButtonDisabled, { marginTop: 20 }],
|
|
@@ -17457,12 +17561,12 @@ import React11, { useEffect as useEffect7, useMemo as useMemo6 } from "react";
|
|
|
17457
17561
|
import { View as View11, Text as Text9, StyleSheet as StyleSheet11 } from "react-native";
|
|
17458
17562
|
function ReportSuccessScreen({ nav }) {
|
|
17459
17563
|
const { widgetColorScheme } = useBugBear();
|
|
17460
|
-
const
|
|
17564
|
+
const styles7 = useMemo6(() => createStyles6(), [widgetColorScheme]);
|
|
17461
17565
|
useEffect7(() => {
|
|
17462
17566
|
const timer = setTimeout(() => nav.reset(), 2e3);
|
|
17463
17567
|
return () => clearTimeout(timer);
|
|
17464
17568
|
}, [nav]);
|
|
17465
|
-
return /* @__PURE__ */ React11.createElement(View11, { style:
|
|
17569
|
+
return /* @__PURE__ */ React11.createElement(View11, { style: styles7.container }, /* @__PURE__ */ React11.createElement(Text9, { style: styles7.emoji }, "\u{1F389}"), /* @__PURE__ */ React11.createElement(Text9, { style: styles7.title }, "Report submitted!"), /* @__PURE__ */ React11.createElement(Text9, { style: styles7.subtitle }, "Thank you for your feedback"));
|
|
17466
17570
|
}
|
|
17467
17571
|
function createStyles6() {
|
|
17468
17572
|
return StyleSheet11.create({
|
|
@@ -17478,7 +17582,7 @@ import React12, { useMemo as useMemo7, useState as useState9 } from "react";
|
|
|
17478
17582
|
import { View as View12, Text as Text10, TouchableOpacity as TouchableOpacity9, ScrollView as ScrollView3, StyleSheet as StyleSheet12, Linking as Linking3 } from "react-native";
|
|
17479
17583
|
function MessageListScreen({ nav }) {
|
|
17480
17584
|
const { threads, unreadCount, refreshThreads, dashboardUrl, isLoading, widgetColorScheme } = useBugBear();
|
|
17481
|
-
const
|
|
17585
|
+
const styles7 = useMemo7(() => createStyles7(), [widgetColorScheme]);
|
|
17482
17586
|
const [activeFilter, setActiveFilter] = useState9("all");
|
|
17483
17587
|
const filteredThreads = threads.filter((thread) => {
|
|
17484
17588
|
if (activeFilter === "all") return true;
|
|
@@ -17496,10 +17600,10 @@ function MessageListScreen({ nav }) {
|
|
|
17496
17600
|
return /* @__PURE__ */ React12.createElement(View12, null, /* @__PURE__ */ React12.createElement(
|
|
17497
17601
|
TouchableOpacity9,
|
|
17498
17602
|
{
|
|
17499
|
-
style:
|
|
17603
|
+
style: styles7.newMsgButton,
|
|
17500
17604
|
onPress: () => nav.push({ name: "COMPOSE_MESSAGE" })
|
|
17501
17605
|
},
|
|
17502
|
-
/* @__PURE__ */ React12.createElement(Text10, { style:
|
|
17606
|
+
/* @__PURE__ */ React12.createElement(Text10, { style: styles7.newMsgText }, "\u2709\uFE0F New Message")
|
|
17503
17607
|
), /* @__PURE__ */ React12.createElement(
|
|
17504
17608
|
ScrollView3,
|
|
17505
17609
|
{
|
|
@@ -17544,20 +17648,20 @@ function MessageListScreen({ nav }) {
|
|
|
17544
17648
|
TouchableOpacity9,
|
|
17545
17649
|
{
|
|
17546
17650
|
key: thread.id,
|
|
17547
|
-
style: [
|
|
17651
|
+
style: [styles7.threadItem, thread.unreadCount > 0 && styles7.threadItemUnread],
|
|
17548
17652
|
onPress: () => nav.push({ name: "THREAD_DETAIL", thread })
|
|
17549
17653
|
},
|
|
17550
|
-
/* @__PURE__ */ React12.createElement(View12, { style:
|
|
17551
|
-
/* @__PURE__ */ React12.createElement(View12, { style:
|
|
17654
|
+
/* @__PURE__ */ React12.createElement(View12, { style: styles7.threadLeft }, /* @__PURE__ */ React12.createElement(Text10, { style: styles7.threadIcon }, getThreadTypeIcon(thread.threadType)), /* @__PURE__ */ React12.createElement(View12, { style: styles7.threadInfo }, /* @__PURE__ */ React12.createElement(View12, { style: styles7.threadTitleRow }, thread.isPinned && /* @__PURE__ */ React12.createElement(Text10, { style: styles7.pinIcon }, "\u{1F4CC}"), /* @__PURE__ */ React12.createElement(Text10, { style: styles7.threadSubject, numberOfLines: 1 }, thread.subject || "No subject")), thread.threadType === "report" && thread.reporterName && /* @__PURE__ */ React12.createElement(Text10, { style: { fontSize: 11, color: colors.textMuted } }, "Reported by: ", thread.reporterName), thread.lastMessage && /* @__PURE__ */ React12.createElement(Text10, { style: styles7.threadPreview, numberOfLines: 1 }, thread.lastMessage.senderName, ": ", thread.lastMessage.content))),
|
|
17655
|
+
/* @__PURE__ */ React12.createElement(View12, { style: styles7.threadRight }, /* @__PURE__ */ React12.createElement(Text10, { style: styles7.threadTime }, formatRelativeTime(thread.lastMessageAt)), thread.unreadCount > 0 && /* @__PURE__ */ React12.createElement(View12, { style: styles7.unreadBadge }, /* @__PURE__ */ React12.createElement(Text10, { style: styles7.unreadText }, thread.unreadCount)), thread.priority !== "normal" && /* @__PURE__ */ React12.createElement(View12, { style: [styles7.priorityDot, { backgroundColor: getPriorityColor(thread.priority) }] }))
|
|
17552
17656
|
))), dashboardUrl && /* @__PURE__ */ React12.createElement(
|
|
17553
17657
|
TouchableOpacity9,
|
|
17554
17658
|
{
|
|
17555
|
-
style:
|
|
17659
|
+
style: styles7.dashboardLink,
|
|
17556
17660
|
onPress: () => Linking3.openURL(`${dashboardUrl}/discussions`),
|
|
17557
17661
|
activeOpacity: 0.7
|
|
17558
17662
|
},
|
|
17559
|
-
/* @__PURE__ */ React12.createElement(Text10, { style:
|
|
17560
|
-
), /* @__PURE__ */ React12.createElement(View12, { style:
|
|
17663
|
+
/* @__PURE__ */ React12.createElement(Text10, { style: styles7.dashboardLinkText }, "\u{1F310}", " View on Dashboard ", "\u2192")
|
|
17664
|
+
), /* @__PURE__ */ React12.createElement(View12, { style: styles7.footer }, /* @__PURE__ */ React12.createElement(Text10, { style: styles7.footerText }, filteredThreads.length, " thread", filteredThreads.length !== 1 ? "s" : "", " \xB7 ", unreadCount, " unread"), /* @__PURE__ */ React12.createElement(TouchableOpacity9, { onPress: refreshThreads }, /* @__PURE__ */ React12.createElement(Text10, { style: styles7.refreshText }, "\u21BB Refresh"))));
|
|
17561
17665
|
}
|
|
17562
17666
|
function createStyles7() {
|
|
17563
17667
|
return StyleSheet12.create({
|
|
@@ -17590,7 +17694,7 @@ import React13, { useState as useState10, useEffect as useEffect8, useMemo as us
|
|
|
17590
17694
|
import { View as View13, Text as Text11, TouchableOpacity as TouchableOpacity10, TextInput as TextInput5, StyleSheet as StyleSheet13, Image as Image2 } from "react-native";
|
|
17591
17695
|
function ThreadDetailScreen({ thread, nav }) {
|
|
17592
17696
|
const { getThreadMessages, sendMessage, markAsRead, uploadImage, widgetColorScheme } = useBugBear();
|
|
17593
|
-
const
|
|
17697
|
+
const styles7 = useMemo8(() => createStyles8(), [widgetColorScheme]);
|
|
17594
17698
|
const [messages, setMessages] = useState10([]);
|
|
17595
17699
|
const [loading, setLoading] = useState10(true);
|
|
17596
17700
|
const [replyText, setReplyText] = useState10("");
|
|
@@ -17642,20 +17746,20 @@ function ThreadDetailScreen({ thread, nav }) {
|
|
|
17642
17746
|
}
|
|
17643
17747
|
setSending(false);
|
|
17644
17748
|
};
|
|
17645
|
-
return /* @__PURE__ */ React13.createElement(View13, { style:
|
|
17749
|
+
return /* @__PURE__ */ React13.createElement(View13, { style: styles7.container }, /* @__PURE__ */ React13.createElement(View13, { style: styles7.header }, /* @__PURE__ */ React13.createElement(Text11, { style: styles7.headerIcon }, getThreadTypeIcon(thread.threadType)), /* @__PURE__ */ React13.createElement(Text11, { style: styles7.headerSubject, numberOfLines: 2 }, thread.subject || "No subject")), loading ? /* @__PURE__ */ React13.createElement(View13, { style: styles7.loadingContainer }, /* @__PURE__ */ React13.createElement(Text11, { style: styles7.loadingText }, "Loading messages...")) : /* @__PURE__ */ React13.createElement(View13, { style: styles7.messagesContainer }, messages.map((msg) => /* @__PURE__ */ React13.createElement(
|
|
17646
17750
|
View13,
|
|
17647
17751
|
{
|
|
17648
17752
|
key: msg.id,
|
|
17649
|
-
style: [
|
|
17753
|
+
style: [styles7.bubble, msg.senderType === "tester" ? styles7.bubbleTester : styles7.bubbleAdmin]
|
|
17650
17754
|
},
|
|
17651
|
-
/* @__PURE__ */ React13.createElement(Text11, { style: [
|
|
17652
|
-
/* @__PURE__ */ React13.createElement(Text11, { style: [
|
|
17653
|
-
msg.attachments && msg.attachments.length > 0 && /* @__PURE__ */ React13.createElement(View13, { style:
|
|
17654
|
-
/* @__PURE__ */ React13.createElement(Text11, { style: [
|
|
17655
|
-
))), sendError && /* @__PURE__ */ React13.createElement(View13, { style:
|
|
17755
|
+
/* @__PURE__ */ React13.createElement(Text11, { style: [styles7.sender, msg.senderType === "tester" && styles7.senderTester] }, msg.senderType === "tester" ? "You" : msg.senderName),
|
|
17756
|
+
/* @__PURE__ */ React13.createElement(Text11, { style: [styles7.content, msg.senderType === "tester" && styles7.contentTester] }, msg.content),
|
|
17757
|
+
msg.attachments && msg.attachments.length > 0 && /* @__PURE__ */ React13.createElement(View13, { style: styles7.attachments }, msg.attachments.filter((a) => a.type === "image").map((att, idx) => /* @__PURE__ */ React13.createElement(Image2, { key: idx, source: { uri: att.url }, style: styles7.attachmentImage, resizeMode: "cover" }))),
|
|
17758
|
+
/* @__PURE__ */ React13.createElement(Text11, { style: [styles7.time, msg.senderType === "tester" && styles7.timeTester] }, formatMessageTime(msg.createdAt))
|
|
17759
|
+
))), sendError && /* @__PURE__ */ React13.createElement(View13, { style: styles7.errorBar }, /* @__PURE__ */ React13.createElement(Text11, { style: styles7.errorText }, "Failed to send. Tap Send to retry.")), replyImages.images.length > 0 && /* @__PURE__ */ React13.createElement(View13, { style: styles7.replyPreview }, /* @__PURE__ */ React13.createElement(ImagePreviewStrip, { images: replyImages.images, onRemove: replyImages.removeImage })), /* @__PURE__ */ React13.createElement(View13, { style: styles7.composer }, IMAGE_PICKER_AVAILABLE && /* @__PURE__ */ React13.createElement(TouchableOpacity10, { style: styles7.attachBtn, onPress: replyImages.pickFromGallery, disabled: replyImages.images.length >= 3 }, /* @__PURE__ */ React13.createElement(Text11, { style: styles7.attachBtnText }, "\u{1F4CE}")), /* @__PURE__ */ React13.createElement(
|
|
17656
17760
|
TextInput5,
|
|
17657
17761
|
{
|
|
17658
|
-
style:
|
|
17762
|
+
style: styles7.replyInput,
|
|
17659
17763
|
value: replyText,
|
|
17660
17764
|
onChangeText: setReplyText,
|
|
17661
17765
|
placeholder: "Type a reply...",
|
|
@@ -17666,11 +17770,11 @@ function ThreadDetailScreen({ thread, nav }) {
|
|
|
17666
17770
|
), /* @__PURE__ */ React13.createElement(
|
|
17667
17771
|
TouchableOpacity10,
|
|
17668
17772
|
{
|
|
17669
|
-
style: [
|
|
17773
|
+
style: [styles7.sendBtn, (!replyText.trim() && replyImages.images.length === 0 || sending || replyImages.isUploading) && styles7.sendBtnDisabled],
|
|
17670
17774
|
onPress: handleSend,
|
|
17671
17775
|
disabled: !replyText.trim() && replyImages.images.length === 0 || sending || replyImages.isUploading
|
|
17672
17776
|
},
|
|
17673
|
-
/* @__PURE__ */ React13.createElement(Text11, { style:
|
|
17777
|
+
/* @__PURE__ */ React13.createElement(Text11, { style: styles7.sendBtnText }, sending ? "..." : "Send")
|
|
17674
17778
|
)));
|
|
17675
17779
|
}
|
|
17676
17780
|
function createStyles8() {
|
|
@@ -17711,7 +17815,7 @@ import React14, { useState as useState11, useMemo as useMemo9 } from "react";
|
|
|
17711
17815
|
import { View as View14, Text as Text12, TextInput as TextInput6, TouchableOpacity as TouchableOpacity11, StyleSheet as StyleSheet14 } from "react-native";
|
|
17712
17816
|
function ComposeMessageScreen({ nav }) {
|
|
17713
17817
|
const { createThread, uploadImage, widgetColorScheme } = useBugBear();
|
|
17714
|
-
const
|
|
17818
|
+
const styles7 = useMemo9(() => createStyles9(), [widgetColorScheme]);
|
|
17715
17819
|
const [subject, setSubject] = useState11("");
|
|
17716
17820
|
const [message, setMessage] = useState11("");
|
|
17717
17821
|
const [sending, setSending] = useState11(false);
|
|
@@ -17730,10 +17834,10 @@ function ComposeMessageScreen({ nav }) {
|
|
|
17730
17834
|
nav.pop();
|
|
17731
17835
|
}
|
|
17732
17836
|
};
|
|
17733
|
-
return /* @__PURE__ */ React14.createElement(View14, null, /* @__PURE__ */ React14.createElement(View14, { style:
|
|
17837
|
+
return /* @__PURE__ */ React14.createElement(View14, null, /* @__PURE__ */ React14.createElement(View14, { style: styles7.header }, /* @__PURE__ */ React14.createElement(Text12, { style: styles7.title }, "New Message"), /* @__PURE__ */ React14.createElement(Text12, { style: styles7.subtitle }, "Send a message to the QA team")), /* @__PURE__ */ React14.createElement(View14, { style: styles7.form }, /* @__PURE__ */ React14.createElement(Text12, { style: shared.label }, "Subject"), /* @__PURE__ */ React14.createElement(
|
|
17734
17838
|
TextInput6,
|
|
17735
17839
|
{
|
|
17736
|
-
style:
|
|
17840
|
+
style: styles7.subjectInput,
|
|
17737
17841
|
value: subject,
|
|
17738
17842
|
onChangeText: setSubject,
|
|
17739
17843
|
placeholder: "What's this about?",
|
|
@@ -17743,7 +17847,7 @@ function ComposeMessageScreen({ nav }) {
|
|
|
17743
17847
|
), /* @__PURE__ */ React14.createElement(Text12, { style: [shared.label, { marginTop: 16 }] }, "Message"), /* @__PURE__ */ React14.createElement(
|
|
17744
17848
|
TextInput6,
|
|
17745
17849
|
{
|
|
17746
|
-
style:
|
|
17850
|
+
style: styles7.messageInput,
|
|
17747
17851
|
value: message,
|
|
17748
17852
|
onChangeText: setMessage,
|
|
17749
17853
|
placeholder: "Write your message...",
|
|
@@ -17788,7 +17892,7 @@ import React15, { useState as useState12, useEffect as useEffect9, useMemo as us
|
|
|
17788
17892
|
import { View as View15, Text as Text13, TouchableOpacity as TouchableOpacity12, TextInput as TextInput7, StyleSheet as StyleSheet15 } from "react-native";
|
|
17789
17893
|
function ProfileScreen({ nav }) {
|
|
17790
17894
|
const { testerInfo, assignments, updateTesterProfile, refreshTesterInfo, widgetColorScheme } = useBugBear();
|
|
17791
|
-
const
|
|
17895
|
+
const styles7 = useMemo10(() => createStyles10(), [widgetColorScheme]);
|
|
17792
17896
|
const [editing, setEditing] = useState12(false);
|
|
17793
17897
|
const [name, setName] = useState12(testerInfo?.name || "");
|
|
17794
17898
|
const [additionalEmails, setAdditionalEmails] = useState12(testerInfo?.additionalEmails || []);
|
|
@@ -17839,13 +17943,13 @@ function ProfileScreen({ nav }) {
|
|
|
17839
17943
|
return /* @__PURE__ */ React15.createElement(View15, { style: shared.emptyState }, /* @__PURE__ */ React15.createElement(Text13, { style: shared.emptyEmoji }, "\u{1F464}"), /* @__PURE__ */ React15.createElement(Text13, { style: shared.emptyTitle }, "No profile found"));
|
|
17840
17944
|
}
|
|
17841
17945
|
if (editing) {
|
|
17842
|
-
return /* @__PURE__ */ React15.createElement(View15, null, /* @__PURE__ */ React15.createElement(View15, { style:
|
|
17946
|
+
return /* @__PURE__ */ React15.createElement(View15, null, /* @__PURE__ */ React15.createElement(View15, { style: styles7.editHeader }, /* @__PURE__ */ React15.createElement(Text13, { style: styles7.editTitle }, "Edit Profile"), /* @__PURE__ */ React15.createElement(TouchableOpacity12, { onPress: () => {
|
|
17843
17947
|
setEditing(false);
|
|
17844
17948
|
setNewEmailInput("");
|
|
17845
|
-
} }, /* @__PURE__ */ React15.createElement(Text13, { style:
|
|
17949
|
+
} }, /* @__PURE__ */ React15.createElement(Text13, { style: styles7.cancelText }, "Cancel"))), /* @__PURE__ */ React15.createElement(View15, { style: styles7.field }, /* @__PURE__ */ React15.createElement(Text13, { style: shared.label }, "Name"), /* @__PURE__ */ React15.createElement(TextInput7, { style: styles7.input, value: name, onChangeText: setName, placeholder: "Your name", placeholderTextColor: colors.textMuted })), /* @__PURE__ */ React15.createElement(View15, { style: styles7.field }, /* @__PURE__ */ React15.createElement(Text13, { style: shared.label }, "Primary Email"), /* @__PURE__ */ React15.createElement(Text13, { style: styles7.emailFixed }, testerInfo.email)), /* @__PURE__ */ React15.createElement(View15, { style: styles7.field }, /* @__PURE__ */ React15.createElement(Text13, { style: shared.label }, "Additional Emails"), additionalEmails.map((email) => /* @__PURE__ */ React15.createElement(View15, { key: email, style: styles7.emailRow }, /* @__PURE__ */ React15.createElement(Text13, { style: styles7.emailText }, email), /* @__PURE__ */ React15.createElement(TouchableOpacity12, { onPress: () => setAdditionalEmails(additionalEmails.filter((e) => e !== email)) }, /* @__PURE__ */ React15.createElement(Text13, { style: styles7.removeEmail }, "\u2715")))), /* @__PURE__ */ React15.createElement(View15, { style: styles7.addEmailRow }, /* @__PURE__ */ React15.createElement(
|
|
17846
17950
|
TextInput7,
|
|
17847
17951
|
{
|
|
17848
|
-
style: [
|
|
17952
|
+
style: [styles7.input, { flex: 1, marginRight: 8 }],
|
|
17849
17953
|
value: newEmailInput,
|
|
17850
17954
|
onChangeText: setNewEmailInput,
|
|
17851
17955
|
placeholder: "Add email",
|
|
@@ -17853,17 +17957,17 @@ function ProfileScreen({ nav }) {
|
|
|
17853
17957
|
keyboardType: "email-address",
|
|
17854
17958
|
autoCapitalize: "none"
|
|
17855
17959
|
}
|
|
17856
|
-
), /* @__PURE__ */ React15.createElement(TouchableOpacity12, { style:
|
|
17960
|
+
), /* @__PURE__ */ React15.createElement(TouchableOpacity12, { style: styles7.addButton, onPress: handleAddEmail }, /* @__PURE__ */ React15.createElement(Text13, { style: styles7.addButtonText }, "Add")))), /* @__PURE__ */ React15.createElement(View15, { style: styles7.field }, /* @__PURE__ */ React15.createElement(Text13, { style: shared.label }, "Testing Platforms"), /* @__PURE__ */ React15.createElement(View15, { style: styles7.platformRow }, [{ key: "ios", label: "\u{1F4F1} iOS" }, { key: "android", label: "\u{1F916} Android" }, { key: "web", label: "\u{1F310} Web" }].map(({ key, label }) => /* @__PURE__ */ React15.createElement(
|
|
17857
17961
|
TouchableOpacity12,
|
|
17858
17962
|
{
|
|
17859
17963
|
key,
|
|
17860
|
-
style: [
|
|
17964
|
+
style: [styles7.platformBtn, platforms.includes(key) && styles7.platformBtnActive],
|
|
17861
17965
|
onPress: () => setPlatforms((prev) => prev.includes(key) ? prev.filter((p) => p !== key) : [...prev, key])
|
|
17862
17966
|
},
|
|
17863
|
-
/* @__PURE__ */ React15.createElement(Text13, { style: [
|
|
17967
|
+
/* @__PURE__ */ React15.createElement(Text13, { style: [styles7.platformText, platforms.includes(key) && styles7.platformTextActive] }, label)
|
|
17864
17968
|
)))), /* @__PURE__ */ React15.createElement(TouchableOpacity12, { style: [shared.primaryButton, { marginTop: 20 }], onPress: handleSave, disabled: saving }, /* @__PURE__ */ React15.createElement(Text13, { style: shared.primaryButtonText }, saving ? "Saving..." : "Save Profile")));
|
|
17865
17969
|
}
|
|
17866
|
-
return /* @__PURE__ */ React15.createElement(View15, null, /* @__PURE__ */ React15.createElement(View15, { style:
|
|
17970
|
+
return /* @__PURE__ */ React15.createElement(View15, null, /* @__PURE__ */ React15.createElement(View15, { style: styles7.profileCard }, /* @__PURE__ */ React15.createElement(View15, { style: styles7.avatar }, /* @__PURE__ */ React15.createElement(Text13, { style: styles7.avatarText }, testerInfo.name.charAt(0).toUpperCase())), /* @__PURE__ */ React15.createElement(Text13, { style: styles7.profileName }, testerInfo.name), /* @__PURE__ */ React15.createElement(Text13, { style: styles7.profileEmail }, testerInfo.email)), /* @__PURE__ */ React15.createElement(View15, { style: styles7.statsRow }, /* @__PURE__ */ React15.createElement(View15, { style: styles7.statItem }, /* @__PURE__ */ React15.createElement(Text13, { style: styles7.statNumber }, completedCount), /* @__PURE__ */ React15.createElement(Text13, { style: styles7.statLabel }, "Completed")), /* @__PURE__ */ React15.createElement(View15, { style: styles7.statDivider }), /* @__PURE__ */ React15.createElement(View15, { style: styles7.statItem }, /* @__PURE__ */ React15.createElement(Text13, { style: styles7.statNumber }, assignments.length), /* @__PURE__ */ React15.createElement(Text13, { style: styles7.statLabel }, "Total Assigned"))), /* @__PURE__ */ React15.createElement(TouchableOpacity12, { onPress: () => setShowDetails(!showDetails), style: styles7.detailsToggle }, /* @__PURE__ */ React15.createElement(Text13, { style: styles7.detailsToggleText }, showDetails ? "\u25BC" : "\u25B6", " Details")), showDetails && /* @__PURE__ */ React15.createElement(View15, { style: styles7.detailsSection }, additionalEmails.length > 0 && /* @__PURE__ */ React15.createElement(View15, { style: styles7.detailBlock }, /* @__PURE__ */ React15.createElement(Text13, { style: styles7.detailLabel }, "Additional Emails"), additionalEmails.map((e) => /* @__PURE__ */ React15.createElement(Text13, { key: e, style: styles7.detailValue }, e))), platforms.length > 0 && /* @__PURE__ */ React15.createElement(View15, { style: styles7.detailBlock }, /* @__PURE__ */ React15.createElement(Text13, { style: styles7.detailLabel }, "Platforms"), /* @__PURE__ */ React15.createElement(View15, { style: styles7.platformTags }, platforms.map((p) => /* @__PURE__ */ React15.createElement(View15, { key: p, style: styles7.platformTag }, /* @__PURE__ */ React15.createElement(Text13, { style: styles7.platformTagText }, p === "ios" ? "\u{1F4F1} iOS" : p === "android" ? "\u{1F916} Android" : "\u{1F310} Web")))))), /* @__PURE__ */ React15.createElement(
|
|
17867
17971
|
TouchableOpacity12,
|
|
17868
17972
|
{
|
|
17869
17973
|
style: [shared.primaryButton, { marginTop: 20 }],
|
|
@@ -17921,7 +18025,7 @@ var CATEGORIES = ["open", "done", "reopened"];
|
|
|
17921
18025
|
var SEVERITY_ORDER2 = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
17922
18026
|
function IssueListScreen({ nav, category }) {
|
|
17923
18027
|
const { client, widgetColorScheme } = useBugBear();
|
|
17924
|
-
const
|
|
18028
|
+
const styles7 = useMemo11(() => createStyles11(), [widgetColorScheme]);
|
|
17925
18029
|
const CATEGORY_CONFIG = useMemo11(() => ({
|
|
17926
18030
|
open: { label: "Open", accent: colors.orange, emptyIcon: "\u2705", emptyText: "No open issues" },
|
|
17927
18031
|
done: { label: "Done", accent: colors.green, emptyIcon: "\u{1F389}", emptyText: "No completed issues yet" },
|
|
@@ -17991,7 +18095,7 @@ function IssueListScreen({ nav, category }) {
|
|
|
17991
18095
|
const searchFilteredIssues = debouncedQuery ? sortedIssues.filter(
|
|
17992
18096
|
(issue) => (issue.title || "").toLowerCase().includes(debouncedQuery.toLowerCase()) || (issue.description || "").toLowerCase().includes(debouncedQuery.toLowerCase())
|
|
17993
18097
|
) : sortedIssues;
|
|
17994
|
-
return /* @__PURE__ */ React16.createElement(View16, null, /* @__PURE__ */ React16.createElement(View16, { style:
|
|
18098
|
+
return /* @__PURE__ */ React16.createElement(View16, null, /* @__PURE__ */ React16.createElement(View16, { style: styles7.tabBar }, CATEGORIES.map((cat) => {
|
|
17995
18099
|
const catConfig = CATEGORY_CONFIG[cat];
|
|
17996
18100
|
const isActive = activeCategory === cat;
|
|
17997
18101
|
const count = counts?.[cat];
|
|
@@ -18000,7 +18104,7 @@ function IssueListScreen({ nav, category }) {
|
|
|
18000
18104
|
{
|
|
18001
18105
|
key: cat,
|
|
18002
18106
|
style: [
|
|
18003
|
-
|
|
18107
|
+
styles7.tab,
|
|
18004
18108
|
{ borderBottomColor: isActive ? catConfig.accent : "transparent" }
|
|
18005
18109
|
],
|
|
18006
18110
|
onPress: () => {
|
|
@@ -18010,20 +18114,20 @@ function IssueListScreen({ nav, category }) {
|
|
|
18010
18114
|
activeOpacity: 0.7
|
|
18011
18115
|
},
|
|
18012
18116
|
/* @__PURE__ */ React16.createElement(Text14, { style: [
|
|
18013
|
-
|
|
18117
|
+
styles7.tabLabel,
|
|
18014
18118
|
isActive && { fontWeight: "600", color: colors.textPrimary }
|
|
18015
18119
|
] }, catConfig.label),
|
|
18016
18120
|
count !== void 0 && /* @__PURE__ */ React16.createElement(View16, { style: [
|
|
18017
|
-
|
|
18121
|
+
styles7.countBadge,
|
|
18018
18122
|
{
|
|
18019
18123
|
backgroundColor: isActive ? catConfig.accent + "18" : colors.card
|
|
18020
18124
|
}
|
|
18021
18125
|
] }, /* @__PURE__ */ React16.createElement(Text14, { style: [
|
|
18022
|
-
|
|
18126
|
+
styles7.countText,
|
|
18023
18127
|
{ color: isActive ? catConfig.accent : colors.textDim }
|
|
18024
18128
|
] }, count))
|
|
18025
18129
|
);
|
|
18026
|
-
})), /* @__PURE__ */ React16.createElement(View16, { style:
|
|
18130
|
+
})), /* @__PURE__ */ React16.createElement(View16, { style: styles7.sortRow }, [
|
|
18027
18131
|
{ key: "severity", label: "Severity" },
|
|
18028
18132
|
{ key: "recent", label: "Recent" }
|
|
18029
18133
|
].map((s2) => /* @__PURE__ */ React16.createElement(
|
|
@@ -18031,14 +18135,14 @@ function IssueListScreen({ nav, category }) {
|
|
|
18031
18135
|
{
|
|
18032
18136
|
key: s2.key,
|
|
18033
18137
|
style: [
|
|
18034
|
-
|
|
18035
|
-
sortMode === s2.key &&
|
|
18138
|
+
styles7.sortBtn,
|
|
18139
|
+
sortMode === s2.key && styles7.sortBtnActive
|
|
18036
18140
|
],
|
|
18037
18141
|
onPress: () => setSortMode(s2.key)
|
|
18038
18142
|
},
|
|
18039
18143
|
/* @__PURE__ */ React16.createElement(Text14, { style: [
|
|
18040
|
-
|
|
18041
|
-
sortMode === s2.key &&
|
|
18144
|
+
styles7.sortBtnText,
|
|
18145
|
+
sortMode === s2.key && styles7.sortBtnTextActive
|
|
18042
18146
|
] }, s2.label)
|
|
18043
18147
|
))), /* @__PURE__ */ React16.createElement(View16, { style: { paddingHorizontal: 16, paddingBottom: 12 } }, /* @__PURE__ */ React16.createElement(
|
|
18044
18148
|
TextInput8,
|
|
@@ -18058,18 +18162,18 @@ function IssueListScreen({ nav, category }) {
|
|
|
18058
18162
|
fontSize: 13
|
|
18059
18163
|
}
|
|
18060
18164
|
}
|
|
18061
|
-
)), loading ? /* @__PURE__ */ React16.createElement(IssueListScreenSkeleton, null) : searchFilteredIssues.length === 0 ? /* @__PURE__ */ React16.createElement(View16, { style:
|
|
18165
|
+
)), loading ? /* @__PURE__ */ React16.createElement(IssueListScreenSkeleton, null) : searchFilteredIssues.length === 0 ? /* @__PURE__ */ React16.createElement(View16, { style: styles7.emptyContainer }, /* @__PURE__ */ React16.createElement(Text14, { style: styles7.emptyIcon }, debouncedQuery ? "\u{1F50D}" : config.emptyIcon), /* @__PURE__ */ React16.createElement(Text14, { style: styles7.emptyText }, debouncedQuery ? "No matching issues" : config.emptyText)) : searchFilteredIssues.map((issue) => /* @__PURE__ */ React16.createElement(
|
|
18062
18166
|
TouchableOpacity13,
|
|
18063
18167
|
{
|
|
18064
18168
|
key: issue.id,
|
|
18065
|
-
style:
|
|
18169
|
+
style: styles7.issueCard,
|
|
18066
18170
|
onPress: () => nav.push({ name: "ISSUE_DETAIL", issue }),
|
|
18067
18171
|
activeOpacity: 0.7
|
|
18068
18172
|
},
|
|
18069
|
-
/* @__PURE__ */ React16.createElement(View16, { style:
|
|
18070
|
-
/* @__PURE__ */ React16.createElement(View16, { style:
|
|
18071
|
-
activeCategory === "done" && issue.verifiedByName && /* @__PURE__ */ React16.createElement(View16, { style:
|
|
18072
|
-
activeCategory === "reopened" && issue.originalBugTitle && /* @__PURE__ */ React16.createElement(View16, { style:
|
|
18173
|
+
/* @__PURE__ */ React16.createElement(View16, { style: styles7.topRow }, issue.severity && /* @__PURE__ */ React16.createElement(View16, { style: [styles7.severityDot, { backgroundColor: SEVERITY_COLORS[issue.severity] || colors.textDim }] }), /* @__PURE__ */ React16.createElement(Text14, { style: styles7.issueTitle, numberOfLines: 1 }, issue.title)),
|
|
18174
|
+
/* @__PURE__ */ React16.createElement(View16, { style: styles7.bottomRow }, issue.route && /* @__PURE__ */ React16.createElement(Text14, { style: styles7.routeText, numberOfLines: 1 }, issue.route), /* @__PURE__ */ React16.createElement(Text14, { style: styles7.timeText }, formatRelativeTime(issue.updatedAt))),
|
|
18175
|
+
activeCategory === "done" && issue.verifiedByName && /* @__PURE__ */ React16.createElement(View16, { style: styles7.verifiedBadge }, /* @__PURE__ */ React16.createElement(Text14, { style: styles7.verifiedBadgeText }, "\u2714", " Verified by ", issue.verifiedByName)),
|
|
18176
|
+
activeCategory === "reopened" && issue.originalBugTitle && /* @__PURE__ */ React16.createElement(View16, { style: styles7.reopenedBadge }, /* @__PURE__ */ React16.createElement(Text14, { style: styles7.reopenedBadgeText, numberOfLines: 1 }, "\u{1F504}", " Retest of: ", issue.originalBugTitle))
|
|
18073
18177
|
)));
|
|
18074
18178
|
}
|
|
18075
18179
|
function createStyles11() {
|
|
@@ -18228,7 +18332,7 @@ import { View as View17, Text as Text15, Image as Image3, StyleSheet as StyleShe
|
|
|
18228
18332
|
var DONE_STATUSES = ["verified", "resolved", "closed", "reviewed"];
|
|
18229
18333
|
function IssueDetailScreen({ nav, issue }) {
|
|
18230
18334
|
const { dashboardUrl, widgetColorScheme, reopenReport } = useBugBear();
|
|
18231
|
-
const
|
|
18335
|
+
const styles7 = useMemo12(() => createStyles12(), [widgetColorScheme]);
|
|
18232
18336
|
const [showReopenForm, setShowReopenForm] = useState14(false);
|
|
18233
18337
|
const [reopenReason, setReopenReason] = useState14("");
|
|
18234
18338
|
const [isSubmitting, setIsSubmitting] = useState14(false);
|
|
@@ -18270,44 +18374,44 @@ function IssueDetailScreen({ nav, issue }) {
|
|
|
18270
18374
|
setReopenError(result.error || "Failed to reopen");
|
|
18271
18375
|
}
|
|
18272
18376
|
}, [reopenReason, reopenReport, issue.id]);
|
|
18273
|
-
return /* @__PURE__ */ React17.createElement(View17, null, /* @__PURE__ */ React17.createElement(View17, { style:
|
|
18377
|
+
return /* @__PURE__ */ React17.createElement(View17, null, /* @__PURE__ */ React17.createElement(View17, { style: styles7.badgeRow }, /* @__PURE__ */ React17.createElement(View17, { style: [styles7.badge, { backgroundColor: wasReopened ? colors.yellowDark : statusConfig.bg }] }, /* @__PURE__ */ React17.createElement(Text15, { style: [styles7.badgeText, { color: wasReopened ? colors.yellowLight : statusConfig.color }] }, wasReopened ? "Reopened" : statusConfig.label)), severityConfig && /* @__PURE__ */ React17.createElement(View17, { style: [styles7.badge, { backgroundColor: severityConfig.bg }] }, /* @__PURE__ */ React17.createElement(Text15, { style: [styles7.badgeText, { color: severityConfig.color }] }, severityConfig.label))), /* @__PURE__ */ React17.createElement(Text15, { style: styles7.title }, issue.title), issue.route && /* @__PURE__ */ React17.createElement(Text15, { style: styles7.route }, issue.route), issue.description && /* @__PURE__ */ React17.createElement(View17, { style: styles7.descriptionCard }, /* @__PURE__ */ React17.createElement(Text15, { style: styles7.descriptionText }, issue.description)), wasReopened && /* @__PURE__ */ React17.createElement(View17, { style: styles7.reopenedCard }, /* @__PURE__ */ React17.createElement(View17, { style: styles7.reopenedRow }, /* @__PURE__ */ React17.createElement(Text15, { style: styles7.reopenedIcon }, "\u{1F504}"), /* @__PURE__ */ React17.createElement(Text15, { style: styles7.reopenedText }, "Issue reopened \u2014 your team has been notified"))), issue.verifiedByName && !wasReopened && /* @__PURE__ */ React17.createElement(View17, { style: styles7.verifiedCard }, /* @__PURE__ */ React17.createElement(View17, { style: styles7.verifiedHeader }, /* @__PURE__ */ React17.createElement(Text15, { style: styles7.verifiedIcon }, "\u2705"), /* @__PURE__ */ React17.createElement(Text15, { style: styles7.verifiedTitle }, "Retesting Proof")), /* @__PURE__ */ React17.createElement(Text15, { style: styles7.verifiedBody }, "Verified by ", issue.verifiedByName, issue.verifiedAt && ` on ${new Date(issue.verifiedAt).toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" })}`)), issue.originalBugTitle && /* @__PURE__ */ React17.createElement(View17, { style: styles7.originalBugCard }, /* @__PURE__ */ React17.createElement(View17, { style: styles7.originalBugHeader }, /* @__PURE__ */ React17.createElement(Text15, { style: styles7.originalBugIcon }, "\u{1F504}"), /* @__PURE__ */ React17.createElement(Text15, { style: styles7.originalBugTitleText }, "Original Bug")), /* @__PURE__ */ React17.createElement(Text15, { style: styles7.originalBugBody }, "Retest of: ", issue.originalBugTitle)), isDone && !wasReopened && !showReopenForm && /* @__PURE__ */ React17.createElement(
|
|
18274
18378
|
TouchableOpacity14,
|
|
18275
18379
|
{
|
|
18276
|
-
style:
|
|
18380
|
+
style: styles7.reopenButton,
|
|
18277
18381
|
onPress: () => setShowReopenForm(true),
|
|
18278
18382
|
activeOpacity: 0.7
|
|
18279
18383
|
},
|
|
18280
|
-
/* @__PURE__ */ React17.createElement(Text15, { style:
|
|
18281
|
-
), showReopenForm && !wasReopened && /* @__PURE__ */ React17.createElement(View17, { style:
|
|
18384
|
+
/* @__PURE__ */ React17.createElement(Text15, { style: styles7.reopenButtonText }, "\u{1F504}", " Not Fixed \u2014 Reopen Issue")
|
|
18385
|
+
), showReopenForm && !wasReopened && /* @__PURE__ */ React17.createElement(View17, { style: styles7.reopenForm }, /* @__PURE__ */ React17.createElement(Text15, { style: styles7.reopenFormTitle }, "Why isn't this fixed?"), /* @__PURE__ */ React17.createElement(
|
|
18282
18386
|
TextInput9,
|
|
18283
18387
|
{
|
|
18284
18388
|
value: reopenReason,
|
|
18285
18389
|
onChangeText: setReopenReason,
|
|
18286
18390
|
placeholder: "Describe what you're still seeing...",
|
|
18287
18391
|
placeholderTextColor: colors.textMuted,
|
|
18288
|
-
style:
|
|
18392
|
+
style: styles7.reopenInput,
|
|
18289
18393
|
multiline: true,
|
|
18290
18394
|
autoFocus: true
|
|
18291
18395
|
}
|
|
18292
|
-
), reopenError && /* @__PURE__ */ React17.createElement(Text15, { style:
|
|
18396
|
+
), reopenError && /* @__PURE__ */ React17.createElement(Text15, { style: styles7.reopenErrorText }, reopenError), /* @__PURE__ */ React17.createElement(View17, { style: styles7.reopenActions }, /* @__PURE__ */ React17.createElement(
|
|
18293
18397
|
TouchableOpacity14,
|
|
18294
18398
|
{
|
|
18295
18399
|
style: [
|
|
18296
|
-
|
|
18297
|
-
(!reopenReason.trim() || isSubmitting) &&
|
|
18400
|
+
styles7.reopenSubmitButton,
|
|
18401
|
+
(!reopenReason.trim() || isSubmitting) && styles7.reopenSubmitDisabled
|
|
18298
18402
|
],
|
|
18299
18403
|
onPress: handleReopen,
|
|
18300
18404
|
disabled: isSubmitting || !reopenReason.trim(),
|
|
18301
18405
|
activeOpacity: 0.7
|
|
18302
18406
|
},
|
|
18303
18407
|
isSubmitting ? /* @__PURE__ */ React17.createElement(ActivityIndicator2, { size: "small", color: "#fff" }) : /* @__PURE__ */ React17.createElement(Text15, { style: [
|
|
18304
|
-
|
|
18305
|
-
!reopenReason.trim() &&
|
|
18408
|
+
styles7.reopenSubmitText,
|
|
18409
|
+
!reopenReason.trim() && styles7.reopenSubmitTextDisabled
|
|
18306
18410
|
] }, "Reopen Issue")
|
|
18307
18411
|
), /* @__PURE__ */ React17.createElement(
|
|
18308
18412
|
TouchableOpacity14,
|
|
18309
18413
|
{
|
|
18310
|
-
style:
|
|
18414
|
+
style: styles7.reopenCancelButton,
|
|
18311
18415
|
onPress: () => {
|
|
18312
18416
|
setShowReopenForm(false);
|
|
18313
18417
|
setReopenReason("");
|
|
@@ -18316,7 +18420,7 @@ function IssueDetailScreen({ nav, issue }) {
|
|
|
18316
18420
|
disabled: isSubmitting,
|
|
18317
18421
|
activeOpacity: 0.7
|
|
18318
18422
|
},
|
|
18319
|
-
/* @__PURE__ */ React17.createElement(Text15, { style:
|
|
18423
|
+
/* @__PURE__ */ React17.createElement(Text15, { style: styles7.reopenCancelText }, "Cancel")
|
|
18320
18424
|
))), issue.status === "ready_to_test" && (issue.fixCommitSha || issue.resolutionNotes) && /* @__PURE__ */ React17.createElement(View17, { style: {
|
|
18321
18425
|
backgroundColor: "rgba(59, 130, 246, 0.1)",
|
|
18322
18426
|
borderWidth: 1,
|
|
@@ -18324,14 +18428,14 @@ function IssueDetailScreen({ nav, issue }) {
|
|
|
18324
18428
|
borderRadius: 8,
|
|
18325
18429
|
padding: 12,
|
|
18326
18430
|
marginBottom: 12
|
|
18327
|
-
} }, /* @__PURE__ */ React17.createElement(View17, { style: { flexDirection: "row", alignItems: "center", gap: 6, marginBottom: 8 } }, /* @__PURE__ */ React17.createElement(Text15, { style: { fontSize: 13 } }, "\u{1F527}"), /* @__PURE__ */ React17.createElement(Text15, { style: { fontSize: 12, fontWeight: "600", color: "#60a5fa" } }, "Fix Details")), issue.resolutionNotes ? /* @__PURE__ */ React17.createElement(Text15, { style: { fontSize: 12, color: colors.textSecondary, marginBottom: 6, lineHeight: 17 } }, issue.resolutionNotes) : null, issue.fixCommitSha ? /* @__PURE__ */ React17.createElement(Text15, { style: { fontSize: 11, color: colors.textDim, fontFamily: "monospace" } }, "Commit: ", issue.fixCommitSha.slice(0, 7), issue.fixCommitMessage && ` \u2014 ${issue.fixCommitMessage}`) : null, issue.fixFilesChanged && issue.fixFilesChanged.length > 0 ? /* @__PURE__ */ React17.createElement(Text15, { style: { fontSize: 11, color: colors.textDim, marginTop: 4 } }, issue.fixFilesChanged.length, " file", issue.fixFilesChanged.length > 1 ? "s" : "", " changed") : null), issue.screenshotUrls && issue.screenshotUrls.length > 0 && /* @__PURE__ */ React17.createElement(View17, { style:
|
|
18431
|
+
} }, /* @__PURE__ */ React17.createElement(View17, { style: { flexDirection: "row", alignItems: "center", gap: 6, marginBottom: 8 } }, /* @__PURE__ */ React17.createElement(Text15, { style: { fontSize: 13 } }, "\u{1F527}"), /* @__PURE__ */ React17.createElement(Text15, { style: { fontSize: 12, fontWeight: "600", color: "#60a5fa" } }, "Fix Details")), issue.resolutionNotes ? /* @__PURE__ */ React17.createElement(Text15, { style: { fontSize: 12, color: colors.textSecondary, marginBottom: 6, lineHeight: 17 } }, issue.resolutionNotes) : null, issue.fixCommitSha ? /* @__PURE__ */ React17.createElement(Text15, { style: { fontSize: 11, color: colors.textDim, fontFamily: "monospace" } }, "Commit: ", issue.fixCommitSha.slice(0, 7), issue.fixCommitMessage && ` \u2014 ${issue.fixCommitMessage}`) : null, issue.fixFilesChanged && issue.fixFilesChanged.length > 0 ? /* @__PURE__ */ React17.createElement(Text15, { style: { fontSize: 11, color: colors.textDim, marginTop: 4 } }, issue.fixFilesChanged.length, " file", issue.fixFilesChanged.length > 1 ? "s" : "", " changed") : null), issue.screenshotUrls && issue.screenshotUrls.length > 0 && /* @__PURE__ */ React17.createElement(View17, { style: styles7.screenshotSection }, /* @__PURE__ */ React17.createElement(Text15, { style: styles7.screenshotLabel }, "Screenshots (", issue.screenshotUrls.length, ")"), /* @__PURE__ */ React17.createElement(View17, { style: styles7.screenshotRow }, issue.screenshotUrls.map((url, i) => /* @__PURE__ */ React17.createElement(TouchableOpacity14, { key: i, onPress: () => Linking4.openURL(url), activeOpacity: 0.7 }, /* @__PURE__ */ React17.createElement(Image3, { source: { uri: url }, style: styles7.screenshotThumb }))))), /* @__PURE__ */ React17.createElement(View17, { style: styles7.metaSection }, issue.reporterName && /* @__PURE__ */ React17.createElement(Text15, { style: styles7.metaText }, "Reported by ", issue.reporterName), /* @__PURE__ */ React17.createElement(Text15, { style: styles7.metaTextSmall }, "Created ", formatRelativeTime(issue.createdAt), " ", "\xB7", " Updated ", formatRelativeTime(issue.updatedAt))), dashboardUrl && /* @__PURE__ */ React17.createElement(
|
|
18328
18432
|
TouchableOpacity14,
|
|
18329
18433
|
{
|
|
18330
|
-
style:
|
|
18434
|
+
style: styles7.dashboardLink,
|
|
18331
18435
|
onPress: () => Linking4.openURL(`${dashboardUrl}/reports`),
|
|
18332
18436
|
activeOpacity: 0.7
|
|
18333
18437
|
},
|
|
18334
|
-
/* @__PURE__ */ React17.createElement(Text15, { style:
|
|
18438
|
+
/* @__PURE__ */ React17.createElement(Text15, { style: styles7.dashboardLinkText }, "\u{1F310}", " View on Dashboard ", "\u2192")
|
|
18335
18439
|
));
|
|
18336
18440
|
}
|
|
18337
18441
|
function createStyles12() {
|
|
@@ -18588,7 +18692,7 @@ import React18, { useState as useState15, useMemo as useMemo13 } from "react";
|
|
|
18588
18692
|
import { View as View18, Text as Text16, TextInput as TextInput10, TouchableOpacity as TouchableOpacity15, StyleSheet as StyleSheet18, Keyboard as Keyboard2 } from "react-native";
|
|
18589
18693
|
function SessionStartScreen({ nav }) {
|
|
18590
18694
|
const { startSession, assignments, widgetColorScheme } = useBugBear();
|
|
18591
|
-
const
|
|
18695
|
+
const styles7 = useMemo13(() => createStyles13(), [widgetColorScheme]);
|
|
18592
18696
|
const [focusArea, setFocusArea] = useState15("");
|
|
18593
18697
|
const [isStarting, setIsStarting] = useState15(false);
|
|
18594
18698
|
const [error, setError] = useState15(null);
|
|
@@ -18615,35 +18719,35 @@ function SessionStartScreen({ nav }) {
|
|
|
18615
18719
|
setIsStarting(false);
|
|
18616
18720
|
}
|
|
18617
18721
|
};
|
|
18618
|
-
return /* @__PURE__ */ React18.createElement(View18, null, /* @__PURE__ */ React18.createElement(View18, { style:
|
|
18722
|
+
return /* @__PURE__ */ React18.createElement(View18, null, /* @__PURE__ */ React18.createElement(View18, { style: styles7.header }, /* @__PURE__ */ React18.createElement(Text16, { style: styles7.headerIcon }, "\u{1F50D}"), /* @__PURE__ */ React18.createElement(Text16, { style: styles7.headerDesc }, "Start an exploratory QA session. Log findings as you go \u2014 bugs, concerns, suggestions, or questions.")), /* @__PURE__ */ React18.createElement(View18, { style: styles7.inputSection }, /* @__PURE__ */ React18.createElement(Text16, { style: styles7.label }, "What are you testing?"), /* @__PURE__ */ React18.createElement(
|
|
18619
18723
|
TextInput10,
|
|
18620
18724
|
{
|
|
18621
18725
|
value: focusArea,
|
|
18622
18726
|
onChangeText: setFocusArea,
|
|
18623
18727
|
placeholder: "e.g. Checkout flow, Settings page...",
|
|
18624
18728
|
placeholderTextColor: colors.textMuted,
|
|
18625
|
-
style:
|
|
18729
|
+
style: styles7.input,
|
|
18626
18730
|
returnKeyType: "done",
|
|
18627
18731
|
onSubmitEditing: handleStart
|
|
18628
18732
|
}
|
|
18629
|
-
)), trackNames.length > 0 && /* @__PURE__ */ React18.createElement(View18, { style:
|
|
18733
|
+
)), trackNames.length > 0 && /* @__PURE__ */ React18.createElement(View18, { style: styles7.chipsSection }, /* @__PURE__ */ React18.createElement(Text16, { style: styles7.chipsLabel }, "Quick pick:"), /* @__PURE__ */ React18.createElement(View18, { style: styles7.chipsRow }, trackNames.map((name) => /* @__PURE__ */ React18.createElement(
|
|
18630
18734
|
TouchableOpacity15,
|
|
18631
18735
|
{
|
|
18632
18736
|
key: name,
|
|
18633
|
-
style: [
|
|
18737
|
+
style: [styles7.chip, focusArea === name && styles7.chipActive],
|
|
18634
18738
|
onPress: () => setFocusArea(name),
|
|
18635
18739
|
activeOpacity: 0.7
|
|
18636
18740
|
},
|
|
18637
|
-
/* @__PURE__ */ React18.createElement(Text16, { style: [
|
|
18638
|
-
)))), error && /* @__PURE__ */ React18.createElement(View18, { style:
|
|
18741
|
+
/* @__PURE__ */ React18.createElement(Text16, { style: [styles7.chipText, focusArea === name && styles7.chipTextActive] }, name)
|
|
18742
|
+
)))), error && /* @__PURE__ */ React18.createElement(View18, { style: styles7.errorBox }, /* @__PURE__ */ React18.createElement(Text16, { style: styles7.errorText }, error)), /* @__PURE__ */ React18.createElement(
|
|
18639
18743
|
TouchableOpacity15,
|
|
18640
18744
|
{
|
|
18641
|
-
style: [
|
|
18745
|
+
style: [styles7.startBtn, isStarting && styles7.startBtnDisabled],
|
|
18642
18746
|
onPress: handleStart,
|
|
18643
18747
|
disabled: isStarting,
|
|
18644
18748
|
activeOpacity: 0.8
|
|
18645
18749
|
},
|
|
18646
|
-
/* @__PURE__ */ React18.createElement(Text16, { style:
|
|
18750
|
+
/* @__PURE__ */ React18.createElement(Text16, { style: styles7.startBtnText }, isStarting ? "Starting..." : "\u25B6 Start Session")
|
|
18647
18751
|
));
|
|
18648
18752
|
}
|
|
18649
18753
|
function createStyles13() {
|
|
@@ -18752,7 +18856,7 @@ import React19, { useState as useState16, useEffect as useEffect11, useRef as us
|
|
|
18752
18856
|
import { View as View19, Text as Text17, TouchableOpacity as TouchableOpacity16, StyleSheet as StyleSheet19 } from "react-native";
|
|
18753
18857
|
function SessionActiveScreen({ nav }) {
|
|
18754
18858
|
const { activeSession, sessionFindings, endSession, refreshSession, widgetColorScheme } = useBugBear();
|
|
18755
|
-
const
|
|
18859
|
+
const styles7 = useMemo14(() => createStyles14(), [widgetColorScheme]);
|
|
18756
18860
|
const FINDING_TYPE_CONFIG = useMemo14(() => ({
|
|
18757
18861
|
bug: { icon: "\u{1F41B}", label: "Bug", color: colors.red },
|
|
18758
18862
|
concern: { icon: "\u26A0\uFE0F", label: "Concern", color: colors.amber },
|
|
@@ -18794,30 +18898,38 @@ function SessionActiveScreen({ nav }) {
|
|
|
18794
18898
|
}
|
|
18795
18899
|
};
|
|
18796
18900
|
if (!activeSession) {
|
|
18797
|
-
return /* @__PURE__ */ React19.createElement(View19, { style:
|
|
18901
|
+
return /* @__PURE__ */ React19.createElement(View19, { style: styles7.emptyContainer }, /* @__PURE__ */ React19.createElement(Text17, { style: styles7.emptyText }, "No active session"), /* @__PURE__ */ React19.createElement(TouchableOpacity16, { onPress: () => nav.replace({ name: "SESSION_START" }) }, /* @__PURE__ */ React19.createElement(Text17, { style: styles7.emptyLink }, "Start a new session")));
|
|
18798
18902
|
}
|
|
18799
18903
|
const renderFinding = (finding) => {
|
|
18800
18904
|
const config = FINDING_TYPE_CONFIG[finding.type] || FINDING_TYPE_CONFIG.bug;
|
|
18801
|
-
return /* @__PURE__ */ React19.createElement(View19, { key: finding.id, style:
|
|
18905
|
+
return /* @__PURE__ */ React19.createElement(View19, { key: finding.id, style: styles7.findingRow }, /* @__PURE__ */ React19.createElement(Text17, { style: styles7.findingIcon }, config.icon), /* @__PURE__ */ React19.createElement(View19, { style: styles7.findingContent }, /* @__PURE__ */ React19.createElement(Text17, { style: styles7.findingTitle, numberOfLines: 1 }, finding.title), /* @__PURE__ */ React19.createElement(View19, { style: styles7.findingMeta }, /* @__PURE__ */ React19.createElement(Text17, { style: [styles7.findingType, { color: config.color }] }, config.label), /* @__PURE__ */ React19.createElement(Text17, { style: styles7.findingSeverity }, finding.severity), finding.convertedToBugId && /* @__PURE__ */ React19.createElement(Text17, { style: styles7.findingConverted }, "\u2192 Bug filed"))));
|
|
18802
18906
|
};
|
|
18803
|
-
return /* @__PURE__ */ React19.createElement(View19, null, /* @__PURE__ */ React19.createElement(View19, { style:
|
|
18907
|
+
return /* @__PURE__ */ React19.createElement(View19, null, /* @__PURE__ */ React19.createElement(View19, { style: styles7.timerCard }, /* @__PURE__ */ React19.createElement(View19, { style: styles7.recordingRow }, /* @__PURE__ */ React19.createElement(View19, { style: styles7.recordingDot }), /* @__PURE__ */ React19.createElement(Text17, { style: styles7.recordingLabel }, "Recording")), /* @__PURE__ */ React19.createElement(Text17, { style: styles7.timerText }, formatTimer(elapsed)), activeSession.focusArea ? /* @__PURE__ */ React19.createElement(Text17, { style: styles7.focusArea }, activeSession.focusArea) : null), /* @__PURE__ */ React19.createElement(View19, { style: styles7.actionRow }, /* @__PURE__ */ React19.createElement(
|
|
18804
18908
|
TouchableOpacity16,
|
|
18805
18909
|
{
|
|
18806
|
-
style:
|
|
18910
|
+
style: styles7.addFindingBtn,
|
|
18807
18911
|
onPress: () => nav.push({ name: "SESSION_FINDING" }),
|
|
18808
18912
|
activeOpacity: 0.8
|
|
18809
18913
|
},
|
|
18810
|
-
/* @__PURE__ */ React19.createElement(Text17, { style:
|
|
18914
|
+
/* @__PURE__ */ React19.createElement(Text17, { style: styles7.addFindingText }, "+ Add Finding")
|
|
18915
|
+
), nav.minimizeToAdHoc && /* @__PURE__ */ React19.createElement(
|
|
18916
|
+
TouchableOpacity16,
|
|
18917
|
+
{
|
|
18918
|
+
style: styles7.minimizeBtn,
|
|
18919
|
+
onPress: nav.minimizeToAdHoc,
|
|
18920
|
+
activeOpacity: 0.8
|
|
18921
|
+
},
|
|
18922
|
+
/* @__PURE__ */ React19.createElement(Text17, { style: styles7.minimizeBtnText }, "\u2199")
|
|
18811
18923
|
), /* @__PURE__ */ React19.createElement(
|
|
18812
18924
|
TouchableOpacity16,
|
|
18813
18925
|
{
|
|
18814
|
-
style: [
|
|
18926
|
+
style: [styles7.endBtn, isEnding && styles7.endBtnDisabled],
|
|
18815
18927
|
onPress: handleEnd,
|
|
18816
18928
|
disabled: isEnding,
|
|
18817
18929
|
activeOpacity: 0.8
|
|
18818
18930
|
},
|
|
18819
|
-
/* @__PURE__ */ React19.createElement(Text17, { style:
|
|
18820
|
-
)), /* @__PURE__ */ React19.createElement(Text17, { style:
|
|
18931
|
+
/* @__PURE__ */ React19.createElement(Text17, { style: styles7.endBtnText }, isEnding ? "..." : "End")
|
|
18932
|
+
)), /* @__PURE__ */ React19.createElement(Text17, { style: styles7.sectionTitle }, "Findings (", sessionFindings.length, ")"), sessionFindings.length === 0 ? /* @__PURE__ */ React19.createElement(View19, { style: styles7.emptyFindings }, /* @__PURE__ */ React19.createElement(Text17, { style: styles7.emptyFindingsIcon }, "\u{1F4CB}"), /* @__PURE__ */ React19.createElement(Text17, { style: styles7.emptyFindingsText }, 'No findings yet. Tap "Add Finding" to log something.')) : /* @__PURE__ */ React19.createElement(View19, { style: styles7.findingsList }, sessionFindings.map(renderFinding)));
|
|
18821
18933
|
}
|
|
18822
18934
|
function createStyles14() {
|
|
18823
18935
|
return StyleSheet19.create({
|
|
@@ -18894,6 +19006,21 @@ function createStyles14() {
|
|
|
18894
19006
|
fontWeight: "600",
|
|
18895
19007
|
color: colors.blueLight
|
|
18896
19008
|
},
|
|
19009
|
+
minimizeBtn: {
|
|
19010
|
+
paddingVertical: 12,
|
|
19011
|
+
paddingHorizontal: 16,
|
|
19012
|
+
backgroundColor: colors.card,
|
|
19013
|
+
borderWidth: 1,
|
|
19014
|
+
borderColor: colors.border,
|
|
19015
|
+
borderRadius: 10,
|
|
19016
|
+
alignItems: "center",
|
|
19017
|
+
justifyContent: "center"
|
|
19018
|
+
},
|
|
19019
|
+
minimizeBtnText: {
|
|
19020
|
+
fontSize: 14,
|
|
19021
|
+
fontWeight: "600",
|
|
19022
|
+
color: colors.textSecondary
|
|
19023
|
+
},
|
|
18897
19024
|
endBtn: {
|
|
18898
19025
|
paddingVertical: 12,
|
|
18899
19026
|
paddingHorizontal: 16,
|
|
@@ -18995,7 +19122,7 @@ var FINDING_TYPES = [
|
|
|
18995
19122
|
];
|
|
18996
19123
|
function SessionFindingScreen({ nav }) {
|
|
18997
19124
|
const { addFinding, widgetColorScheme } = useBugBear();
|
|
18998
|
-
const
|
|
19125
|
+
const styles7 = useMemo15(() => createStyles15(), [widgetColorScheme]);
|
|
18999
19126
|
const SEVERITIES = useMemo15(() => [
|
|
19000
19127
|
{ value: "critical", label: "Critical", color: colors.red },
|
|
19001
19128
|
{ value: "high", label: "High", color: colors.orange },
|
|
@@ -19027,46 +19154,46 @@ function SessionFindingScreen({ nav }) {
|
|
|
19027
19154
|
}
|
|
19028
19155
|
};
|
|
19029
19156
|
const canSubmit = title.trim().length > 0 && !isSubmitting;
|
|
19030
|
-
return /* @__PURE__ */ React20.createElement(View20, null, /* @__PURE__ */ React20.createElement(View20, { style:
|
|
19157
|
+
return /* @__PURE__ */ React20.createElement(View20, null, /* @__PURE__ */ React20.createElement(View20, { style: styles7.section }, /* @__PURE__ */ React20.createElement(Text18, { style: styles7.sectionLabel }, "Type"), /* @__PURE__ */ React20.createElement(View20, { style: styles7.typeRow }, FINDING_TYPES.map((ft) => /* @__PURE__ */ React20.createElement(
|
|
19031
19158
|
TouchableOpacity17,
|
|
19032
19159
|
{
|
|
19033
19160
|
key: ft.value,
|
|
19034
|
-
style: [
|
|
19161
|
+
style: [styles7.typePill, type === ft.value && styles7.typePillActive],
|
|
19035
19162
|
onPress: () => setType(ft.value),
|
|
19036
19163
|
activeOpacity: 0.7
|
|
19037
19164
|
},
|
|
19038
|
-
/* @__PURE__ */ React20.createElement(Text18, { style:
|
|
19039
|
-
/* @__PURE__ */ React20.createElement(Text18, { style: [
|
|
19040
|
-
)))), /* @__PURE__ */ React20.createElement(View20, { style:
|
|
19165
|
+
/* @__PURE__ */ React20.createElement(Text18, { style: styles7.typePillIcon }, ft.icon),
|
|
19166
|
+
/* @__PURE__ */ React20.createElement(Text18, { style: [styles7.typePillLabel, type === ft.value && styles7.typePillLabelActive] }, ft.label)
|
|
19167
|
+
)))), /* @__PURE__ */ React20.createElement(View20, { style: styles7.section }, /* @__PURE__ */ React20.createElement(Text18, { style: styles7.sectionLabel }, "Severity"), /* @__PURE__ */ React20.createElement(View20, { style: styles7.severityRow }, SEVERITIES.map((s2) => /* @__PURE__ */ React20.createElement(
|
|
19041
19168
|
TouchableOpacity17,
|
|
19042
19169
|
{
|
|
19043
19170
|
key: s2.value,
|
|
19044
19171
|
style: [
|
|
19045
|
-
|
|
19172
|
+
styles7.severityPill,
|
|
19046
19173
|
severity === s2.value && { backgroundColor: `${s2.color}20`, borderColor: s2.color }
|
|
19047
19174
|
],
|
|
19048
19175
|
onPress: () => setSeverity(s2.value),
|
|
19049
19176
|
activeOpacity: 0.7
|
|
19050
19177
|
},
|
|
19051
|
-
/* @__PURE__ */ React20.createElement(Text18, { style: [
|
|
19052
|
-
)))), /* @__PURE__ */ React20.createElement(View20, { style:
|
|
19178
|
+
/* @__PURE__ */ React20.createElement(Text18, { style: [styles7.severityText, severity === s2.value && { color: s2.color }] }, s2.label)
|
|
19179
|
+
)))), /* @__PURE__ */ React20.createElement(View20, { style: styles7.inputSection }, /* @__PURE__ */ React20.createElement(
|
|
19053
19180
|
TextInput11,
|
|
19054
19181
|
{
|
|
19055
19182
|
value: title,
|
|
19056
19183
|
onChangeText: setTitle,
|
|
19057
19184
|
placeholder: "What did you find?",
|
|
19058
19185
|
placeholderTextColor: colors.textMuted,
|
|
19059
|
-
style:
|
|
19186
|
+
style: styles7.titleInput,
|
|
19060
19187
|
returnKeyType: "next"
|
|
19061
19188
|
}
|
|
19062
|
-
)), /* @__PURE__ */ React20.createElement(View20, { style:
|
|
19189
|
+
)), /* @__PURE__ */ React20.createElement(View20, { style: styles7.inputSection }, /* @__PURE__ */ React20.createElement(
|
|
19063
19190
|
TextInput11,
|
|
19064
19191
|
{
|
|
19065
19192
|
value: description,
|
|
19066
19193
|
onChangeText: setDescription,
|
|
19067
19194
|
placeholder: "Details (optional)",
|
|
19068
19195
|
placeholderTextColor: colors.textMuted,
|
|
19069
|
-
style:
|
|
19196
|
+
style: styles7.descInput,
|
|
19070
19197
|
multiline: true,
|
|
19071
19198
|
numberOfLines: 3,
|
|
19072
19199
|
textAlignVertical: "top"
|
|
@@ -19074,12 +19201,12 @@ function SessionFindingScreen({ nav }) {
|
|
|
19074
19201
|
)), /* @__PURE__ */ React20.createElement(
|
|
19075
19202
|
TouchableOpacity17,
|
|
19076
19203
|
{
|
|
19077
|
-
style: [
|
|
19204
|
+
style: [styles7.submitBtn, !canSubmit && styles7.submitBtnDisabled],
|
|
19078
19205
|
onPress: handleSubmit,
|
|
19079
19206
|
disabled: !canSubmit,
|
|
19080
19207
|
activeOpacity: 0.8
|
|
19081
19208
|
},
|
|
19082
|
-
/* @__PURE__ */ React20.createElement(Text18, { style: [
|
|
19209
|
+
/* @__PURE__ */ React20.createElement(Text18, { style: [styles7.submitBtnText, !canSubmit && styles7.submitBtnTextDisabled] }, isSubmitting ? "Saving..." : "Save Finding")
|
|
19083
19210
|
));
|
|
19084
19211
|
}
|
|
19085
19212
|
function createStyles15() {
|
|
@@ -19464,10 +19591,376 @@ var styles4 = StyleSheet21.create({
|
|
|
19464
19591
|
}
|
|
19465
19592
|
});
|
|
19466
19593
|
|
|
19467
|
-
// src/
|
|
19594
|
+
// src/widget/AdHocOverlay.tsx
|
|
19595
|
+
import React22, { useState as useState19, useEffect as useEffect13, useCallback as useCallback7, useRef as useRef8 } from "react";
|
|
19596
|
+
import {
|
|
19597
|
+
View as View22,
|
|
19598
|
+
Text as Text20,
|
|
19599
|
+
TextInput as TextInput12,
|
|
19600
|
+
TouchableOpacity as TouchableOpacity19,
|
|
19601
|
+
StyleSheet as StyleSheet22,
|
|
19602
|
+
Animated as Animated4,
|
|
19603
|
+
PanResponder as PanResponder2,
|
|
19604
|
+
Dimensions as Dimensions3,
|
|
19605
|
+
Platform as Platform6,
|
|
19606
|
+
Keyboard as Keyboard4
|
|
19607
|
+
} from "react-native";
|
|
19468
19608
|
var screenWidth2 = Dimensions3.get("window").width;
|
|
19469
19609
|
var screenHeight2 = Dimensions3.get("window").height;
|
|
19610
|
+
var OVERLAY_WIDTH = 280;
|
|
19611
|
+
var OVERLAY_MARGIN = 16;
|
|
19612
|
+
var MIN_Y2 = 80;
|
|
19470
19613
|
var BOTTOM_SAFE_PADDING2 = Platform6.OS === "ios" ? 34 : 24;
|
|
19614
|
+
var SAFE_MAX_Y2 = screenHeight2 - 200 - BOTTOM_SAFE_PADDING2;
|
|
19615
|
+
function AdHocOverlay({ sessionId, focusArea, startedAt, onExpand, onComplete }) {
|
|
19616
|
+
const { client, addFinding, endSession, activeSession } = useBugBear();
|
|
19617
|
+
const [inputMode, setInputMode] = useState19("closed");
|
|
19618
|
+
const [inputText, setInputText] = useState19("");
|
|
19619
|
+
const [isSubmitting, setIsSubmitting] = useState19(false);
|
|
19620
|
+
const [flashMessage, setFlashMessage] = useState19(null);
|
|
19621
|
+
const [elapsedTime, setElapsedTime] = useState19(0);
|
|
19622
|
+
const inputRef = useRef8(null);
|
|
19623
|
+
const screenshotRef = useRef8(null);
|
|
19624
|
+
const mountAnim = useRef8(new Animated4.Value(0)).current;
|
|
19625
|
+
useEffect13(() => {
|
|
19626
|
+
Animated4.spring(mountAnim, { toValue: 1, useNativeDriver: true, tension: 80, friction: 10 }).start();
|
|
19627
|
+
}, []);
|
|
19628
|
+
const pan = useRef8(new Animated4.ValueXY({
|
|
19629
|
+
x: screenWidth2 - OVERLAY_WIDTH - OVERLAY_MARGIN,
|
|
19630
|
+
y: SAFE_MAX_Y2
|
|
19631
|
+
})).current;
|
|
19632
|
+
const panResponder = useRef8(
|
|
19633
|
+
PanResponder2.create({
|
|
19634
|
+
onStartShouldSetPanResponder: () => true,
|
|
19635
|
+
onMoveShouldSetPanResponder: (_, gs) => Math.abs(gs.dx) > 5 || Math.abs(gs.dy) > 5,
|
|
19636
|
+
onPanResponderGrant: () => {
|
|
19637
|
+
pan.setOffset({
|
|
19638
|
+
x: Math.max(OVERLAY_MARGIN, Math.min(getAnimatedValue(pan.x), screenWidth2 - OVERLAY_WIDTH - OVERLAY_MARGIN)),
|
|
19639
|
+
y: Math.max(MIN_Y2, Math.min(getAnimatedValue(pan.y), SAFE_MAX_Y2))
|
|
19640
|
+
});
|
|
19641
|
+
pan.setValue({ x: 0, y: 0 });
|
|
19642
|
+
},
|
|
19643
|
+
onPanResponderMove: Animated4.event(
|
|
19644
|
+
[null, { dx: pan.x, dy: pan.y }],
|
|
19645
|
+
{ useNativeDriver: false }
|
|
19646
|
+
),
|
|
19647
|
+
onPanResponderRelease: () => {
|
|
19648
|
+
pan.flattenOffset();
|
|
19649
|
+
const currentX = getAnimatedValue(pan.x);
|
|
19650
|
+
const currentY = getAnimatedValue(pan.y);
|
|
19651
|
+
const snapX = currentX < screenWidth2 / 2 ? OVERLAY_MARGIN : screenWidth2 - OVERLAY_WIDTH - OVERLAY_MARGIN;
|
|
19652
|
+
const snapY = Math.max(MIN_Y2, Math.min(currentY, SAFE_MAX_Y2));
|
|
19653
|
+
Animated4.spring(pan, {
|
|
19654
|
+
toValue: { x: snapX, y: snapY },
|
|
19655
|
+
useNativeDriver: false,
|
|
19656
|
+
friction: 7,
|
|
19657
|
+
tension: 40
|
|
19658
|
+
}).start();
|
|
19659
|
+
}
|
|
19660
|
+
})
|
|
19661
|
+
).current;
|
|
19662
|
+
useEffect13(() => {
|
|
19663
|
+
const startTime = new Date(startedAt).getTime();
|
|
19664
|
+
setElapsedTime(Math.floor((Date.now() - startTime) / 1e3));
|
|
19665
|
+
const interval = setInterval(() => {
|
|
19666
|
+
setElapsedTime(Math.floor((Date.now() - startTime) / 1e3));
|
|
19667
|
+
}, 1e3);
|
|
19668
|
+
return () => clearInterval(interval);
|
|
19669
|
+
}, [startedAt]);
|
|
19670
|
+
useEffect13(() => {
|
|
19671
|
+
if (inputMode !== "closed") {
|
|
19672
|
+
setTimeout(() => inputRef.current?.focus(), 50);
|
|
19673
|
+
}
|
|
19674
|
+
}, [inputMode]);
|
|
19675
|
+
const handleOpenInput = useCallback7(async (mode) => {
|
|
19676
|
+
Keyboard4.dismiss();
|
|
19677
|
+
const uri = await captureAppScreen();
|
|
19678
|
+
screenshotRef.current = uri;
|
|
19679
|
+
setInputMode(mode);
|
|
19680
|
+
setInputText("");
|
|
19681
|
+
}, []);
|
|
19682
|
+
const handleCancel = useCallback7(() => {
|
|
19683
|
+
Keyboard4.dismiss();
|
|
19684
|
+
setInputMode("closed");
|
|
19685
|
+
setInputText("");
|
|
19686
|
+
screenshotRef.current = null;
|
|
19687
|
+
}, []);
|
|
19688
|
+
const handleSend = useCallback7(async () => {
|
|
19689
|
+
if (!inputText.trim() || isSubmitting) return;
|
|
19690
|
+
Keyboard4.dismiss();
|
|
19691
|
+
setIsSubmitting(true);
|
|
19692
|
+
try {
|
|
19693
|
+
let screenshotUrl;
|
|
19694
|
+
if (screenshotRef.current && client) {
|
|
19695
|
+
screenshotUrl = await client.uploadImageFromUri(screenshotRef.current) || void 0;
|
|
19696
|
+
}
|
|
19697
|
+
const enhanced = contextCapture.getEnhancedContext();
|
|
19698
|
+
await addFinding({
|
|
19699
|
+
type: inputMode === "bug" ? "bug" : "concern",
|
|
19700
|
+
title: inputText.trim(),
|
|
19701
|
+
severity: inputMode === "bug" ? "medium" : "observation",
|
|
19702
|
+
screenshotUrl,
|
|
19703
|
+
consoleLogs: enhanced.consoleLogs,
|
|
19704
|
+
networkSnapshot: enhanced.networkRequests
|
|
19705
|
+
});
|
|
19706
|
+
setFlashMessage("Saved!");
|
|
19707
|
+
setInputMode("closed");
|
|
19708
|
+
setInputText("");
|
|
19709
|
+
screenshotRef.current = null;
|
|
19710
|
+
setTimeout(() => setFlashMessage(null), 1500);
|
|
19711
|
+
} finally {
|
|
19712
|
+
setIsSubmitting(false);
|
|
19713
|
+
}
|
|
19714
|
+
}, [inputText, isSubmitting, inputMode, client, addFinding]);
|
|
19715
|
+
const handleComplete = useCallback7(async () => {
|
|
19716
|
+
if (isSubmitting) return;
|
|
19717
|
+
Keyboard4.dismiss();
|
|
19718
|
+
setIsSubmitting(true);
|
|
19719
|
+
try {
|
|
19720
|
+
const result = await endSession();
|
|
19721
|
+
if (result.success) {
|
|
19722
|
+
const mins = activeSession?.durationMinutes ?? Math.round(elapsedTime / 60);
|
|
19723
|
+
const findings = activeSession?.findingsCount ?? 0;
|
|
19724
|
+
setFlashMessage(`Session complete! ${mins} min, ${findings} finding${findings !== 1 ? "s" : ""}`);
|
|
19725
|
+
setTimeout(() => {
|
|
19726
|
+
setFlashMessage(null);
|
|
19727
|
+
onComplete();
|
|
19728
|
+
}, 2e3);
|
|
19729
|
+
}
|
|
19730
|
+
} finally {
|
|
19731
|
+
setIsSubmitting(false);
|
|
19732
|
+
}
|
|
19733
|
+
}, [isSubmitting, endSession, activeSession, elapsedTime, onComplete]);
|
|
19734
|
+
return /* @__PURE__ */ React22.createElement(
|
|
19735
|
+
Animated4.View,
|
|
19736
|
+
{
|
|
19737
|
+
style: [
|
|
19738
|
+
styles5.container,
|
|
19739
|
+
{
|
|
19740
|
+
opacity: mountAnim,
|
|
19741
|
+
transform: [
|
|
19742
|
+
...pan.getTranslateTransform(),
|
|
19743
|
+
{ scale: mountAnim.interpolate({ inputRange: [0, 1], outputRange: [0.8, 1] }) }
|
|
19744
|
+
]
|
|
19745
|
+
}
|
|
19746
|
+
],
|
|
19747
|
+
...panResponder.panHandlers
|
|
19748
|
+
},
|
|
19749
|
+
/* @__PURE__ */ React22.createElement(View22, { style: styles5.header }, /* @__PURE__ */ React22.createElement(View22, { style: styles5.headerLeft }, /* @__PURE__ */ React22.createElement(Text20, { style: styles5.headerLabel }, "Ad Hoc"), focusArea ? /* @__PURE__ */ React22.createElement(Text20, { style: styles5.focusText, numberOfLines: 1 }, "\xB7 ", focusArea) : null, /* @__PURE__ */ React22.createElement(Text20, { style: styles5.timer }, formatElapsedTime(elapsedTime))), /* @__PURE__ */ React22.createElement(TouchableOpacity19, { onPress: onExpand, style: styles5.expandButton }, /* @__PURE__ */ React22.createElement(Text20, { style: styles5.expandText }, "\u2197"))),
|
|
19750
|
+
flashMessage ? /* @__PURE__ */ React22.createElement(View22, { style: styles5.flash }, /* @__PURE__ */ React22.createElement(Text20, { style: styles5.flashText }, flashMessage)) : null,
|
|
19751
|
+
inputMode !== "closed" && !flashMessage ? /* @__PURE__ */ React22.createElement(View22, { style: styles5.inputArea }, /* @__PURE__ */ React22.createElement(
|
|
19752
|
+
TextInput12,
|
|
19753
|
+
{
|
|
19754
|
+
ref: inputRef,
|
|
19755
|
+
value: inputText,
|
|
19756
|
+
onChangeText: setInputText,
|
|
19757
|
+
placeholder: inputMode === "bug" ? "What went wrong?" : "What did you notice?",
|
|
19758
|
+
placeholderTextColor: colors.textDim,
|
|
19759
|
+
multiline: true,
|
|
19760
|
+
numberOfLines: 2,
|
|
19761
|
+
style: styles5.textInput
|
|
19762
|
+
}
|
|
19763
|
+
), /* @__PURE__ */ React22.createElement(View22, { style: styles5.inputActions }, /* @__PURE__ */ React22.createElement(TouchableOpacity19, { onPress: handleCancel }, /* @__PURE__ */ React22.createElement(Text20, { style: styles5.cancelText }, "Cancel")), /* @__PURE__ */ React22.createElement(
|
|
19764
|
+
TouchableOpacity19,
|
|
19765
|
+
{
|
|
19766
|
+
onPress: handleSend,
|
|
19767
|
+
disabled: !inputText.trim() || isSubmitting,
|
|
19768
|
+
style: [
|
|
19769
|
+
styles5.sendBtn,
|
|
19770
|
+
{ backgroundColor: inputMode === "bug" ? colors.red : colors.blue },
|
|
19771
|
+
(!inputText.trim() || isSubmitting) && { opacity: 0.5 }
|
|
19772
|
+
]
|
|
19773
|
+
},
|
|
19774
|
+
/* @__PURE__ */ React22.createElement(Text20, { style: styles5.sendText }, isSubmitting ? "Sending..." : "Send \u2192")
|
|
19775
|
+
))) : null,
|
|
19776
|
+
inputMode === "closed" && !flashMessage ? /* @__PURE__ */ React22.createElement(View22, { style: styles5.actions }, /* @__PURE__ */ React22.createElement(
|
|
19777
|
+
TouchableOpacity19,
|
|
19778
|
+
{
|
|
19779
|
+
style: [styles5.feedbackBtn, isSubmitting && { opacity: 0.5 }],
|
|
19780
|
+
onPress: () => handleOpenInput("feedback"),
|
|
19781
|
+
disabled: isSubmitting
|
|
19782
|
+
},
|
|
19783
|
+
/* @__PURE__ */ React22.createElement(Text20, { style: styles5.feedbackText }, "Feedback")
|
|
19784
|
+
), /* @__PURE__ */ React22.createElement(
|
|
19785
|
+
TouchableOpacity19,
|
|
19786
|
+
{
|
|
19787
|
+
style: [styles5.bugBtn, isSubmitting && { opacity: 0.5 }],
|
|
19788
|
+
onPress: () => handleOpenInput("bug"),
|
|
19789
|
+
disabled: isSubmitting
|
|
19790
|
+
},
|
|
19791
|
+
/* @__PURE__ */ React22.createElement(Text20, { style: styles5.bugText }, "Bug")
|
|
19792
|
+
), /* @__PURE__ */ React22.createElement(
|
|
19793
|
+
TouchableOpacity19,
|
|
19794
|
+
{
|
|
19795
|
+
style: [styles5.completeBtn, isSubmitting && { opacity: 0.5 }],
|
|
19796
|
+
onPress: handleComplete,
|
|
19797
|
+
disabled: isSubmitting
|
|
19798
|
+
},
|
|
19799
|
+
/* @__PURE__ */ React22.createElement(Text20, { style: styles5.completeText }, "Complete")
|
|
19800
|
+
)) : null
|
|
19801
|
+
);
|
|
19802
|
+
}
|
|
19803
|
+
var styles5 = StyleSheet22.create({
|
|
19804
|
+
container: {
|
|
19805
|
+
position: "absolute",
|
|
19806
|
+
width: OVERLAY_WIDTH,
|
|
19807
|
+
zIndex: 9999,
|
|
19808
|
+
backgroundColor: colors.bg,
|
|
19809
|
+
borderRadius: 12,
|
|
19810
|
+
borderWidth: 1,
|
|
19811
|
+
borderColor: colors.border,
|
|
19812
|
+
shadowColor: "#000",
|
|
19813
|
+
shadowOffset: { width: 0, height: 8 },
|
|
19814
|
+
shadowOpacity: 0.4,
|
|
19815
|
+
shadowRadius: 16,
|
|
19816
|
+
elevation: 20,
|
|
19817
|
+
overflow: "hidden"
|
|
19818
|
+
},
|
|
19819
|
+
header: {
|
|
19820
|
+
backgroundColor: colors.bgDarker,
|
|
19821
|
+
paddingVertical: 6,
|
|
19822
|
+
paddingHorizontal: 12,
|
|
19823
|
+
flexDirection: "row",
|
|
19824
|
+
alignItems: "center",
|
|
19825
|
+
justifyContent: "space-between",
|
|
19826
|
+
borderBottomWidth: 1,
|
|
19827
|
+
borderBottomColor: colors.border
|
|
19828
|
+
},
|
|
19829
|
+
headerLeft: {
|
|
19830
|
+
flexDirection: "row",
|
|
19831
|
+
alignItems: "center",
|
|
19832
|
+
gap: 6,
|
|
19833
|
+
flex: 1
|
|
19834
|
+
},
|
|
19835
|
+
headerLabel: {
|
|
19836
|
+
fontSize: 11,
|
|
19837
|
+
color: colors.textMuted,
|
|
19838
|
+
fontWeight: "600"
|
|
19839
|
+
},
|
|
19840
|
+
focusText: {
|
|
19841
|
+
fontSize: 10,
|
|
19842
|
+
color: colors.textDim,
|
|
19843
|
+
maxWidth: 100
|
|
19844
|
+
},
|
|
19845
|
+
timer: {
|
|
19846
|
+
fontSize: 10,
|
|
19847
|
+
color: colors.green,
|
|
19848
|
+
fontWeight: "600",
|
|
19849
|
+
fontVariant: ["tabular-nums"]
|
|
19850
|
+
},
|
|
19851
|
+
expandButton: {
|
|
19852
|
+
paddingVertical: 2,
|
|
19853
|
+
paddingHorizontal: 4
|
|
19854
|
+
},
|
|
19855
|
+
expandText: {
|
|
19856
|
+
fontSize: 12,
|
|
19857
|
+
color: colors.blue,
|
|
19858
|
+
fontWeight: "500"
|
|
19859
|
+
},
|
|
19860
|
+
flash: {
|
|
19861
|
+
paddingVertical: 6,
|
|
19862
|
+
paddingHorizontal: 12,
|
|
19863
|
+
backgroundColor: colors.greenDark,
|
|
19864
|
+
alignItems: "center"
|
|
19865
|
+
},
|
|
19866
|
+
flashText: {
|
|
19867
|
+
fontSize: 12,
|
|
19868
|
+
fontWeight: "600",
|
|
19869
|
+
color: colors.greenLight
|
|
19870
|
+
},
|
|
19871
|
+
inputArea: {
|
|
19872
|
+
padding: 8,
|
|
19873
|
+
paddingHorizontal: 10
|
|
19874
|
+
},
|
|
19875
|
+
textInput: {
|
|
19876
|
+
backgroundColor: colors.card,
|
|
19877
|
+
borderWidth: 1,
|
|
19878
|
+
borderColor: colors.border,
|
|
19879
|
+
borderRadius: 8,
|
|
19880
|
+
padding: 6,
|
|
19881
|
+
paddingHorizontal: 8,
|
|
19882
|
+
color: colors.textPrimary,
|
|
19883
|
+
fontSize: 12,
|
|
19884
|
+
lineHeight: 16,
|
|
19885
|
+
minHeight: 40,
|
|
19886
|
+
textAlignVertical: "top"
|
|
19887
|
+
},
|
|
19888
|
+
inputActions: {
|
|
19889
|
+
flexDirection: "row",
|
|
19890
|
+
justifyContent: "space-between",
|
|
19891
|
+
marginTop: 6
|
|
19892
|
+
},
|
|
19893
|
+
cancelText: {
|
|
19894
|
+
fontSize: 11,
|
|
19895
|
+
color: colors.textMuted,
|
|
19896
|
+
paddingVertical: 4,
|
|
19897
|
+
paddingHorizontal: 8
|
|
19898
|
+
},
|
|
19899
|
+
sendBtn: {
|
|
19900
|
+
paddingVertical: 4,
|
|
19901
|
+
paddingHorizontal: 14,
|
|
19902
|
+
borderRadius: 6
|
|
19903
|
+
},
|
|
19904
|
+
sendText: {
|
|
19905
|
+
fontSize: 11,
|
|
19906
|
+
fontWeight: "600",
|
|
19907
|
+
color: "#fff"
|
|
19908
|
+
},
|
|
19909
|
+
actions: {
|
|
19910
|
+
flexDirection: "row",
|
|
19911
|
+
gap: 6,
|
|
19912
|
+
padding: 8,
|
|
19913
|
+
paddingHorizontal: 10,
|
|
19914
|
+
paddingBottom: 10
|
|
19915
|
+
},
|
|
19916
|
+
feedbackBtn: {
|
|
19917
|
+
flex: 1,
|
|
19918
|
+
paddingVertical: 8,
|
|
19919
|
+
borderRadius: 8,
|
|
19920
|
+
backgroundColor: colors.blueDark,
|
|
19921
|
+
borderWidth: 1,
|
|
19922
|
+
borderColor: `${colors.blue}40`,
|
|
19923
|
+
alignItems: "center"
|
|
19924
|
+
},
|
|
19925
|
+
feedbackText: {
|
|
19926
|
+
fontSize: 11,
|
|
19927
|
+
fontWeight: "600",
|
|
19928
|
+
color: colors.blueLight
|
|
19929
|
+
},
|
|
19930
|
+
bugBtn: {
|
|
19931
|
+
flex: 1,
|
|
19932
|
+
paddingVertical: 8,
|
|
19933
|
+
borderRadius: 8,
|
|
19934
|
+
backgroundColor: colors.redDark,
|
|
19935
|
+
borderWidth: 1,
|
|
19936
|
+
borderColor: colors.red,
|
|
19937
|
+
alignItems: "center"
|
|
19938
|
+
},
|
|
19939
|
+
bugText: {
|
|
19940
|
+
fontSize: 11,
|
|
19941
|
+
fontWeight: "600",
|
|
19942
|
+
color: colors.redLight
|
|
19943
|
+
},
|
|
19944
|
+
completeBtn: {
|
|
19945
|
+
flex: 1,
|
|
19946
|
+
paddingVertical: 8,
|
|
19947
|
+
borderRadius: 8,
|
|
19948
|
+
backgroundColor: colors.greenDark,
|
|
19949
|
+
borderWidth: 1,
|
|
19950
|
+
borderColor: colors.green,
|
|
19951
|
+
alignItems: "center"
|
|
19952
|
+
},
|
|
19953
|
+
completeText: {
|
|
19954
|
+
fontSize: 11,
|
|
19955
|
+
fontWeight: "600",
|
|
19956
|
+
color: colors.greenLight
|
|
19957
|
+
}
|
|
19958
|
+
});
|
|
19959
|
+
|
|
19960
|
+
// src/BugBearButton.tsx
|
|
19961
|
+
var screenWidth3 = Dimensions4.get("window").width;
|
|
19962
|
+
var screenHeight3 = Dimensions4.get("window").height;
|
|
19963
|
+
var BOTTOM_SAFE_PADDING3 = Platform7.OS === "ios" ? 34 : 24;
|
|
19471
19964
|
function BugBearButton({
|
|
19472
19965
|
position = "bottom-right",
|
|
19473
19966
|
buttonStyle,
|
|
@@ -19477,20 +19970,20 @@ function BugBearButton({
|
|
|
19477
19970
|
minY = 100,
|
|
19478
19971
|
maxYOffset = 160
|
|
19479
19972
|
}) {
|
|
19480
|
-
const { shouldShowWidget, testerInfo, isLoading, unreadCount, assignments, widgetMode, widgetColorScheme } = useBugBear();
|
|
19973
|
+
const { shouldShowWidget, testerInfo, isLoading, unreadCount, assignments, widgetMode, widgetColorScheme, activeSession, startSession } = useBugBear();
|
|
19481
19974
|
const { currentScreen, canGoBack, push, pop, replace, reset } = useNavigation();
|
|
19482
|
-
const [viewMode, setViewMode] =
|
|
19483
|
-
const [miniRunnerAssignmentId, setMiniRunnerAssignmentId] =
|
|
19484
|
-
const panelAnim =
|
|
19485
|
-
const
|
|
19975
|
+
const [viewMode, setViewMode] = useState20("closed");
|
|
19976
|
+
const [miniRunnerAssignmentId, setMiniRunnerAssignmentId] = useState20(null);
|
|
19977
|
+
const panelAnim = useRef9(new Animated5.Value(0)).current;
|
|
19978
|
+
const styles7 = useMemo16(() => createStyles16(), [widgetColorScheme]);
|
|
19486
19979
|
const panelVisible = viewMode === "panel";
|
|
19487
|
-
const screenCaptureRef =
|
|
19980
|
+
const screenCaptureRef = useRef9(null);
|
|
19488
19981
|
const openPanel = () => {
|
|
19489
19982
|
captureAppScreen().then((uri) => {
|
|
19490
19983
|
screenCaptureRef.current = uri;
|
|
19491
19984
|
});
|
|
19492
19985
|
setViewMode("panel");
|
|
19493
|
-
|
|
19986
|
+
Animated5.spring(panelAnim, {
|
|
19494
19987
|
toValue: 1,
|
|
19495
19988
|
useNativeDriver: true,
|
|
19496
19989
|
friction: 8,
|
|
@@ -19498,8 +19991,8 @@ function BugBearButton({
|
|
|
19498
19991
|
}).start();
|
|
19499
19992
|
};
|
|
19500
19993
|
const closePanel = () => {
|
|
19501
|
-
|
|
19502
|
-
|
|
19994
|
+
Keyboard5.dismiss();
|
|
19995
|
+
Animated5.timing(panelAnim, {
|
|
19503
19996
|
toValue: 0,
|
|
19504
19997
|
duration: 250,
|
|
19505
19998
|
useNativeDriver: true
|
|
@@ -19509,26 +20002,26 @@ function BugBearButton({
|
|
|
19509
20002
|
};
|
|
19510
20003
|
const buttonSize = 56;
|
|
19511
20004
|
const margin = 16;
|
|
19512
|
-
const safeMaxY =
|
|
20005
|
+
const safeMaxY = screenHeight3 - maxYOffset - BOTTOM_SAFE_PADDING3;
|
|
19513
20006
|
const getInitialPosition = () => {
|
|
19514
20007
|
if (initialX !== void 0 && initialY !== void 0) {
|
|
19515
20008
|
return { x: initialX, y: initialY };
|
|
19516
20009
|
}
|
|
19517
|
-
const x = position === "bottom-right" ?
|
|
19518
|
-
const y =
|
|
20010
|
+
const x = position === "bottom-right" ? screenWidth3 - buttonSize - margin : margin;
|
|
20011
|
+
const y = screenHeight3 - maxYOffset - BOTTOM_SAFE_PADDING3;
|
|
19519
20012
|
return { x, y };
|
|
19520
20013
|
};
|
|
19521
20014
|
const initialPos = getInitialPosition();
|
|
19522
|
-
const pan =
|
|
19523
|
-
const isDragging =
|
|
19524
|
-
const panResponder =
|
|
19525
|
-
|
|
20015
|
+
const pan = useRef9(new Animated5.ValueXY(initialPos)).current;
|
|
20016
|
+
const isDragging = useRef9(false);
|
|
20017
|
+
const panResponder = useRef9(
|
|
20018
|
+
PanResponder3.create({
|
|
19526
20019
|
onStartShouldSetPanResponder: () => draggable,
|
|
19527
20020
|
onMoveShouldSetPanResponder: (_, gs) => draggable && (Math.abs(gs.dx) > 5 || Math.abs(gs.dy) > 5),
|
|
19528
20021
|
onPanResponderGrant: () => {
|
|
19529
20022
|
isDragging.current = false;
|
|
19530
20023
|
pan.setOffset({
|
|
19531
|
-
x: Math.max(margin, Math.min(getAnimatedValue(pan.x),
|
|
20024
|
+
x: Math.max(margin, Math.min(getAnimatedValue(pan.x), screenWidth3 - buttonSize - margin)),
|
|
19532
20025
|
y: Math.max(minY, Math.min(getAnimatedValue(pan.y), safeMaxY))
|
|
19533
20026
|
});
|
|
19534
20027
|
pan.setValue({ x: 0, y: 0 });
|
|
@@ -19537,7 +20030,7 @@ function BugBearButton({
|
|
|
19537
20030
|
if (Math.abs(gs.dx) > 5 || Math.abs(gs.dy) > 5) {
|
|
19538
20031
|
isDragging.current = true;
|
|
19539
20032
|
}
|
|
19540
|
-
|
|
20033
|
+
Animated5.event(
|
|
19541
20034
|
[null, { dx: pan.x, dy: pan.y }],
|
|
19542
20035
|
{ useNativeDriver: false }
|
|
19543
20036
|
)(_, gs);
|
|
@@ -19546,9 +20039,9 @@ function BugBearButton({
|
|
|
19546
20039
|
pan.flattenOffset();
|
|
19547
20040
|
const currentX = getAnimatedValue(pan.x);
|
|
19548
20041
|
const currentY = getAnimatedValue(pan.y);
|
|
19549
|
-
const snapX = currentX <
|
|
20042
|
+
const snapX = currentX < screenWidth3 / 2 ? margin : screenWidth3 - buttonSize - margin;
|
|
19550
20043
|
const snapY = Math.max(minY, Math.min(currentY, safeMaxY));
|
|
19551
|
-
|
|
20044
|
+
Animated5.spring(pan, {
|
|
19552
20045
|
toValue: { x: snapX, y: snapY },
|
|
19553
20046
|
useNativeDriver: false,
|
|
19554
20047
|
friction: 7,
|
|
@@ -19563,11 +20056,11 @@ function BugBearButton({
|
|
|
19563
20056
|
).current;
|
|
19564
20057
|
const pendingTests = widgetMode === "qa" ? assignments.filter((a) => a.status === "pending" || a.status === "in_progress").length : 0;
|
|
19565
20058
|
const badgeCount = pendingTests + unreadCount;
|
|
19566
|
-
|
|
19567
|
-
if (!panelVisible ||
|
|
20059
|
+
useEffect14(() => {
|
|
20060
|
+
if (!panelVisible || Platform7.OS !== "android") return;
|
|
19568
20061
|
const handler = BackHandler.addEventListener("hardwareBackPress", () => {
|
|
19569
20062
|
if (canGoBack) {
|
|
19570
|
-
|
|
20063
|
+
Keyboard5.dismiss();
|
|
19571
20064
|
pop();
|
|
19572
20065
|
} else {
|
|
19573
20066
|
closePanel();
|
|
@@ -19576,9 +20069,9 @@ function BugBearButton({
|
|
|
19576
20069
|
});
|
|
19577
20070
|
return () => handler.remove();
|
|
19578
20071
|
}, [panelVisible, canGoBack]);
|
|
19579
|
-
const startMiniRunner =
|
|
19580
|
-
|
|
19581
|
-
|
|
20072
|
+
const startMiniRunner = useCallback8((assignId) => {
|
|
20073
|
+
Keyboard5.dismiss();
|
|
20074
|
+
Animated5.timing(panelAnim, {
|
|
19582
20075
|
toValue: 0,
|
|
19583
20076
|
duration: 200,
|
|
19584
20077
|
useNativeDriver: true
|
|
@@ -19587,40 +20080,83 @@ function BugBearButton({
|
|
|
19587
20080
|
setViewMode("mini-runner");
|
|
19588
20081
|
});
|
|
19589
20082
|
}, [panelAnim]);
|
|
19590
|
-
const expandFromMiniRunner =
|
|
20083
|
+
const expandFromMiniRunner = useCallback8(() => {
|
|
19591
20084
|
setViewMode("panel");
|
|
19592
20085
|
if (miniRunnerAssignmentId) {
|
|
19593
20086
|
replace({ name: "TEST_DETAIL", testId: miniRunnerAssignmentId });
|
|
19594
20087
|
}
|
|
19595
20088
|
setMiniRunnerAssignmentId(null);
|
|
19596
|
-
|
|
20089
|
+
Animated5.spring(panelAnim, {
|
|
19597
20090
|
toValue: 1,
|
|
19598
20091
|
useNativeDriver: true,
|
|
19599
20092
|
friction: 8,
|
|
19600
20093
|
tension: 65
|
|
19601
20094
|
}).start();
|
|
19602
20095
|
}, [miniRunnerAssignmentId, replace, panelAnim]);
|
|
19603
|
-
const handleMiniRunnerAdvance =
|
|
20096
|
+
const handleMiniRunnerAdvance = useCallback8((nextId) => {
|
|
19604
20097
|
setMiniRunnerAssignmentId(nextId);
|
|
19605
20098
|
}, []);
|
|
19606
|
-
const handleMiniRunnerComplete =
|
|
20099
|
+
const handleMiniRunnerComplete = useCallback8(() => {
|
|
19607
20100
|
setMiniRunnerAssignmentId(null);
|
|
19608
20101
|
setViewMode("closed");
|
|
19609
20102
|
}, []);
|
|
19610
|
-
const handleMiniRunnerReport =
|
|
20103
|
+
const handleMiniRunnerReport = useCallback8((assignId, testCaseId) => {
|
|
19611
20104
|
setMiniRunnerAssignmentId(null);
|
|
19612
20105
|
setViewMode("panel");
|
|
19613
20106
|
replace({
|
|
19614
20107
|
name: "REPORT",
|
|
19615
20108
|
prefill: { type: "test_fail", assignmentId: assignId, testCaseId }
|
|
19616
20109
|
});
|
|
19617
|
-
|
|
20110
|
+
Animated5.spring(panelAnim, {
|
|
20111
|
+
toValue: 1,
|
|
20112
|
+
useNativeDriver: true,
|
|
20113
|
+
friction: 8,
|
|
20114
|
+
tension: 65
|
|
20115
|
+
}).start();
|
|
20116
|
+
}, [replace, panelAnim]);
|
|
20117
|
+
const startAdHoc = useCallback8(async (taskId, focusArea) => {
|
|
20118
|
+
Keyboard5.dismiss();
|
|
20119
|
+
const result = await startSession({
|
|
20120
|
+
sessionType: "ad_hoc",
|
|
20121
|
+
taskId,
|
|
20122
|
+
focusArea,
|
|
20123
|
+
platform: "ios"
|
|
20124
|
+
});
|
|
20125
|
+
if (result.success) {
|
|
20126
|
+
Animated5.timing(panelAnim, {
|
|
20127
|
+
toValue: 0,
|
|
20128
|
+
duration: 200,
|
|
20129
|
+
useNativeDriver: true
|
|
20130
|
+
}).start(() => {
|
|
20131
|
+
setViewMode("ad-hoc");
|
|
20132
|
+
});
|
|
20133
|
+
}
|
|
20134
|
+
}, [startSession, panelAnim]);
|
|
20135
|
+
const expandFromAdHoc = useCallback8(() => {
|
|
20136
|
+
setViewMode("panel");
|
|
20137
|
+
replace({ name: "SESSION_ACTIVE" });
|
|
20138
|
+
Animated5.spring(panelAnim, {
|
|
19618
20139
|
toValue: 1,
|
|
19619
20140
|
useNativeDriver: true,
|
|
19620
20141
|
friction: 8,
|
|
19621
20142
|
tension: 65
|
|
19622
20143
|
}).start();
|
|
19623
20144
|
}, [replace, panelAnim]);
|
|
20145
|
+
const handleAdHocComplete = useCallback8(() => {
|
|
20146
|
+
setViewMode("closed");
|
|
20147
|
+
}, []);
|
|
20148
|
+
const minimizeToAdHoc = useCallback8(() => {
|
|
20149
|
+
if (activeSession?.sessionType === "ad_hoc") {
|
|
20150
|
+
Keyboard5.dismiss();
|
|
20151
|
+
Animated5.timing(panelAnim, {
|
|
20152
|
+
toValue: 0,
|
|
20153
|
+
duration: 200,
|
|
20154
|
+
useNativeDriver: true
|
|
20155
|
+
}).start(() => {
|
|
20156
|
+
setViewMode("ad-hoc");
|
|
20157
|
+
});
|
|
20158
|
+
}
|
|
20159
|
+
}, [activeSession, panelAnim]);
|
|
19624
20160
|
if (!shouldShowWidget) return null;
|
|
19625
20161
|
const getHeaderTitle = () => {
|
|
19626
20162
|
switch (currentScreen.name) {
|
|
@@ -19663,41 +20199,43 @@ function BugBearButton({
|
|
|
19663
20199
|
};
|
|
19664
20200
|
const nav = {
|
|
19665
20201
|
push: (screen) => {
|
|
19666
|
-
|
|
20202
|
+
Keyboard5.dismiss();
|
|
19667
20203
|
push(screen);
|
|
19668
20204
|
},
|
|
19669
20205
|
pop: () => {
|
|
19670
|
-
|
|
20206
|
+
Keyboard5.dismiss();
|
|
19671
20207
|
pop();
|
|
19672
20208
|
},
|
|
19673
20209
|
replace: (screen) => {
|
|
19674
|
-
|
|
20210
|
+
Keyboard5.dismiss();
|
|
19675
20211
|
replace(screen);
|
|
19676
20212
|
},
|
|
19677
20213
|
reset: () => {
|
|
19678
|
-
|
|
20214
|
+
Keyboard5.dismiss();
|
|
19679
20215
|
reset();
|
|
19680
20216
|
},
|
|
19681
20217
|
canGoBack,
|
|
19682
20218
|
closeWidget: handleClose,
|
|
19683
|
-
startMiniRunner
|
|
20219
|
+
startMiniRunner,
|
|
20220
|
+
startAdHoc,
|
|
20221
|
+
minimizeToAdHoc: activeSession?.sessionType === "ad_hoc" ? minimizeToAdHoc : void 0
|
|
19684
20222
|
};
|
|
19685
20223
|
const QA_ONLY_SCREENS = ["TEST_DETAIL", "TEST_LIST", "TEST_FEEDBACK", "SESSION_START", "SESSION_ACTIVE", "SESSION_FINDING"];
|
|
19686
20224
|
const renderScreen = () => {
|
|
19687
20225
|
if (widgetMode === "feedback" && QA_ONLY_SCREENS.includes(currentScreen.name)) {
|
|
19688
|
-
return /* @__PURE__ */
|
|
20226
|
+
return /* @__PURE__ */ React23.createElement(HomeScreen, { nav });
|
|
19689
20227
|
}
|
|
19690
20228
|
switch (currentScreen.name) {
|
|
19691
20229
|
case "HOME":
|
|
19692
|
-
return /* @__PURE__ */
|
|
20230
|
+
return /* @__PURE__ */ React23.createElement(HomeScreen, { nav });
|
|
19693
20231
|
case "TEST_DETAIL":
|
|
19694
|
-
return /* @__PURE__ */
|
|
20232
|
+
return /* @__PURE__ */ React23.createElement(TestDetailScreen, { testId: currentScreen.testId, nav });
|
|
19695
20233
|
case "TEST_LIST":
|
|
19696
|
-
return /* @__PURE__ */
|
|
20234
|
+
return /* @__PURE__ */ React23.createElement(TestListScreen, { nav });
|
|
19697
20235
|
case "TEST_FEEDBACK":
|
|
19698
|
-
return /* @__PURE__ */
|
|
20236
|
+
return /* @__PURE__ */ React23.createElement(TestFeedbackScreen, { status: currentScreen.status, assignmentId: currentScreen.assignmentId, nav });
|
|
19699
20237
|
case "REPORT":
|
|
19700
|
-
return /* @__PURE__ */
|
|
20238
|
+
return /* @__PURE__ */ React23.createElement(
|
|
19701
20239
|
ReportScreen,
|
|
19702
20240
|
{
|
|
19703
20241
|
nav,
|
|
@@ -19709,30 +20247,30 @@ function BugBearButton({
|
|
|
19709
20247
|
}
|
|
19710
20248
|
);
|
|
19711
20249
|
case "REPORT_SUCCESS":
|
|
19712
|
-
return /* @__PURE__ */
|
|
20250
|
+
return /* @__PURE__ */ React23.createElement(ReportSuccessScreen, { nav });
|
|
19713
20251
|
case "MESSAGE_LIST":
|
|
19714
|
-
return /* @__PURE__ */
|
|
20252
|
+
return /* @__PURE__ */ React23.createElement(MessageListScreen, { nav });
|
|
19715
20253
|
case "THREAD_DETAIL":
|
|
19716
|
-
return /* @__PURE__ */
|
|
20254
|
+
return /* @__PURE__ */ React23.createElement(ThreadDetailScreen, { thread: currentScreen.thread, nav });
|
|
19717
20255
|
case "COMPOSE_MESSAGE":
|
|
19718
|
-
return /* @__PURE__ */
|
|
20256
|
+
return /* @__PURE__ */ React23.createElement(ComposeMessageScreen, { nav });
|
|
19719
20257
|
case "ISSUE_LIST":
|
|
19720
|
-
return /* @__PURE__ */
|
|
20258
|
+
return /* @__PURE__ */ React23.createElement(IssueListScreen, { nav, category: currentScreen.category });
|
|
19721
20259
|
case "ISSUE_DETAIL":
|
|
19722
|
-
return /* @__PURE__ */
|
|
20260
|
+
return /* @__PURE__ */ React23.createElement(IssueDetailScreen, { nav, issue: currentScreen.issue });
|
|
19723
20261
|
case "PROFILE":
|
|
19724
|
-
return /* @__PURE__ */
|
|
20262
|
+
return /* @__PURE__ */ React23.createElement(ProfileScreen, { nav });
|
|
19725
20263
|
case "SESSION_START":
|
|
19726
|
-
return /* @__PURE__ */
|
|
20264
|
+
return /* @__PURE__ */ React23.createElement(SessionStartScreen, { nav });
|
|
19727
20265
|
case "SESSION_ACTIVE":
|
|
19728
|
-
return /* @__PURE__ */
|
|
20266
|
+
return /* @__PURE__ */ React23.createElement(SessionActiveScreen, { nav });
|
|
19729
20267
|
case "SESSION_FINDING":
|
|
19730
|
-
return /* @__PURE__ */
|
|
20268
|
+
return /* @__PURE__ */ React23.createElement(SessionFindingScreen, { nav });
|
|
19731
20269
|
default:
|
|
19732
|
-
return /* @__PURE__ */
|
|
20270
|
+
return /* @__PURE__ */ React23.createElement(HomeScreen, { nav });
|
|
19733
20271
|
}
|
|
19734
20272
|
};
|
|
19735
|
-
return /* @__PURE__ */
|
|
20273
|
+
return /* @__PURE__ */ React23.createElement(React23.Fragment, null, viewMode === "mini-runner" && miniRunnerAssignmentId && /* @__PURE__ */ React23.createElement(
|
|
19736
20274
|
MiniTestRunner,
|
|
19737
20275
|
{
|
|
19738
20276
|
assignmentId: miniRunnerAssignmentId,
|
|
@@ -19741,61 +20279,70 @@ function BugBearButton({
|
|
|
19741
20279
|
onComplete: handleMiniRunnerComplete,
|
|
19742
20280
|
onNavigateToReport: handleMiniRunnerReport
|
|
19743
20281
|
}
|
|
19744
|
-
), viewMode === "
|
|
19745
|
-
|
|
20282
|
+
), viewMode === "ad-hoc" && activeSession && /* @__PURE__ */ React23.createElement(
|
|
20283
|
+
AdHocOverlay,
|
|
19746
20284
|
{
|
|
19747
|
-
|
|
20285
|
+
sessionId: activeSession.id,
|
|
20286
|
+
focusArea: activeSession.focusArea,
|
|
20287
|
+
startedAt: activeSession.startedAt,
|
|
20288
|
+
onExpand: expandFromAdHoc,
|
|
20289
|
+
onComplete: handleAdHocComplete
|
|
20290
|
+
}
|
|
20291
|
+
), viewMode === "closed" && /* @__PURE__ */ React23.createElement(
|
|
20292
|
+
Animated5.View,
|
|
20293
|
+
{
|
|
20294
|
+
style: [styles7.fabContainer, { transform: pan.getTranslateTransform() }, buttonStyle],
|
|
19748
20295
|
...panResponder.panHandlers
|
|
19749
20296
|
},
|
|
19750
|
-
/* @__PURE__ */
|
|
19751
|
-
|
|
20297
|
+
/* @__PURE__ */ React23.createElement(
|
|
20298
|
+
TouchableOpacity20,
|
|
19752
20299
|
{
|
|
19753
|
-
style:
|
|
20300
|
+
style: styles7.fab,
|
|
19754
20301
|
onPress: openPanel,
|
|
19755
20302
|
activeOpacity: draggable ? 1 : 0.7
|
|
19756
20303
|
},
|
|
19757
|
-
/* @__PURE__ */
|
|
19758
|
-
badgeCount > 0 && /* @__PURE__ */
|
|
20304
|
+
/* @__PURE__ */ React23.createElement(Image4, { source: { uri: BUGBEAR_LOGO_BASE64 }, style: styles7.fabIcon }),
|
|
20305
|
+
badgeCount > 0 && /* @__PURE__ */ React23.createElement(View23, { style: styles7.badge }, /* @__PURE__ */ React23.createElement(Text21, { style: styles7.badgeText }, badgeCount > 9 ? "9+" : badgeCount))
|
|
19759
20306
|
)
|
|
19760
|
-
), viewMode === "panel" && /* @__PURE__ */
|
|
20307
|
+
), viewMode === "panel" && /* @__PURE__ */ React23.createElement(View23, { style: styles7.panelWrapper, pointerEvents: "box-none" }, /* @__PURE__ */ React23.createElement(
|
|
19761
20308
|
KeyboardAvoidingView,
|
|
19762
20309
|
{
|
|
19763
|
-
behavior:
|
|
19764
|
-
style:
|
|
20310
|
+
behavior: Platform7.OS === "ios" ? "padding" : "height",
|
|
20311
|
+
style: styles7.panelKeyboardAvoid,
|
|
19765
20312
|
pointerEvents: "box-none"
|
|
19766
20313
|
},
|
|
19767
|
-
/* @__PURE__ */
|
|
19768
|
-
|
|
20314
|
+
/* @__PURE__ */ React23.createElement(
|
|
20315
|
+
Animated5.View,
|
|
19769
20316
|
{
|
|
19770
20317
|
style: [
|
|
19771
|
-
|
|
20318
|
+
styles7.panelContainer,
|
|
19772
20319
|
{
|
|
19773
20320
|
transform: [{
|
|
19774
20321
|
translateY: panelAnim.interpolate({
|
|
19775
20322
|
inputRange: [0, 1],
|
|
19776
|
-
outputRange: [
|
|
20323
|
+
outputRange: [screenHeight3, 0]
|
|
19777
20324
|
})
|
|
19778
20325
|
}]
|
|
19779
20326
|
}
|
|
19780
20327
|
]
|
|
19781
20328
|
},
|
|
19782
|
-
/* @__PURE__ */
|
|
19783
|
-
/* @__PURE__ */
|
|
19784
|
-
/* @__PURE__ */
|
|
20329
|
+
/* @__PURE__ */ React23.createElement(View23, { style: styles7.panelHandle }, /* @__PURE__ */ React23.createElement(View23, { style: styles7.panelHandleBar })),
|
|
20330
|
+
/* @__PURE__ */ React23.createElement(View23, { style: styles7.header }, /* @__PURE__ */ React23.createElement(View23, { style: styles7.headerLeft }, canGoBack ? /* @__PURE__ */ React23.createElement(TouchableOpacity20, { onPress: () => nav.pop(), style: styles7.backButton }, /* @__PURE__ */ React23.createElement(Text21, { style: styles7.backText }, "\u2190 Back")) : /* @__PURE__ */ React23.createElement(View23, { style: styles7.headerTitleRow }, /* @__PURE__ */ React23.createElement(Text21, { style: styles7.headerTitle }, "BugBear"), testerInfo && /* @__PURE__ */ React23.createElement(TouchableOpacity20, { onPress: () => push({ name: "PROFILE" }) }, /* @__PURE__ */ React23.createElement(Text21, { style: styles7.headerName }, testerInfo.name, " \u270E")))), getHeaderTitle() ? /* @__PURE__ */ React23.createElement(Text21, { style: styles7.headerScreenTitle, numberOfLines: 1 }, getHeaderTitle()) : null, /* @__PURE__ */ React23.createElement(View23, { style: styles7.headerActions }, currentScreen.name !== "HOME" && /* @__PURE__ */ React23.createElement(TouchableOpacity20, { onPress: () => nav.reset(), style: styles7.homeButton }, /* @__PURE__ */ React23.createElement(Text21, { style: styles7.homeIcon }, "\u2302")), /* @__PURE__ */ React23.createElement(TouchableOpacity20, { onPress: handleClose, style: styles7.closeButton }, /* @__PURE__ */ React23.createElement(Text21, { style: styles7.closeText }, "\u2715")))),
|
|
20331
|
+
/* @__PURE__ */ React23.createElement(
|
|
19785
20332
|
ScrollView4,
|
|
19786
20333
|
{
|
|
19787
|
-
style:
|
|
19788
|
-
contentContainerStyle:
|
|
20334
|
+
style: styles7.content,
|
|
20335
|
+
contentContainerStyle: styles7.contentContainer,
|
|
19789
20336
|
keyboardShouldPersistTaps: "handled",
|
|
19790
20337
|
showsVerticalScrollIndicator: false
|
|
19791
20338
|
},
|
|
19792
|
-
isLoading ? /* @__PURE__ */
|
|
20339
|
+
isLoading ? /* @__PURE__ */ React23.createElement(View23, { style: styles7.loadingContainer }, /* @__PURE__ */ React23.createElement(ActivityIndicator3, { size: "large", color: colors.blue }), /* @__PURE__ */ React23.createElement(Text21, { style: styles7.loadingText }, "Loading...")) : renderScreen()
|
|
19793
20340
|
)
|
|
19794
20341
|
)
|
|
19795
20342
|
)));
|
|
19796
20343
|
}
|
|
19797
20344
|
function createStyles16() {
|
|
19798
|
-
return
|
|
20345
|
+
return StyleSheet23.create({
|
|
19799
20346
|
// FAB
|
|
19800
20347
|
fabContainer: {
|
|
19801
20348
|
position: "absolute",
|
|
@@ -19954,7 +20501,7 @@ function createStyles16() {
|
|
|
19954
20501
|
},
|
|
19955
20502
|
contentContainer: {
|
|
19956
20503
|
padding: 16,
|
|
19957
|
-
paddingBottom:
|
|
20504
|
+
paddingBottom: Platform7.OS === "ios" ? 50 : 28
|
|
19958
20505
|
},
|
|
19959
20506
|
// Loading
|
|
19960
20507
|
loadingContainer: {
|
|
@@ -19970,8 +20517,8 @@ function createStyles16() {
|
|
|
19970
20517
|
}
|
|
19971
20518
|
|
|
19972
20519
|
// src/BugBearErrorBoundary.tsx
|
|
19973
|
-
import
|
|
19974
|
-
import { View as
|
|
20520
|
+
import React24, { Component } from "react";
|
|
20521
|
+
import { View as View24, Text as Text22, TouchableOpacity as TouchableOpacity21, StyleSheet as StyleSheet24 } from "react-native";
|
|
19975
20522
|
var BugBearErrorBoundary = class extends Component {
|
|
19976
20523
|
constructor(props) {
|
|
19977
20524
|
super(props);
|
|
@@ -20016,7 +20563,7 @@ var BugBearErrorBoundary = class extends Component {
|
|
|
20016
20563
|
if (fallback) {
|
|
20017
20564
|
return fallback;
|
|
20018
20565
|
}
|
|
20019
|
-
return /* @__PURE__ */
|
|
20566
|
+
return /* @__PURE__ */ React24.createElement(View24, { style: styles6.container }, /* @__PURE__ */ React24.createElement(Text22, { style: styles6.title }, "Something went wrong"), /* @__PURE__ */ React24.createElement(Text22, { style: styles6.message }, error.message), /* @__PURE__ */ React24.createElement(TouchableOpacity21, { style: styles6.button, onPress: this.reset }, /* @__PURE__ */ React24.createElement(Text22, { style: styles6.buttonText }, "Try Again")), /* @__PURE__ */ React24.createElement(Text22, { style: styles6.caption }, "The error has been captured by BugBear"));
|
|
20020
20567
|
}
|
|
20021
20568
|
return children;
|
|
20022
20569
|
}
|
|
@@ -20027,7 +20574,7 @@ function useErrorContext() {
|
|
|
20027
20574
|
getEnhancedContext: () => contextCapture.getEnhancedContext()
|
|
20028
20575
|
};
|
|
20029
20576
|
}
|
|
20030
|
-
var
|
|
20577
|
+
var styles6 = StyleSheet24.create({
|
|
20031
20578
|
container: {
|
|
20032
20579
|
padding: 20,
|
|
20033
20580
|
margin: 20,
|