@bbearai/react-native 0.5.2 → 0.5.4

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 CHANGED
@@ -13119,6 +13119,10 @@ var BugBearContext = (0, import_react.createContext)({
13119
13119
  updateTesterProfile: async () => ({ success: false }),
13120
13120
  refreshTesterInfo: async () => {
13121
13121
  },
13122
+ // Issue tracking
13123
+ issueCounts: { open: 0, done: 0, reopened: 0 },
13124
+ refreshIssueCounts: async () => {
13125
+ },
13122
13126
  dashboardUrl: void 0,
13123
13127
  onError: void 0
13124
13128
  });
@@ -13134,6 +13138,7 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
13134
13138
  const [isLoading, setIsLoading] = (0, import_react.useState)(true);
13135
13139
  const [threads, setThreads] = (0, import_react.useState)([]);
13136
13140
  const [unreadCount, setUnreadCount] = (0, import_react.useState)(0);
13141
+ const [issueCounts, setIssueCounts] = (0, import_react.useState)({ open: 0, done: 0, reopened: 0 });
13137
13142
  const [activeSession, setActiveSession] = (0, import_react.useState)(null);
13138
13143
  const [sessionFindings, setSessionFindings] = (0, import_react.useState)([]);
13139
13144
  const hasInitialized = (0, import_react.useRef)(false);
@@ -13240,6 +13245,11 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
13240
13245
  if (!client) return null;
13241
13246
  return client.uploadImageFromUri(uri, void 0, bucket);
13242
13247
  }, [client]);
