Skip to content

Surface daily quest and streak in the editor - #3326

Merged
feruzm merged 2 commits into
developmentfrom
feature/quest-chip
Jul 6, 2026
Merged

Surface daily quest and streak in the editor#3326
feruzm merged 2 commits into
developmentfrom
feature/quest-chip

Conversation

@feruzm

@feruzm feruzm commented Jul 6, 2026

Copy link
Copy Markdown
Member

Phase 1 of quest surfacing: the long-form editor shows a small dismissible chip above the toolbar with the daily post quest progress and check-in streak, so the strongest habit loop is visible at the moment of creation instead of only under Perks.

What

  • Chip reads the existing quests query (no new endpoints): "Daily post 0/1", plus streak count when one is active and a "keep your streak alive" note when it is at risk (orange accent). Tap opens Perks; the close button hides it for the session.
  • Hidden in reply mode (and the quests query is disabled there so comment composers do zero extra fetching), in preview, and while a toolbar extension is open, mirroring the clipboard chip gating.
  • Pure deriveQuestChipState helper with unit tests; visibility = active streak or incomplete daily post quest.

Notes

  • Full suite passes (545 tests); eslint delta clean on changed files.
  • Chip state can be briefly stale right after publishing until the quests query refetches; acceptable for v1.

Summary by CodeRabbit

  • New Features

    • Added a new quest-related chip in the markdown editor toolbar with streak and daily post messaging.
    • The chip can be dismissed for the current app session and includes a shortcut to the Perks screen.
    • Added localized text for the new quest messaging.
  • Bug Fixes

    • The quest chip now stays hidden after dismissal during the active session.
    • Quest-related content is no longer shown in reply mode.

@greptile-apps

greptile-apps Bot commented Jul 6, 2026

Copy link
Copy Markdown

Greptile Summary

This PR surfaces daily quest progress and posting streak info as a small dismissible chip just above the editor toolbar, triggered during post composition (not replies, not edit-mode). It reuses the existing quests query, adds a pure deriveQuestChipState helper with full unit coverage, and scopes session dismissals per-username via a module-level Set.

  • Quest chip logic (src/utils/questChip.ts): pure derivation of chip visibility, streak, and at-risk state from the quests API response; 6 unit tests cover null/undefined inputs, completion, streak visibility, at-risk, and missing fields.
  • EditorToolbar (src/components/markdownEditor/children/editorToolbar.tsx): adds isReply prop, disables the quests query in reply/edit-mode, renders the chip above the toolbar behind the same preview/extension gates as the clipboard chip, and mutually excludes it with the clipboard chip.
  • Locale (en-US.json): three new quest_chip.* keys for daily-post label, streak count, and keep-alive reminder.

Confidence Score: 5/5

Safe to merge — the change is additive, well-isolated behind multiple guards, and reuses an existing query with no new endpoints.

All three issues flagged in the previous review round (edit-mode chip leak, global dismiss flag not scoped to user, and clipboard/quest chip stacking) have been addressed correctly. The quests query is disabled via enabled: !!username whenever username is falsy or the composer is in reply/edit-mode. The per-username dismiss Set is module-level but correctly keyed on username, so multi-account and re-mount scenarios are handled. The quest chip guards itself against the clipboard chip being visible, preventing simultaneous display. The pure deriveQuestChipState helper has thorough unit tests covering all edge cases including missing fields and null inputs.

No files require special attention.

Important Files Changed

