-
-
Notifications
You must be signed in to change notification settings - Fork 37
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Summary
Create a clean, extensible settings infrastructure that:
- Stores user preferences in Supabase (synced across devices)
- Provides sensible defaults without requiring user configuration
- Redesigns the settings page with sectioned navigation
- Makes it trivial to add new settings in the future
Background
Current state:
- Settings are fragmented (localStorage, next-themes, IndexedDB)
- No central user preferences table in Supabase
- Settings page is minimal and unorganized
Architecture Decisions
These decisions are already made - implementer should follow them:
| Decision | Choice | Rationale |
|---|---|---|
| Storage | Supabase user_settings table |
Sync across devices/browsers |
| Schema | Columns with defaults (not JSONB) | Type safety, easy to add new settings |
| Scope | User-level only (not per-account) | Simplicity; per-account can be added later |
| Defaults | TypeScript constants + DB defaults | Dual-layer fallback |
| Row creation | Lazy (on first settings change) | Use defaults until user customizes |
| Migration | Reset all users to new defaults | Clean slate, no legacy migration |
Database Schema
-- Migration: create_user_settings
create table public.user_settings (
id uuid primary key default gen_random_uuid(),
user_id uuid references auth.users(id) on delete cascade not null unique,
-- Appearance
theme text default 'system' check (theme in ('light', 'dark', 'system')),
-- Navigation
default_view text default 'following' check (default_view in ('following', 'trending', 'inbox', 'dms')),
-- Timestamps
created_at timestamptz default now(),
updated_at timestamptz default now()
);
-- RLS Policies
alter table public.user_settings enable row level security;
create policy "Users can view own settings"
on public.user_settings for select
using (auth.uid() = user_id);
create policy "Users can insert own settings"
on public.user_settings for insert
with check (auth.uid() = user_id);
create policy "Users can update own settings"
on public.user_settings for update
using (auth.uid() = user_id);
-- Auto-update updated_at
create trigger update_user_settings_updated_at
before update on public.user_settings
for each row execute function update_updated_at_column();Implementation Tasks
1. Database & Types
- Create Supabase migration for
user_settingstable - Run
pnpm supabase gen typesto update TypeScript types - Create
src/common/constants/settings.tswith defaults:
export const DEFAULT_SETTINGS = {
theme: 'system',
default_view: 'following',
} as const;
export type Theme = 'light' | 'dark' | 'system';
export type DefaultView = 'following' | 'trending' | 'inbox' | 'dms';
export interface UserSettings {
theme: Theme;
default_view: DefaultView;
}2. Settings Store
- Create
src/stores/useSettingsStore.ts:- State:
settings,isLoaded,isUpdating - Actions:
loadSettings(),updateSetting(key, value) - Load from Supabase on auth, merge with defaults
- Upsert to Supabase on change (creates row if doesn't exist)
- Optimistic updates for snappy UI
- State:
3. Settings Page Redesign
- Redesign
app/(app)/settings/page.tsxwith sectioned layout - Create section components in
src/common/components/Settings/:GeneralSettings.tsx- Default view dropdownAppearanceSettings.tsx- Theme toggle (migrate from ThemeToggle)SidebarSettings.tsx- Links to channels/lists pagesShortcutsSettings.tsx- View-only hotkey reference
Settings Page Layout:
┌────────────────────────────────────────────────┐
│ Settings │
├─────────────┬──────────────────────────────────┤
│ General │ [Content for selected section] │
│ Appearance │ │
│ Sidebar │ │
│ Shortcuts │ │
└─────────────┴──────────────────────────────────┘
4. Integration
- Initialize settings store in app startup (
initializeStores) - Apply
default_viewsetting on app load (navigate to chosen page) - Connect theme setting to
next-themes(settings store becomes source of truth) - Remove old theme localStorage usage
5. Section Details
General:
| Setting | UI | Options |
|---|---|---|
| Default view | Dropdown | Following, Trending, Inbox, DMs |
Appearance:
| Setting | UI | Options |
|---|---|---|
| Theme | Icon buttons (sun/moon/system) | Light, Dark, System |
Sidebar:
| Item | Action |
|---|---|
| Manage Channels | Link to /channels |
| Manage Lists | Link to /lists (or relevant page) |
Shortcuts:
- Render
hotkeyDefinitionsas a reference table - Group by category if applicable
- View-only (no customization)
Adding New Settings (Future Reference)
To add a new setting:
- Add column to
user_settingswith DEFAULT value (1 migration) - Add to
DEFAULT_SETTINGSconstant andUserSettingstype - Add UI control in appropriate section
No data backfill needed - existing rows get default automatically.
Out of Scope
- ❌ Email preferences (no email system yet)
- ❌ Notification settings (none exist)
- ❌ Per-account settings (separate future work)
- ❌ Billing settings (already handled elsewhere)
- ❌ Account management (lives on
/accounts) - ❌ List configuration (has dedicated pages)
- ❌ Custom keyboard shortcuts (view-only for now)
- ❌ Settings search
Acceptance Criteria
- User can change theme and it persists across sessions/devices
- User can set default view and app opens to that page
- Settings page has clear sectioned navigation
- New users see sensible defaults without touching settings
- Adding a new setting requires minimal code changes
- Works on both web and desktop (Tauri)
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request