convex-feedback-ui 0.1.2 → 0.1.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.
Files changed (165) hide show
  1. package/README.md +119 -18
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/native/expo/ExpoFeedbackBody.d.ts +4 -0
  4. package/dist/native/expo/ExpoFeedbackBody.d.ts.map +1 -0
  5. package/dist/native/expo/ExpoFeedbackBody.js +26 -0
  6. package/dist/native/expo/ExpoFeedbackBody.js.map +1 -0
  7. package/dist/native/expo/FeedbackScreen.d.ts +3 -0
  8. package/dist/native/expo/FeedbackScreen.d.ts.map +1 -0
  9. package/dist/native/expo/FeedbackScreen.js +9 -0
  10. package/dist/native/expo/FeedbackScreen.js.map +1 -0
  11. package/dist/native/expo/FeedbackStack.d.ts +3 -0
  12. package/dist/native/expo/FeedbackStack.d.ts.map +1 -0
  13. package/dist/native/expo/FeedbackStack.js +41 -0
  14. package/dist/native/expo/FeedbackStack.js.map +1 -0
  15. package/dist/native/expo/index.d.ts +9 -0
  16. package/dist/native/expo/index.d.ts.map +1 -0
  17. package/dist/native/expo/index.js +7 -0
  18. package/dist/native/expo/index.js.map +1 -0
  19. package/dist/native/expo/types.d.ts +20 -0
  20. package/dist/native/expo/types.d.ts.map +1 -0
  21. package/dist/native/expo/types.js +2 -0
  22. package/dist/native/expo/types.js.map +1 -0
  23. package/dist/native/native/FeedbackScreen.d.ts +3 -0
  24. package/dist/native/native/FeedbackScreen.d.ts.map +1 -0
  25. package/dist/native/native/FeedbackScreen.js +9 -0
  26. package/dist/native/native/FeedbackScreen.js.map +1 -0
  27. package/dist/native/native/index.d.ts +8 -0
  28. package/dist/native/native/index.d.ts.map +1 -0
  29. package/dist/native/native/index.js +7 -0
  30. package/dist/native/native/index.js.map +1 -0
  31. package/dist/native/shared/helpers.d.ts +3 -0
  32. package/dist/native/shared/helpers.d.ts.map +1 -0
  33. package/dist/native/shared/helpers.js +4 -0
  34. package/dist/native/shared/helpers.js.map +1 -0
  35. package/dist/native/shared/ui/BodyContent.d.ts +3 -0
  36. package/dist/native/shared/ui/BodyContent.d.ts.map +1 -0
  37. package/dist/native/shared/ui/BodyContent.js +18 -0
  38. package/dist/native/shared/ui/BodyContent.js.map +1 -0
  39. package/dist/native/shared/ui/Button.d.ts +5 -0
  40. package/dist/native/shared/ui/Button.d.ts.map +1 -0
  41. package/dist/native/shared/ui/Button.js +15 -0
  42. package/dist/native/shared/ui/Button.js.map +1 -0
  43. package/dist/native/shared/ui/CommentBranch.d.ts +5 -0
  44. package/dist/native/shared/ui/CommentBranch.d.ts.map +1 -0
  45. package/dist/native/shared/ui/CommentBranch.js +45 -0
  46. package/dist/native/shared/ui/CommentBranch.js.map +1 -0
  47. package/dist/native/shared/ui/EntryCard.d.ts +3 -0
  48. package/dist/native/shared/ui/EntryCard.d.ts.map +1 -0
  49. package/dist/native/shared/ui/EntryCard.js +13 -0
  50. package/dist/native/shared/ui/EntryCard.js.map +1 -0
  51. package/dist/native/shared/ui/EntryDetail.d.ts +3 -0
  52. package/dist/native/shared/ui/EntryDetail.d.ts.map +1 -0
  53. package/dist/native/shared/ui/EntryDetail.js +37 -0
  54. package/dist/native/shared/ui/EntryDetail.js.map +1 -0
  55. package/dist/native/shared/ui/FeedbackScreenHeader.d.ts +2 -0
  56. package/dist/native/shared/ui/FeedbackScreenHeader.d.ts.map +1 -0
  57. package/dist/native/shared/ui/FeedbackScreenHeader.js +22 -0
  58. package/dist/native/shared/ui/FeedbackScreenHeader.js.map +1 -0
  59. package/dist/native/shared/ui/FeedbackScreenList.d.ts +3 -0
  60. package/dist/native/shared/ui/FeedbackScreenList.d.ts.map +1 -0
  61. package/dist/native/shared/ui/FeedbackScreenList.js +19 -0
  62. package/dist/native/shared/ui/FeedbackScreenList.js.map +1 -0
  63. package/dist/native/shared/ui/NewEntry.d.ts +5 -0
  64. package/dist/native/shared/ui/NewEntry.d.ts.map +1 -0
  65. package/dist/native/shared/ui/NewEntry.js +158 -0
  66. package/dist/native/shared/ui/NewEntry.js.map +1 -0
  67. package/dist/native/shared/ui/ReplyList.d.ts +3 -0
  68. package/dist/native/shared/ui/ReplyList.d.ts.map +1 -0
  69. package/dist/native/shared/ui/ReplyList.js +19 -0
  70. package/dist/native/shared/ui/ReplyList.js.map +1 -0
  71. package/dist/native/{primitives.d.ts → shared/ui/primitives.d.ts} +10 -12
  72. package/dist/native/shared/ui/primitives.d.ts.map +1 -0
  73. package/dist/native/{primitives.js → shared/ui/primitives.js} +19 -25
  74. package/dist/native/shared/ui/primitives.js.map +1 -0
  75. package/dist/react/{context.d.ts → css.d.ts} +2 -4
  76. package/dist/react/css.d.ts.map +1 -0
  77. package/dist/react/css.js +18 -0
  78. package/dist/react/css.js.map +1 -0
  79. package/dist/react/index.d.ts +1 -1
  80. package/dist/react/index.d.ts.map +1 -1
  81. package/dist/react/index.js +1 -1
  82. package/dist/react/index.js.map +1 -1
  83. package/dist/react/primitives.d.ts.map +1 -1
  84. package/dist/react/primitives.js +2 -1
  85. package/dist/react/primitives.js.map +1 -1
  86. package/dist/react/screen.d.ts +3 -3
  87. package/dist/react/screen.d.ts.map +1 -1
  88. package/dist/react/screen.js +25 -22
  89. package/dist/react/screen.js.map +1 -1
  90. package/dist/shared/context/FeedbackBodyProvider.d.ts +5 -0
  91. package/dist/shared/context/FeedbackBodyProvider.d.ts.map +1 -0
  92. package/dist/shared/context/FeedbackBodyProvider.js +43 -0
  93. package/dist/shared/context/FeedbackBodyProvider.js.map +1 -0
  94. package/dist/{native/context.d.ts → shared/context/FeedbackProvider.d.ts} +2 -2
  95. package/dist/shared/context/FeedbackProvider.d.ts.map +1 -0
  96. package/dist/{native/context.js → shared/context/FeedbackProvider.js} +3 -3
  97. package/dist/shared/context/FeedbackProvider.js.map +1 -0
  98. package/dist/shared/helpers.d.ts +7 -0
  99. package/dist/shared/helpers.d.ts.map +1 -0
  100. package/dist/shared/helpers.js +24 -0
  101. package/dist/shared/helpers.js.map +1 -0
  102. package/dist/shared/messages.d.ts.map +1 -1
  103. package/dist/shared/messages.js +23 -14
  104. package/dist/shared/messages.js.map +1 -1
  105. package/dist/shared/theme.d.ts.map +1 -1
  106. package/dist/shared/theme.js +1 -0
  107. package/dist/shared/theme.js.map +1 -1
  108. package/dist/shared/types/context.d.ts +4 -0
  109. package/dist/shared/types/context.d.ts.map +1 -1
  110. package/dist/shared/types/messages.d.ts +12 -1
  111. package/dist/shared/types/messages.d.ts.map +1 -1
  112. package/dist/shared/types/screen.d.ts +55 -18
  113. package/dist/shared/types/screen.d.ts.map +1 -1
  114. package/dist/shared/types/theme.d.ts +4 -0
  115. package/dist/shared/types/theme.d.ts.map +1 -1
  116. package/package.json +27 -12
  117. package/src/native/expo/ExpoFeedbackBody.tsx +48 -0
  118. package/src/native/expo/FeedbackScreen.tsx +37 -0
  119. package/src/native/expo/FeedbackStack.tsx +99 -0
  120. package/src/native/expo/README.md +17 -0
  121. package/src/native/expo/index.ts +8 -0
  122. package/src/native/expo/types.ts +23 -0
  123. package/src/native/native/FeedbackScreen.tsx +37 -0
  124. package/src/native/native/index.ts +7 -0
  125. package/src/native/shared/helpers.ts +9 -0
  126. package/src/native/shared/ui/BodyContent.tsx +43 -0
  127. package/src/native/shared/ui/Button.tsx +29 -0
  128. package/src/native/shared/ui/CommentBranch.tsx +122 -0
  129. package/src/native/shared/ui/EntryCard.tsx +37 -0
  130. package/src/native/shared/ui/EntryDetail.tsx +103 -0
  131. package/src/native/shared/ui/FeedbackScreenHeader.tsx +42 -0
  132. package/src/native/shared/ui/FeedbackScreenList.tsx +61 -0
  133. package/src/native/shared/ui/NewEntry.tsx +375 -0
  134. package/src/native/{primitives.tsx → shared/ui/primitives.tsx} +84 -92
  135. package/src/react/{context.tsx → css.tsx} +2 -44
  136. package/src/react/index.ts +1 -1
  137. package/src/react/primitives.tsx +2 -1
  138. package/src/react/screen.tsx +67 -123
  139. package/src/shared/context/FeedbackBodyProvider.tsx +82 -0
  140. package/src/{native/context.tsx → shared/context/FeedbackProvider.tsx} +3 -3
  141. package/src/shared/helpers.ts +33 -0
  142. package/src/shared/messages.ts +23 -22
  143. package/src/shared/theme.ts +1 -0
  144. package/src/shared/types/context.ts +5 -0
  145. package/src/shared/types/messages.ts +16 -1
  146. package/src/shared/types/screen.ts +69 -23
  147. package/src/shared/types/theme.ts +5 -0
  148. package/dist/native/context.d.ts.map +0 -1
  149. package/dist/native/context.js.map +0 -1
  150. package/dist/native/index.d.ts +0 -7
  151. package/dist/native/index.d.ts.map +0 -1
  152. package/dist/native/index.js +0 -6
  153. package/dist/native/index.js.map +0 -1
  154. package/dist/native/primitives.d.ts.map +0 -1
  155. package/dist/native/primitives.js.map +0 -1
  156. package/dist/native/screen.d.ts +0 -3
  157. package/dist/native/screen.d.ts.map +0 -1
  158. package/dist/native/screen.js +0 -284
  159. package/dist/native/screen.js.map +0 -1
  160. package/dist/react/context.d.ts.map +0 -1
  161. package/dist/react/context.js +0 -41
  162. package/dist/react/context.js.map +0 -1
  163. package/src/native/index.ts +0 -6
  164. package/src/native/screen.tsx +0 -831
  165. /package/src/native/{README.md → native/README.md} +0 -0
