bigblocks
Version:
Complete Bitcoin UI component library - authentication, social, wallet, market, inscriptions, and blockchain interactions for React
18 lines • 3.75 kB
JSON
{
"name": "social-hooks-usesocialfeed",
"type": "registry:hook",
"dependencies": [
"@tanstack/react-query",
"bmap-api-types"
],
"devDependencies": [],
"registryDependencies": [],
"files": [
{
"path": "components/social/hooks/useSocialFeed.ts",
"type": "registry:hook",
"content": "import { useQuery } from \"@tanstack/react-query\";\nimport type { PostsResponse } from \"bmap-api-types\";\nimport { useState } from \"react\";\nimport { useApiClient } from \"./useApiClient.js\";\n\ninterface UseSocialFeedOptions {\n\tbapId?: string;\n\tfeedType?: \"search\" | \"user\" | \"address\";\n\tlimit?: number;\n\tpage?: number;\n\tenabled?: boolean;\n\tsearchQuery?: string;\n\taddress?: string;\n}\n\nexport function useSocialFeed({\n\tbapId,\n\tfeedType = \"search\",\n\tlimit = 20,\n\tpage = 0,\n\tenabled = true,\n\tsearchQuery = \"bitcoin\",\n\taddress,\n}: UseSocialFeedOptions = {}) {\n\tconst apiClient = useApiClient();\n\tconst queryKey = [\n\t\t\"socialFeed\",\n\t\tfeedType,\n\t\tbapId,\n\t\tpage,\n\t\tlimit,\n\t\tsearchQuery,\n\t\taddress,\n\t];\n\n\tconst { data, isLoading, error, refetch } = useQuery<PostsResponse, Error>({\n\t\tqueryKey,\n\t\tqueryFn: async (): Promise<PostsResponse> => {\n\t\t\tswitch (feedType) {\n\t\t\t\tcase \"user\":\n\t\t\t\t\tif (!bapId) {\n\t\t\t\t\t\tthrow new Error(\"bapId is required for user feed type\");\n\t\t\t\t\t}\n\t\t\t\t\t// API client expects 1-based page numbers\n\t\t\t\t\treturn await apiClient.posts.byBapId({\n\t\t\t\t\t\tbapId,\n\t\t\t\t\t\tpage: page + 1,\n\t\t\t\t\t\tlimit,\n\t\t\t\t\t});\n\t\t\t\tcase \"address\":\n\t\t\t\t\tif (!address) {\n\t\t\t\t\t\tthrow new Error(\"address is required for address feed type\");\n\t\t\t\t\t}\n\t\t\t\t\t// API client expects 1-based page numbers\n\t\t\t\t\treturn await apiClient.posts.byAddress({\n\t\t\t\t\t\taddress,\n\t\t\t\t\t\tpage: page + 1,\n\t\t\t\t\t\tlimit,\n\t\t\t\t\t});\n\t\t\t\tdefault:\n\t\t\t\t\tif (!searchQuery) {\n\t\t\t\t\t\tthrow new Error(\"searchQuery is required for search feed type\");\n\t\t\t\t\t}\n\t\t\t\t\treturn await apiClient.posts.search({\n\t\t\t\t\t\tq: searchQuery,\n\t\t\t\t\t\tlimit,\n\t\t\t\t\t\toffset: page * limit,\n\t\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tenabled,\n\t\tstaleTime: 1000 * 60 * 5,\n\t\trefetchInterval: 1000 * 60 * 2,\n\t});\n\n\treturn {\n\t\tdata,\n\t\tisLoading,\n\t\terror,\n\t\trefetch,\n\t\thasError: !!error,\n\t};\n}\n\nexport function usePostSearch() {\n\tconst apiClient = useApiClient();\n\tconst [searchResults, setSearchResults] = useState<PostsResponse | null>(\n\t\tnull,\n\t);\n\tconst [isSearching, setIsSearching] = useState(false);\n\tconst [searchError, setSearchError] = useState<Error | null>(null);\n\n\tconst searchPosts = async (query: string): Promise<PostsResponse> => {\n\t\tif (!query.trim()) {\n\t\t\tsetSearchResults(null);\n\t\t\treturn {\n\t\t\t\tpage: 0,\n\t\t\t\tlimit: 0,\n\t\t\t\tcount: 0,\n\t\t\t\tresults: [],\n\t\t\t\tsigners: [],\n\t\t\t\tmeta: [],\n\t\t\t};\n\t\t}\n\n\t\tsetIsSearching(true);\n\t\tsetSearchError(null);\n\n\t\ttry {\n\t\t\tconst postsResponse = await apiClient.posts.search({\n\t\t\t\tq: query,\n\t\t\t\tlimit: 20,\n\t\t\t\toffset: 0,\n\t\t\t});\n\t\t\tsetSearchResults(postsResponse);\n\t\t\treturn postsResponse;\n\t\t} catch (error) {\n\t\t\tconst errorObj =\n\t\t\t\terror instanceof Error ? error : new Error(\"Search failed\");\n\t\t\tsetSearchError(errorObj);\n\t\t\tsetSearchResults(null);\n\t\t\tthrow errorObj;\n\t\t} finally {\n\t\t\tsetIsSearching(false);\n\t\t}\n\t};\n\n\treturn {\n\t\tsearchPosts,\n\t\tisSearching,\n\t\tsearchResults,\n\t\tsearchError,\n\t\thasSearchError: !!searchError,\n\t};\n}\n",
"target": "<%- config.aliases.hooks %>/usesocialfeed.ts"
}
]
}