feat: safe area fix, delete from repo, add Mistral provider
Release APK / build (push) Has been cancelled
Release APK / build (push) Has been cancelled
- Wrap root layout with SafeAreaProvider, use useSafeAreaInsets in all screens so FAB/action bar/scroll content clear Android nav bar - Add deleteIncidentFromGit() (Gitea/GitHub/GitLab) — detail screen now offers Cancel / Local only / Local + Repo when incident was pushed - Add Mistral as AI provider (OpenAI-compat, api.mistral.ai/v1, mistral-small-latest default) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+53
-17
@@ -8,11 +8,13 @@ import {
|
||||
Share,
|
||||
} from "react-native";
|
||||
import { useLocalSearchParams, router, useNavigation } from "expo-router";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import * as Clipboard from "expo-clipboard";
|
||||
import * as SecureStore from "expo-secure-store";
|
||||
import { getIncidentById, updateIncident, deleteIncident, markIncidentPushed } from "@/lib/db";
|
||||
import { renderMarkdown } from "@/lib/markdown";
|
||||
import { pushIncidentToGit, loadGitConfig } from "@/lib/git";
|
||||
import { pushIncidentToGit, loadGitConfig, deleteIncidentFromGit } from "@/lib/git";
|
||||
import type { GitConfig } from "@/lib/git";
|
||||
import type { Incident } from "@/types/incident";
|
||||
import { Colors } from "@/constants/theme";
|
||||
|
||||
@@ -41,11 +43,14 @@ export default function IncidentDetailScreen() {
|
||||
const navigation = useNavigation();
|
||||
const [incident, setIncident] = useState<Incident | null>(null);
|
||||
const [pushing, setPushing] = useState(false);
|
||||
const [gitConfig, setGitConfig] = useState<GitConfig | null>(null);
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
useEffect(() => {
|
||||
if (id) {
|
||||
getIncidentById(id).then((inc) => {
|
||||
Promise.all([getIncidentById(id), loadGitConfig()]).then(([inc, config]) => {
|
||||
setIncident(inc);
|
||||
setGitConfig(config);
|
||||
if (inc) {
|
||||
navigation.setOptions({ title: inc.title || "Incident" });
|
||||
}
|
||||
@@ -55,21 +60,52 @@ export default function IncidentDetailScreen() {
|
||||
|
||||
async function handleDelete() {
|
||||
if (!incident) return;
|
||||
Alert.alert(
|
||||
"Delete incident?",
|
||||
"This action cannot be undone.",
|
||||
[
|
||||
{ text: "Cancel", style: "cancel" },
|
||||
{
|
||||
text: "Delete",
|
||||
style: "destructive",
|
||||
onPress: async () => {
|
||||
await deleteIncident(incident.id);
|
||||
router.replace("/");
|
||||
|
||||
const canDeleteFromRepo = !!incident.gitPushedAt && gitConfig !== null;
|
||||
|
||||
const doDelete = async (deleteFromRepo: boolean) => {
|
||||
if (deleteFromRepo && gitConfig) {
|
||||
const result = await deleteIncidentFromGit(incident, gitConfig);
|
||||
if (!result.success) {
|
||||
Alert.alert("Repo deletion failed", result.error ?? "Unknown error");
|
||||
return;
|
||||
}
|
||||
}
|
||||
await deleteIncident(incident.id);
|
||||
router.replace("/");
|
||||
};
|
||||
|
||||
if (canDeleteFromRepo) {
|
||||
Alert.alert(
|
||||
"Delete incident?",
|
||||
"This incident was pushed to the repository. Do you also want to delete the file from the repo?",
|
||||
[
|
||||
{ text: "Cancel", style: "cancel" },
|
||||
{
|
||||
text: "Local only",
|
||||
onPress: () => doDelete(false),
|
||||
},
|
||||
},
|
||||
]
|
||||
);
|
||||
{
|
||||
text: "Local + Repo",
|
||||
style: "destructive",
|
||||
onPress: () => doDelete(true),
|
||||
},
|
||||
]
|
||||
);
|
||||
} else {
|
||||
Alert.alert(
|
||||
"Delete incident?",
|
||||
"This action cannot be undone.",
|
||||
[
|
||||
{ text: "Cancel", style: "cancel" },
|
||||
{
|
||||
text: "Delete",
|
||||
style: "destructive",
|
||||
onPress: () => doDelete(false),
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleResolve() {
|
||||
@@ -125,7 +161,7 @@ export default function IncidentDetailScreen() {
|
||||
return (
|
||||
<ScrollView
|
||||
style={{ flex: 1, backgroundColor: Colors.bg }}
|
||||
contentContainerStyle={{ padding: 16, paddingBottom: 32 }}
|
||||
contentContainerStyle={{ padding: 16, paddingBottom: 32 + insets.bottom }}
|
||||
>
|
||||
{/* Status badge */}
|
||||
<View style={{ flexDirection: "row", alignItems: "center", gap: 8, marginBottom: 4 }}>
|
||||
|
||||
Reference in New Issue
Block a user