Filename Overview
src/utils/questChip.ts New pure helper; derives chip visibility, streak, and at-risk state from QuestsResponse. Handles null/undefined gracefully; uses catalog goal as the completion threshold.
src/utils/questChip.test.ts Comprehensive unit tests covering null inputs, completion, active streak, at-risk flag, missing daily/streak sections — all pass.
src/components/markdownEditor/children/editorToolbar.tsx Adds quest chip with correct guards (isReply, isEditMode, isPreviewActive, isExtensionVisible, clipboardChipVisible, dismissed). Per-username session dismiss via module-level Set; query disabled via enabled:!!username when reply/edit-mode.
src/components/markdownEditor/view/markdownEditorView.tsx One-line change: forwards existing isReply prop down to EditorToolbar so the toolbar can gate the quest chip and query.
src/components/markdownEditor/styles/editorToolbarStyles.ts Adds five new style entries for the quest chip wrapper, chip touchable, close button, text, and at-risk (orange) text variant. Consistent with existing clipboard chip styles.
src/config/locales/en-US.json Adds three quest_chip locale keys (daily_post, streak, keep_streak) in the correct location.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant MV as MarkdownEditorView
    participant ET as EditorToolbar
    participant Q as useGetQuestsQuery
    participant API as Quests API
    participant D as deriveQuestChipState

    MV->>ET: isReply, isEditMode props
    ET->>Q: "username (undefined if isReply || isEditMode)"
    Note over Q: enabled: !!username skips fetch when undefined
    Q->>API: GET /quests (only for new posts)
    API-->>Q: QuestsResponse
    Q-->>ET: questsData
    ET->>D: deriveQuestChipState(questsData)
    D-->>ET: "QuestChipState | null"
    Note over ET: Guards: isReply, isEditMode, dismissed, isPreviewActive, isExtensionVisible, clipboardChipVisible, questChip.visible
    ET-->>MV: Renders chip or null
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant MV as MarkdownEditorView
    participant ET as EditorToolbar
    participant Q as useGetQuestsQuery
    participant API as Quests API
    participant D as deriveQuestChipState

    MV->>ET: isReply, isEditMode props
    ET->>Q: "username (undefined if isReply || isEditMode)"
    Note over Q: enabled: !!username skips fetch when undefined
    Q->>API: GET /quests (only for new posts)
    API-->>Q: QuestsResponse
    Q-->>ET: questsData
    ET->>D: deriveQuestChipState(questsData)
    D-->>ET: "QuestChipState | null"
    Note over ET: Guards: isReply, isEditMode, dismissed, isPreviewActive, isExtensionVisible, clipboardChipVisible, questChip.visible
    ET-->>MV: Renders chip or null
Loading

Reviews (2): Last reviewed commit: "fix(editor): scope quest chip dismissal ..." | Re-trigger Greptile

Comment thread src/components/markdownEditor/children/editorToolbar.tsx Outdated
Comment thread src/components/markdownEditor/children/editorToolbar.tsx Outdated
Comment thread src/components/markdownEditor/children/editorToolbar.tsx
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@feruzm, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 39 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6d08bd27-1f88-4772-b964-2b4c3195211e

📥 Commits

Reviewing files that changed from the base of the PR and between 8754e22 and 12673fc.

📒 Files selected for processing (1)
  • src/components/markdownEditor/children/editorToolbar.tsx
📝 Walkthrough

Walkthrough

This PR adds a "quest chip" UI element to the markdown editor toolbar. A new utility derives quest chip state (visibility, daily post completion, streak, at-risk status) from quest data. The toolbar fetches quests conditionally, renders the chip with dismiss/navigate handlers, adds styles and localization strings.

Changes

Quest Chip Feature

Layer / File(s) Summary
Quest chip state derivation and tests
src/utils/questChip.ts, src/utils/questChip.test.ts
Adds QuestChipState interface and deriveQuestChipState function computing visibility, completion, progress, streak, and at-risk status; adds Jest tests covering null handling, visibility, and edge cases.
Editor toolbar integration
src/components/markdownEditor/children/editorToolbar.tsx
Adds isReply prop, fetches quests via useGetQuestsQuery (disabled for replies), adds session-scoped dismissal state, dismiss/navigate-to-Perks handlers, and renders the quest chip conditionally.
Styling, wiring, and localization
src/components/markdownEditor/styles/editorToolbarStyles.ts, src/components/markdownEditor/view/markdownEditorView.tsx, src/config/locales/en-US.json
Adds quest chip style rules, passes isReply from the editor view into the toolbar, and adds quest_chip localization strings.

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MarkdownEditorView
  participant EditorToolbar
  participant useGetQuestsQuery
  participant deriveQuestChipState

  MarkdownEditorView->>EditorToolbar: render with isReply prop
  EditorToolbar->>useGetQuestsQuery: fetch quests (disabled if isReply)
  useGetQuestsQuery-->>EditorToolbar: questsData
  EditorToolbar->>deriveQuestChipState: derive chip state from questsData
  deriveQuestChipState-->>EditorToolbar: QuestChipState or null
  EditorToolbar->>EditorToolbar: render quest chip if visible and not dismissed
Loading

