Skip to content

Antoinekm/no follow followers#2

Merged
antoinekm merged 3 commits intomasterfrom
antoinekm/no-follow-followers
Dec 26, 2025
Merged

Antoinekm/no follow followers#2
antoinekm merged 3 commits intomasterfrom
antoinekm/no-follow-followers

Conversation

@antoinekm
Copy link
Owner

@antoinekm antoinekm commented Dec 26, 2025

Summary by CodeRabbit

  • New Features

    • Added "Skip Followers" toggle in settings to exclude existing followers from mass-follow operations.
    • Added "Remove from list" action on followed profiles (with tooltip) to remove from lists while keeping follow state.
    • Mass-follow now respects the skip setting and shows a notification with how many users were skipped.
  • Style

    • Increased toast stacking order to ensure notifications and tooltips appear above other UI layers.
  • Chores

    • Version bumped to 0.2.0.

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings December 26, 2025 00:06
@coderabbitai
Copy link

coderabbitai bot commented Dec 26, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds a "skip followers" feature that prevents following users who already follow you during mass-follow; includes a settings toggle, storage defaults/migrations, friendship checks in the mass-follow flow with skipped-count reporting, a Remove-from-list action, increased toast z-index, and a package version bump.

Changes

Cohort / File(s) Summary
Toast styling
components/ui/toast.tsx
Increased z-index values from z-50 to z-10001 for toast viewport/positioner.
Limits & Settings UI
entrypoints/content/components/side-panel/settings/limits-section.tsx, entrypoints/content/side-panel/settings.tsx
Added skipFollowers boolean, onSkipFollowersChange handler, UI toggle in LimitsSection, wired setting load/save/reset and live updates in SettingsTab.
Followed list UI
entrypoints/content/side-panel/followed.tsx
Added Remove-from-list action with XIcon and tooltip; new handler to remove a profile from the followed list (keeps following).
Mass-follow logic
entrypoints/content/side-panel/suggestions.tsx
Read skipFollowers setting during mass-follow; check friendship status per user, skip users who already follow you, track skipped count, and show an info toast if any skipped.
Storage & exports
lib/storage.ts
Added skipFollowers to UserSettings, introduced DEFAULT_SKIP_FOLLOWERS = true, included in default data and migrations, exported constant.
Versioning
package.json
Bumped version to 0.2.0; added version:patch, version:minor, version:major npm scripts.

Sequence Diagram

sequenceDiagram
    participant User
    participant SettingsUI as Settings UI
    participant Storage
    participant Suggestions as Mass-Follow Handler
    participant InstagramAPI as Instagram API
    participant Toast

    User->>SettingsUI: Toggle "Skip Followers"
    SettingsUI->>Storage: save(skipFollowers)
    Storage-->>SettingsUI: ack

    User->>Suggestions: start mass-follow(selectedUsers)
    Suggestions->>Storage: read(skipFollowers)
    Storage-->>Suggestions: return skipFollowers

    loop for each user
        alt skipFollowers == true
            Suggestions->>InstagramAPI: getFriendshipStatus(user)
            InstagramAPI-->>Suggestions: followsMe? (yes/no)
            alt yes
                Suggestions->>Suggestions: skip user (remove, ++skippedCount)
            else no
                Suggestions->>InstagramAPI: follow(user)
                InstagramAPI-->>Suggestions: follow result
            end
        else
            Suggestions->>InstagramAPI: follow(user)
            InstagramAPI-->>Suggestions: follow result
        end
    end

    Suggestions->>Toast: show("X users skipped") when skippedCount > 0
    Toast-->>User: display notification
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nudge the toggle, nimble and sly,
Skip those who follow — no need to try.
Toasts leap higher so messages gleam,
Lists trimmed neat, and the mass-follow's clean.
Version bumped up — hop onward we beam!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Antoinekm/no follow followers' directly relates to the main feature: adding ability to skip users who already follow you during mass-follow operations.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch antoinekm/no-follow-followers

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b2350d8 and 65a6e80.

