Add MVP features: edit mode, voice input, Gitea push, service autocomplete
- new.tsx: edit mode via editId param, per-field voice dictation (MIC/STOP), service autocomplete dropdown from DB history - incident/[id].tsx: Push to Gitea action reads SecureStore config + md template - index.tsx: homeView=capture redirects to /new on first mount - _layout.tsx: onboarding gate wired (useSettings + router.replace) - ci: GitHub Actions workflow builds debug APK via expo prebuild + Gradle Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,8 +9,10 @@ import {
|
||||
} from "react-native";
|
||||
import { useLocalSearchParams, router, useNavigation } from "expo-router";
|
||||
import * as Clipboard from "expo-clipboard";
|
||||
import * as SecureStore from "expo-secure-store";
|
||||
import { getIncidentById, updateIncident } from "@/lib/db";
|
||||
import { renderMarkdown } from "@/lib/markdown";
|
||||
import { pushIncidentToGitea } from "@/lib/gitea";
|
||||
import type { Incident } from "@/types/incident";
|
||||
import { Colors } from "@/constants/theme";
|
||||
|
||||
@@ -38,6 +40,7 @@ export default function IncidentDetailScreen() {
|
||||
const { id } = useLocalSearchParams<{ id: string }>();
|
||||
const navigation = useNavigation();
|
||||
const [incident, setIncident] = useState<Incident | null>(null);
|
||||
const [pushing, setPushing] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (id) {
|
||||
@@ -56,6 +59,33 @@ export default function IncidentDetailScreen() {
|
||||
setIncident({ ...incident, status: "resolved" });
|
||||
}
|
||||
|
||||
async function handleGiteaPush() {
|
||||
if (!incident) return;
|
||||
const [url, token, owner, repo, template] = await Promise.all([
|
||||
SecureStore.getItemAsync("gitea_url"),
|
||||
SecureStore.getItemAsync("gitea_token"),
|
||||
SecureStore.getItemAsync("gitea_owner"),
|
||||
SecureStore.getItemAsync("gitea_repo"),
|
||||
SecureStore.getItemAsync("md_template"),
|
||||
]);
|
||||
if (!url || !token || !owner || !repo) {
|
||||
Alert.alert("Gitea not configured", "Set up Gitea in Settings first.");
|
||||
return;
|
||||
}
|
||||
setPushing(true);
|
||||
const result = await pushIncidentToGitea(
|
||||
incident,
|
||||
{ url, token, owner, repo },
|
||||
template ?? undefined
|
||||
);
|
||||
setPushing(false);
|
||||
if (result.success) {
|
||||
Alert.alert("Pushed", result.url ? `${result.url}` : "Push successful.");
|
||||
} else {
|
||||
Alert.alert("Push failed", result.error ?? "Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
async function handleExport() {
|
||||
if (!incident) return;
|
||||
const md = renderMarkdown(incident);
|
||||
@@ -188,6 +218,29 @@ export default function IncidentDetailScreen() {
|
||||
</Text>
|
||||
</Pressable>
|
||||
|
||||
<Pressable
|
||||
onPress={handleGiteaPush}
|
||||
disabled={pushing}
|
||||
style={{
|
||||
backgroundColor: pushing ? Colors.surface2 : Colors.surface,
|
||||
borderWidth: 1,
|
||||
borderColor: pushing ? Colors.border : Colors.primary,
|
||||
borderRadius: 10,
|
||||
padding: 14,
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: pushing ? Colors.textDim : Colors.primary,
|
||||
fontWeight: "600",
|
||||
fontSize: 15,
|
||||
}}
|
||||
>
|
||||
{pushing ? "Pushing…" : "Push to Gitea"}
|
||||
</Text>
|
||||
</Pressable>
|
||||
|
||||
<Pressable
|
||||
onPress={() => router.push({ pathname: "/new", params: { editId: incident.id } })}
|
||||
style={{
|
||||
|
||||
Reference in New Issue
Block a user