import axios, { AxiosInstance } from "axios"; import * as SecureStore from "expo-secure-store"; import React, { createContext, useCallback, useContext, useEffect, useState, } from "react"; const WORKSPACES_KEY = "postiz_workspaces_v2"; const LEGACY_API_KEY = "postiz_api_key"; const LEGACY_BASE_URL = "postiz_base_url"; export const DEFAULT_BASE_URL = "https://postiz.gyozamancave.fr/api/public/v1"; export interface PostizWorkspace { id: string; name: string; apiKey: string; baseUrl: string; } export interface PostizIntegration { id: string; name: string; type: string; picture?: string; identifier?: string; internalType?: string; } export interface PostizMediaItem { id: string; path: string; } export interface PostizPost { id: string; content: string; state: "QUEUE" | "PUBLISHED" | "ERROR" | "DRAFT"; publishDate: string; integration?: PostizIntegration; integrations?: PostizIntegration[]; image?: PostizMediaItem[]; group?: string; errorMessage?: string; } export interface PostizUploadResult { id: string; path: string; } interface PostizContextValue { workspaces: PostizWorkspace[]; isConfigured: boolean; isLoading: boolean; clients: Record; addWorkspace: (ws: Omit) => Promise; updateWorkspace: (ws: PostizWorkspace) => Promise; removeWorkspace: (id: string) => Promise; // backward compat for posts.tsx (first workspace) client: AxiosInstance | null; apiKey: string; baseUrl: string; } const PostizContext = createContext({ workspaces: [], isConfigured: false, isLoading: true, clients: {}, addWorkspace: async () => {}, updateWorkspace: async () => {}, removeWorkspace: async () => {}, client: null, apiKey: "", baseUrl: DEFAULT_BASE_URL, }); function makeClient(ws: PostizWorkspace): AxiosInstance { const baseURL = ws.baseUrl.endsWith("/") ? ws.baseUrl : ws.baseUrl + "/"; const instance = axios.create({ baseURL, headers: { Authorization: ws.apiKey, "Content-Type": "application/json" }, timeout: 15000, }); instance.interceptors.request.use((config) => { console.log(">>> REQUEST:", config.method?.toUpperCase(), (config.baseURL ?? "") + (config.url ?? "")); return config; }); return instance; } function buildClients(list: PostizWorkspace[]): Record { return Object.fromEntries(list.map((ws) => [ws.id, makeClient(ws)])); } export function PostizProvider({ children }: { children: React.ReactNode }) { const [workspaces, setWorkspaces] = useState([]); const [clients, setClients] = useState>({}); const [isLoading, setIsLoading] = useState(true); useEffect(() => { (async () => { try { const stored = await SecureStore.getItemAsync(WORKSPACES_KEY); if (stored) { const list: PostizWorkspace[] = JSON.parse(stored); setWorkspaces(list); setClients(buildClients(list)); } else { // Migrate legacy single-workspace config const legacyKey = await SecureStore.getItemAsync(LEGACY_API_KEY); const legacyUrl = await SecureStore.getItemAsync(LEGACY_BASE_URL); if (legacyKey) { const migrated: PostizWorkspace = { id: Date.now().toString(), name: "Default", apiKey: legacyKey, baseUrl: (legacyUrl || DEFAULT_BASE_URL).replace(/\/$/, ""), }; const list = [migrated]; await SecureStore.setItemAsync(WORKSPACES_KEY, JSON.stringify(list)); setWorkspaces(list); setClients(buildClients(list)); } } } catch { } finally { setIsLoading(false); } })(); }, []); const persist = useCallback(async (list: PostizWorkspace[]) => { await SecureStore.setItemAsync(WORKSPACES_KEY, JSON.stringify(list)); setWorkspaces(list); setClients(buildClients(list)); }, []); const addWorkspace = useCallback( async (ws: Omit) => { await persist([...workspaces, { ...ws, id: Date.now().toString() }]); }, [workspaces, persist] ); const updateWorkspace = useCallback( async (ws: PostizWorkspace) => { await persist(workspaces.map((w) => (w.id === ws.id ? ws : w))); }, [workspaces, persist] ); const removeWorkspace = useCallback( async (id: string) => { await persist(workspaces.filter((w) => w.id !== id)); }, [workspaces, persist] ); const primaryWorkspace = workspaces[0] ?? null; return ( 0, isLoading, clients, addWorkspace, updateWorkspace, removeWorkspace, client: primaryWorkspace ? (clients[primaryWorkspace.id] ?? null) : null, apiKey: primaryWorkspace?.apiKey ?? "", baseUrl: primaryWorkspace?.baseUrl ?? DEFAULT_BASE_URL, }} > {children} ); } export function usePostiz() { return useContext(PostizContext); }