📒 Files selected for processing (1)
  • entrypoints/content/side-panel/suggestions.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • entrypoints/content/side-panel/suggestions.tsx

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

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a "skip existing followers" feature for the mass-follow operation and adds quality-of-life improvements to the extension. The version is bumped from 0.1.0 to 0.2.0 to reflect these new capabilities.

Key changes:

  • Adds a new setting to skip users who already follow you during mass-follow operations
  • Introduces ability to remove users from the followed list without unfollowing them on Instagram
  • Adds npm scripts for versioning workflow automation

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
package.json Bumps version to 0.2.0 and adds versioning scripts for patch, minor, and major releases
lib/storage.ts Adds skipFollowers setting with default value true and migration logic for existing users
entrypoints/content/side-panel/suggestions.tsx Implements skip followers logic in mass-follow operation with friendship status check and user feedback
entrypoints/content/side-panel/settings.tsx Adds state management for the skip followers setting in the settings UI
entrypoints/content/side-panel/followed.tsx Adds "remove from list" functionality with new UI button to remove users without unfollowing
entrypoints/content/components/side-panel/settings/limits-section.tsx Adds toggle switch UI control for the skip followers setting
components/ui/toast.tsx Updates z-index from z-50 to z-10001 for toast components

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
package.json (1)

16-18: Consider cross-platform compatibility for version scripts.

The version scripts use shell command substitution which requires bash/zsh. These may not work on Windows without WSL or Git Bash. Consider using a cross-platform solution (e.g., cross-env, tsx script) or document the bash requirement.

Alternative: Cross-platform version script using Node.js

Create scripts/version.js:

#!/usr/bin/env node
const { execSync } = require('child_process');
const { readFileSync } = require('fs');

const level = process.argv[2];
if (!['patch', 'minor', 'major'].includes(level)) {
  console.error('Usage: node scripts/version.js <patch|minor|major>');
  process.exit(1);
}

execSync(`npm version ${level} --no-git-tag-version`, { stdio: 'inherit' });
const pkg = JSON.parse(readFileSync('./package.json', 'utf8'));
execSync(`git add package.json && git commit -m "🔖 release v${pkg.version}"`, { stdio: 'inherit' });

Then update package.json:

-"version:patch": "npm version patch --no-git-tag-version && git add package.json && git commit -m \"🔖 release v$(node -p \"require('./package.json').version\")\"",
-"version:minor": "npm version minor --no-git-tag-version && git add package.json && git commit -m \"🔖 release v$(node -p \"require('./package.json').version\")\"",
-"version:major": "npm version major --no-git-tag-version && git add package.json && git commit -m \"🔖 release v$(node -p \"require('./package.json').version\")\""
+"version:patch": "node scripts/version.js patch",
+"version:minor": "node scripts/version.js minor",
+"version:major": "node scripts/version.js major"
entrypoints/content/side-panel/suggestions.tsx (1)

177-192: Consider increasing delay between friendship checks.

The skip logic correctly checks followed_by status before following. However, the delay (500-1000ms) is significantly shorter than the post-follow delay (2000-4000ms). If many users are skipped in succession, this could trigger Instagram's rate limiting on friendship status checks.

Recommended: Increase delay to match follow cadence
           if (friendshipStatus.followed_by) {
             // User already follows us, skip them
             setSelectedUsers((prev) => {
               const next = new Set(prev);
               next.delete(suggestion.user.pk);
               return next;
             });
             skippedCount++;
             // Small delay before checking next user
-            await new Promise((resolve) => setTimeout(resolve, 500 + Math.random() * 500));
+            await new Promise((resolve) => setTimeout(resolve, 1500 + Math.random() * 1000));
             continue;
           }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 85d7fb6 and b2350d8.

