You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Boy-scout follow-up: #653/#669 converged the tag pages but touched SiteTagPage,
which still carries #[expect(clippy::too_many_lines)]. Per the #306 thin-component
direction, decompose the three timeline pages — and, following the #655 example
(the analogous TagInput thinning, #328), do it so the decomposition turns
currently-exempt reactive code into host-tested code, rather than merely
shuffling wasm sub-components.
The three pages
SiteTagPage, UserTagPage, and UserTimelinePage (web/src/posts/component.rs)
are now byte-for-byte near-identical wiring around the shared crate::timeline
bundle: build a keyed Resource, TimelineState::default() + a loaded gate,
adopt the PageSeed seed, a resolve Effect, a spawn_load_more load-more, a read_errorMemo, then chrome + the error/loading/TimelineRows gate. All three
carry #[expect(clippy::too_many_lines)].
Host-testable core.#329 already split the pure model
(TimelineCursor/LoadStatus/fold logic → host-tested timeline/state.rs) from
the reactive TimelineState signal-bundle (wasm-only timeline/component.rs,
gated at mod.rs:14). The one uncovered behavior is TimelineState's
transitions (adopt/resolve/fail, and the page's "apply the fetched result"
dispatch) — exempt today only because the bundle is wasm-gated. Relocate the TimelineState signal-bundle into host-compiled state.rs and cover its
transitions under an Owner (the web::reactive::Invalidator / forms::Field
convention web(tags): co-locate TagInput into the tags vertical (#328) #655 used) — no #[client_only]. This is the "decomposing made it
host-testable" win.
Shared reactive residue → one component + one helper. Extract a TimelineGate #[component] (the error → loading → <TimelineRows/> gate, taking state/loaded/read_error/on_mutate/on_load_more + tag_context/empty_text)
and a wire_timeline_resolve(state, loaded, initial_page) -> Memo<Option<String>>
helper (the resolve Effect + the failure Memo). Both in crate::timeline.
Sweep all three pages onto the extracted pieces; each collapses to its
page-specific bits (params, keyed Resource, PageSeed adoption, load-more fetch,
chrome). Drop all three #[expect(clippy::too_many_lines)].
Acceptance
All three timeline pages free of #[expect(clippy::too_many_lines)]; no #[client_only] added.
TimelineState host-compiled with Owner-based tests covering adopt/resolve/ fail (+ the apply-result dispatch); coverage stays clean (the relocated code is
now measured — the tests are what keep the gate green).
TimelineGate + wire_timeline_resolve shared by all three pages (and consider
home/cockpit, which already inline the gate differently — evaluate, don't force).
Boy-scout follow-up: #653/#669 converged the tag pages but touched
SiteTagPage,which still carries
#[expect(clippy::too_many_lines)]. Per the #306 thin-componentdirection, decompose the three timeline pages — and, following the #655 example
(the analogous
TagInputthinning, #328), do it so the decomposition turnscurrently-exempt reactive code into host-tested code, rather than merely
shuffling wasm sub-components.
The three pages
SiteTagPage,UserTagPage, andUserTimelinePage(web/src/posts/component.rs)are now byte-for-byte near-identical wiring around the shared
crate::timelinebundle: build a keyed
Resource,TimelineState::default()+ aloadedgate,adopt the
PageSeedseed, a resolveEffect, aspawn_load_moreload-more, aread_errorMemo, then chrome + the error/loading/TimelineRowsgate. All threecarry
#[expect(clippy::too_many_lines)].What to do (mirroring #655)
#329already split the pure model(
TimelineCursor/LoadStatus/fold logic → host-testedtimeline/state.rs) fromthe reactive
TimelineStatesignal-bundle (wasm-onlytimeline/component.rs,gated at
mod.rs:14). The one uncovered behavior isTimelineState'stransitions (
adopt/resolve/fail, and the page's "apply the fetched result"dispatch) — exempt today only because the bundle is wasm-gated. Relocate the
TimelineStatesignal-bundle into host-compiledstate.rsand cover itstransitions under an
Owner(theweb::reactive::Invalidator/forms::Fieldconvention web(tags): co-locate TagInput into the tags vertical (#328) #655 used) — no
#[client_only]. This is the "decomposing made ithost-testable" win.
TimelineGate#[component](theerror → loading → <TimelineRows/>gate, takingstate/loaded/read_error/on_mutate/on_load_more+tag_context/empty_text)and a
wire_timeline_resolve(state, loaded, initial_page) -> Memo<Option<String>>helper (the resolve
Effect+ the failureMemo). Both incrate::timeline.page-specific bits (params, keyed
Resource,PageSeedadoption, load-more fetch,chrome). Drop all three
#[expect(clippy::too_many_lines)].Acceptance
#[expect(clippy::too_many_lines)]; no#[client_only]added.TimelineStatehost-compiled withOwner-based tests coveringadopt/resolve/fail(+ the apply-result dispatch); coverage stays clean (the relocated code isnow measured — the tests are what keep the gate green).
TimelineGate+wire_timeline_resolveshared by all three pages (and considerhome/cockpit, which already inline the gate differently — evaluate, don't force).
cargo xtask validategreen (incl. e2e); behavior identical — the tag/profile e2e(incl. posts: converge SiteTagPage/UserTagPage onto the shared TimelineState bundle #653's
user tag pagesmoke test) stays green.Origin: #653/#669 (touched
SiteTagPage). Model: #655/#328. Family: #301, #306.