# Custom emoji packs — handoff

## Summary

Built-in (non-plugin) custom emoji system: read image packs from room state, resolve shortcodes to images in messages and autocomplete. Distinct from user-installed JS plugins but shares pack format concepts.

## User-facing behavior

- Room/space emoji packs in settings
- `:shortcode:` in composer resolves to pack image
- Pack viewer for browsing stickers/emojis
- Integrates with `im.ponies.room_emotes` and pack MXC structure

## Architecture

```
plugins/custom-emoji/
  PackMetaReader, PackImageReader, PackImagesReader
  ImagePack.ts, PackAddress.ts
emoji plugin (plugins/emoji.ts) — render shortcodes
settings emojis-stickers + common-settings emojis
```

## Key files

| Path | Role |
|------|------|
| `cinny/src/app/plugins/custom-emoji/PackMetaReader.ts` | Read pack metadata |
| `cinny/src/app/plugins/custom-emoji/PackImageReader.ts` | Single image |
| `cinny/src/app/plugins/custom-emoji/PackImagesReader.ts` | Bulk images |
| `cinny/src/app/plugins/custom-emoji/ImagePack.ts` | Pack model |
| `cinny/src/app/plugins/custom-emoji/types.ts` | Types |
| `cinny/src/app/plugins/emoji.ts` | Shortcode rendering |
| `cinny/src/app/plugins/recent-emoji.ts` | Recent emoji helper |
| `cinny/src/app/components/image-pack-view/ImagePackView.tsx` | Pack browser UI |
| `cinny/src/app/hooks/useImagePackRooms.ts` | Rooms with packs |

## Data model

| Event | Purpose |
|-------|---------|
| `im.ponies.room_emotes` | Room emoji pack definition |
| Image pack account data | User/global packs (see emoji-stickers) |

## Dependencies

- MXC media URLs
- `useMediaAuthentication` for protected media

## Integration points

- **emoji-stickers**: settings UI for packs + Telegram import
- **message-rendering**: emoji.ts in parse pipeline
- **editor-and-composer**: EmoticonAutocomplete

## Testing

### Manual

1. Add emoji pack to room.
2. Type `:shortcode:` in composer; image inserts.
3. View pack in ImagePackView.
4. Encrypted room pack visibility.

### Automated

- None

## Known issues & gotchas

- Pack address parsing in `PackAddress.ts` — MXC format sensitive
- Large packs slow autocomplete — consider lazy load
- Telegram import creates separate pack ids (`telegram_*`)

## Future work

- Pack CDN cache
- Animated emoji support audit

## Related docs

- [emoji-stickers HANDOFF](../emoji-stickers/HANDOFF.md)
- [message-rendering HANDOFF](../message-rendering/HANDOFF.md)

## Add your extra things here

- `StateEvent.PoniesRoomEmotes = 'im.ponies.room_emotes'` in room.ts