📒 Files selected for processing (7)
  • components/ui/toast.tsx
  • entrypoints/content/components/side-panel/settings/limits-section.tsx
  • entrypoints/content/side-panel/followed.tsx
  • entrypoints/content/side-panel/settings.tsx
  • entrypoints/content/side-panel/suggestions.tsx
  • lib/storage.ts
  • package.json
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Store centralized app constants (name, short name, developer info) in constants/app.ts and reference via APP.NAME, APP.SHORT_NAME, etc.
Define shared TypeScript types for API responses and messages in lib/types.ts
Implement Instagram API functions (fetchSuggestions, followUser, unfollowUser, checkFollowStatus) in lib/instagram.ts
Implement browser storage with multi-account support in lib/storage.ts, scoped per Instagram user ID with daily limits reset at midnight
Implement background automation logic in lib/automation.ts
Use coss/ui components (Button, Avatar, ScrollArea, etc.) from components/ui/ for consistent styling with Tailwind CSS v4
Include x-csrftoken header from cookies and x-ig-app-id: 936619743392459 in all Instagram API requests

Files:

  • entrypoints/content/side-panel/followed.tsx
  • entrypoints/content/components/side-panel/settings/limits-section.tsx
  • components/ui/toast.tsx
  • lib/storage.ts
  • entrypoints/content/side-panel/settings.tsx
  • entrypoints/content/side-panel/suggestions.tsx
entrypoints/content/side-panel/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Organize tab components (suggestions, followed, settings) in entrypoints/content/side-panel/

Files:

  • entrypoints/content/side-panel/followed.tsx
  • entrypoints/content/side-panel/settings.tsx
  • entrypoints/content/side-panel/suggestions.tsx
entrypoints/content/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Inject main content script UI into *.instagram.com/* via Shadow DOM from entrypoints/content/

Files:

  • entrypoints/content/side-panel/followed.tsx
  • entrypoints/content/components/side-panel/settings/limits-section.tsx
  • entrypoints/content/side-panel/settings.tsx
  • entrypoints/content/side-panel/suggestions.tsx
entrypoints/content/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Place reusable UI components for content script in entrypoints/content/components/

Files:

  • entrypoints/content/components/side-panel/settings/limits-section.tsx
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: antoinekm/charognard PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T23:33:42.465Z
Learning: Track followed profiles, daily action counts, and automation settings in browser storage with separate daily limits for follow and unfollow actions resetting at midnight
📚 Learning: 2025-12-25T23:33:42.465Z
Learnt from: CR
Repo: antoinekm/charognard PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T23:33:42.465Z
Learning: WXT browser extension architecture for Instagram follow/unfollow functionality built with React, TypeScript, and Tailwind CSS v4

Applied to files:

  • entrypoints/content/side-panel/followed.tsx
  • entrypoints/content/components/side-panel/settings/limits-section.tsx
  • entrypoints/content/side-panel/suggestions.tsx
  • package.json
📚 Learning: 2025-12-25T23:33:42.465Z
Learnt from: CR
Repo: antoinekm/charognard PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T23:33:42.465Z
Learning: Applies to entrypoints/content/side-panel/**/*.{ts,tsx} : Organize tab components (suggestions, followed, settings) in `entrypoints/content/side-panel/`

Applied to files:

  • entrypoints/content/side-panel/followed.tsx
  • entrypoints/content/components/side-panel/settings/limits-section.tsx
  • entrypoints/content/side-panel/settings.tsx
  • entrypoints/content/side-panel/suggestions.tsx
📚 Learning: 2025-12-25T23:33:42.465Z
Learnt from: CR
Repo: antoinekm/charognard PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T23:33:42.465Z
Learning: Applies to **/*.{ts,tsx} : Implement Instagram API functions (fetchSuggestions, followUser, unfollowUser, checkFollowStatus) in `lib/instagram.ts`

Applied to files:

  • entrypoints/content/side-panel/followed.tsx
  • entrypoints/content/side-panel/suggestions.tsx
📚 Learning: 2025-12-25T23:33:42.465Z
Learnt from: CR
Repo: antoinekm/charognard PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T23:33:42.465Z
Learning: Applies to entrypoints/popup/**/*.{ts,tsx} : Implement popup entry point in `entrypoints/popup/` that opens Instagram and triggers the side panel