13248
+ const refreshIssueCounts = (0, import_react.useCallback)(async () => {
13249
+ if (!client) return;
13250
+ const counts = await client.getIssueCounts();
13251
+ setIssueCounts(counts);
13252
+ }, [client]);
13243
13253
  const initializeBugBear = (0, import_react.useCallback)(async (bugBearClient) => {
13244
13254
  setIsLoading(true);
13245
13255
  try {
@@ -13252,16 +13262,18 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
13252
13262
  setTesterInfo(info);
13253
13263
  setIsTester(!!info);
13254
13264
  if (info && qaEnabled) {
13255
- const [newAssignments, newThreads, session] = await Promise.all([
13265
+ const [newAssignments, newThreads, session, counts] = await Promise.all([
13256
13266
  bugBearClient.getAssignedTests(),
13257
13267
  bugBearClient.getThreadsForTester(),
13258
- bugBearClient.getActiveSession()
13268
+ bugBearClient.getActiveSession(),
13269
+ bugBearClient.getIssueCounts()
13259
13270
  ]);
13260
13271
  setAssignments(newAssignments);
13261
13272
  setThreads(newThreads);
13262
13273
  const totalUnread = newThreads.reduce((sum, t) => sum + t.unreadCount, 0);
13263
13274
  setUnreadCount(totalUnread);
13264
13275
  setActiveSession(session);
13276
+ setIssueCounts(counts);
13265
13277
  if (session) {
13266
13278
  const findings = await bugBearClient.getSessionFindings(session.id);
13267
13279
  setSessionFindings(findings);
@@ -13290,6 +13302,14 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
13290
13302
  initializeBugBear(newClient);
13291
13303
  }
13292
13304
  }, [enabled, config, initializeBugBear]);
13305
+ (0, import_react.useEffect)(() => {
13306
+ if (!client || !isTester || !isQAEnabled) return;
13307
+ const interval = setInterval(() => {
13308
+ refreshThreads();
13309
+ refreshIssueCounts();
13310
+ }, 3e4);
13311
+ return () => clearInterval(interval);
13312
+ }, [client, isTester, isQAEnabled, refreshThreads, refreshIssueCounts]);
13293
13313
  const currentAssignment = assignments.find(
13294
13314
  (a) => a.status === "in_progress"
13295
13315
  ) || assignments.find(
@@ -13329,6 +13349,9 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
13329
13349
  refreshTesterStatus,
13330
13350
  updateTesterProfile,
13331
13351
  refreshTesterInfo,
13352
+ // Issue tracking
13353
+ issueCounts,
13354
+ refreshIssueCounts,
13332
13355
  dashboardUrl: config.dashboardUrl,
13333
13356
  onError: config.onError
13334
13357
  }
@@ -13338,8 +13361,8 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
13338
13361
  }
13339
13362
 
13340
13363
  // src/BugBearButton.tsx
13341
- var import_react16 = __toESM(require("react"));
13342
- var import_react_native15 = require("react-native");
13364
+ var import_react18 = __toESM(require("react"));
13365
+ var import_react_native17 = require("react-native");
13343
13366
 
13344
13367
  // src/widget/logo.ts
13345
13368
  var BUGBEAR_LOGO_BASE64 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAJhlWElmTU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUAAAABAAAARgEoAAMAAAABAAIAAIdpAAQAAAABAAAATgAAAAAAAABIAAAAAQAAAEgAAAABAASQBAACAAAAFAAAAISgAQADAAAAAQABAACgAgAEAAAAAQAAAGCgAwAEAAAAAQAAAGAAAAAAMjAyNjowMToyNCAxNjoyMTozOABbbVCuAAAACXBIWXMAAAsTAAALEwEAmpwYAAACo2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpJcHRjNHhtcEV4dD0iaHR0cDovL2lwdGMub3JnL3N0ZC9JcHRjNHhtcEV4dC8yMDA4LTAyLTI5LyIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIj4KICAgICAgICAgPElwdGM0eG1wRXh0OkRpZ2l0YWxTb3VyY2VUeXBlPmh0dHA6Ly9jdi5pcHRjLm9yZy9uZXdzY29kZXMvZGlnaXRhbHNvdXJjZXR5cGUvdHJhaW5lZEFsZ29yaXRobWljTWVkaWE8L0lwdGM0eG1wRXh0OkRpZ2l0YWxTb3VyY2VUeXBlPgogICAgICAgICA8SXB0YzR4bXBFeHQ6RGlnSW1hZ2VHVUlEPmZjNzJlN2Q2LTYyYTEtNDE1ZS04MjY5LWM2NjA4MjY0OWRiMDwvSXB0YzR4bXBFeHQ6RGlnSW1hZ2VHVUlEPgogICAgICAgICA8eG1wOkNyZWF0ZURhdGU+MjAyNi0wMS0yNFQxNjoyMTozODwveG1wOkNyZWF0ZURhdGU+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+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";
@@ -13560,10 +13583,11 @@ var templateInfo = {
13560
13583
  var import_react3 = __toESM(require("react"));
13561
13584
  var import_react_native3 = require("react-native");
13562
13585
  function HomeScreen({ nav }) {
13563
- const { assignments, unreadCount, threads, refreshAssignments, refreshThreads, dashboardUrl } = useBugBear();
13586
+ const { assignments, unreadCount, threads, refreshAssignments, refreshThreads, issueCounts, refreshIssueCounts, dashboardUrl } = useBugBear();
13564
13587
  (0, import_react3.useEffect)(() => {
13565
13588
  refreshAssignments();
13566
13589
  refreshThreads();
13590
+ refreshIssueCounts();
13567
13591
  }, []);
13568
13592
  const pendingAssignments = assignments.filter((a) => a.status === "pending" || a.status === "in_progress");
13569
13593
  const pendingCount = pendingAssignments.length;
@@ -13629,6 +13653,33 @@ function HomeScreen({ nav }) {
13629
13653
  /* @__PURE__ */ import_react3.default.createElement(import_react_native3.Text, { style: styles.actionIcon }, "\u{1F4AC}"),
13630
13654
  /* @__PURE__ */ import_react3.default.createElement(import_react_native3.Text, { style: styles.actionLabel }, "Messages"),
13631
13655
  unreadCount > 0 && /* @__PURE__ */ import_react3.default.createElement(import_react_native3.View, { style: [styles.actionBadge, styles.actionBadgeMsg] }, /* @__PURE__ */ import_react3.default.createElement(import_react_native3.Text, { style: styles.actionBadgeText }, unreadCount))
13656
+ )), /* @__PURE__ */ import_react3.default.createElement(import_react_native3.View, { style: styles.issueGrid }, /* @__PURE__ */ import_react3.default.createElement(
13657
+ import_react_native3.TouchableOpacity,
13658
+ {
13659
+ style: [styles.issueCard, styles.issueCardOpen],
13660
+ onPress: () => nav.push({ name: "ISSUE_LIST", category: "open" }),
13661
+ activeOpacity: 0.7
13662
+ },
13663
+ /* @__PURE__ */ import_react3.default.createElement(import_react_native3.Text, { style: styles.issueCountOpen }, issueCounts.open),
13664
+ /* @__PURE__ */ import_react3.default.createElement(import_react_native3.Text, { style: styles.issueLabel }, "Open")
13665
+ ), /* @__PURE__ */ import_react3.default.createElement(
13666
+ import_react_native3.TouchableOpacity,
13667
+ {
13668
+ style: [styles.issueCard, styles.issueCardDone],
13669
+ onPress: () => nav.push({ name: "ISSUE_LIST", category: "done" }),
13670
+ activeOpacity: 0.7
13671
+ },
13672
+ /* @__PURE__ */ import_react3.default.createElement(import_react_native3.Text, { style: styles.issueCountDone }, issueCounts.done),
13673
+ /* @__PURE__ */ import_react3.default.createElement(import_react_native3.Text, { style: styles.issueLabel }, "Done")
13674
+ ), /* @__PURE__ */ import_react3.default.createElement(
13675
+ import_react_native3.TouchableOpacity,
13676
+ {
13677
+ style: [styles.issueCard, styles.issueCardReopened],
13678
+ onPress: () => nav.push({ name: "ISSUE_LIST", category: "reopened" }),
13679
+ activeOpacity: 0.7
13680
+ },
13681
+ /* @__PURE__ */ import_react3.default.createElement(import_react_native3.Text, { style: styles.issueCountReopened }, issueCounts.reopened),
13682
+ /* @__PURE__ */ import_react3.default.createElement(import_react_native3.Text, { style: styles.issueLabel }, "Reopened")
13632
13683
  )), totalTests > 0 && /* @__PURE__ */ import_react3.default.createElement(import_react_native3.View, { style: styles.progressSection }, /* @__PURE__ */ import_react3.default.createElement(import_react_native3.View, { style: styles.progressBar }, /* @__PURE__ */ import_react3.default.createElement(import_react_native3.View, { style: [styles.progressFill, { width: `${Math.round(completedCount / totalTests * 100)}%` }] })), /* @__PURE__ */ import_react3.default.createElement(import_react_native3.Text, { style: styles.progressText }, completedCount, "/", totalTests, " tests completed")), dashboardUrl && /* @__PURE__ */ import_react3.default.createElement(
13633
13684
  import_react_native3.TouchableOpacity,
13634
13685
  {
@@ -13646,6 +13697,7 @@ function HomeScreen({ nav }) {
13646
13697
  onPress: () => {
13647
13698
  refreshAssignments();
13648
13699
  refreshThreads();
13700
+ refreshIssueCounts();
13649
13701
  }
13650
13702
  },
13651
13703
  /* @__PURE__ */ import_react3.default.createElement(import_react_native3.Text, { style: styles.refreshText }, "\u21BB Refresh")
@@ -13816,6 +13868,54 @@ var styles = import_react_native3.StyleSheet.create({
13816
13868
  color: colors.textMuted,
13817
13869
  marginLeft: 8
13818
13870
  },
13871
+ issueGrid: {
13872
+ flexDirection: "row",
13873
+ gap: 10,
13874
+ marginBottom: 20
13875
+ },
13876
+ issueCard: {
13877
+ flex: 1,
13878
+ backgroundColor: colors.card,
13879
+ borderWidth: 1,
13880
+ borderColor: colors.border,
13881
+ borderRadius: 10,
13882
+ paddingVertical: 12,
13883
+ paddingHorizontal: 8,
13884
+ alignItems: "center"
13885
+ },
13886
+ issueCardOpen: {
13887
+ borderTopWidth: 3,
13888
+ borderTopColor: "#f97316"
13889
+ },
13890
+ issueCardDone: {
13891
+ borderTopWidth: 3,
13892
+ borderTopColor: "#22c55e"
13893
+ },
13894
+ issueCardReopened: {
13895
+ borderTopWidth: 3,
13896
+ borderTopColor: "#ef4444"
13897
+ },
13898
+ issueCountOpen: {
13899
+ fontSize: 22,
13900
+ fontWeight: "700",
13901
+ color: "#f97316"
13902
+ },
13903
+ issueCountDone: {
13904
+ fontSize: 22,
13905
+ fontWeight: "700",
13906
+ color: "#22c55e"
13907
+ },
13908
+ issueCountReopened: {
13909
+ fontSize: 22,
13910
+ fontWeight: "700",
13911
+ color: "#ef4444"
13912
+ },
13913
+ issueLabel: {
13914
+ fontSize: 11,
13915
+ fontWeight: "600",
13916
+ color: colors.textSecondary,
13917
+ marginTop: 2
13918
+ },
13819
13919
  refreshButton: {
13820
13920
  alignItems: "center",
13821
13921
  paddingVertical: 8
@@ -14171,10 +14271,16 @@ function TestListScreen({ nav }) {
14171
14271
  const filterAssignment = (a) => {
14172
14272
  if (roleFilter && a.testCase.role?.id !== roleFilter) return false;
14173
14273
  if (filter === "pending") return a.status === "pending" || a.status === "in_progress";
14174
- if (filter === "completed") return a.status === "passed" || a.status === "failed";
14274
+ if (filter === "done") return a.status === "passed";
14275
+ if (filter === "reopened") return a.status === "failed";
14175
14276
  return true;
14176
14277
  };
14177
- return /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, null, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.filterBar }, ["all", "pending", "completed"].map((f) => /* @__PURE__ */ import_react5.default.createElement(import_react_native5.TouchableOpacity, { key: f, style: [styles3.filterBtn, filter === f && styles3.filterBtnActive], onPress: () => setFilter(f) }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: [styles3.filterBtnText, filter === f && styles3.filterBtnTextActive] }, f === "all" ? `All (${assignments.length})` : f === "pending" ? `To Do (${assignments.filter((a) => a.status === "pending" || a.status === "in_progress").length})` : `Done (${assignments.filter((a) => a.status === "passed" || a.status === "failed").length})`)))), availableRoles.length >= 2 && /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.roleSection }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, style: styles3.roleBar }, /* @__PURE__ */ import_react5.default.createElement(
14278
+ return /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, null, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.filterBar }, [
14279
+ { key: "all", label: "All", count: assignments.length },
14280
+ { key: "pending", label: "To Do", count: assignments.filter((a) => a.status === "pending" || a.status === "in_progress").length },
14281
+ { key: "done", label: "Done", count: assignments.filter((a) => a.status === "passed").length },
14282
+ { key: "reopened", label: "Re Opened", count: assignments.filter((a) => a.status === "failed").length }
14283
+ ].map((f) => /* @__PURE__ */ import_react5.default.createElement(import_react_native5.TouchableOpacity, { key: f.key, style: [styles3.filterBtn, filter === f.key && styles3.filterBtnActive], onPress: () => setFilter(f.key) }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: [styles3.filterBtnText, filter === f.key && styles3.filterBtnTextActive] }, f.label, " (", f.count, ")")))), availableRoles.length >= 2 && /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.roleSection }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, style: styles3.roleBar }, /* @__PURE__ */ import_react5.default.createElement(
14178
14284
  import_react_native5.TouchableOpacity,
14179
14285
  {
14180
14286
  style: [styles3.roleBtn, !roleFilter && styles3.roleBtnActive],
@@ -14212,7 +14318,19 @@ function TestListScreen({ nav }) {
14212
14318
  onPress: () => nav.push({ name: "TEST_DETAIL", testId: assignment.id })
14213
14319
  },
14214
14320
  /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.testBadge }, badge.icon),
