**Major Features Added:** - **Inline Reply System**: Replace compose screen with inline reply boxes - **Thread Navigation**: Parent/child navigation with jump functionality - **Chain Flow UI**: Reply counts, expand/collapse animations, visual hierarchy - **Enhanced Animations**: Smooth transitions, hover effects, micro-interactions **Frontend Changes:** - **ThreadedCommentWidget**: Complete rewrite with animations and navigation - **ThreadNode Model**: Added parent references and descendant counting - **ThreadedConversationScreen**: Integrated navigation handlers - **PostDetailScreen**: Replaced with threaded conversation view - **ComposeScreen**: Added reply indicators and context - **PostActions**: Fixed visibility checks for chain buttons **Backend Changes:** - **API Route**: Added /posts/:id/thread endpoint - **Post Repository**: Include allow_chain and visibility fields in feed - **Thread Handler**: Support for fetching post chains **UI/UX Improvements:** - **Reply Context**: Clear indication when replying to specific posts - **Character Counting**: 500 character limit with live counter - **Visual Hierarchy**: Depth-based indentation and styling - **Smooth Animations**: SizeTransition, FadeTransition, hover states - **Chain Navigation**: Parent/child buttons with visual feedback **Technical Enhancements:** - **Animation Controllers**: Proper lifecycle management - **State Management**: Clean separation of concerns - **Navigation Callbacks**: Reusable navigation system - **Error Handling**: Graceful fallbacks and user feedback This creates a Reddit-style threaded conversation experience with smooth animations, inline replies, and intuitive navigation between posts in a chain.
5.5 KiB
5.5 KiB
Beacon System Architecture
Overview
Sojorn has two separate posting systems that share the same database but create slightly different content:
- Regular Posts (compose_screen.dart) - Standard social media posts
- Beacon Posts (create-beacon_sheet.dart) - GPS-tagged safety alerts
How It Works
Database Structure
Both systems create records in the posts table, but with different flags:
| Field | Regular Post | Beacon Post |
|---|---|---|
is_beacon |
FALSE |
TRUE |
beacon_type |
NULL |
'police', 'checkpoint', 'taskForce', 'hazard', 'safety', or 'community' |
location |
NULL |
GPS coordinates (PostGIS POINT) |
confidence_score |
NULL |
0.5 - 1.0 (starts at 50-80% based on user trust) |
is_active_beacon |
NULL |
TRUE (becomes FALSE when pruned) |
allow_chain |
User choice | Always FALSE |
User Opt-In System
Critical Feature: Beacon posts are OPT-IN ONLY for feeds.
profiles.beacon_enabled Column
- Default:
FALSE(opted out) - When FALSE: User NEVER sees beacon posts in their Following or Sojorn feeds
- When TRUE: User sees beacon posts mixed in with regular posts
- Beacon Map: ALWAYS visible regardless of this setting
Why Opt-In?
Some users don't want safety alerts mixed into their social feed. The opt-in system allows:
- Casual users: Just social content
- Community safety advocates: Social content + beacons
- Everyone: Can still view the Beacon Network map anytime
Feed Filtering Logic
feed-personal (Following Feed)
// Check user's beacon preference
const { data: profile } = await supabase
.from("profiles")
.select("beacon_enabled")
.eq("id", user.id)
.single();
const beaconEnabled = profile?.beacon_enabled || false;
// Build query
let postsQuery = supabase.from("posts").select(...);
// Filter out beacons if user has NOT opted in
if (!beaconEnabled) {
postsQuery = postsQuery.eq("is_beacon", false);
}
feed-sojorn (Algorithmic Feed)
Same logic - beacons are filtered unless beacon_enabled = TRUE.
Beacon Creation Flow
- User opens Beacon Network tab
- Taps map to drop beacon
- Fills out CreateBeaconSheet:
- Type (police, checkpoint, etc.)
- Title
- Description
- Optional photo
- Submits → Edge function
create-beacon - Creates a POST in the
poststable with:is_beacon = TRUEbeacon_type = <selected_type>location = GPS pointcategory_id = "Beacon Alerts"categoryconfidence_scorebased on user's trust scoreallow_chain = FALSE
Regular Post Creation Flow
- User taps "New Post" button
- Fills out ComposeScreen:
- Community selection
- Body text
- Optional photo
- Toggle for chain responses
- Submits → Edge function
publish-post - Creates a POST in the
poststable with:is_beacon = FALSE- No GPS data
- User-selected category
- User's chain preference
Key Differences
| Feature | Regular Post | Beacon Post |
|---|---|---|
| Purpose | Social sharing | Safety alerts |
| GPS Data | No | Required |
| Visible On | Feeds (if user follows author) | Beacon map + feeds (if user opted in) |
| Category | User selects | Always "Beacon Alerts" |
| Chaining | User choice | Disabled |
| Confidence Score | No | Yes (trust-based) |
| Voting | No | Yes (vouch/report) |
| Auto-Pruning | No | Yes (low confidence + old = disabled) |
User Experience Scenarios
Scenario 1: User With Beacons Disabled (Default)
Following Feed: ✓ Regular posts from people they follow
Sojorn Feed: ✓ Algorithmic regular posts
Beacon Map: ✓ All active beacons in area
Scenario 2: User With Beacons Enabled
Following Feed: ✓ Regular posts + beacons from people they follow
Sojorn Feed: ✓ Algorithmic regular posts + beacons
Beacon Map: ✓ All active beacons in area
Scenario 3: User Creates Beacon
- Beacon appears on map IMMEDIATELY for ALL users
- Beacon appears in creator's feed (if they have beacons enabled)
- Beacon appears in OTHER users' feeds (if they follow creator AND have beacons enabled)
Migration Required
To enable this system, run:
-- Add beacon_enabled column to profiles
ALTER TABLE profiles ADD COLUMN IF NOT EXISTS beacon_enabled BOOLEAN NOT NULL DEFAULT FALSE;
-- Add index for fast filtering
CREATE INDEX IF NOT EXISTS idx_profiles_beacon_enabled ON profiles(beacon_enabled) WHERE beacon_enabled = TRUE;
Or apply the migration file:
# Via Supabase Dashboard SQL Editor
# Paste contents of: supabase/migrations/add_beacon_opt_in.sql
Edge Functions Updated
- ✅ feed-personal - Now filters beacons based on user preference
- ✅ feed-sojorn - Now filters beacons based on user preference
- ✅ create-beacon - Creates beacon posts correctly
- ✅ publish-post - Creates regular posts correctly
Frontend Components
- ✅ ComposeScreen - Regular post composer
- ✅ CreateBeaconSheet - Beacon post composer
- 🔲 Settings Screen - TODO: Add toggle for
beacon_enabledpreference - ✅ BeaconScreen - Shows beacons on map (always visible)
- ✅ FeedPersonalScreen - Filtered feed
- ✅ FeedSojornScreen - Filtered feed
Next Steps
- Apply database migration (
add_beacon_opt_in.sql) - Deploy updated edge functions
- Add UI toggle in user settings for beacon opt-in
- Test both posting flows
- Verify feed filtering works correctly