Applied to files:

  • entrypoints/content/side-panel/followed.tsx
  • entrypoints/content/side-panel/suggestions.tsx
📚 Learning: 2025-12-25T23:33:42.465Z
Learnt from: CR
Repo: antoinekm/charognard PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T23:33:42.465Z
Learning: Applies to **/*.{ts,tsx} : Use coss/ui components (Button, Avatar, ScrollArea, etc.) from `components/ui/` for consistent styling with Tailwind CSS v4

Applied to files:

  • entrypoints/content/components/side-panel/settings/limits-section.tsx
📚 Learning: 2025-12-25T23:33:42.465Z
Learnt from: CR
Repo: antoinekm/charognard PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T23:33:42.465Z
Learning: Applies to entrypoints/content/contexts/**/*.{ts,tsx} : Use React contexts for shared state management in `entrypoints/content/contexts/` (AuthContext, HideButtonContext)

Applied to files:

  • entrypoints/content/components/side-panel/settings/limits-section.tsx
📚 Learning: 2025-12-25T23:33:42.465Z
Learnt from: CR
Repo: antoinekm/charognard PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T23:33:42.465Z
Learning: Applies to components/icons/**/*.{ts,tsx} : Store custom SVG icons (CharognardIcon) in `components/icons/`

Applied to files:

  • entrypoints/content/components/side-panel/settings/limits-section.tsx
📚 Learning: 2025-12-25T23:33:42.465Z
Learnt from: CR
Repo: antoinekm/charognard PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T23:33:42.465Z
Learning: Track followed profiles, daily action counts, and automation settings in browser storage with separate daily limits for follow and unfollow actions resetting at midnight

Applied to files:

  • entrypoints/content/components/side-panel/settings/limits-section.tsx
  • lib/storage.ts
  • entrypoints/content/side-panel/settings.tsx
  • entrypoints/content/side-panel/suggestions.tsx
📚 Learning: 2025-12-25T23:33:42.465Z
Learnt from: CR
Repo: antoinekm/charognard PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T23:33:42.465Z
Learning: Applies to **/*.{ts,tsx} : Implement browser storage with multi-account support in `lib/storage.ts`, scoped per Instagram user ID with daily limits reset at midnight

Applied to files:

  • lib/storage.ts
  • entrypoints/content/side-panel/settings.tsx
📚 Learning: 2025-12-25T23:33:42.465Z
Learnt from: CR
Repo: antoinekm/charognard PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-25T23:33:42.465Z
Learning: Applies to entrypoints/content/hooks/**/*.{ts,tsx} : Implement custom hooks in `entrypoints/content/hooks/` (useAuth, useHideButton, useSessionStorage)

Applied to files:

  • entrypoints/content/side-panel/suggestions.tsx
🧬 Code graph analysis (4)
entrypoints/content/side-panel/followed.tsx (5)
lib/storage.ts (1)
  • removeFollowedProfile (208-212)
components/ui/toast.tsx (1)
  • toastManager (268-268)
components/ui/button.tsx (1)
  • Button (70-70)
components/ui/spinner.tsx (1)
  • Spinner (18-18)
components/ui/tooltip.tsx (4)
  • Tooltip (63-63)
  • TooltipTrigger (64-64)
  • TooltipPopup (65-65)
  • TooltipPopup (66-66)
entrypoints/content/components/side-panel/settings/limits-section.tsx (1)
components/ui/switch.tsx (1)
  • Switch (27-27)
entrypoints/content/side-panel/settings.tsx (1)
lib/storage.ts (4)
  • DEFAULT_SKIP_FOLLOWERS (345-345)
  • updateSettings (191-195)
  • DEFAULT_FOLLOW_LIMIT (345-345)
  • DEFAULT_UNFOLLOW_LIMIT (345-345)