14215
- /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.testInfo }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.testTitle, numberOfLines: 1 }, assignment.testCase.title), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.testMetaRow }, assignment.isVerification && /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.retestTag }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.retestTagText }, "Retest")), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.testMeta }, assignment.testCase.testKey, " \xB7 ", assignment.testCase.priority), assignment.testCase.role && /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.roleBadgeRow }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.testMeta }, " \xB7 "), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: [styles3.roleBadgeDot, { backgroundColor: assignment.testCase.role.color }] }), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: [styles3.testMeta, { color: assignment.testCase.role.color, fontWeight: "500" }] }, assignment.testCase.role.name))))
14321
+ /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.testInfo }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.testTitle, numberOfLines: 1 }, assignment.testCase.title), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.testMetaRow }, assignment.isVerification && /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.retestTag }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.retestTagText }, "Retest")), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.testMeta }, assignment.testCase.testKey, " \xB7 ", assignment.testCase.priority), assignment.testCase.role && /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.roleBadgeRow }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.testMeta }, " \xB7 "), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: [styles3.roleBadgeDot, { backgroundColor: assignment.testCase.role.color }] }), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: [styles3.testMeta, { color: assignment.testCase.role.color, fontWeight: "500" }] }, assignment.testCase.role.name)))),
14322
+ /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: [
14323
+ styles3.statusPill,
14324
+ {
14325
+ backgroundColor: assignment.status === "passed" ? "#14532d" : assignment.status === "failed" ? "#450a0a" : assignment.status === "in_progress" ? "#172554" : "#27272a",
14326
+ borderColor: assignment.status === "passed" ? "#166534" : assignment.status === "failed" ? "#7f1d1d" : assignment.status === "in_progress" ? "#1e3a5f" : "#3f3f46"
14327
+ }
14328
+ ] }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: [
14329
+ styles3.statusPillText,
14330
+ {
14331
+ color: assignment.status === "passed" ? "#4ade80" : assignment.status === "failed" ? "#f87171" : assignment.status === "in_progress" ? "#60a5fa" : "#d4d4d8"
14332
+ }
14333
+ ] }, badge.label))
14216
14334
  );
14217
14335
  }));
14218
14336
  }), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.TouchableOpacity, { style: styles3.refreshBtn, onPress: refreshAssignments }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.refreshText }, "\u21BB", " Refresh")));
@@ -14250,6 +14368,8 @@ var styles3 = import_react_native5.StyleSheet.create({
14250
14368
  retestTag: { backgroundColor: "#422006", borderWidth: 1, borderColor: "#854d0e", borderRadius: 4, paddingHorizontal: 5, paddingVertical: 1 },
14251
14369
  retestTagText: { fontSize: 10, fontWeight: "600", color: "#fbbf24" },
14252
14370
  testMeta: { fontSize: 11, color: colors.textDim },
14371
+ statusPill: { paddingHorizontal: 8, paddingVertical: 3, borderRadius: 6, borderWidth: 1, marginLeft: 8 },
14372
+ statusPillText: { fontSize: 10, fontWeight: "600" },
14253
14373
  refreshBtn: { alignItems: "center", paddingVertical: 12 },
14254
14374
  refreshText: { fontSize: 13, color: colors.blue }
14255
14375
  });
@@ -15134,9 +15254,311 @@ var styles12 = import_react_native14.StyleSheet.create({
15134
15254
  platformTextActive: { color: colors.blueLight }
15135
15255
  });
15136
15256
 