Possibly related PRs

  • ecency/ecency-mobile#3204: Both PRs use the shared useGetQuestsQuery hook for quest data—this PR consumes it for the editor quest chip, while that PR introduces it for the Perks dashboard quests tracker.

Poem

A chip appears where I write and post,
Streaks and goals, I track them most.
Dismiss it once, it stays away,
Hop to Perks to save the day! 🐇
With tests in tow, my burrow's neat,
A tiny quest, a big treat! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: surfacing daily quest and streak information in the editor.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/quest-chip

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/components/markdownEditor/styles/editorToolbarStyles.ts (2)

133-157: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate style definitions with clipboardChip*.

questChipWrapper/questChip/questChipClose/questChipText duplicate the existing clipboardChip* styles verbatim. Consider extracting a shared base style object.

♻️ Suggested consolidation
+const _dismissibleChipWrapper: ViewStyle = {
+  flexDirection: 'row',
+  alignItems: 'center',
+  alignSelf: 'flex-start',
+  marginHorizontal: 12,
+  marginTop: 6,
+  marginBottom: 4,
+  paddingLeft: 12,
+  paddingRight: 4,
+  paddingVertical: 6,
+  borderRadius: 16,
+  backgroundColor: '$primaryLightBackground',
+};
+const _dismissibleChipText = {
+  color: '$primaryDarkText',
+  fontSize: 12,
+  fontWeight: '600',
+};
...
-  clipboardChipWrapper: { ... } as ViewStyle,
+  clipboardChipWrapper: { ..._dismissibleChipWrapper } as ViewStyle,
...
-  questChipWrapper: { ... } as ViewStyle,
+  questChipWrapper: { ..._dismissibleChipWrapper } as ViewStyle,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/markdownEditor/styles/editorToolbarStyles.ts` around lines 133
- 157, The questChip styles duplicate the existing clipboardChip styles, so
consolidate the repeated definitions in editorToolbarStyles by extracting a
shared base style object and reusing it for both chip variants. Update
questChipWrapper, questChip, questChipClose, and questChipText to reference the
shared style alongside any chip-specific overrides, keeping the existing
clipboardChip* and questChip* symbols intact for clarity.

158-160: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Hardcoded hex color instead of theme variable.

Every other color in this file uses a $-prefixed EStyleSheet variable; #f97316 bypasses theming.

♻️ Suggested fix
  questChipTextAtRisk: {
-    color: '`#f97316`',
+    color: '$warningColor', // or whichever theme token represents "at risk"/warning orange
  },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/markdownEditor/styles/editorToolbarStyles.ts` around lines 158
- 160, The questChipTextAtRisk style is using a hardcoded hex color instead of
the file’s theme-driven EStyleSheet variables, which bypasses theming. Update
the questChipTextAtRisk color in editorToolbarStyles to use the same $-prefixed
variable pattern used by the other styles in this stylesheet, so it participates
in theme changes consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/components/markdownEditor/styles/editorToolbarStyles.ts`:
- Around line 133-157: The questChip styles duplicate the existing clipboardChip
styles, so consolidate the repeated definitions in editorToolbarStyles by
extracting a shared base style object and reusing it for both chip variants.
Update questChipWrapper, questChip, questChipClose, and questChipText to
reference the shared style alongside any chip-specific overrides, keeping the
existing clipboardChip* and questChip* symbols intact for clarity.
- Around line 158-160: The questChipTextAtRisk style is using a hardcoded hex
color instead of the file’s theme-driven EStyleSheet variables, which bypasses
theming. Update the questChipTextAtRisk color in editorToolbarStyles to use the
same $-prefixed variable pattern used by the other styles in this stylesheet, so
it participates in theme changes consistently.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 35311d50-5111-446b-8c88-d34ffa796092

📥 Commits

Reviewing files that changed from the base of the PR and between 4e8f62b and 8754e22.

📒 Files selected for processing (6)
  • src/components/markdownEditor/children/editorToolbar.tsx
  • src/components/markdownEditor/styles/editorToolbarStyles.ts
  • src/components/markdownEditor/view/markdownEditorView.tsx
  • src/config/locales/en-US.json
  • src/utils/questChip.test.ts
  • src/utils/questChip.ts

@feruzm
feruzm merged commit 1e6fea2 into development Jul 6, 2026
11 of 13 checks passed
@feruzm
feruzm deleted the feature/quest-chip branch July 6, 2026 19:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant