OverviewFilesCommitsIssuesDocsReleasesPeers

favela-android commits / fa1eeee

the home feed now comes from favela-web, not from my hand-written query
favela-web has been running in this process since the last build and nothing on screen used it — "I see the exact same thing" was exactly right. This switches the first screen over. /api/timeline returns {posts, cursor} from the same Appview._hydrate shape <Post> already renders, so the change is small; what differs is WHO is behind it. favela-web owns the appview and the inbound lens and is already following ashatron's and loser-club's firehoses (its own boot log: "following firehose front … e2jev", "BACKFILL from seq 0 … frames 75", "viewing wqnwulql … rev 3mrfgnyiurk22"), so a hand-written query beside it could only ever show less. The legacy path stays as a fallback while the other screens are ported: if favela-web did not start, the screen still works instead of going blank. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
fa1eeeea90b27f471e851654e208656f2f91118a
by plankatron <fleeky@gmail.com> · 2026-08-11T01:14:41.000Z

Changed files (1) +21 -7

app/App.jsx +21 -7
……@@ -118,7 +118,7 @@ function Shell ({ client, status, onPaired }) {
118118 </Pressable>
119119 : null}
120120 <View style={s.fill}>
121 {tab === 'home' ? <Timeline client={client} nav={nav} acting={acting} /> : null}
121 {tab === 'home' ? <Timeline client={client} nav={nav} acting={acting} favelaUrl={status && status.favelaUrl} /> : null}
122122 {tab === 'search' ? <Search client={client} nav={nav} /> : null}
123123 {tab === 'browse' ? <Communities client={client} nav={nav} /> : null}
124124 {tab === 'settings' ? <Settings client={client} status={status} nav={nav} /> : null}
……@@ -134,7 +134,14 @@ function Shell ({ client, status, onPaired }) {
134134 )
135135}
136136
137function Timeline ({ client, nav, acting }) {
137// THE FEED COMES FROM favela-web. It runs in this same process (the worklet starts it on loopback), it
138// owns the appview and the inbound lens, and it is already following ashatron's and loser-club's
139// firehoses — which is why hand-written queries beside it could only ever show less. This is the first
140// screen switched over; the rest follow, and the hand-written verbs go when their route takes over.
141//
142// The fallback is deliberate and temporary: if favela-web did not start, the screen still works on the
143// legacy surface rather than being blank, and the log says which one is in use.
144function Timeline ({ client, nav, acting, favelaUrl }) {
138145 const [posts, setPosts] = useState([])
139146 const [cursor, setCursor] = useState(null)
140147 const [refreshing, setRefreshing] = useState(false)
……@@ -146,14 +153,21 @@ function Timeline ({ client, nav, acting }) {
146153 const community = acting && !acting.primary ? acting.did : null
147154 const load = useCallback(async (reset) => {
148155 try {
149 const r = community
150 ? await client.author({ did: community, limit: 30, cursor: reset ? null : cursor })
151 : await client.timeline({ limit: 30, cursor: reset ? null : cursor })
152 setPosts((prev) => (reset ? r.posts : [...prev, ...r.posts]))
156 let r
157 if (favelaUrl && !community) {
158 const res = await fetch(favelaUrl + '/api/timeline?limit=30')
159 if (!res.ok) throw new Error('favela-web /api/timeline ' + res.status)
160 r = await res.json()
161 } else {
162 r = community
163 ? await client.author({ did: community, limit: 30, cursor: reset ? null : cursor })
164 : await client.timeline({ limit: 30, cursor: reset ? null : cursor })
165 }
166 setPosts((prev) => (reset ? (r.posts || []) : [...prev, ...(r.posts || [])]))
153167 setCursor(r.cursor)
154168 setErr(null)
155169 } catch (e) { setErr(e.message) }
156 }, [client, cursor, community])
170 }, [client, cursor, community, favelaUrl])
157171
158172 // Reload when the identity changes — otherwise switching shows the previous identity's feed.
159173 useEffect(() => { setPosts([]); setCursor(null); load(true) }, [community]) // eslint-disable-line react-hooks/exhaustive-deps