entrypoints/content/side-panel/suggestions.tsx (3)
lib/storage.ts (1)
  • getSettings (186-189)
lib/instagram.ts (1)
  • checkFriendshipStatus (85-97)
components/ui/toast.tsx (1)
  • toastManager (268-268)
🔇 Additional comments (17)
package.json (1)

5-5: LGTM! Version bump aligns with feature addition.

The minor version bump to 0.2.0 appropriately reflects the addition of the skipFollowers feature.

entrypoints/content/side-panel/suggestions.tsx (2)

9-9: LGTM! Clean settings integration.

The skipFollowers setting is properly read from storage before the mass-follow loop begins.

Also applies to: 159-161


213-218: LGTM! Clear user feedback for skipped users.

The toast notification appropriately informs users about skipped profiles with proper pluralization.

lib/storage.ts (5)

20-20: LGTM! Well-documented type definition.

The skipFollowers field is properly typed and includes a clear explanatory comment.


61-61: LGTM! Safe default value.

Defaulting to true is appropriate—it prevents accidentally following users who already follow you during mass-follow operations.


76-86: LGTM! Proper default storage initialization.

The skipFollowers setting is correctly included in default storage data.


147-150: LGTM! Comprehensive migration coverage.

The migration logic properly handles existing users by ensuring skipFollowers is initialized to the default value if undefined. All migration paths are covered (legacy data, missing settings, and partial settings).


345-345: LGTM! Proper module export.

DEFAULT_SKIP_FOLLOWERS is correctly exported alongside other default constants.

entrypoints/content/side-panel/followed.tsx (2)

120-136: LGTM! Clean implementation of remove-from-list feature.

The handler correctly removes the profile from local storage without calling unfollowUser, preserving the Instagram follow relationship while cleaning up the extension's tracking list.


375-406: LGTM! Excellent UX with clear tooltip.

The UI integration is well-executed. The tooltip text "Remove from list (keep following)" clearly differentiates this action from unfollowing, preventing user confusion.

entrypoints/content/components/side-panel/settings/limits-section.tsx (2)

8-22: LGTM! Clean props interface for new toggle.

The skipFollowers and onSkipFollowersChange props are properly typed and integrated into the component signature.

Also applies to: 24-38


53-62: LGTM! Clear and well-positioned UI toggle.

The skip followers section is well-placed after the warning and includes a descriptive label that clearly explains the feature's purpose.

entrypoints/content/side-panel/settings.tsx (4)

15-15: LGTM! Proper state initialization.

The skipFollowers state is correctly initialized with the default value of true.

Also applies to: 38-38


55-66: LGTM! Proper settings loading.

The skipFollowers setting is correctly loaded from storage alongside other settings.


83-127: LGTM! Complete save and reset logic.

The skipFollowers setting is properly included in both save and reset operations, with the reset correctly restoring the default value.


162-176: LGTM! Proper component wiring.

The skipFollowers state and update handler are correctly passed to the LimitsSection component.

components/ui/toast.tsx (1)

61-61: Z-index strategy is appropriate and well-organized.

The z-index value of 10001 for toasts is correctly positioned above other UI elements (side panel at z-9999, dropdowns at z-10000, overlays at z-9998). This layering ensures toasts remain visible as intended notifications. The extension's z-index strategy is intentionally high to layer above Instagram's native UI, which is expected for a content script extension.

Also applies to: 203-203

@antoinekm antoinekm merged commit fadda5a into master Dec 26, 2025
1 check passed
@antoinekm antoinekm deleted the antoinekm/no-follow-followers branch December 26, 2025 00:17
@antoinekm antoinekm changed the title Antoinekm/no follow followers @coderabbitai Dec 26, 2025
@antoinekm antoinekm changed the title @coderabbitai Antoinekm/no follow followers Dec 26, 2025
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.

2 participants