| 1 | import { |
| 2 | codexFeedbackNotice, |
| 3 | type CodexFeedbackSubmission, |
| 4 | } from "@t3tools/client-runtime/state/threads"; |
| 5 | import { Pressable, View } from "react-native"; |
| 6 | |
| 7 | import { AppText as Text } from "../../components/AppText"; |
| 8 | import { SymbolView } from "../../components/AppSymbol"; |
| 9 | import { copyTextWithHaptic } from "../../lib/copyTextWithHaptic"; |
| 10 | |
| 11 | export function ComposerFeedback({ |
| 12 | submission, |
| 13 | onDismiss, |
| 14 | }: { |
| 15 | readonly submission: CodexFeedbackSubmission; |
| 16 | readonly onDismiss: () => void; |
| 17 | }) { |
| 18 | const notice = codexFeedbackNotice(submission); |
| 19 | if (!notice) return null; |
| 20 | return ( |
| 21 | <View className="px-4 pb-3"> |
| 22 | <View className="gap-2 rounded-[20px] border-continuous bg-card p-4"> |
| 23 | <View className="flex-row items-center gap-3"> |
| 24 | <Text accessibilityLiveRegion="polite" className="min-w-0 flex-1 text-sm text-foreground"> |
| 25 | {notice.title} |
| 26 | </Text> |
| 27 | {submission.status !== "uploading" ? ( |
| 28 | <Pressable |
| 29 | accessibilityLabel="Dismiss feedback notice" |
| 30 | accessibilityRole="button" |
| 31 | hitSlop={12} |
| 32 | onPress={onDismiss} |
| 33 | className="p-1 active:opacity-60" |
| 34 | > |
| 35 | <SymbolView |
| 36 | name="xmark" |
| 37 | size={14} |
| 38 | tintColorClassName="accent-icon-muted" |
| 39 | type="monochrome" |
| 40 | /> |
| 41 | </Pressable> |
| 42 | ) : null} |
| 43 | </View> |
| 44 | {notice.description ? ( |
| 45 | <Text selectable className="text-xs text-foreground-muted"> |
| 46 | {notice.description} |
| 47 | </Text> |
| 48 | ) : null} |
| 49 | {submission.status === "sent" ? ( |
| 50 | <Pressable |
| 51 | accessibilityRole="button" |
| 52 | onPress={() => |
| 53 | copyTextWithHaptic(submission.feedbackId, { target: "Codex feedback thread ID" }) |
| 54 | } |
| 55 | className="self-start py-1 active:opacity-60" |
| 56 | > |
| 57 | <Text className="text-sm text-foreground">Copy ID</Text> |
| 58 | </Pressable> |
| 59 | ) : null} |
| 60 | </View> |
| 61 | </View> |
| 62 | ); |
| 63 | } |