@@ -0,0 +1,122 @@
1
+ import { useMemo, useState } from "react";
2
+ import { Text, View } from "react-native";
3
+
4
+ import { useFeedbackBody } from "../../../shared/context/FeedbackBodyProvider.js";
5
+ import { useFeedbackUi } from "../../../shared/context/FeedbackProvider.js";
6
+ import type { FeedbackScreenCommentBranchProps } from "../../../shared/types";
7
+ import { Button } from "./Button";
8
+ import { Comment, FeedbackForm } from "./primitives.js";
9
+
10
+ import type { FeedbackScreenReplyListProps } from "../../../shared/types";
11
+
12
+ export function ReplyList({
13
+ entryId,
14
+ parentCommentId,
15
+ }: FeedbackScreenReplyListProps) {
16
+ const { hooks, commentSort, transformComments } = useFeedbackBody();
17
+ const { messages } = useFeedbackUi();
18
+
19
+ const replies = hooks.useComments({
20
+ entryId,
21
+ parentCommentId,
22
+ sort: commentSort,
23
+ });
24
+
25
+ const visible = useMemo(
26
+ () => transformComments?.(replies.results) ?? replies.results,
27
+ [replies.results, transformComments],
28
+ );
29
+
30
+ return (
31
+ <Comment.Children>
32
+ {visible.map((reply) => (
33
+ <CommentBranch key={reply.id} comment={reply} entryId={entryId} />
34
+ ))}
35
+ {replies.status === "CanLoadMore" && (
36
+ <Button
37
+ label={messages.comments.loadMore}
38
+ onPress={() => replies.loadMore(hooks.pageSizes.replies)}
39
+ />
40
+ )}
41
+ </Comment.Children>
42
+ );
43
+ }
44
+
45
+ export function CommentBranch({
46
+ comment,
47
+ entryId,
48
+ }: FeedbackScreenCommentBranchProps) {
49
+ const { hooks, maxCommentDepth, renderActor } = useFeedbackBody();
50
+ const { messages, theme } = useFeedbackUi();
51
+ const [expanded, setExpanded] = useState(false);
52
+ const [replying, setReplying] = useState(false);
53
+ const [replyBody, setReplyBody] = useState("");
54
+ const setLike = hooks.useSetCommentLike();
55
+ const createComment = hooks.useCreateComment();
56
+
57
+ return (
58
+ <Comment.Root comment={comment}>
59
+ {renderActor === undefined ? null : (
60
+ <View>{renderActor(comment.actorId)}</View>
61
+ )}
62
+ <Comment.Body />
63
+ <View
64
+ style={{
65
+ flexDirection: "row",
66
+ flexWrap: "wrap",
67
+ alignItems: "center",
68
+ gap: 4,
69
+ }}
70
+ >
71
+ <Comment.Like
72
+ onToggle={(active) =>
73
+ void setLike({ commentId: comment.id, desiredState: active })
74
+ }
75
+ />
76
+ {comment.body !== null && comment.depth < maxCommentDepth ? (
77
+ <Comment.Reply onActivate={() => setReplying((value) => !value)} />
78
+ ) : null}
79
+ <Comment.RepliesButton
80
+ expanded={expanded}
81
+ onExpandedChange={setExpanded}
82
+ />
83
+ </View>
84
+ {replying ? (
85
+ <FeedbackForm.Root>
86
+ <FeedbackForm.Textarea
87
+ value={replyBody}
88
+ onChangeText={setReplyBody}
89
+ placeholder={messages.comments.placeholder}
90
+ />
91
+ <FeedbackForm.Submit
92
+ onPress={async () => {
93
+ if (replyBody.trim().length === 0) return;
94
+ await createComment({
95
+ entryId,
96
+ parentCommentId: comment.id,
97
+ body: replyBody,
98
+ });
99
+ setReplyBody("");
100
+ setReplying(false);
101
+ setExpanded(true);
102
+ }}
103
+ >
104
+ {messages.comments.reply}
105
+ </FeedbackForm.Submit>
106
+ <Button
107
+ label={messages.comments.cancelReply}
108
+ onPress={() => setReplying(false)}
109
+ />
110
+ </FeedbackForm.Root>
111
+ ) : null}
112
+ {expanded ? (
113
+ <ReplyList entryId={entryId} parentCommentId={comment.id} />
114
+ ) : null}
115
+ {comment.deletedAt !== undefined ? (
116
+ <Text style={{ color: theme.colors.mutedText, fontSize: 11 }}>
117
+ {messages.comments.deleted}
118
+ </Text>
119
+ ) : null}
120
+ </Comment.Root>
121
+ );
122
+ }
@@ -0,0 +1,37 @@
1
+ import { Pressable, View } from "react-native";
2
+
3
+ import type { FeedbackScreenEntryCardProps } from "../../../shared/types";
4
+ import { FeedbackEntry } from "./primitives";
5
+
6
+ export function EntryCard({
7
+ entry,
8
+ hooks,
9
+ onOpen,
10
+ }: FeedbackScreenEntryCardProps) {
11
+ const setUpvote = hooks.useSetEntryUpvote();
12
+ return (
13
+ <FeedbackEntry.Root entry={entry}>
14
+ <FeedbackEntry.Upvote
15
+ onToggle={(active) =>
16
+ void setUpvote({ entryId: entry.id, desiredState: active })
17
+ }
18
+ />
19
+ <Pressable onPress={onOpen} style={{ flex: 1, gap: 4 }}>
20
+ <View
21
+ style={{
22
+ flexDirection: "row",
23
+ alignItems: "center",
24
+ justifyContent: "space-between",
25
+ gap: 8,
26
+ }}
27
+ >
28
+ <FeedbackEntry.Kind />
29
+ <FeedbackEntry.Status />
30
+ </View>
31
+ <FeedbackEntry.Title />
32
+ <FeedbackEntry.Body numberOfLines={3} />
33
+ <FeedbackEntry.CommentCount />
34
+ </Pressable>
35
+ </FeedbackEntry.Root>
36
+ );
37
+ }
@@ -0,0 +1,103 @@
1
+ import { useMemo, useState } from "react";
2
+ import { ActivityIndicator, Text, View } from "react-native";
3
+
4
+ import { useFeedbackBody } from "../../../shared/context/FeedbackBodyProvider";
5
+ import { useFeedbackUi } from "../../../shared/context/FeedbackProvider";
6
+ import type { FeedbackScreenEntryDetailProps } from "../../../shared/types";
7
+ import { Button } from "./Button";
8
+ import { CommentBranch } from "./CommentBranch";
9
+ import { FeedbackEntry, FeedbackForm } from "./primitives";
10
+
11
+ export function EntryDetail({
12
+ entryId,
13
+ onBack,
14
+ hideBackButton,
15
+ }: FeedbackScreenEntryDetailProps) {
16
+ const { hooks, commentSort, transformComments } = useFeedbackBody();
17
+
18
+ const { messages, theme } = useFeedbackUi();
19
+ const entry = hooks.useEntry(entryId);
20
+ const comments = hooks.useComments({ entryId, sort: commentSort });
21
+ const setUpvote = hooks.useSetEntryUpvote();
22
+ const createComment = hooks.useCreateComment();
23
+ const [body, setBody] = useState("");
24
+ const visible = useMemo(
25
+ () => transformComments?.(comments.results) ?? comments.results,
26
+ [comments.results, transformComments],
27
+ );
28
+
29
+ if (entry === undefined)
30
+ return (
31
+ <View
32
+ style={{
33
+ flex: 1,
34
+ gap: 8,
35
+ alignItems: "center",
36
+ justifyContent: "center",
37
+ }}
38
+ >
39
+ <ActivityIndicator size="large" />
40
+ <Text style={{ color: theme.colors.mutedText }}>
41
+ {messages.board.loading}
42
+ </Text>
43
+ </View>
44
+ );
45
+
46
+ if (entry === null) {
47
+ if (hideBackButton) return;
48
+ return <Button label={messages.entry.back} onPress={onBack} />;
49
+ }
50
+
51
+ return (
52
+ <View style={{ gap: 12 }}>
53
+ {!hideBackButton && (
54
+ <Button label={messages.entry.back} onPress={onBack} />
55
+ )}
56
+ <FeedbackEntry.Root entry={entry}>
57
+ <FeedbackEntry.Upvote
58
+ onToggle={(active) =>
59
+ void setUpvote({ entryId, desiredState: active })
60
+ }
61
+ />
62
+ <FeedbackEntry.Content style={{ gap: 5 }}>
63
+ <FeedbackEntry.Status />
64
+ <FeedbackEntry.Title />
65
+ <FeedbackEntry.Body />
66
+ <FeedbackEntry.CommentCount />
67
+ </FeedbackEntry.Content>
68
+ </FeedbackEntry.Root>
69
+ <Text
70
+ style={{ color: theme.colors.text, fontSize: 18, fontWeight: "700" }}
71
+ >
72
+ {messages.comments.title}
73
+ </Text>
74
+ <FeedbackForm.Root>
75
+ <FeedbackForm.Textarea
76
+ value={body}
77
+ onChangeText={setBody}
78
+ placeholder={messages.comments.placeholder}
79
+ />
80
+ <FeedbackForm.Submit
81
+ onPress={async () => {
82
+ if (body.trim().length === 0) return;
83
+ await createComment({ entryId, body });
84
+ setBody("");
85
+ }}
86
+ >
87
+ {messages.comments.submit}
88
+ </FeedbackForm.Submit>
89
+ </FeedbackForm.Root>
90
+ <View style={{ gap: 8 }}>
91
+ {visible.map((comment) => (
92
+ <CommentBranch key={comment.id} comment={comment} entryId={entryId} />
93
+ ))}
94
+ </View>
95
+ {comments.status === "CanLoadMore" && (
96
+ <Button
97
+ label={messages.comments.loadMore}
98
+ onPress={() => comments.loadMore(hooks.pageSizes.comments)}
99
+ />
100
+ )}
101
+ </View>
102
+ );
103
+ }
@@ -0,0 +1,42 @@
1
+ import { Pressable, Text } from "react-native";
2
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
3
+ import { useFeedbackBody } from "../../../shared/context/FeedbackBodyProvider";
4
+ import { useFeedbackUi } from "../../../shared/context/FeedbackProvider";
5
+ import { FeedbackBoard } from "./primitives";
6
+
7
+ export function FeedbackScreenHeader() {
8
+ const { query, setShowForm, setQuery, enabledKinds } = useFeedbackBody();
9
+ const { messages, theme } = useFeedbackUi();
10
+ const { top } = useSafeAreaInsets();
11
+
12
+ const pageTitle =
13
+ enabledKinds.length === 1
14
+ ? messages.kindsPlural[enabledKinds.at(0)!]
15
+ : messages.board.title;
16
+
17
+ return (
18
+ <FeedbackBoard.Header style={{ padding: theme.spacing, paddingTop: top }}>
19
+ <FeedbackBoard.Title>{pageTitle}</FeedbackBoard.Title>
20
+ <Text style={{ color: theme.colors.mutedText }}>
21
+ {messages.board.subtitle}
22
+ </Text>
23
+ <Pressable
24
+ onPress={() => setShowForm(true)}
25
+ style={{
26
+ alignSelf: "flex-start",
27
+ paddingVertical: 9,
28
+ paddingHorizontal: 12,
29
+ borderRadius: 9,
30
+ backgroundColor: theme.colors.primary,
31
+ }}
32
+ >
33
+ <Text
34
+ style={{ color: theme.colors.primaryForeground, fontWeight: "700" }}
35
+ >
36
+ {messages.board.createEntry}
37
+ </Text>
38
+ </Pressable>
39
+ <FeedbackBoard.Search value={query} onValueChange={(q) => setQuery(q)} />
40
+ </FeedbackBoard.Header>
41
+ );
42
+ }
@@ -0,0 +1,61 @@
1
+ import { useFeedbackBody } from "../../../shared/context/FeedbackBodyProvider.js";
2
+ import { useFeedbackUi } from "../../../shared/context/FeedbackProvider.js";
3
+ import type { FeedbackScreenListProps } from "../../../shared/types/index.js";
4
+ import { Button } from "./Button.js";
5
+ import { EntryCard } from "./EntryCard.js";
6
+ import { EntryDetail } from "./EntryDetail.js";
7
+ import { FeedbackBoard } from "./primitives.js";
8
+
9
+ export function FeedbackScreenList({
10
+ hideBackButton = false,
11
+ onEntryOpen,
12
+ }: FeedbackScreenListProps) {
13
+ const {
14
+ hooks,
15
+ entrySort,
16
+ isSearching,
17
+ enabledKinds,
18
+ selectedEntryId,
19
+ debouncedQuery,
20
+ setSelectedEntryId,
21
+ } = useFeedbackBody();
22
+ const { messages, theme } = useFeedbackUi();
23
+
24
+ const list = hooks.useEntries({ sort: entrySort, kinds: enabledKinds });
25
+ const search = hooks.useSearchEntries({
26
+ searchQuery: debouncedQuery,
27
+ kinds: enabledKinds,
28
+ });
29
+
30
+ const entries = isSearching ? search : list.results;
31
+
32
+ return (
33
+ <>
34
+ <FeedbackBoard.List style={{ padding: theme.spacing }}>
35
+ {selectedEntryId ? (
36
+ <EntryDetail
37
+ entryId={selectedEntryId}
38
+ hideBackButton={hideBackButton}
39
+ onBack={() => setSelectedEntryId(null)}
40
+ />
41
+ ) : (
42
+ (entries ?? []).map((entry) => (
43
+ <EntryCard
44
+ key={entry.id}
45
+ entry={entry}
46
+ hooks={hooks}
47
+ onOpen={() => onEntryOpen(entry.id)}
48
+ />
49
+ ))
50
+ )}
51
+ </FeedbackBoard.List>
52
+
53
+ {!isSearching && list.status === "CanLoadMore" && (
54
+ <Button
55
+ label={messages.board.loadMore}
56
+ onPress={() => list.loadMore(hooks.pageSizes.entries)}
57
+ />
58
+ )}
59
+ </>
60
+ );
61
+ }