Feedback UI
Fedo ships two UI entry points on each platform:
| Android (Compose) | iOS (SwiftUI) | |
|---|---|---|
| Full feedback board (list, details, editor) | FedoFeedbackScreen() | FedoFeedbackView() |
| Submission-only sheet | FedoCreateFeedbackSheet() | .presentFedoCreateFeedback(isPresented:) |
Signature​
- Kotlin
- Swift
@Composable
fun FedoFeedbackScreen(
modifier: Modifier = Modifier,
onDismiss: () -> Unit,
)
| Parameter | Type | Description |
|---|---|---|
modifier | Modifier | Compose modifier for sizing/padding |
onDismiss | () -> Unit | Called when user navigates back from the root screen |
struct FedoFeedbackView: View {
init()
}
No parameters: the view reads everything it needs from the SDK singleton.
It pushes its screens onto the enclosing NavigationStack, so present it
with a NavigationLink:
NavigationLink("Feedbacks List") {
FedoFeedbackView()
}
To show it modally, give it its own NavigationStack:
.sheet(isPresented: $showFeedbacks) {
NavigationStack {
FedoFeedbackView()
}
}
There is no onDismiss: back navigation is the system's. If the SDK was
never initialized, the view renders a placeholder instead of the list.
Screens​
The board manages its own internal navigation with three screens (identical on both platforms):
1. Feedback List​
- Shows feedback items in a vertical list with pull-to-refresh
- Status filter tabs: All, In review, Planned, In progress, Done, Closed (each with a count on iOS)
- FAB to create new feedback
- Vote buttons on each item
Android
iOS
The board follows each platform's own conventions, so Android and iOS look different by design.
2. Feedback Details​
- Full feedback description
- Threaded comments section
- Vote on the feedback
- Edit/delete own feedback (when status allows)
- Reply to existing comments
Android
3. Feedback Editor​
- Create new feedback (title + description)
- Edit existing feedback (pre-populated fields)
- Validation before submit
Android
Navigation​
Back navigation is automatic. On Android:
- Editor → Details / List
- Details → List
- List →
onDismissfires
The onDismiss lambda is only called when the user presses back on the root list screen. Your app handles this by popping its own navigation stack.
On iOS there is no onDismiss: FedoFeedbackView pushes onto your
NavigationStack, so the system back button pops it for you.
State handling​
The screen handles loading, error, and empty states internally. No extra UI work needed.
If the SDK has not been initialized, FedoFeedbackScreen() renders a full-screen "Fedo not initialized" placeholder in place of the board. It does not crash.
Feedback Sheet​
The submission sheet is built per platform. On Android, FedoCreateFeedbackSheet() renders a self-contained creation form (title + details fields) as a ModalBottomSheet, with its own submit state and validation - no navigation setup or FedoFeedbackScreen() host required. On iOS, the equivalent is the .presentCreateFeedback(isPresented:) view modifier, which presents the same sheet without requiring a NavigationStack or FedoFeedbackView host. Use it when you want a lightweight "suggest a feature" entry point (e.g. from a menu or FAB) instead of the full feedback flow.
Signature​
- Kotlin
- Swift
@Composable
fun FedoCreateFeedbackSheet(
onDismiss: () -> Unit,
modifier: Modifier = Modifier,
)
| Parameter | Type | Description |
|---|---|---|
onDismiss | () -> Unit | Called when the sheet is dismissed by the user (swipe/scrim/close button) or automatically after a successful submit |
modifier | Modifier | Compose modifier applied to the ModalBottomSheet container |
There's no visible param - toggle composition yourself:
@Composable
fun MyScreen() {
var showFeedbackSheet by remember { mutableStateOf(false) }
Button(onClick = { showFeedbackSheet = true }) {
Text("Suggest a feature")
}
if (showFeedbackSheet) {
FedoCreateFeedbackSheet(
onDismiss = { showFeedbackSheet = false }
)
}
}
On success, the form is replaced with a brief thank-you message before the sheet auto-dismisses, which fires onDismiss.
extension View {
func presentCreateFeedback(isPresented: Binding<Bool>) -> some View
}
| Parameter | Type | Description |
|---|---|---|
isPresented | Binding<Bool> | Drives presentation, exactly like SwiftUI's sheet(isPresented:content:). Set back to false on swipe-down, close button, or auto-dismiss after a successful submit |
struct SettingsView: View {
@State private var showFeedbackSheet = false
var body: some View {
Button("Suggest a feature") {
showFeedbackSheet = true
}
.presentCreateFeedback(isPresented: $showFeedbackSheet)
}
}
No NavigationStack or FedoFeedbackView host required.
If Fedo.initialize has not been called, FedoCreateFeedbackSheet() shows the same "Fedo not initialized" error inside the sheet, while FedoFeedbackScreen() shows it full-screen. On both platforms, calls to user-management methods (setUserID, setUserEmail, etc.) are silent no-ops — they do not throw.
Android