Files
Artstr-Studio/docs/TEMPLATE_FORKING_FEATURE.md
2026-05-15 21:13:49 -04:00

163 lines
5.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Template Forking / Remix Feature Plan
## Overview
Allow users to import any community template as a starting point for their own design,
with automatic attribution to the original creator baked into the Nostr event. Forks are
discoverable — anyone can see a template's remix lineage — and the original creator gets
notified via a Nostr mention when someone forks their work.
## Complexity
**Low–Moderate** — Estimated 2–4 hours
---
## How It Works
### Forking Flow
1. User clicks "Remix this design" on a community template card
2. App imports the template payload into the editor (same as existing "Import" flow)
3. When the user publishes their remixed version, the new event includes a reference
to the original template event ID in its tags
4. Original creator receives a Nostr notification (kind 1 mention) that their template
was remixed
### Nostr Event Tags for a Fork
Add two tags to the published kind 30078 event:
```json
{
"tags": [
["e", "<original-event-id>", "<relay-hint>", "fork"],
["p", "<original-creator-pubkey>"]
]
}
```
- `["e", ..., "fork"]` — marks this as a derivative work; the marker `"fork"` is a
custom convention (Nostr allows arbitrary `e` tag markers)
- `["p", ...]` — notifies the original creator; their client will surface this as a mention
### Attribution Display
In the template detail view, show a "Forked from" row when a `fork` e-tag is present:
```
Forked from: [Alice's Spider-Man Wrap] by [email protected] →
```
Clicking the arrow navigates to the original template in the feed.
---
## Key Components
### 1. Remix Button
Add "Remix this design" to the template card action menu alongside existing Import option.
Visually distinguish it (⑃ fork icon) so users understand it's different from a plain import.
```javascript
function remixTemplate(event) {
importDiscDesignFromPayload(event.content); // existing import function
state.community.forkSourceEventId = event.id;
state.community.forkSourcePubkey = event.pubkey;
showNotification('Template loaded — your remix will credit the original creator.');
}
```
### 2. Fork State
Track pending fork metadata in state so it can be attached at publish time:
```javascript
// Add to state:
fork: {
sourceEventId: null, // event ID of the template being remixed
sourcePubkey: null, // pubkey of the original creator
}
```
Clear `state.fork` when the user starts a fresh project or imports without remixing.
### 3. Publish Hook
In the existing publish function, inject fork tags when `state.fork.sourceEventId` is set:
```javascript
function buildPublishTags(existingTags) {
const tags = [...existingTags];
if (state.fork.sourceEventId) {
tags.push(['e', state.fork.sourceEventId, '', 'fork']);
tags.push(['p', state.fork.sourcePubkey]);
}
return tags;
}
```
### 4. Fork Detection on Render
When rendering a template detail card, check for a `fork` e-tag and fetch + display the
source template title and author:
```javascript
function getForkSource(event) {
const tag = event.tags?.find(t => t[0] === 'e' && t[3] === 'fork');
return tag ? { eventId: tag[1], relayHint: tag[2] } : null;
}
```
### 5. Remix Count
In the community feed, a template's remix count = number of kind 30078 events that
reference it with a `fork` e-tag. This can be fetched lazily:
```javascript
async function fetchRemixCount(eventId) {
const events = await queryRelays(relays, {
kinds: [30078],
'#e': [eventId],
}, { timeoutMs: 2000 });
return events.filter(e => e.tags.some(t => t[0] === 'e' && t[3] === 'fork')).length;
}
```
---
## UI Changes
- Template card action menu: add "⑃ Remix this design" below "Import"
- Editor header: show "Remixing: [original title]" badge while fork state is active
- Editor header: "Clear remix" link to discard attribution and start fresh
- Template detail panel: "Forked from" row (when fork e-tag present)
- Template detail panel: "X remixes" count below reaction row
---
## Performance Considerations
- Fork source lookup is a single relay query — run it lazily when the detail panel opens
- Remix count query can be skipped on initial feed load and fetched on hover/click
- No new relay subscriptions needed — reuses existing `queryRelays()` helper
---
## Limitations
- Fork attribution is opt-in convention — anyone can publish a derivative without tagging;
this feature makes attribution easy but cannot enforce it
- Relay hints in the `e` tag are best-effort; original event may not be on all relays
- No fork graph visualization (full lineage tree) — out of scope for initial version
---
## Future Enhancements
- Fork tree visualization: show the full remix lineage of popular templates
- "See all remixes" panel on template detail
- Notify original creator via kind 1 DM or push notification service
- Attribution in exported PDF metadata
---
## Testing Checklist
- [ ] "Remix this design" imports template content into editor correctly
- [ ] Fork state (`sourceEventId`, `sourcePubkey`) is set after remix
- [ ] Published event contains `["e", ..., "fork"]` and `["p", ...]` tags
- [ ] Fork state clears on new project / plain import
- [ ] "Remixing: [title]" badge shows in editor while fork is active
- [ ] "Clear remix" removes fork state and badge
- [ ] Template detail shows "Forked from" row when fork e-tag is present
- [ ] "Forked from" link navigates to source template in feed
- [ ] Remix count displays on template detail (fetched lazily)
- [ ] Publishing without remix produces no fork tags