circles/URL_ROUTING_STRATEGY.md
2025-06-25 03:51:29 +03:00

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() and AppView::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 and replaceState

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 component
  • on_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

  • /libraryLibraryRoute::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:

  1. Enhanced route parsing in AppView::from_path()
  2. Route segment extraction and passing to components
  3. Popstate event handling for browser navigation
  4. Updated URL building logic

Step 3: LibraryView Transformation

Key changes:

  1. Add current_route: LibraryRoute to component state
  2. Initialize state from URL on component creation
  3. Update URL when state changes via message handlers
  4. 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

  1. Clean Separation: Router logic separated from component logic
  2. Reusable: Router trait can be implemented by other views
  3. Minimal Code: Leverages existing URL infrastructure
  4. Link Sharing: Full state encoded in URLs
  5. Browser Integration: Proper back/forward navigation support
  6. SEO Friendly: Meaningful URLs for each state

Migration Strategy

  1. Backward Compatibility: Existing URLs continue to work
  2. Gradual Rollout: Start with LibraryView, extend to other components
  3. Fallback Handling: Graceful degradation for invalid routes
  4. Progressive Enhancement: Add URL support without breaking existing functionality

Implementation Order

  1. Create router infrastructure
  2. Extend App.rs routing capabilities
  3. Transform LibraryView to be URL-aware
  4. Test and refine
  5. Extend pattern to other views (Intelligence, Publishing, etc.)

Testing Strategy

  1. Unit Tests: Router parsing and building functions
  2. Integration Tests: Component state synchronization with URLs
  3. Browser Tests: Back/forward navigation, refresh behavior
  4. 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.