updated open-questions.md and design.md
This commit is contained in:
parent
fde4e11f24
commit
0aca8b3ffa
4 changed files with 218 additions and 30 deletions
17
README.md
Normal file
17
README.md
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# eutopic
|
||||
|
||||
*a small good place. social media that visits you when you visit it.*
|
||||
|
||||
photo-first social app for small trusted communities. features:
|
||||
- slide posts (carousel)
|
||||
- stories
|
||||
- emoji reactions
|
||||
- "flyer" event page
|
||||
chronological feed, no algorithm, no notifications, no tracking. invite-only.
|
||||
|
||||
→ [docs/CONCEPT.md](docs/CONCEPT.md) for full concept, stack, and design decisions.
|
||||
|
||||
---
|
||||
|
||||
**radicle:** `rad:z3pNdxS2udZaPJjFvAMNA6sxEVvVi`
|
||||
**web:** https://radicle.network/nodes/iris.radicle.network/rad%3Az3pNdxS2udZaPJjFvAMNA6sxEVvVi
|
||||
|
|
@ -30,7 +30,7 @@ the immediate goal is to give a specific community a real alternative to instagr
|
|||
- **no DMs** — use signal, element, or another tool. for now, profiles include "message me at [telegram/signal/element/matrix handle]". eutopic stays focused on photo-sharing only. defensible posture — "we do one thing, well." mirrors the no-notifications stance.actual dm impl deferred to v2.
|
||||
- **no analytics or tracking** — none. zero. not even self-hosted.
|
||||
- **no algorithm** — chronological feed, no ranking, no engagement bait.
|
||||
- **no scheduling, drafts, or queue UI** — bad-wifi handled invisibly via background upload.
|
||||
- **no scheduling, or queue UI** — bad-wifi handled invisibly via background upload.
|
||||
- **no federation** — initially. the protocol is there but turned off.
|
||||
|
||||
## what makes it different
|
||||
|
|
@ -66,25 +66,9 @@ the immediate goal is to give a specific community a real alternative to instagr
|
|||
- **domain**: eutopic.space canonical, eutopic.eu redirect
|
||||
- **code forge**: radicle (p2p, no github)
|
||||
- **CI**: self-hosted radicle CI runner
|
||||
- **editor**: vscodium (no microsoft telemetry)
|
||||
- cle primary, github mirror as `eutopiacode`.
|
||||
- **package manager**: bun (no separate npm/yarn)
|
||||
- **funding**: liberapay primary, ko-fi/open collective backup, mobilepay deferred
|
||||
|
||||
### dev toolchain (the ai-stack + front-desk)
|
||||
front-desk is a CLI orchestrator that routes coding sessions to models based on **user state**, not task type. 4-choice check-in on session start:
|
||||
|
||||
- **fresh** ── clean slate → gemma-4-E4B-it (local, LM Studio)
|
||||
- **continuing** ── picking up prior work → gemma-4-E4B-it (local, LM Studio)
|
||||
- **stuck** ── need help thinking through blockers → claude sonnet (native, subscription)
|
||||
- **overwhelmed** ── small steps, one at a time → qwen3-4b-instruct-2507-mlx (local, LM Studio)
|
||||
|
||||
cloud stack via opencode for involved work: GLM-4.7 (z.ai, apache 2.0) as conversational daily, DeepSeek V3.2 as cost-efficient workhorse, GLM-4.7-Flash for lightweight tasks.
|
||||
|
||||
escalation: `/escalate` writes `~/.claude/handover.md` and exits; front-desk detects it on next start and execs native claude.
|
||||
|
||||
hardware ceiling: M3 MBP, 18GB unified memory → practical local model ceiling ~10–11GB.
|
||||
|
||||
repo: `/Users/pthfndr/dev/ai-stack`, radicle primary, github mirror as `eutopiacode`.
|
||||
- **funding**: liberapay primary, ko-fi/open collective backup, mobilepay possible
|
||||
|
||||
### shared context for eutopic
|
||||
single `AGENTS.md` at the eutopic repo root, read by all routed models in front-desk. terse and decision-focused — encodes the locked-in choices (no notifications, federation off, invisibly leftist tone, etc.) so any model invoked produces consistent output.
|
||||
|
|
@ -110,11 +94,6 @@ single `AGENTS.md` at the eutopic repo root, read by all routed models in front-
|
|||
- "the slowest part of using social media" disappears
|
||||
- tus protocol is open, multiple implementations
|
||||
|
||||
### why njalla day one, not laptop
|
||||
- laptop-server experience killed pixelfed adoption in this community before
|
||||
- residential bandwidth + sleep + ISP outages = trust death
|
||||
- €15-30/mo on njalla covers 20-100 users comfortably
|
||||
- migration path to bigger hosts exists if needed
|
||||
|
||||
## the meta-migration problem (named)
|
||||
|
||||
|
|
|
|||
191
docs/DESIGN.md
191
docs/DESIGN.md
|
|
@ -1,5 +1,192 @@
|
|||
# DESIGN.md — eutopic
|
||||
|
||||
*to be drafted. captures interaction model, UI surfaces, and UX decisions.*
|
||||
what the user experiences and why. not what gets stored (see DATA-MODEL.md). not stack decisions (see CONCEPT.md).
|
||||
|
||||
scope: what the user experiences and why. not what gets stored (see DATA-MODEL.md).
|
||||
---
|
||||
|
||||
## design principles
|
||||
|
||||
- users should never be asked to understand anything instagram doesn't ask them to understand.
|
||||
- friction is a feature when it slows down compulsive checking. friction is a bug when it slows down posting.
|
||||
- no dark patterns. no engagement optimization. no "one more thing" loops.
|
||||
- imperfection is intentional. DIY aesthetic over polish-as-performance.
|
||||
|
||||
---
|
||||
|
||||
## visual identity
|
||||
|
||||
**status**: design collab in progress. nothing locked yet.
|
||||
|
||||
**direction**:
|
||||
- wordmark only. no separate logomark — "eutopic" is distinctive enough as a word.
|
||||
- typographic register: considered, a bit odd, not startup-clean. something with character.
|
||||
- glyph set for nav icons to be developed as custom symbols, not system unicode or standard icon libraries.
|
||||
- aesthetic reference: zine, risograph print, hand-stamped, dingbat. not flat SaaS icons.
|
||||
- tool: figma. brief to follow from design collab.
|
||||
|
||||
**nav icon candidates** (to be refined or replaced by collab):
|
||||
- home: ⒣
|
||||
- posters: ⇶
|
||||
- compose: ◲
|
||||
- stories: ❣
|
||||
- profile: ☺
|
||||
|
||||
these should ship as SVG assets or a custom icon font in the actual app — unicode rendering is inconsistent across android devices and system fonts.
|
||||
|
||||
---
|
||||
|
||||
## navigation
|
||||
|
||||
five-slot bottom tab bar:
|
||||
|
||||
```
|
||||
⒣ home | ⇶ posters | ◲ compose | ❣ stories | ☺ profile
|
||||
```
|
||||
|
||||
- **home** — chronological feed
|
||||
- **posters** — bulletin board (`/posters`, `is_event` posts + informational posts + fundraisers)
|
||||
- **compose** — center slot, filled/distinct treatment. opens compose flow (modal or full screen — TBD)
|
||||
- **stories** — dedicated tab, not a top strip. intentional destination, not ambient anxiety ring.
|
||||
- **profile** — own profile. viewing others' profiles navigates within the app but doesn't change the active tab.
|
||||
|
||||
stories as a bottom tab (vs instagram-style top strip) is a deliberate choice: it frames stories as something you visit, not something that nags you to check.
|
||||
|
||||
---
|
||||
|
||||
## screens
|
||||
|
||||
### onboarding (unauthenticated)
|
||||
|
||||
```
|
||||
invite gate
|
||||
└── invite code prefilled from deep link, or entered manually
|
||||
email + username entry
|
||||
magic link sent / confirm screen
|
||||
social handle opt-in
|
||||
└── signal / telegram / custom. skippable. "re-enable anytime in settings."
|
||||
follow suggestions
|
||||
└── friends-of-inviter auto-suggested. skippable.
|
||||
```
|
||||
|
||||
zero technology decisions for the user. no server picker. no handle explanation. no fediverse vocabulary.
|
||||
|
||||
---
|
||||
|
||||
### feed (`/`)
|
||||
|
||||
- chronological. no algorithm. no ranked content.
|
||||
- posts with 1–10 photos (swipeable within the post card).
|
||||
- reactions inline below each post.
|
||||
- comments accessible via tap (flat, chronological thread).
|
||||
- **survey card** injected at slot 1 when an active survey exists. GIF cover. taps to `/feedback`. disappears per-user once responded. not a real post.
|
||||
- no unread indicators. no "new posts" banner. pull to refresh is fine.
|
||||
|
||||
---
|
||||
|
||||
### posters (`/posters`)
|
||||
|
||||
formerly "bulletin board". renamed because the scope is broader than events:
|
||||
|
||||
**post types** (single tag, required, choose one):
|
||||
- `event` — dated gathering, auto-archives 1 day after `event_ends_at`
|
||||
- `fundraiser` — community fundraising
|
||||
- `current affairs` — informational, reading, things worth knowing
|
||||
|
||||
layout: 2-column grid (`FlatList numColumns={2}`), infinite scroll, paginated fetch.
|
||||
|
||||
filtering by tag: TBD (tab strip or dropdown above grid).
|
||||
|
||||
reactions on poster posts: visible to post author only. no public counts. no hierarchy.
|
||||
|
||||
RSVP interaction model: open question, not designed yet. see OPEN-QUESTIONS.md.
|
||||
|
||||
---
|
||||
|
||||
### compose (◲)
|
||||
|
||||
- triggered from center nav slot.
|
||||
- photo picker first (up to 10 photos).
|
||||
- caption optional.
|
||||
- toggle: post to feed or post to posters. if posters: tag picker (single tag required) + event fields if `event`.
|
||||
- toggle: saveable on/off (default off).
|
||||
- toggle: reaction set — choose up to 5 emoji, or leave open (open picker only).
|
||||
- upload starts in background immediately on confirm. progress shown via hand-drawn animation. bad wifi handled invisibly via tus.io resumable upload.
|
||||
- no drafts, no scheduling, no queue UI.
|
||||
|
||||
---
|
||||
|
||||
### stories (❣)
|
||||
|
||||
- dedicated tab, not a top strip.
|
||||
- 10s auto-advance per story.
|
||||
- filters via swipe gesture (basic, applied at view time or capture time — TBD).
|
||||
- no replies. "witnessed" metadata only: private per-viewer row, expires with story (24h).
|
||||
- story author can see flat witness list (like instagram). no public count.
|
||||
- story creation: camera or photo picker, then post. no drafts.
|
||||
|
||||
---
|
||||
|
||||
### profile (☺)
|
||||
|
||||
**own profile:**
|
||||
- avatar, display name, username, bio.
|
||||
- social handles (signal / telegram / custom) — shown based on `display_social_handle` setting: none / mutuals / all.
|
||||
- `contact_prefs` free text ("bad texter", "weekends only").
|
||||
- own posts grid.
|
||||
- settings access.
|
||||
|
||||
**others' profiles:**
|
||||
- same view, minus settings. follow/unfollow action.
|
||||
- social handles visible per their `display_social_handle` setting.
|
||||
|
||||
---
|
||||
|
||||
### feedback (`/feedback`)
|
||||
|
||||
- always accessible (settings link or survey card tap).
|
||||
- active survey renders at top if one exists (multiple choice, 36h expiry).
|
||||
- permanent free text field below, always present regardless of active survey.
|
||||
- no results shown to users. dev use only.
|
||||
|
||||
---
|
||||
|
||||
### settings + about
|
||||
|
||||
**settings:**
|
||||
- account (username, display name, avatar, bio)
|
||||
- social handles (add / hide / remove)
|
||||
- contact prefs
|
||||
- `display_social_handle` toggle
|
||||
|
||||
**about:**
|
||||
- "eutopic is a quiet place for friends to share photos."
|
||||
- "we don't track you. we don't run ads. we don't sell your data."
|
||||
- "we don't notify you — visit when you want to."
|
||||
- running costs (hosting, domain, apple developer program) — real numbers, updated manually.
|
||||
- liberapay donation link (opens in browser).
|
||||
- credit line: "eutopic uses react native, an open-source framework made by meta. we use their open work to build something they wouldn't."
|
||||
- "made with care in EU."
|
||||
|
||||
no donor badges. no public donor list. donation is private.
|
||||
|
||||
---
|
||||
|
||||
## animations
|
||||
|
||||
- upload progress: hand-drawn, DIY aesthetic. lottie or APNG. not a standard spinner.
|
||||
- reactions: subtle, not dopamine-optimized. no confetti, no burst animations.
|
||||
- transitions: simple. no parallax, no over-engineered motion.
|
||||
- imperfection is okay. "designed" imperfection is part of the identity.
|
||||
|
||||
---
|
||||
|
||||
## open UX questions
|
||||
|
||||
see OPEN-QUESTIONS.md for live status. currently open:
|
||||
|
||||
- compose: modal sheet over current screen, or full dedicated screen?
|
||||
- stories: filters applied at capture or at view time?
|
||||
- posters: tag filter UI — tab strip or dropdown?
|
||||
- RSVP interaction model (not designed yet)
|
||||
- comment hearts/likes — do comments get a reaction? tension with no-hierarchy value.
|
||||
- stories access: purely via tab, or also accessible from profile (own stories)?
|
||||
|
|
|
|||
|
|
@ -15,10 +15,12 @@ priority 0:
|
|||
- DMs — websockets/simple in-app vs matrix vs no DMs ever. decide before v2 launch.
|
||||
- social handle platform list expansion (signal + telegram primaries. custom covers edge cases. expand tbd.)
|
||||
- server/media migration path — which host migration is least painful for media storage (filesystem → s3-compatible). greenhost/hetzner candidates.
|
||||
|
||||
- which njalla plan tier?
|
||||
- comment hearts/likes — do comments get a heart reaction? tension with "no hierarchy" value. deferred.
|
||||
- event tags — max count per event. starting point: 2 (survey community on this).
|
||||
- compose — modal sheet over current screen, or full dedicated screen?
|
||||
- stories — filters applied at capture time or view time?
|
||||
- posters — tag filter UI: tab strip or dropdown?
|
||||
- stories access — purely via tab, or also accessible from own profile?
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -45,3 +47,6 @@ priority 0:
|
|||
- ~~survey feature~~ → v1, non-negotiable. community sees product is actively iterated on their feedback.
|
||||
- ~~survey delivery~~ → slot 1 in feed as injected card (not a real post). GIF cover image. tapping routes to `/feedback` where active survey renders above permanent free text field. card drops from slot 1 per-user once they've responded (checks `survey_response` on feed load). no modal.
|
||||
- ~~survey expiry~~ → ephemeral, 36h.
|
||||
- ~~bulletin board route + name~~ → `/posters`. scope is broader than events: three post types, single required tag (choose one): `event`, `fundraiser`, `current affairs`.
|
||||
- ~~event tags — max count~~ → max 1 tag per poster post. single required tag forces a clear primary classification, reduces compose cognitive load.
|
||||
- ~~nav structure~~ → five-slot bottom tab bar: home / posters / compose (center) / stories / stories / profile. stories as dedicated tab, not top strip — intentional destination, not ambient check-in prompt.
|
||||
|
|
|
|||
Loading…
Reference in a new issue