5.5 KiB
5.5 KiB
URL and History Support Implementation Strategy
Overview
This document outlines the strategy for implementing clean URL and history support in the Circles application, starting with the LibraryView component. The goal is to enable component state changes to trigger URL updates and allow initial component state to be calculated from URLs for link sharing and refresh support.
Current State Analysis
Strengths
- App-level routing already implemented with
AppView::to_path()
andAppView::from_path()
- Browser history API integration in
App::update()
- Query parameter support for circles context (
?circles=url1,url2
)
Gaps
- Component-level state changes don't update URLs
- Initial component state isn't derived from URLs
- No support for nested routing (e.g.,
/library/collection/123/item/456
)
Architecture Overview
graph TD
A[Browser URL] --> B[App Router]
B --> C[AppView Route Parser]
C --> D[Component Route Parser]
D --> E[Component State]
E --> F[Component Renders]
F --> G[User Interaction]
G --> H[State Change]
H --> I[URL Update]
I --> A
subgraph "URL Structure"
J["/library/collection/123/item/456?circles=ws1,ws2"]
K["Path: /library/collection/123/item/456"]
L["Query: ?circles=ws1,ws2"]
end
Implementation Strategy
Phase 1: Create URL Routing Infrastructure
1.1 Router Trait Definition
Create a reusable UrlRouter
trait that components can implement:
pub trait UrlRouter {
type RouteState;
fn parse_route(path: &str) -> Option<Self::RouteState>;
fn build_route(state: &Self::RouteState) -> String;
}
1.2 History Manager
Centralized history management with:
- Prevention of duplicate history entries
- Handling of popstate events for back/forward navigation
- Smart decision between
pushState
andreplaceState
Phase 2: Extend App-Level Routing
2.1 Enhanced AppView Routing
Modify AppView::from_path()
to:
- Extract base view from path (e.g.,
/library
from/library/collection/123
) - Pass remaining path segments to components
- Handle nested route parsing
2.2 Route Segment Passing
Update component props to include:
initial_route: Option<String>
- route segment for componenton_route_change: Callback<String>
- notify app of route changes
Phase 3: LibraryView URL Integration
3.1 LibraryRoute Definition
#[derive(Clone, Debug, PartialEq)]
pub enum LibraryRoute {
Collections,
Collection { collection_id: String },
Item { collection_id: String, item_id: String },
}
3.2 URL Pattern Mapping
/library
→LibraryRoute::Collections
/library/collection/{id}
→LibraryRoute::Collection
/library/collection/{id}/item/{item_id}
→LibraryRoute::Item
3.3 State Synchronization
- Parse initial route on component creation
- Update URL when
ViewState
changes - Handle browser back/forward navigation
Detailed Implementation Plan
Step 1: Router Infrastructure
Files to create:
src/app/src/routing/mod.rs
src/app/src/routing/url_router.rs
src/app/src/routing/library_router.rs
src/app/src/routing/route_parser.rs
Step 2: App.rs Modifications
Changes to App
:
- Enhanced route parsing in
AppView::from_path()
- Route segment extraction and passing to components
- Popstate event handling for browser navigation
- Updated URL building logic
Step 3: LibraryView Transformation
Key changes:
- Add
current_route: LibraryRoute
to component state - Initialize state from URL on component creation
- Update URL when state changes via message handlers
- Handle route changes from browser navigation
Step 4: Component Props Enhancement
New props structure:
#[derive(Clone, PartialEq, Properties)]
pub struct LibraryViewProps {
pub ws_addresses: Vec<String>,
pub initial_route: Option<String>,
pub on_route_change: Callback<String>,
}
URL Examples
LibraryView Routes
/library
- Collections view/library/collection/ws1_collection123
- Items in collection/library/collection/ws1_collection123/item/item456
- Viewing specific item
With Context
/library/collection/ws1_collection123/item/item456?circles=ws1,ws2
- With circles context
Benefits
- Clean Separation: Router logic separated from component logic
- Reusable: Router trait can be implemented by other views
- Minimal Code: Leverages existing URL infrastructure
- Link Sharing: Full state encoded in URLs
- Browser Integration: Proper back/forward navigation support
- SEO Friendly: Meaningful URLs for each state
Migration Strategy
- Backward Compatibility: Existing URLs continue to work
- Gradual Rollout: Start with LibraryView, extend to other components
- Fallback Handling: Graceful degradation for invalid routes
- Progressive Enhancement: Add URL support without breaking existing functionality
Implementation Order
- Create router infrastructure
- Extend App.rs routing capabilities
- Transform LibraryView to be URL-aware
- Test and refine
- Extend pattern to other views (Intelligence, Publishing, etc.)
Testing Strategy
- Unit Tests: Router parsing and building functions
- Integration Tests: Component state synchronization with URLs
- Browser Tests: Back/forward navigation, refresh behavior
- Link Sharing Tests: URLs work when shared and opened in new tabs
This strategy provides a clean, scalable approach to URL and history support that can be extended to other components in the application.