From a0c44fb3e4e690c5cc6071e37ac64973c12387d9 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 17:31:47 +0200 Subject: [PATCH 01/24] Rename const --- src/components/Journal/ProjectPosts.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Journal/ProjectPosts.tsx b/src/components/Journal/ProjectPosts.tsx index d5709a487..8571f3b19 100644 --- a/src/components/Journal/ProjectPosts.tsx +++ b/src/components/Journal/ProjectPosts.tsx @@ -20,7 +20,7 @@ interface Props { projectTitle?: string; } -const PostsForProjects = ( { +const ProjectPosts = ( { projectIcon, projectId, projectTitle, @@ -81,4 +81,4 @@ const PostsForProjects = ( { ); }; -export default PostsForProjects; +export default ProjectPosts; From 0c72151024b2a526e96a21a25e80c89de6b80d77 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 19:06:52 +0200 Subject: [PATCH 02/24] Duplicate ProjectPosts --- src/components/Journal/UserPosts.tsx | 84 ++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/components/Journal/UserPosts.tsx diff --git a/src/components/Journal/UserPosts.tsx b/src/components/Journal/UserPosts.tsx new file mode 100644 index 000000000..8571f3b19 --- /dev/null +++ b/src/components/Journal/UserPosts.tsx @@ -0,0 +1,84 @@ +import { useNavigation } from "@react-navigation/native"; +import { POST_FOR_PROJECT_FIELDS } from "api/fields"; +import { fetchProjectPosts } from "api/posts"; +import { ScreenShell } from "components/SharedComponents/ViewWrapper"; +import type { TabStackScreenProps } from "navigation/types"; +import React, { + useEffect, + useMemo, +} from "react"; +import { + useInfiniteScroll, + useTranslation, +} from "sharedHooks"; + +import PostList from "./PostList"; + +interface Props { + projectIcon?: string; + projectId?: number; + projectTitle?: string; +} + +const ProjectPosts = ( { + projectIcon, + projectId, + projectTitle, +}: Props ) => { + const navigation + = useNavigation["navigation"]>(); + const { t } = useTranslation(); + + const queryKey = ["fetchProjectPosts", projectId]; + const queryParams = { + id: projectId, + fields: POST_FOR_PROJECT_FIELDS, + }; + + const { + data: projectPosts, + fetchNextPage, + isFetchingNextPage, + totalResults: totalPosts, + } = useInfiniteScroll( queryKey, fetchProjectPosts, queryParams, { + enabled: !!projectId, + } ); + + const headerOptions = useMemo( + () => ( { + headerTitle: projectTitle, + headerSubtitle: t( "X-JOURNAL_POSTS", { + count: totalPosts || 0, + } ), + } ), + [totalPosts, t, projectTitle], + ); + + useEffect( () => { + navigation.setOptions( headerOptions ); + }, [headerOptions, navigation] ); + + const enrichedPosts = useMemo( () => { + if ( !projectPosts ) return null; + + return projectPosts?.map( p => ( { + ...p, + parent: { + id: projectId, + icon_url: projectIcon, + }, + } ) ); + }, [projectIcon, projectId, projectPosts] ); + + return ( + + + + ); +}; + +export default ProjectPosts; From a79f2c0c300f59dbb81242f97f7f9d2a5f6ee273 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:11:50 +0200 Subject: [PATCH 03/24] Add user nav params --- src/components/Journal/Journal.tsx | 5 ++++- src/components/UserProfile/UserProfile.tsx | 4 +++- src/navigation/types.ts | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/components/Journal/Journal.tsx b/src/components/Journal/Journal.tsx index 471b680e3..50ced2d2d 100644 --- a/src/components/Journal/Journal.tsx +++ b/src/components/Journal/Journal.tsx @@ -8,9 +8,12 @@ import ProjectPosts from "./ProjectPosts"; const Journal = ( ) => { const { params } = useRoute["route"]>( ); const { - journalPostsCount, projectIcon, projectId, projectTitle, userLogin, + journalPostsCount, projectIcon, projectId, projectTitle, userId, userIcon, userLogin, } = params || {}; + console.log( "userId", userId ); + console.log( "userIcon", userIcon ); + if ( projectId ) { return ( { const onJournalPostsPressed = ( ) => { navigation.navigate( "Journal", { - userLogin: user?.login, journalPostsCount: user?.journal_posts_count, + userIcon: user?.icon_url, + userId: user?.id, + userLogin: user?.login, } ); }; diff --git a/src/navigation/types.ts b/src/navigation/types.ts index ca5b5f111..9488fd362 100644 --- a/src/navigation/types.ts +++ b/src/navigation/types.ts @@ -337,6 +337,8 @@ export type BaseTabStackParamList = { // projectTitle: project?.title, // } Journal: { + userIcon?: string; + userId?: number; userLogin?: string; projectIcon?: string; projectId?: number; From 8a5efc3c7cf44664b60b7fdb497a44f4834b2d2e Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:19:33 +0200 Subject: [PATCH 04/24] Remove journalPostsCount nav param --- src/components/Journal/Journal.tsx | 3 +-- src/components/UserProfile/UserProfile.tsx | 1 - src/navigation/types.ts | 6 +++--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/Journal/Journal.tsx b/src/components/Journal/Journal.tsx index 50ced2d2d..3286999ac 100644 --- a/src/components/Journal/Journal.tsx +++ b/src/components/Journal/Journal.tsx @@ -8,7 +8,7 @@ import ProjectPosts from "./ProjectPosts"; const Journal = ( ) => { const { params } = useRoute["route"]>( ); const { - journalPostsCount, projectIcon, projectId, projectTitle, userId, userIcon, userLogin, + projectIcon, projectId, projectTitle, userId, userIcon, userLogin, } = params || {}; console.log( "userId", userId ); @@ -26,7 +26,6 @@ const Journal = ( ) => { // TODO: posts for one user if ( userLogin ) { - console.log( journalPostsCount ); return null; } diff --git a/src/components/UserProfile/UserProfile.tsx b/src/components/UserProfile/UserProfile.tsx index 15cb9b6dc..837267bdf 100644 --- a/src/components/UserProfile/UserProfile.tsx +++ b/src/components/UserProfile/UserProfile.tsx @@ -146,7 +146,6 @@ const UserProfile = ( ) => { const onJournalPostsPressed = ( ) => { navigation.navigate( "Journal", { - journalPostsCount: user?.journal_posts_count, userIcon: user?.icon_url, userId: user?.id, userLogin: user?.login, diff --git a/src/navigation/types.ts b/src/navigation/types.ts index 9488fd362..9465e5f41 100644 --- a/src/navigation/types.ts +++ b/src/navigation/types.ts @@ -327,8 +327,9 @@ export type BaseTabStackParamList = { }; // From UserProfile // { - // userLogin: user?.login, - // journalPostsCount: user?.journal_posts_count, + // userId: user?.id, + // userIcon: user?.login, + // userLogin: user?.icon_url, // } // From ProjectDetails // { @@ -343,7 +344,6 @@ export type BaseTabStackParamList = { projectIcon?: string; projectId?: number; projectTitle?: string; - journalPostsCount?: number; } | undefined; Debug: undefined; UILibrary: undefined; From 5cd89b43963a078168f6d8cb7721abb4758f548e Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:20:09 +0200 Subject: [PATCH 05/24] Alphabetical order --- src/navigation/types.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/navigation/types.ts b/src/navigation/types.ts index 9465e5f41..f598bc050 100644 --- a/src/navigation/types.ts +++ b/src/navigation/types.ts @@ -338,12 +338,12 @@ export type BaseTabStackParamList = { // projectTitle: project?.title, // } Journal: { - userIcon?: string; - userId?: number; - userLogin?: string; projectIcon?: string; projectId?: number; projectTitle?: string; + userIcon?: string; + userId?: number; + userLogin?: string; } | undefined; Debug: undefined; UILibrary: undefined; From 5243a00bbf54a4256853630a54cb122c2edcc3bf Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:22:19 +0200 Subject: [PATCH 06/24] Return UserPosts for user --- src/components/Journal/Journal.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/components/Journal/Journal.tsx b/src/components/Journal/Journal.tsx index 3286999ac..a239aa94d 100644 --- a/src/components/Journal/Journal.tsx +++ b/src/components/Journal/Journal.tsx @@ -4,16 +4,14 @@ import React from "react"; import Blog from "./Blog"; import ProjectPosts from "./ProjectPosts"; +import UserPosts from "./UserPosts"; const Journal = ( ) => { const { params } = useRoute["route"]>( ); const { - projectIcon, projectId, projectTitle, userId, userIcon, userLogin, + projectIcon, projectId, projectTitle, userIcon, userId, userLogin, } = params || {}; - console.log( "userId", userId ); - console.log( "userIcon", userIcon ); - if ( projectId ) { return ( { ); } - // TODO: posts for one user if ( userLogin ) { - return null; + return ( + + ); } return ( From 147e233f47abbb3703c66661dc2b3daff4a0b428 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:23:38 +0200 Subject: [PATCH 07/24] Project id must be defined --- src/components/Journal/ProjectPosts.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Journal/ProjectPosts.tsx b/src/components/Journal/ProjectPosts.tsx index 8571f3b19..f45c1dd04 100644 --- a/src/components/Journal/ProjectPosts.tsx +++ b/src/components/Journal/ProjectPosts.tsx @@ -16,7 +16,7 @@ import PostList from "./PostList"; interface Props { projectIcon?: string; - projectId?: number; + projectId: number; projectTitle?: string; } From eba4a563aab733c03626404af4291ce5a3c9a1fe Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:23:56 +0200 Subject: [PATCH 08/24] Change if to check for id --- src/components/Journal/Journal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Journal/Journal.tsx b/src/components/Journal/Journal.tsx index a239aa94d..c223036c3 100644 --- a/src/components/Journal/Journal.tsx +++ b/src/components/Journal/Journal.tsx @@ -22,7 +22,7 @@ const Journal = ( ) => { ); } - if ( userLogin ) { + if ( userId ) { return ( Date: Thu, 16 Jul 2026 20:24:50 +0200 Subject: [PATCH 09/24] Update post list params --- src/components/Journal/UserPosts.tsx | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/components/Journal/UserPosts.tsx b/src/components/Journal/UserPosts.tsx index 8571f3b19..600c685e0 100644 --- a/src/components/Journal/UserPosts.tsx +++ b/src/components/Journal/UserPosts.tsx @@ -15,23 +15,23 @@ import { import PostList from "./PostList"; interface Props { - projectIcon?: string; - projectId?: number; - projectTitle?: string; + userIcon?: string; + userId: number; + userLogin?: string; } const ProjectPosts = ( { - projectIcon, - projectId, - projectTitle, + userIcon, + userId, + userLogin, }: Props ) => { const navigation = useNavigation["navigation"]>(); const { t } = useTranslation(); - const queryKey = ["fetchProjectPosts", projectId]; + const queryKey = ["fetchProjectPosts", userId]; const queryParams = { - id: projectId, + id: userId, fields: POST_FOR_PROJECT_FIELDS, }; @@ -41,17 +41,17 @@ const ProjectPosts = ( { isFetchingNextPage, totalResults: totalPosts, } = useInfiniteScroll( queryKey, fetchProjectPosts, queryParams, { - enabled: !!projectId, + enabled: !!userId, } ); const headerOptions = useMemo( () => ( { - headerTitle: projectTitle, + headerTitle: userLogin, headerSubtitle: t( "X-JOURNAL_POSTS", { count: totalPosts || 0, } ), } ), - [totalPosts, t, projectTitle], + [totalPosts, t, userLogin], ); useEffect( () => { @@ -64,11 +64,11 @@ const ProjectPosts = ( { return projectPosts?.map( p => ( { ...p, parent: { - id: projectId, - icon_url: projectIcon, + id: userId, + icon_url: userIcon, }, } ) ); - }, [projectIcon, projectId, projectPosts] ); + }, [userIcon, userId, projectPosts] ); return ( From a163885afe928d31ab3975822e3a8f8737ce99b5 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:29:51 +0200 Subject: [PATCH 10/24] Rename api call wrapper to fetchBlogPosts --- src/api/posts.ts | 7 ++++--- src/components/Journal/Blog.tsx | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/api/posts.ts b/src/api/posts.ts index 713d036c2..376014978 100644 --- a/src/api/posts.ts +++ b/src/api/posts.ts @@ -2,7 +2,7 @@ import type { ErrorWithResponse, INatApiError } from "api/error"; import handleError from "api/error"; import inatjs from "inaturalistjs"; -const fetchUserPosts = async ( +const fetchBlogPosts = async ( params: Record = {}, opts: Record = {}, ): Promise | null | ErrorWithResponse | INatApiError> => { @@ -11,7 +11,7 @@ const fetchUserPosts = async ( } catch ( e ) { return handleError( e as ErrorWithResponse, - { context: { functionName: "fetchUserPosts", opts } }, + { context: { functionName: "fetchBlogPosts", opts } }, ); } }; @@ -31,6 +31,7 @@ const fetchProjectPosts = async ( }; export { + fetchBlogPosts, fetchProjectPosts, - fetchUserPosts, + // fetchUserPosts, }; diff --git a/src/components/Journal/Blog.tsx b/src/components/Journal/Blog.tsx index 000c0d287..714c22ba9 100644 --- a/src/components/Journal/Blog.tsx +++ b/src/components/Journal/Blog.tsx @@ -1,6 +1,6 @@ import { useNavigation } from "@react-navigation/native"; import { POST_FOR_USER_FIELDS } from "api/fields"; -import { fetchUserPosts } from "api/posts"; +import { fetchBlogPosts } from "api/posts"; import { ScreenShell } from "components/SharedComponents/ViewWrapper"; import type { TabStackScreenProps } from "navigation/types"; import React, { @@ -18,7 +18,7 @@ const Blog = ( ) => { const navigation = useNavigation["navigation"]>( ); const { t } = useTranslation( ); - const queryKey = ["fetchUserPosts"]; + const queryKey = ["fetchBlogPosts"]; const queryParams = { fields: POST_FOR_USER_FIELDS, }; @@ -28,7 +28,7 @@ const Blog = ( ) => { fetchNextPage, isFetchingNextPage, totalResults: totalPosts, - } = useInfiniteScroll( queryKey, fetchUserPosts, queryParams, { + } = useInfiniteScroll( queryKey, fetchBlogPosts, queryParams, { enabled: true, } ); From eb444be09c821026905cb07366ac5a6a42659ac4 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:31:29 +0200 Subject: [PATCH 11/24] Add new fetchUserPosts, a call that fetches posts of a user --- src/api/posts.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/api/posts.ts b/src/api/posts.ts index 376014978..3ebc6fad6 100644 --- a/src/api/posts.ts +++ b/src/api/posts.ts @@ -30,8 +30,22 @@ const fetchProjectPosts = async ( } }; +const fetchUserPosts = async ( + params: Record = {}, + opts: Record = {}, +): Promise | null | ErrorWithResponse | INatApiError> => { + try { + return await inatjs.users.posts( params, opts ); + } catch ( e ) { + return handleError( + e as ErrorWithResponse, + { context: { functionName: "fetchUserPosts", opts } }, + ); + } +}; + export { fetchBlogPosts, fetchProjectPosts, - // fetchUserPosts, + fetchUserPosts, }; From 3c0a66a71e68988fe8a99ae2b123b8bece9ce14a Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:33:46 +0200 Subject: [PATCH 12/24] Use new api call --- src/components/Journal/UserPosts.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Journal/UserPosts.tsx b/src/components/Journal/UserPosts.tsx index 600c685e0..aa1670ac8 100644 --- a/src/components/Journal/UserPosts.tsx +++ b/src/components/Journal/UserPosts.tsx @@ -1,6 +1,6 @@ import { useNavigation } from "@react-navigation/native"; import { POST_FOR_PROJECT_FIELDS } from "api/fields"; -import { fetchProjectPosts } from "api/posts"; +import { fetchUserPosts } from "api/posts"; import { ScreenShell } from "components/SharedComponents/ViewWrapper"; import type { TabStackScreenProps } from "navigation/types"; import React, { @@ -29,7 +29,7 @@ const ProjectPosts = ( { = useNavigation["navigation"]>(); const { t } = useTranslation(); - const queryKey = ["fetchProjectPosts", userId]; + const queryKey = ["fetchUserPosts", userId]; const queryParams = { id: userId, fields: POST_FOR_PROJECT_FIELDS, @@ -40,7 +40,7 @@ const ProjectPosts = ( { fetchNextPage, isFetchingNextPage, totalResults: totalPosts, - } = useInfiniteScroll( queryKey, fetchProjectPosts, queryParams, { + } = useInfiniteScroll( queryKey, fetchUserPosts, queryParams, { enabled: !!userId, } ); From 06b7a94903a8996a13fe77be7b0e6b5e369dddfe Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:35:41 +0200 Subject: [PATCH 13/24] Add params type --- src/api/posts.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/api/posts.ts b/src/api/posts.ts index 3ebc6fad6..c5105df73 100644 --- a/src/api/posts.ts +++ b/src/api/posts.ts @@ -1,5 +1,6 @@ import type { ErrorWithResponse, INatApiError } from "api/error"; import handleError from "api/error"; +import type { ApiParams } from "api/types"; import inatjs from "inaturalistjs"; const fetchBlogPosts = async ( @@ -16,8 +17,12 @@ const fetchBlogPosts = async ( } }; +interface ProjectPostsParams extends ApiParams { + id: number; +} + const fetchProjectPosts = async ( - params: Record = {}, + params: ProjectPostsParams, opts: Record = {}, ): Promise | null | ErrorWithResponse | INatApiError> => { try { @@ -30,8 +35,12 @@ const fetchProjectPosts = async ( } }; +interface UserPostsParams extends ApiParams { + id: number; +} + const fetchUserPosts = async ( - params: Record = {}, + params: UserPostsParams, opts: Record = {}, ): Promise | null | ErrorWithResponse | INatApiError> => { try { From b9061706a07980da55660ff9d5da6e1b848d188a Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:41:15 +0200 Subject: [PATCH 14/24] Type opts --- src/api/posts.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/api/posts.ts b/src/api/posts.ts index c5105df73..73585e9a9 100644 --- a/src/api/posts.ts +++ b/src/api/posts.ts @@ -1,11 +1,11 @@ import type { ErrorWithResponse, INatApiError } from "api/error"; import handleError from "api/error"; -import type { ApiParams } from "api/types"; +import type { ApiOpts, ApiParams } from "api/types"; import inatjs from "inaturalistjs"; const fetchBlogPosts = async ( params: Record = {}, - opts: Record = {}, + opts: ApiOpts = {}, ): Promise | null | ErrorWithResponse | INatApiError> => { try { return await inatjs.posts.for_user( params, opts ); @@ -23,7 +23,7 @@ interface ProjectPostsParams extends ApiParams { const fetchProjectPosts = async ( params: ProjectPostsParams, - opts: Record = {}, + opts: ApiOpts = {}, ): Promise | null | ErrorWithResponse | INatApiError> => { try { return await inatjs.projects.posts( params, opts ); @@ -41,7 +41,7 @@ interface UserPostsParams extends ApiParams { const fetchUserPosts = async ( params: UserPostsParams, - opts: Record = {}, + opts: ApiOpts = {}, ): Promise | null | ErrorWithResponse | INatApiError> => { try { return await inatjs.users.posts( params, opts ); From 02e868fca02b22194898970e338214013ea80d98 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:41:59 +0200 Subject: [PATCH 15/24] Type params --- src/api/posts.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/posts.ts b/src/api/posts.ts index 73585e9a9..08730b661 100644 --- a/src/api/posts.ts +++ b/src/api/posts.ts @@ -4,7 +4,7 @@ import type { ApiOpts, ApiParams } from "api/types"; import inatjs from "inaturalistjs"; const fetchBlogPosts = async ( - params: Record = {}, + params: ApiParams = {}, opts: ApiOpts = {}, ): Promise | null | ErrorWithResponse | INatApiError> => { try { From 9223ddcea9ed630e3b359f6ffd10872da47deab1 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:44:39 +0200 Subject: [PATCH 16/24] Type default response --- src/api/posts.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/api/posts.ts b/src/api/posts.ts index 08730b661..9fe6926ed 100644 --- a/src/api/posts.ts +++ b/src/api/posts.ts @@ -1,12 +1,14 @@ import type { ErrorWithResponse, INatApiError } from "api/error"; import handleError from "api/error"; -import type { ApiOpts, ApiParams } from "api/types"; +import type { + ApiDefaultResult, ApiOpts, ApiParams, ApiResponse, +} from "api/types"; import inatjs from "inaturalistjs"; -const fetchBlogPosts = async ( +const fetchBlogPosts = async ( params: ApiParams = {}, opts: ApiOpts = {}, -): Promise | null | ErrorWithResponse | INatApiError> => { +): Promise | null | ErrorWithResponse | INatApiError> => { try { return await inatjs.posts.for_user( params, opts ); } catch ( e ) { @@ -21,10 +23,10 @@ interface ProjectPostsParams extends ApiParams { id: number; } -const fetchProjectPosts = async ( +const fetchProjectPosts = async ( params: ProjectPostsParams, opts: ApiOpts = {}, -): Promise | null | ErrorWithResponse | INatApiError> => { +): Promise | null | ErrorWithResponse | INatApiError> => { try { return await inatjs.projects.posts( params, opts ); } catch ( e ) { @@ -39,10 +41,10 @@ interface UserPostsParams extends ApiParams { id: number; } -const fetchUserPosts = async ( +const fetchUserPosts = async ( params: UserPostsParams, opts: ApiOpts = {}, -): Promise | null | ErrorWithResponse | INatApiError> => { +): Promise | null | ErrorWithResponse | INatApiError> => { try { return await inatjs.users.posts( params, opts ); } catch ( e ) { From 72dba22418e78cf5c4c149803f9533b0ab4d92d0 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:45:56 +0200 Subject: [PATCH 17/24] Catch faulty response and return null --- src/api/posts.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/api/posts.ts b/src/api/posts.ts index 9fe6926ed..a658e10df 100644 --- a/src/api/posts.ts +++ b/src/api/posts.ts @@ -10,7 +10,9 @@ const fetchBlogPosts = async ( opts: ApiOpts = {}, ): Promise | null | ErrorWithResponse | INatApiError> => { try { - return await inatjs.posts.for_user( params, opts ); + const response = await inatjs.posts.for_user( params, opts ); + if ( !response ) { return null; } + return response; } catch ( e ) { return handleError( e as ErrorWithResponse, @@ -28,7 +30,9 @@ const fetchProjectPosts = async ( opts: ApiOpts = {}, ): Promise | null | ErrorWithResponse | INatApiError> => { try { - return await inatjs.projects.posts( params, opts ); + const response = await inatjs.projects.posts( params, opts ); + if ( !response ) { return null; } + return response; } catch ( e ) { return handleError( e as ErrorWithResponse, @@ -46,7 +50,9 @@ const fetchUserPosts = async ( opts: ApiOpts = {}, ): Promise | null | ErrorWithResponse | INatApiError> => { try { - return await inatjs.users.posts( params, opts ); + const response = await inatjs.users.posts( params, opts ); + if ( !response ) { return null; } + return response; } catch ( e ) { return handleError( e as ErrorWithResponse, From 1e74199ed16649c3902106a81be7ba5d1cd60973 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:47:40 +0200 Subject: [PATCH 18/24] Refactor imports --- src/api/usersTyped.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/api/usersTyped.ts b/src/api/usersTyped.ts index aa0cde902..154fab349 100644 --- a/src/api/usersTyped.ts +++ b/src/api/usersTyped.ts @@ -1,10 +1,9 @@ -import inatjs from "inaturalistjs"; - -import type { ErrorWithResponse, INatApiError } from "./error"; -import handleError from "./error"; +import type { ErrorWithResponse, INatApiError } from "api/error"; +import handleError from "api/error"; import type { ApiDefaultResult, ApiOpts, ApiParams, ApiResponse, -} from "./types"; +} from "api/types"; +import inatjs from "inaturalistjs"; interface UsersProjectsParams extends ApiParams { id: number; From 4fc7296b6ea867095539d8fb7a8d180e5d350c8b Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:51:20 +0200 Subject: [PATCH 19/24] More generic name --- src/api/types.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/types.d.ts b/src/api/types.d.ts index 94e388fef..92a932493 100644 --- a/src/api/types.d.ts +++ b/src/api/types.d.ts @@ -21,7 +21,7 @@ export interface ApiPlace { place_type?: number | null; } -export interface ApiPostForProject { +export interface ApiPost { body: string; id: number; published_at: string; @@ -29,7 +29,7 @@ export interface ApiPostForProject { } // When using POST_FOR_USER_FIELDS -export interface ApiPostForUser extends ApiPostForProject { +export interface ApiPostForUser extends ApiPost { parent: { id: number; icon_url: string | null; From 2212fb5a26bcd8aec03ca3cef6f38603c218d583 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:53:27 +0200 Subject: [PATCH 20/24] Rename data --- src/components/Journal/UserPosts.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/Journal/UserPosts.tsx b/src/components/Journal/UserPosts.tsx index aa1670ac8..d9bcfae77 100644 --- a/src/components/Journal/UserPosts.tsx +++ b/src/components/Journal/UserPosts.tsx @@ -36,7 +36,7 @@ const ProjectPosts = ( { }; const { - data: projectPosts, + data: userPosts, fetchNextPage, isFetchingNextPage, totalResults: totalPosts, @@ -59,16 +59,16 @@ const ProjectPosts = ( { }, [headerOptions, navigation] ); const enrichedPosts = useMemo( () => { - if ( !projectPosts ) return null; + if ( !userPosts ) return null; - return projectPosts?.map( p => ( { + return userPosts?.map( p => ( { ...p, parent: { id: userId, icon_url: userIcon, }, } ) ); - }, [userIcon, userId, projectPosts] ); + }, [userIcon, userId, userPosts] ); return ( From 0dab1e9fa58662170acc20882e19dad22bd650de Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 21:04:15 +0200 Subject: [PATCH 21/24] Use uri access fct --- src/components/UserProfile/UserProfile.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/UserProfile/UserProfile.tsx b/src/components/UserProfile/UserProfile.tsx index 837267bdf..c8d7d8e90 100644 --- a/src/components/UserProfile/UserProfile.tsx +++ b/src/components/UserProfile/UserProfile.tsx @@ -146,7 +146,7 @@ const UserProfile = ( ) => { const onJournalPostsPressed = ( ) => { navigation.navigate( "Journal", { - userIcon: user?.icon_url, + userIcon: User.uri( user ), userId: user?.id, userLogin: user?.login, } ); From f3f526bec976a2457b87bd11ac26dabf30982b60 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Thu, 16 Jul 2026 21:13:35 +0200 Subject: [PATCH 22/24] Update UserPosts.tsx --- src/components/Journal/UserPosts.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Journal/UserPosts.tsx b/src/components/Journal/UserPosts.tsx index d9bcfae77..c7e672b54 100644 --- a/src/components/Journal/UserPosts.tsx +++ b/src/components/Journal/UserPosts.tsx @@ -20,7 +20,7 @@ interface Props { userLogin?: string; } -const ProjectPosts = ( { +const UserPosts = ( { userIcon, userId, userLogin, @@ -81,4 +81,4 @@ const ProjectPosts = ( { ); }; -export default ProjectPosts; +export default UserPosts; From cafe0a49dede6ec7d7c182ed5cd4cbf6ec29a7fc Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Fri, 17 Jul 2026 13:30:06 +0200 Subject: [PATCH 23/24] Swap comment --- src/navigation/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/navigation/types.ts b/src/navigation/types.ts index f598bc050..2efec5f07 100644 --- a/src/navigation/types.ts +++ b/src/navigation/types.ts @@ -328,8 +328,8 @@ export type BaseTabStackParamList = { // From UserProfile // { // userId: user?.id, - // userIcon: user?.login, - // userLogin: user?.icon_url, + // userIcon: user?.icon_url, + // userLogin: user?.login, // } // From ProjectDetails // { From c5e6d6447cb94bc00a11a1de37670d0f976b36e2 Mon Sep 17 00:00:00 2001 From: Johannes Klein <17345891+jtklein@users.noreply.github.com> Date: Fri, 17 Jul 2026 13:32:58 +0200 Subject: [PATCH 24/24] Generic params type to get a record by id from api --- src/api/posts.ts | 14 +++----------- src/api/types.d.ts | 4 ++++ src/api/usersTyped.ts | 8 ++------ 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/api/posts.ts b/src/api/posts.ts index a658e10df..84ecf505a 100644 --- a/src/api/posts.ts +++ b/src/api/posts.ts @@ -1,7 +1,7 @@ import type { ErrorWithResponse, INatApiError } from "api/error"; import handleError from "api/error"; import type { - ApiDefaultResult, ApiOpts, ApiParams, ApiResponse, + ApiDefaultResult, ApiGetByIdParams, ApiOpts, ApiParams, ApiResponse, } from "api/types"; import inatjs from "inaturalistjs"; @@ -21,12 +21,8 @@ const fetchBlogPosts = async ( } }; -interface ProjectPostsParams extends ApiParams { - id: number; -} - const fetchProjectPosts = async ( - params: ProjectPostsParams, + params: ApiGetByIdParams, opts: ApiOpts = {}, ): Promise | null | ErrorWithResponse | INatApiError> => { try { @@ -41,12 +37,8 @@ const fetchProjectPosts = async ( } }; -interface UserPostsParams extends ApiParams { - id: number; -} - const fetchUserPosts = async ( - params: UserPostsParams, + params: ApiGetByIdParams, opts: ApiOpts = {}, ): Promise | null | ErrorWithResponse | INatApiError> => { try { diff --git a/src/api/types.d.ts b/src/api/types.d.ts index 92a932493..d6e4281b3 100644 --- a/src/api/types.d.ts +++ b/src/api/types.d.ts @@ -14,6 +14,10 @@ export interface ApiParams { ttl?: number; } +export interface ApiGetByIdParams extends ApiParams { + id: number; +} + export interface ApiPlace { id?: number; name?: string; diff --git a/src/api/usersTyped.ts b/src/api/usersTyped.ts index 154fab349..fb93b7936 100644 --- a/src/api/usersTyped.ts +++ b/src/api/usersTyped.ts @@ -1,16 +1,12 @@ import type { ErrorWithResponse, INatApiError } from "api/error"; import handleError from "api/error"; import type { - ApiDefaultResult, ApiOpts, ApiParams, ApiResponse, + ApiDefaultResult, ApiGetByIdParams, ApiOpts, ApiResponse, } from "api/types"; import inatjs from "inaturalistjs"; -interface UsersProjectsParams extends ApiParams { - id: number; -} - const fetchUserProjects = async ( - params: UsersProjectsParams, + params: ApiGetByIdParams, opts: ApiOpts = {}, ): Promise | null | ErrorWithResponse | INatApiError> => { try {