import { useState, useEffect } from "react";
import {
View,
Text,
TextInput,
ScrollView,
Switch,
Pressable,
Alert,
} from "react-native";
import * as SecureStore from "expo-secure-store";
import { Colors } from "@/constants/theme";
import { DEFAULT_TEMPLATE } from "@/lib/markdown";
const KEYS = {
INPUT_MODE: "pref_input_mode",
HOME_VIEW: "pref_home_view",
AI_ENABLED: "pref_ai_enabled",
AI_KEY: "pref_ai_key",
GITEA_URL: "gitea_url",
GITEA_TOKEN: "gitea_token",
GITEA_OWNER: "gitea_owner",
GITEA_REPO: "gitea_repo",
MD_TEMPLATE: "md_template",
} as const;
const LABEL = {
color: Colors.text2,
fontSize: 11,
fontWeight: "700" as const,
textTransform: "uppercase" as const,
letterSpacing: 0.6,
marginBottom: 6,
} as const;
const SECTION_TITLE = {
color: Colors.text1,
fontSize: 16,
fontWeight: "700" as const,
marginTop: 28,
marginBottom: 12,
} as const;
const INPUT = {
backgroundColor: Colors.surface,
borderColor: Colors.border,
borderWidth: 1,
borderRadius: 8,
color: Colors.text1,
padding: 12,
fontSize: 14,
marginBottom: 14,
fontFamily: "monospace",
} as const;
export default function SettingsScreen() {
const [inputMode, setInputMode] = useState<"voice" | "form">("form");
const [homeView, setHomeView] = useState<"dashboard" | "capture">("dashboard");
const [aiEnabled, setAiEnabled] = useState(false);
const [aiKey, setAiKey] = useState("");
const [giteaUrl, setGiteaUrl] = useState("");
const [giteaToken, setGiteaToken] = useState("");
const [giteaOwner, setGiteaOwner] = useState("");
const [giteaRepo, setGiteaRepo] = useState("");
const [mdTemplate, setMdTemplate] = useState(DEFAULT_TEMPLATE);
const [saved, setSaved] = useState(false);
useEffect(() => {
(async () => {
const [im, hv, ai, key, gu, gt, go, gr, tpl] = await Promise.all([
SecureStore.getItemAsync(KEYS.INPUT_MODE),
SecureStore.getItemAsync(KEYS.HOME_VIEW),
SecureStore.getItemAsync(KEYS.AI_ENABLED),
SecureStore.getItemAsync(KEYS.AI_KEY),
SecureStore.getItemAsync(KEYS.GITEA_URL),
SecureStore.getItemAsync(KEYS.GITEA_TOKEN),
SecureStore.getItemAsync(KEYS.GITEA_OWNER),
SecureStore.getItemAsync(KEYS.GITEA_REPO),
SecureStore.getItemAsync(KEYS.MD_TEMPLATE),
]);
if (im) setInputMode(im as "voice" | "form");
if (hv) setHomeView(hv as "dashboard" | "capture");
if (ai) setAiEnabled(ai === "true");
if (key) setAiKey(key);
if (gu) setGiteaUrl(gu);
if (gt) setGiteaToken(gt);
if (go) setGiteaOwner(go);
if (gr) setGiteaRepo(gr);
if (tpl) setMdTemplate(tpl);
})();
}, []);
async function handleSave() {
await Promise.all([
SecureStore.setItemAsync(KEYS.INPUT_MODE, inputMode),
SecureStore.setItemAsync(KEYS.HOME_VIEW, homeView),
SecureStore.setItemAsync(KEYS.AI_ENABLED, String(aiEnabled)),
SecureStore.setItemAsync(KEYS.AI_KEY, aiKey),
SecureStore.setItemAsync(KEYS.GITEA_URL, giteaUrl),
SecureStore.setItemAsync(KEYS.GITEA_TOKEN, giteaToken),
SecureStore.setItemAsync(KEYS.GITEA_OWNER, giteaOwner),
SecureStore.setItemAsync(KEYS.GITEA_REPO, giteaRepo),
SecureStore.setItemAsync(KEYS.MD_TEMPLATE, mdTemplate),
]);
setSaved(true);
setTimeout(() => setSaved(false), 2000);
}
function ToggleRow({
label,
value,
onValueChange,
}: {
label: string;
value: boolean;
onValueChange: (v: boolean) => void;
}) {
return (
{label}
);
}
function SegmentRow({
label,
options,
value,
onChange,
}: {
label: string;
options: { key: string; label: string }[];
value: string;
onChange: (v: string) => void;
}) {
return (
{label}
{options.map((opt) => (
onChange(opt.key)}
style={{
flex: 1,
backgroundColor:
value === opt.key ? Colors.primary : Colors.surface,
borderRadius: 8,
padding: 12,
alignItems: "center",
borderWidth: 1,
borderColor:
value === opt.key ? Colors.primary : Colors.border,
}}
>
{opt.label}
))}
);
}
return (
Preferences
setInputMode(v as "voice" | "form")}
options={[
{ key: "form", label: "Form" },
{ key: "voice", label: "Voice" },
]}
/>
setHomeView(v as "dashboard" | "capture")}
options={[
{ key: "dashboard", label: "Dashboard" },
{ key: "capture", label: "Quick Capture" },
]}
/>
AI (optional)
{aiEnabled && (
<>
API Key
>
)}
Gitea
Instance URL
Token
Owner
Repository
Markdown Template
{saved ? "Saved ✓" : "Save Settings"}
);
}