|
|
|
@@ -35,6 +35,7 @@ interface Props {
|
|
|
|
|
maxSelect: number;
|
|
|
|
|
onClose: () => void;
|
|
|
|
|
onSelect: (items: LibraryMediaItem[]) => void;
|
|
|
|
|
onPickFromDevice?: () => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function resolveUrl(path: string, baseUrl: string): string {
|
|
|
|
@@ -43,7 +44,7 @@ function resolveUrl(path: string, baseUrl: string): string {
|
|
|
|
|
return `${origin}/${path.replace(/^\//, "")}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function MediaLibraryModal({ visible, workspaces, defaultWorkspaceId, maxSelect, onClose, onSelect }: Props) {
|
|
|
|
|
export function MediaLibraryModal({ visible, workspaces, defaultWorkspaceId, maxSelect, onClose, onSelect, onPickFromDevice }: Props) {
|
|
|
|
|
const colors = useColors();
|
|
|
|
|
const insets = useSafeAreaInsets();
|
|
|
|
|
const [activeId, setActiveId] = useState<string>("");
|
|
|
|
@@ -66,17 +67,19 @@ export function MediaLibraryModal({ visible, workspaces, defaultWorkspaceId, max
|
|
|
|
|
if (!activeWorkspace) return;
|
|
|
|
|
setLoading(true);
|
|
|
|
|
setError(null);
|
|
|
|
|
const url = `${activeWorkspace.baseUrl}/media`;
|
|
|
|
|
const apiBase = activeWorkspace.baseUrl.replace(/\/public\/v1$/, "");
|
|
|
|
|
const url = `${apiBase}/media?page=0&search=`;
|
|
|
|
|
try {
|
|
|
|
|
// eslint-disable-next-line no-undef
|
|
|
|
|
const res = await globalThis.fetch(url, {
|
|
|
|
|
headers: { Authorization: activeWorkspace.apiKey },
|
|
|
|
|
});
|
|
|
|
|
if (!res.ok) {
|
|
|
|
|
if (res.status === 401 || res.status === 403) {
|
|
|
|
|
throw new Error("SESSION_REQUIRED");
|
|
|
|
|
}
|
|
|
|
|
if (res.status === 404) {
|
|
|
|
|
throw new Error(
|
|
|
|
|
`Media listing endpoint not found (404).\nURL tried: ${url}\n\nThis feature requires Postiz to expose GET /media in its public API. Your version may not support it yet.`
|
|
|
|
|
);
|
|
|
|
|
throw new Error("ENDPOINT_NOT_FOUND");
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`HTTP ${res.status} — ${url}`);
|
|
|
|
|
}
|
|
|
|
@@ -171,6 +174,29 @@ export function MediaLibraryModal({ visible, workspaces, defaultWorkspaceId, max
|
|
|
|
|
<View style={styles.centered}>
|
|
|
|
|
<ActivityIndicator color={colors.primary} size="large" />
|
|
|
|
|
</View>
|
|
|
|
|
) : error === "SESSION_REQUIRED" ? (
|
|
|
|
|
<View style={styles.centered}>
|
|
|
|
|
<Feather name="lock" size={28} color={colors.mutedForeground} />
|
|
|
|
|
<Text style={[styles.errorText, { color: colors.mutedForeground }]}>
|
|
|
|
|
{"Media library requires a web session.\nAPI key access is not supported by Postiz."}
|
|
|
|
|
</Text>
|
|
|
|
|
{onPickFromDevice && (
|
|
|
|
|
<TouchableOpacity
|
|
|
|
|
onPress={() => { onClose(); onPickFromDevice(); }}
|
|
|
|
|
style={[styles.retryBtn, { backgroundColor: colors.primary }]}
|
|
|
|
|
activeOpacity={0.8}
|
|
|
|
|
>
|
|
|
|
|
<Text style={[styles.retryText, { color: colors.primaryForeground }]}>Use device gallery</Text>
|
|
|
|
|
</TouchableOpacity>
|
|
|
|
|
)}
|
|
|
|
|
</View>
|
|
|
|
|
) : error === "ENDPOINT_NOT_FOUND" ? (
|
|
|
|
|
<View style={styles.centered}>
|
|
|
|
|
<Feather name="slash" size={28} color={colors.mutedForeground} />
|
|
|
|
|
<Text style={[styles.errorText, { color: colors.mutedForeground }]}>
|
|
|
|
|
{"Media library endpoint not found on this server."}
|
|
|
|
|
</Text>
|
|
|
|
|
</View>
|
|
|
|
|
) : error ? (
|
|
|
|
|
<View style={styles.centered}>
|
|
|
|
|
<Feather name="alert-circle" size={28} color={colors.error} />
|
|
|
|
|