import React, { useRef, useState } from "react";
import {
Animated, LayoutAnimation, Linking,
Platform, Text, TouchableOpacity,
UIManager, View, useColorScheme,
} from "react-native";
import { Ionicons } from "@expo/vector-icons";
import { Entry } from "../services/api";
if (Platform.OS === "android") {
UIManager.setLayoutAnimationEnabledExperimental?.(true);
}
function formatDate(iso: string): string {
try {
return new Date(iso).toLocaleDateString("en-GB", {
day: "numeric", month: "short", year: "numeric",
});
} catch {
return iso;
}
}
function fileName(path: string): string {
return path.split(/[\\/]/).pop() ?? path;
}
export default function ExpandableItem({ item }: { item: Entry }) {
const [expanded, setExpanded] = useState(false);
const rotateAnim = useRef(new Animated.Value(0)).current;
const dark = useColorScheme() === "dark";
const toggle = () => {
LayoutAnimation.configureNext({
duration: 280,
create: { type: "easeInEaseOut", property: "opacity" },
update: { type: "spring", springDamping: 0.8 },
});
Animated.timing(rotateAnim, {
toValue: expanded ? 0 : 1,
duration: 250,
useNativeDriver: true,
}).start();
setExpanded((v) => !v);
};
const chevronRotation = rotateAnim.interpolate({
inputRange: [0, 1],
outputRange: ["0deg", "180deg"],
});
return (
{/* ── Collapsed header ── */}
{/* Subject tag + date */}
{item.subject?.name ?? item.groupName}
{item.groupName}
{formatDate(item.timePublished)}
{/* Title */}
{item.title}
{/* info_entry — always visible as subtitle */}
{item.infoEntry ? (
{item.infoEntry}
) : null}
{/* ── Expanded body ── */}
{expanded && (
{/* paragraph */}
{item.paragraph ? (
Content
{item.paragraph}
) : null}
{/* Meta row: subject + group + date */}
{/* filepath — clickable attachment */}
{item.filepath ? (
Linking.openURL(item.filepath!)}
activeOpacity={0.75}
className={`mx-4 mb-4 flex-row items-center gap-3 px-4 py-3 rounded-xl border ${
dark
? "bg-obsidian-50 border-border-dark"
: "bg-parchment-100 border-border-light"
}`}
// stop the expand/collapse toggle firing
onStartShouldSetResponder={() => true}
>
{fileName(item.filepath)}
Tap to open attachment
) : null}
)}
);
}
function Row({ label, value, dark, last = false }: {
label: string;
value?: string;
dark: boolean;
last?: boolean;
}) {
if (!value) return null;
return (
{label}
{value}
);
}