15257
+ // src/widget/screens/IssueListScreen.tsx
15258
+ var import_react16 = __toESM(require("react"));
15259
+ var import_react_native15 = require("react-native");
15260
+ var CATEGORY_CONFIG = {
15261
+ open: { label: "Open Issues", accent: "#f97316", emptyIcon: "\u2705", emptyText: "No open issues" },
15262
+ done: { label: "Done", accent: "#22c55e", emptyIcon: "\u{1F389}", emptyText: "No completed issues yet" },
15263
+ reopened: { label: "Reopened", accent: "#ef4444", emptyIcon: "\u{1F44D}", emptyText: "No reopened issues" }
15264
+ };
15265
+ var SEVERITY_COLORS = {
15266
+ critical: "#ef4444",
15267
+ high: "#f97316",
15268
+ medium: "#eab308",
15269
+ low: "#71717a"
15270
+ };
15271
+ function IssueListScreen({ nav, category }) {
15272
+ const { client } = useBugBear();
15273
+ const [issues, setIssues] = (0, import_react16.useState)([]);
15274
+ const [loading, setLoading] = (0, import_react16.useState)(true);
15275
+ const config = CATEGORY_CONFIG[category];
15276
+ (0, import_react16.useEffect)(() => {
15277
+ let cancelled = false;
15278
+ setLoading(true);
15279
+ (async () => {
15280
+ if (!client) return;
15281
+ const data = await client.getIssues(category);
15282
+ if (!cancelled) {
15283
+ setIssues(data);
15284
+ setLoading(false);
15285
+ }
15286
+ })();
15287
+ return () => {
15288
+ cancelled = true;
15289
+ };
15290
+ }, [client, category]);
15291
+ if (loading) {
15292
+ return /* @__PURE__ */ import_react16.default.createElement(import_react_native15.View, { style: styles13.emptyContainer }, /* @__PURE__ */ import_react16.default.createElement(import_react_native15.ActivityIndicator, { size: "small", color: colors.textMuted }), /* @__PURE__ */ import_react16.default.createElement(import_react_native15.Text, { style: styles13.emptyText }, "Loading..."));
15293
+ }
15294
+ if (issues.length === 0) {
15295
+ return /* @__PURE__ */ import_react16.default.createElement(import_react_native15.View, { style: styles13.emptyContainer }, /* @__PURE__ */ import_react16.default.createElement(import_react_native15.Text, { style: styles13.emptyIcon }, config.emptyIcon), /* @__PURE__ */ import_react16.default.createElement(import_react_native15.Text, { style: styles13.emptyText }, config.emptyText));
15296
+ }
15297
+ return /* @__PURE__ */ import_react16.default.createElement(import_react_native15.View, null, issues.map((issue) => /* @__PURE__ */ import_react16.default.createElement(
15298
+ import_react_native15.TouchableOpacity,
15299
+ {
15300
+ key: issue.id,
15301
+ style: styles13.issueCard,
15302
+ onPress: () => nav.push({ name: "ISSUE_DETAIL", issue }),
15303
+ activeOpacity: 0.7
15304
+ },
15305
+ /* @__PURE__ */ import_react16.default.createElement(import_react_native15.View, { style: styles13.topRow }, issue.severity && /* @__PURE__ */ import_react16.default.createElement(import_react_native15.View, { style: [styles13.severityDot, { backgroundColor: SEVERITY_COLORS[issue.severity] || colors.textDim }] }), /* @__PURE__ */ import_react16.default.createElement(import_react_native15.Text, { style: styles13.issueTitle, numberOfLines: 1 }, issue.title)),
15306
+ /* @__PURE__ */ import_react16.default.createElement(import_react_native15.View, { style: styles13.bottomRow }, issue.route && /* @__PURE__ */ import_react16.default.createElement(import_react_native15.Text, { style: styles13.routeText, numberOfLines: 1 }, issue.route), /* @__PURE__ */ import_react16.default.createElement(import_react_native15.Text, { style: styles13.timeText }, formatRelativeTime(issue.updatedAt))),
15307
+ category === "done" && issue.verifiedByName && /* @__PURE__ */ import_react16.default.createElement(import_react_native15.View, { style: styles13.verifiedBadge }, /* @__PURE__ */ import_react16.default.createElement(import_react_native15.Text, { style: styles13.verifiedBadgeText }, "\u2714", " Verified by ", issue.verifiedByName)),
15308
+ category === "reopened" && issue.originalBugTitle && /* @__PURE__ */ import_react16.default.createElement(import_react_native15.View, { style: styles13.reopenedBadge }, /* @__PURE__ */ import_react16.default.createElement(import_react_native15.Text, { style: styles13.reopenedBadgeText, numberOfLines: 1 }, "\u{1F504}", " Retest of: ", issue.originalBugTitle))
15309
+ )));
15310
+ }
15311
+ var styles13 = import_react_native15.StyleSheet.create({
15312
+ emptyContainer: {
15313
+ alignItems: "center",
15314
+ paddingVertical: 40
15315
+ },
15316
+ emptyIcon: {
15317
+ fontSize: 36,
15318
+ marginBottom: 8
15319
+ },
15320
+ emptyText: {
15321
+ color: colors.textMuted,
15322
+ fontSize: 14,
15323
+ marginTop: 4
15324
+ },
15325
+ issueCard: {
15326
+ backgroundColor: colors.card,
15327
+ borderWidth: 1,
15328
+ borderColor: colors.border,
15329
+ borderRadius: 10,
15330
+ padding: 14,
15331
+ marginBottom: 8
15332
+ },
15333
+ topRow: {
15334
+ flexDirection: "row",
15335
+ alignItems: "flex-start",
15336
+ gap: 8
15337
+ },
15338
+ severityDot: {
15339
+ width: 8,
15340
+ height: 8,
15341
+ borderRadius: 4,
15342
+ marginTop: 5
15343
+ },
15344
+ issueTitle: {
15345
+ fontSize: 13,
15346
+ fontWeight: "600",
15347
+ color: colors.textPrimary,
15348
+ flex: 1
15349
+ },
15350
+ bottomRow: {
15351
+ flexDirection: "row",
15352
+ justifyContent: "space-between",
15353
+ marginTop: 6
15354
+ },
15355
+ routeText: {
15356
+ fontSize: 11,
15357
+ color: colors.textDim,
15358
+ maxWidth: "60%"
15359
+ },
15360
+ timeText: {
15361
+ fontSize: 11,
15362
+ color: colors.textDim,
15363
+ marginLeft: "auto"
15364
+ },
15365
+ verifiedBadge: {
15366
+ flexDirection: "row",
15367
+ alignItems: "center",
15368
+ backgroundColor: "#14532d",
15369
+ borderWidth: 1,
15370
+ borderColor: "#166534",
15371
+ borderRadius: 6,
15372
+ paddingHorizontal: 8,
15373
+ paddingVertical: 2,
15374
+ marginTop: 6,
15375
+ alignSelf: "flex-start"
15376
+ },
15377
+ verifiedBadgeText: {
15378
+ fontSize: 10,
15379
+ fontWeight: "600",
15380
+ color: "#4ade80"
15381
+ },
15382
+ reopenedBadge: {
15383
+ flexDirection: "row",
15384
+ alignItems: "center",
15385
+ backgroundColor: "#422006",
15386
+ borderWidth: 1,
15387
+ borderColor: "#854d0e",
15388
+ borderRadius: 6,
15389
+ paddingHorizontal: 8,
15390
+ paddingVertical: 2,
15391
+ marginTop: 6,
15392
+ alignSelf: "flex-start"
15393
+ },
15394
+ reopenedBadgeText: {
15395
+ fontSize: 10,
15396
+ fontWeight: "600",
15397
+ color: "#fbbf24"
15398
+ }
15399
+ });
15400
+
15401
+ // src/widget/screens/IssueDetailScreen.tsx
15402
+ var import_react17 = __toESM(require("react"));
15403
+ var import_react_native16 = require("react-native");
15404
+ var STATUS_LABELS = {
15405
+ new: { label: "New", bg: "#1e3a5f", color: "#60a5fa" },
15406
+ triaging: { label: "Triaging", bg: "#1e3a5f", color: "#60a5fa" },
15407
+ confirmed: { label: "Confirmed", bg: "#422006", color: "#fbbf24" },
15408
+ in_progress: { label: "In Progress", bg: "#1e3a5f", color: "#60a5fa" },
15409
+ fixed: { label: "Fixed", bg: "#14532d", color: "#4ade80" },
15410
+ ready_to_test: { label: "Ready to Test", bg: "#422006", color: "#fbbf24" },
15411
+ verified: { label: "Verified", bg: "#14532d", color: "#4ade80" },
15412
+ resolved: { label: "Resolved", bg: "#14532d", color: "#4ade80" },
15413
+ reviewed: { label: "Reviewed", bg: "#14532d", color: "#4ade80" },
15414
+ closed: { label: "Closed", bg: "#27272a", color: "#71717a" },
15415
+ wont_fix: { label: "Won't Fix", bg: "#27272a", color: "#71717a" },
15416
+ duplicate: { label: "Duplicate", bg: "#27272a", color: "#71717a" }
15417
+ };
15418
+ var SEVERITY_CONFIG = {
15419
+ critical: { label: "Critical", color: "#ef4444", bg: "#7f1d1d" },
15420
+ high: { label: "High", color: "#f97316", bg: "#431407" },
15421
+ medium: { label: "Medium", color: "#eab308", bg: "#422006" },
15422
+ low: { label: "Low", color: "#71717a", bg: "#27272a" }
15423
+ };
15424
+ function IssueDetailScreen({ nav, issue }) {
15425
+ const statusConfig = STATUS_LABELS[issue.status] || { label: issue.status, bg: "#27272a", color: "#a1a1aa" };
15426
+ const severityConfig = issue.severity ? SEVERITY_CONFIG[issue.severity] : null;
15427
+ return /* @__PURE__ */ import_react17.default.createElement(import_react_native16.View, null, /* @__PURE__ */ import_react17.default.createElement(import_react_native16.View, { style: styles14.badgeRow }, /* @__PURE__ */ import_react17.default.createElement(import_react_native16.View, { style: [styles14.badge, { backgroundColor: statusConfig.bg }] }, /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: [styles14.badgeText, { color: statusConfig.color }] }, statusConfig.label)), severityConfig && /* @__PURE__ */ import_react17.default.createElement(import_react_native16.View, { style: [styles14.badge, { backgroundColor: severityConfig.bg }] }, /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: [styles14.badgeText, { color: severityConfig.color }] }, severityConfig.label))), /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: styles14.title }, issue.title), issue.route && /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: styles14.route }, issue.route), issue.description && /* @__PURE__ */ import_react17.default.createElement(import_react_native16.View, { style: styles14.descriptionCard }, /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: styles14.descriptionText }, issue.description)), issue.verifiedByName && /* @__PURE__ */ import_react17.default.createElement(import_react_native16.View, { style: styles14.verifiedCard }, /* @__PURE__ */ import_react17.default.createElement(import_react_native16.View, { style: styles14.verifiedHeader }, /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: styles14.verifiedIcon }, "\u2705"), /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: styles14.verifiedTitle }, "Retesting Proof")), /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: styles14.verifiedBody }, "Verified by ", issue.verifiedByName, issue.verifiedAt && ` on ${new Date(issue.verifiedAt).toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" })}`)), issue.originalBugTitle && /* @__PURE__ */ import_react17.default.createElement(import_react_native16.View, { style: styles14.originalBugCard }, /* @__PURE__ */ import_react17.default.createElement(import_react_native16.View, { style: styles14.originalBugHeader }, /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: styles14.originalBugIcon }, "\u{1F504}"), /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: styles14.originalBugTitle }, "Original Bug")), /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: styles14.originalBugBody }, "Retest of: ", issue.originalBugTitle)), issue.screenshotUrls && issue.screenshotUrls.length > 0 && /* @__PURE__ */ import_react17.default.createElement(import_react_native16.View, { style: styles14.screenshotSection }, /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: styles14.screenshotLabel }, "Screenshots (", issue.screenshotUrls.length, ")"), /* @__PURE__ */ import_react17.default.createElement(import_react_native16.View, { style: styles14.screenshotRow }, issue.screenshotUrls.map((url, i) => /* @__PURE__ */ import_react17.default.createElement(import_react_native16.TouchableOpacity, { key: i, onPress: () => import_react_native16.Linking.openURL(url), activeOpacity: 0.7 }, /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Image, { source: { uri: url }, style: styles14.screenshotThumb }))))), /* @__PURE__ */ import_react17.default.createElement(import_react_native16.View, { style: styles14.metaSection }, issue.reporterName && /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: styles14.metaText }, "Reported by ", issue.reporterName), /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: styles14.metaTextSmall }, "Created ", formatRelativeTime(issue.createdAt), " ", "\xB7", " Updated ", formatRelativeTime(issue.updatedAt))));
15428
+ }
15429
+ var styles14 = import_react_native16.StyleSheet.create({
15430
+ badgeRow: {
15431
+ flexDirection: "row",
15432
+ gap: 8,
15433
+ flexWrap: "wrap",
15434
+ marginBottom: 12
15435
+ },
15436
+ badge: {
15437
+ paddingHorizontal: 10,
15438
+ paddingVertical: 3,
15439
+ borderRadius: 6
15440
+ },
15441
+ badgeText: {
15442
+ fontSize: 11,
15443
+ fontWeight: "600"
15444
+ },
15445
+ title: {
15446
+ fontSize: 16,
15447
+ fontWeight: "700",
15448
+ color: colors.textPrimary,
15449
+ marginBottom: 8,
15450
+ lineHeight: 21
15451
+ },
15452
+ route: {
15453
+ fontSize: 12,
15454
+ color: colors.textDim,
15455
+ marginBottom: 12
15456
+ },
15457
+ descriptionCard: {
15458
+ backgroundColor: colors.card,
15459
+ borderWidth: 1,
15460
+ borderColor: colors.border,
15461
+ borderRadius: 8,
15462
+ padding: 12,
15463
+ marginBottom: 12
15464
+ },
15465
+ descriptionText: {
15466
+ fontSize: 13,
15467
+ color: colors.textSecondary,
15468
+ lineHeight: 19
15469
+ },
15470
+ verifiedCard: {
15471
+ backgroundColor: "#14532d",
15472
+ borderWidth: 1,
15473
+ borderColor: "#166534",
15474
+ borderRadius: 8,
15475
+ padding: 12,
15476
+ marginBottom: 12
15477
+ },
15478
+ verifiedHeader: {
15479
+ flexDirection: "row",
15480
+ alignItems: "center",
15481
+ gap: 8,
15482
+ marginBottom: 4
15483
+ },
15484
+ verifiedIcon: {
15485
+ fontSize: 16
15486
+ },
15487
+ verifiedTitle: {
15488
+ fontSize: 13,
15489
+ fontWeight: "600",
15490
+ color: "#4ade80"
15491
+ },
15492
+ verifiedBody: {
15493
+ fontSize: 12,
15494
+ color: "#86efac"
15495
+ },
15496
+ originalBugCard: {
15497
+ backgroundColor: "#422006",
15498
+ borderWidth: 1,
15499
+ borderColor: "#854d0e",
15500
+ borderRadius: 8,
15501
+ padding: 12,
15502
+ marginBottom: 12
15503
+ },
15504
+ originalBugHeader: {
15505
+ flexDirection: "row",
15506
+ alignItems: "center",
15507
+ gap: 8,
15508
+ marginBottom: 4
15509
+ },
15510
+ originalBugIcon: {
15511
+ fontSize: 16
15512
+ },
15513
+ originalBugTitle: {
15514
+ fontSize: 13,
15515
+ fontWeight: "600",
15516
+ color: "#fbbf24"
15517
+ },
15518
+ originalBugBody: {
15519
+ fontSize: 12,
15520
+ color: "#fde68a"
15521
+ },
15522
+ screenshotSection: {
15523
+ marginBottom: 12
15524
+ },
15525
+ screenshotLabel: {
15526
+ fontSize: 12,
15527
+ fontWeight: "600",
15528
+ color: colors.textMuted,
15529
+ marginBottom: 8
15530
+ },
15531
+ screenshotRow: {
15532
+ flexDirection: "row",
15533
+ gap: 8
15534
+ },
15535
+ screenshotThumb: {
15536
+ width: 80,
15537
+ height: 60,
15538
+ borderRadius: 6,
15539
+ borderWidth: 1,
15540
+ borderColor: colors.border
15541
+ },
15542
+ metaSection: {
15543
+ borderTopWidth: 1,
15544
+ borderTopColor: colors.border,
15545
+ paddingTop: 12,
15546
+ marginTop: 4
15547
+ },
15548
+ metaText: {
15549
+ fontSize: 12,
15550
+ color: colors.textDim,
15551
+ marginBottom: 4
15552
+ },
15553
+ metaTextSmall: {
15554
+ fontSize: 11,
15555
+ color: colors.textDim
15556
+ }
15557
+ });
15558
+
15137
15559
  // src/BugBearButton.tsx
15138
- var screenWidth = import_react_native15.Dimensions.get("window").width;
15139
- var screenHeight = import_react_native15.Dimensions.get("window").height;
15560
+ var screenWidth = import_react_native17.Dimensions.get("window").width;
15561
+ var screenHeight = import_react_native17.Dimensions.get("window").height;
15140
15562
  function BugBearButton({
15141
15563
  position = "bottom-right",
15142
15564
  buttonStyle,
@@ -15148,7 +15570,7 @@ function BugBearButton({
15148
15570
  }) {
15149
15571
  const { shouldShowWidget, testerInfo, isLoading, unreadCount, assignments } = useBugBear();
15150
15572
  const { currentScreen, canGoBack, push, pop, replace, reset } = useNavigation();
15151
- const [modalVisible, setModalVisible] = (0, import_react16.useState)(false);
15573
+ const [modalVisible, setModalVisible] = (0, import_react18.useState)(false);
15152
15574
  const getInitialPosition = () => {
15153
15575
  const buttonSize = 56;
15154
15576
  const margin = 16;
@@ -15160,10 +15582,10 @@ function BugBearButton({
15160
15582
  return { x, y };
15161
15583
  };
15162
15584
  const initialPos = getInitialPosition();
15163
- const pan = (0, import_react16.useRef)(new import_react_native15.Animated.ValueXY(initialPos)).current;
15164
- const isDragging = (0, import_react16.useRef)(false);
15165
- const panResponder = (0, import_react16.useRef)(
15166
- import_react_native15.PanResponder.create({
15585
+ const pan = (0, import_react18.useRef)(new import_react_native17.Animated.ValueXY(initialPos)).current;
15586
+ const isDragging = (0, import_react18.useRef)(false);
15587
+ const panResponder = (0, import_react18.useRef)(
15588
+ import_react_native17.PanResponder.create({
15167
15589
  onStartShouldSetPanResponder: () => draggable,
15168
15590
  onMoveShouldSetPanResponder: (_, gs) => draggable && (Math.abs(gs.dx) > 5 || Math.abs(gs.dy) > 5),
15169
15591
  onPanResponderGrant: () => {
@@ -15178,7 +15600,7 @@ function BugBearButton({
15178
15600
  if (Math.abs(gs.dx) > 5 || Math.abs(gs.dy) > 5) {
15179
15601
  isDragging.current = true;
15180
15602
  }
15181
- import_react_native15.Animated.event(
15603
+ import_react_native17.Animated.event(
15182
15604
  [null, { dx: pan.x, dy: pan.y }],
15183
15605
  { useNativeDriver: false }
15184
15606
  )(_, gs);
@@ -15191,7 +15613,7 @@ function BugBearButton({
15191
15613
  const margin = 16;
15192
15614
  const snapX = currentX < screenWidth / 2 ? margin : screenWidth - buttonSize - margin;
15193
15615
  const snapY = Math.max(minY, Math.min(currentY, screenHeight - maxYOffset));
15194
- import_react_native15.Animated.spring(pan, {
15616
+ import_react_native17.Animated.spring(pan, {
15195
15617
  toValue: { x: snapX, y: snapY },
15196
15618
  useNativeDriver: false,
15197
15619
  friction: 7,
@@ -15227,6 +15649,10 @@ function BugBearButton({
15227
15649
  return currentScreen.thread.subject || "Thread";
15228
15650
  case "COMPOSE_MESSAGE":
15229
15651
  return "New Message";
15652
+ case "ISSUE_LIST":
15653
+ return currentScreen.category === "open" ? "Open Issues" : currentScreen.category === "done" ? "Done" : "Reopened";
15654
+ case "ISSUE_DETAIL":
15655
+ return "Issue Detail";
15230
15656
  case "PROFILE":
15231
15657
  return "Profile";
15232
15658
  default:
@@ -15234,24 +15660,24 @@ function BugBearButton({
15234
15660
  }
15235
15661
  };
15236
15662
  const handleClose = () => {
15237
- import_react_native15.Keyboard.dismiss();
15663
+ import_react_native17.Keyboard.dismiss();
15238
15664
  setModalVisible(false);
15239
15665
  };
15240
15666
  const nav = {
15241
15667
  push: (screen) => {
15242
- import_react_native15.Keyboard.dismiss();
15668
+ import_react_native17.Keyboard.dismiss();
15243
15669
  push(screen);
15244
15670
  },
15245
15671
  pop: () => {
15246
- import_react_native15.Keyboard.dismiss();
15672
+ import_react_native17.Keyboard.dismiss();
15247
15673
  pop();
15248
15674
  },
15249
15675
  replace: (screen) => {
15250
- import_react_native15.Keyboard.dismiss();
15676
+ import_react_native17.Keyboard.dismiss();
15251
15677
  replace(screen);
15252
15678
  },
15253
15679
  reset: () => {
15254
- import_react_native15.Keyboard.dismiss();
15680
+ import_react_native17.Keyboard.dismiss();
15255
15681
  reset();
15256
15682
  },
15257
15683
  canGoBack,
@@ -15260,73 +15686,77 @@ function BugBearButton({
15260
15686
  const renderScreen = () => {
15261
15687
  switch (currentScreen.name) {
15262
15688
  case "HOME":
15263
- return /* @__PURE__ */ import_react16.default.createElement(HomeScreen, { nav });
15689
+ return /* @__PURE__ */ import_react18.default.createElement(HomeScreen, { nav });
15264
15690
  case "TEST_DETAIL":
15265
- return /* @__PURE__ */ import_react16.default.createElement(TestDetailScreen, { testId: currentScreen.testId, nav });
15691
+ return /* @__PURE__ */ import_react18.default.createElement(TestDetailScreen, { testId: currentScreen.testId, nav });
15266
15692
  case "TEST_LIST":
15267
- return /* @__PURE__ */ import_react16.default.createElement(TestListScreen, { nav });
15693
+ return /* @__PURE__ */ import_react18.default.createElement(TestListScreen, { nav });
15268
15694
  case "TEST_FEEDBACK":
15269
- return /* @__PURE__ */ import_react16.default.createElement(TestFeedbackScreen, { status: currentScreen.status, assignmentId: currentScreen.assignmentId, nav });
15695
+ return /* @__PURE__ */ import_react18.default.createElement(TestFeedbackScreen, { status: currentScreen.status, assignmentId: currentScreen.assignmentId, nav });
15270
15696
  case "REPORT":
15271
- return /* @__PURE__ */ import_react16.default.createElement(ReportScreen, { nav, prefill: currentScreen.prefill });
15697
+ return /* @__PURE__ */ import_react18.default.createElement(ReportScreen, { nav, prefill: currentScreen.prefill });
15272
15698
  case "REPORT_SUCCESS":
15273
- return /* @__PURE__ */ import_react16.default.createElement(ReportSuccessScreen, { nav });
15699
+ return /* @__PURE__ */ import_react18.default.createElement(ReportSuccessScreen, { nav });
15274
15700
  case "MESSAGE_LIST":
15275
- return /* @__PURE__ */ import_react16.default.createElement(MessageListScreen, { nav });
15701
+ return /* @__PURE__ */ import_react18.default.createElement(MessageListScreen, { nav });
15276
15702
  case "THREAD_DETAIL":
15277
- return /* @__PURE__ */ import_react16.default.createElement(ThreadDetailScreen, { thread: currentScreen.thread, nav });
15703
+ return /* @__PURE__ */ import_react18.default.createElement(ThreadDetailScreen, { thread: currentScreen.thread, nav });
15278
15704
  case "COMPOSE_MESSAGE":
15279
- return /* @__PURE__ */ import_react16.default.createElement(ComposeMessageScreen, { nav });
15705
+ return /* @__PURE__ */ import_react18.default.createElement(ComposeMessageScreen, { nav });
15706
+ case "ISSUE_LIST":
15707
+ return /* @__PURE__ */ import_react18.default.createElement(IssueListScreen, { nav, category: currentScreen.category });
15708
+ case "ISSUE_DETAIL":
15709
+ return /* @__PURE__ */ import_react18.default.createElement(IssueDetailScreen, { nav, issue: currentScreen.issue });
15280
15710
  case "PROFILE":
15281
- return /* @__PURE__ */ import_react16.default.createElement(ProfileScreen, { nav });
15711
+ return /* @__PURE__ */ import_react18.default.createElement(ProfileScreen, { nav });
15282
15712
  default:
15283
- return /* @__PURE__ */ import_react16.default.createElement(HomeScreen, { nav });
15713
+ return /* @__PURE__ */ import_react18.default.createElement(HomeScreen, { nav });
15284
15714
  }
15285
15715
  };
15286
- return /* @__PURE__ */ import_react16.default.createElement(import_react16.default.Fragment, null, /* @__PURE__ */ import_react16.default.createElement(
15287
- import_react_native15.Animated.View,
15716
+ return /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, null, /* @__PURE__ */ import_react18.default.createElement(
15717
+ import_react_native17.Animated.View,
15288
15718
  {
15289
- style: [styles13.fabContainer, { transform: pan.getTranslateTransform() }, buttonStyle],
15719
+ style: [styles15.fabContainer, { transform: pan.getTranslateTransform() }, buttonStyle],
15290
15720
  ...panResponder.panHandlers
15291
15721
  },
15292
- /* @__PURE__ */ import_react16.default.createElement(
15293
- import_react_native15.TouchableOpacity,
15722
+ /* @__PURE__ */ import_react18.default.createElement(
15723
+ import_react_native17.TouchableOpacity,
15294
15724
  {
15295
- style: styles13.fab,
15725
+ style: styles15.fab,
15296
15726
  onPress: () => setModalVisible(true),
15297
15727
  activeOpacity: draggable ? 1 : 0.7
15298
15728
  },
15299
- /* @__PURE__ */ import_react16.default.createElement(import_react_native15.Image, { source: { uri: BUGBEAR_LOGO_BASE64 }, style: styles13.fabIcon }),
15300
- badgeCount > 0 && /* @__PURE__ */ import_react16.default.createElement(import_react_native15.View, { style: styles13.badge }, /* @__PURE__ */ import_react16.default.createElement(import_react_native15.Text, { style: styles13.badgeText }, badgeCount > 9 ? "9+" : badgeCount))
15729
+ /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Image, { source: { uri: BUGBEAR_LOGO_BASE64 }, style: styles15.fabIcon }),
15730
+ badgeCount > 0 && /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles15.badge }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles15.badgeText }, badgeCount > 9 ? "9+" : badgeCount))
15301
15731
  )
15302
- ), /* @__PURE__ */ import_react16.default.createElement(
15303
- import_react_native15.Modal,
15732
+ ), /* @__PURE__ */ import_react18.default.createElement(
15733
+ import_react_native17.Modal,
15304
15734
  {
15305
15735
  visible: modalVisible,
15306
15736
  animationType: "slide",
15307
15737
  transparent: true,
15308
15738
  onRequestClose: handleClose
15309
15739
  },
15310
- /* @__PURE__ */ import_react16.default.createElement(
15311
- import_react_native15.KeyboardAvoidingView,
15740
+ /* @__PURE__ */ import_react18.default.createElement(
15741
+ import_react_native17.KeyboardAvoidingView,
15312
15742
  {
15313
- behavior: import_react_native15.Platform.OS === "ios" ? "padding" : "height",
15314
- style: styles13.modalOverlay
15743
+ behavior: import_react_native17.Platform.OS === "ios" ? "padding" : "height",
15744
+ style: styles15.modalOverlay
15315
15745
  },
15316
- /* @__PURE__ */ import_react16.default.createElement(import_react_native15.View, { style: styles13.modalContainer }, /* @__PURE__ */ import_react16.default.createElement(import_react_native15.View, { style: styles13.header }, /* @__PURE__ */ import_react16.default.createElement(import_react_native15.View, { style: styles13.headerLeft }, canGoBack ? /* @__PURE__ */ import_react16.default.createElement(import_react_native15.View, { style: styles13.headerNavRow }, /* @__PURE__ */ import_react16.default.createElement(import_react_native15.TouchableOpacity, { onPress: () => nav.pop(), style: styles13.backButton }, /* @__PURE__ */ import_react16.default.createElement(import_react_native15.Text, { style: styles13.backText }, "\u2190 Back")), /* @__PURE__ */ import_react16.default.createElement(import_react_native15.TouchableOpacity, { onPress: () => nav.reset(), style: styles13.homeButton }, /* @__PURE__ */ import_react16.default.createElement(import_react_native15.Text, { style: styles13.homeText }, "\u{1F3E0}"))) : /* @__PURE__ */ import_react16.default.createElement(import_react_native15.View, { style: styles13.headerTitleRow }, /* @__PURE__ */ import_react16.default.createElement(import_react_native15.Text, { style: styles13.headerTitle }, "BugBear"), testerInfo && /* @__PURE__ */ import_react16.default.createElement(import_react_native15.TouchableOpacity, { onPress: () => push({ name: "PROFILE" }) }, /* @__PURE__ */ import_react16.default.createElement(import_react_native15.Text, { style: styles13.headerName }, testerInfo.name, " \u270E")))), getHeaderTitle() ? /* @__PURE__ */ import_react16.default.createElement(import_react_native15.Text, { style: styles13.headerScreenTitle, numberOfLines: 1 }, getHeaderTitle()) : null, /* @__PURE__ */ import_react16.default.createElement(import_react_native15.TouchableOpacity, { onPress: handleClose, style: styles13.closeButton }, /* @__PURE__ */ import_react16.default.createElement(import_react_native15.Text, { style: styles13.closeText }, "\u2715"))), /* @__PURE__ */ import_react16.default.createElement(
15317
- import_react_native15.ScrollView,
15746
+ /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles15.modalContainer }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles15.header }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles15.headerLeft }, canGoBack ? /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles15.headerNavRow }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.TouchableOpacity, { onPress: () => nav.pop(), style: styles15.backButton }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles15.backText }, "\u2190 Back")), /* @__PURE__ */ import_react18.default.createElement(import_react_native17.TouchableOpacity, { onPress: () => nav.reset(), style: styles15.homeButton }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles15.homeText }, "\u{1F3E0}"))) : /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles15.headerTitleRow }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles15.headerTitle }, "BugBear"), testerInfo && /* @__PURE__ */ import_react18.default.createElement(import_react_native17.TouchableOpacity, { onPress: () => push({ name: "PROFILE" }) }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles15.headerName }, testerInfo.name, " \u270E")))), getHeaderTitle() ? /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles15.headerScreenTitle, numberOfLines: 1 }, getHeaderTitle()) : null, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.TouchableOpacity, { onPress: handleClose, style: styles15.closeButton }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles15.closeText }, "\u2715"))), /* @__PURE__ */ import_react18.default.createElement(
15747
+ import_react_native17.ScrollView,
15318
15748
  {
15319
- style: styles13.content,
15320
- contentContainerStyle: styles13.contentContainer,
15749
+ style: styles15.content,
15750
+ contentContainerStyle: styles15.contentContainer,
15321
15751
  keyboardShouldPersistTaps: "handled",
15322
15752
  showsVerticalScrollIndicator: false
15323
15753
  },
15324
- isLoading ? /* @__PURE__ */ import_react16.default.createElement(import_react_native15.View, { style: styles13.loadingContainer }, /* @__PURE__ */ import_react16.default.createElement(import_react_native15.ActivityIndicator, { size: "large", color: colors.blue }), /* @__PURE__ */ import_react16.default.createElement(import_react_native15.Text, { style: styles13.loadingText }, "Loading...")) : renderScreen()
15754
+ isLoading ? /* @__PURE__ */ import_react18.default.createElement(import_react_native17.View, { style: styles15.loadingContainer }, /* @__PURE__ */ import_react18.default.createElement(import_react_native17.ActivityIndicator, { size: "large", color: colors.blue }), /* @__PURE__ */ import_react18.default.createElement(import_react_native17.Text, { style: styles15.loadingText }, "Loading...")) : renderScreen()
15325
15755
  ))
15326
15756
  )
15327
15757
  ));
15328
15758
  }
15329
- var styles13 = import_react_native15.StyleSheet.create({
15759
+ var styles15 = import_react_native17.StyleSheet.create({
15330
15760
  // FAB
15331
15761
  fabContainer: {
15332
15762
  position: "absolute",
@@ -15468,9 +15898,9 @@ var styles13 = import_react_native15.StyleSheet.create({
15468
15898
  });
15469
15899
 
15470
15900
  // src/BugBearErrorBoundary.tsx
15471
- var import_react17 = __toESM(require("react"));
15472
- var import_react_native16 = require("react-native");
15473
- var BugBearErrorBoundary = class extends import_react17.Component {
15901
+ var import_react19 = __toESM(require("react"));
15902
+ var import_react_native18 = require("react-native");
15903
+ var BugBearErrorBoundary = class extends import_react19.Component {
15474
15904
  constructor(props) {
15475
15905
  super(props);
15476
15906
  this.reset = () => {
@@ -15514,7 +15944,7 @@ var BugBearErrorBoundary = class extends import_react17.Component {
15514
15944
  if (fallback) {
15515
15945
  return fallback;
15516
15946
  }
15517
- return /* @__PURE__ */ import_react17.default.createElement(import_react_native16.View, { style: styles14.container }, /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: styles14.title }, "Something went wrong"), /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: styles14.message }, error.message), /* @__PURE__ */ import_react17.default.createElement(import_react_native16.TouchableOpacity, { style: styles14.button, onPress: this.reset }, /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: styles14.buttonText }, "Try Again")), /* @__PURE__ */ import_react17.default.createElement(import_react_native16.Text, { style: styles14.caption }, "The error has been captured by BugBear"));
15947
+ return /* @__PURE__ */ import_react19.default.createElement(import_react_native18.View, { style: styles16.container }, /* @__PURE__ */ import_react19.default.createElement(import_react_native18.Text, { style: styles16.title }, "Something went wrong"), /* @__PURE__ */ import_react19.default.createElement(import_react_native18.Text, { style: styles16.message }, error.message), /* @__PURE__ */ import_react19.default.createElement(import_react_native18.TouchableOpacity, { style: styles16.button, onPress: this.reset }, /* @__PURE__ */ import_react19.default.createElement(import_react_native18.Text, { style: styles16.buttonText }, "Try Again")), /* @__PURE__ */ import_react19.default.createElement(import_react_native18.Text, { style: styles16.caption }, "The error has been captured by BugBear"));
15518
15948
  }
15519
15949
  return children;
15520
15950
  }
@@ -15525,7 +15955,7 @@ function useErrorContext() {
15525
15955
  getEnhancedContext: () => contextCapture.getEnhancedContext()
15526
15956
  };
15527
15957
  }
15528
- var styles14 = import_react_native16.StyleSheet.create({
15958
+ var styles16 = import_react_native18.StyleSheet.create({
15529
15959
  container: {
15530
15960
  padding: 20,
15531
15961
  margin: 20,