Skip to content

Fix #1373: Resolve empty folder issue on instant AI tagging#1380

Open
Takitxt wants to merge 6 commits into
AOSSIE-Org:mainfrom
Takitxt:future-2
Open

Fix #1373: Resolve empty folder issue on instant AI tagging#1380
Takitxt wants to merge 6 commits into
AOSSIE-Org:mainfrom
Takitxt:future-2

Conversation

@Takitxt

@Takitxt Takitxt commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Addressed Issues:

Fix : #1373 Temporary empty folder state during AI Tagging just after uploading a Folder.
Problem:
When a user adds a large folder containing many images, indexing takes some time in the beginning.
If AI Tagging is enabled just after uploading the folder, when the uploading and indexing is in process,
the application displays the folder as empty before the images are loaded and tagging begins.

Proposed Solutions:

  • [ ] Time Stamping : Causing a heuristic bug
  • [ ] Polling: Causing the heuristic bug.
  • [ x ] Using a new Interface indexing_status in the backend so that it can notify the frontend that the indexing is in process.: works perfectly.

Solution:

Backend: Added an indexing_status field ('not_started' | 'in_progress' | 'completed') to FolderDetails and related Pydantic/TypeScript schemas to track the background job state.

Frontend UI: Updated the folder.ts logic to evaluate indexing_status. The UI now displays a loading spinner while indexing is in_progress. It only displays "Folder is Empty" if indexing_status is completed AND image_count becomes 0.

Steps to Test:

  1. Navigate to Folder Management.

  2. Add a large folder containing a significant number of images.

  3. Immediately enable AI Tagging and observe that the folder should display a loading spinner instead of the "Folder is Empty" text.

Screenshots/Recordings:

Pictopy Before:

PICTOPY_BEFORE.mov

Pictopy After:

Pictopy_AFTER.mov

Changes Made:

1. Frontend:
File - 1 : /pages/settings/components/folderManagementCsrd.tsx
Added a spinner.

{folder.indexing_status === 'in_progress' ? (
                      <div className="flex items-center gap-4 [--radius:1.2rem]">
                        <Badge className="bg-oklch(21.4% 0.009 43.1) text-white hover:bg-black/90">
                          <Spinner
                            data-icon="inline-start"
                            className="text-white"
                          />
                          Indexing Folder...
                        </Badge>
                      </div>
                    ) : folder.image_count === 0 &&
                      folder.indexing_status === 'completed' ? (
                      <div className="text-muted-foreground text-sm italic">
                        Folder is empty
                      </div>
                    ) : (

File - 2: /types/folder.ts: Added the indexing_status interface.

File - 3 : hooks/folderOperations.tsx: checking the indexing_status every second to show AI tagging once it completes.

refetchInterval: folders.some(
      (f) => f.AI_Tagging && f.indexing_status === 'in_progress',
    )
      ? 1000
      : false,
    refetchIntervalInBackground: true,
  });
  1. Backend:
    File -4 : /database/folder.py:
  • Added the db_update_folder_indexing_status helper function to handle SQLite database updates for the newly introduced indexing_status field on folders.

  • This is a required backend component to resolve the "Folder is Empty" bug. Background tasks or indexing scripts need a reliable way to update a folder's state (not_started -> in_progress -> completed) in the database as they process images.

def db_update_folder_indexing_status(folder_id: str, status: str) -> None:
    """Update the indexing_status of a specific folder."""
    conn = sqlite3.connect(DATABASE_PATH)
    cursor = conn.cursor()
    try:
        cursor.execute(
            "UPDATE folders SET indexing_status = ? WHERE folder_id = ?",
            (status, folder_id),
        )
        conn.commit()
    except sqlite3.Error as e:
        logger.error(f"Error updating indexing status: {e}")
        conn.rollback()
    finally:
        conn.close()

File - 5 : routes/folder.py: Implemented indexing_status lifecycle in folder routes:

  • Sets indexing_status to "in_progress" immediately upon folder initialization to trigger the frontend loading UI.
  • Maps indexing_status into the API response models.
  • Loops through processed folders to mark them as "completed" once image processing finishes, resolving the UI loading state.
def post_folder_add_sequence(folder_path: str, folder_id: int):
    """
    Post-addition sequence for a folder.
    This function is called after a folder is successfully added.
    It processes images in the folder and updates the database.
    """
    folder_ids_and_paths = []   // added line
    try:
        # Get all folder IDs and paths that match the root path prefix
        folder_data = []
        folder_ids_and_paths = db_get_folder_ids_by_path_prefix(folder_path)

        # Set all folders to non-recursive (False)
        for folder_id_from_db, folder_path_from_db in folder_ids_and_paths:
            folder_data.append((folder_path_from_db, folder_id_from_db, False))
            
            db_update_folder_indexing_status(folder_id_from_db, "in_progress") // added line

        logger.info(f"Add folder: {folder_data}")
        # Process images in all folders
        image_util_process_folder_images(folder_data)

        # Restart sync microservice watcher after processing images
        API_util_restart_sync_microservice_watcher()
        
        for folder_id_from_db, _ in folder_ids_and_paths: // edited line
            db_update_folder_indexing_status(folder_id_from_db, "completed") // edited line

    except Exception as e:
        logger.error(
            f"Error in post processing after folder {folder_path} was added: {e}"
        )
        for folder_id_from_db, _ in folder_ids_and_paths: // edited line
            db_update_folder_indexing_status(folder_id_from_db, "completed") // edited line
        return False
    return True

File - 6 : schemes/folder.py: Added the indexing_status scheme in folderDetails

File - 7 : tests/test_folders.py: Added indexing_status details.

📝 Conclusion

This completely resolves the false positive "Folder is empty" state issue while indexing.#1373

Tests Performed:

Frontend:

  • passes npm test
  • passes npm run lint:check
  • passes npm run format:check
    Backend:
  • passes pytest.

AI Usage Disclosure:

We encourage contributors to use AI tools responsibly when creating Pull Requests. While AI can be a valuable aid, it is essential to ensure that your contributions meet the task requirements, build successfully, include relevant tests, and pass all linters. Submissions that do not meet these standards may be closed without warning to maintain the quality and integrity of the project. Please take the time to understand the changes you are proposing and their impact. AI slop is strongly discouraged and may lead to banning and blocking. Do not spam our repos with AI slop.

Check one of the checkboxes below:

  • This PR does not contain AI-generated code at all.
  • [ x ] This PR contains AI-generated code. I have read the AI Usage Policy and this PR complies with this policy. I have tested the code locally and I am responsible for it.

I have used the following AI models and tools: Claude Sonnet 5 / Google Gemini 3 pro / my own LLM.

Checklist

  • [ x ] My PR addresses a single issue, fixes a single bug or makes a single improvement.
  • [ x ] My code follows the project's code style and conventions
  • If applicable, I have made corresponding changes or additions to the documentation
  • [ x ] If applicable, I have made corresponding changes or additions to tests
  • [ x ] My changes generate no new warnings or errors
  • [ x ] I have joined the Discord server and I will share a link to this PR with the project maintainers there
  • [ x ] I have read the Contribution Guidelines
  • [ x ] Once I submit my PR, CodeRabbit AI will automatically review it and I will address CodeRabbit's comments.
  • [ x ] I have filled this PR template completely and carefully, and I understand that my PR may be closed without review otherwise.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Added folder indexing status tracking with not_started, in_progress, and completed.
    • Folder details now expose indexing_status, and the UI shows an “Indexing Folder...” indicator with a loading spinner during in_progress.
    • Background polling is enabled only while folder indexing is active.
  • Bug Fixes

    • Improved indexing status transitions during the post-add workflow, including error handling.
  • Documentation

    • Updated the API/OpenAPI schema to include the optional indexing_status field.
  • Tests

    • Adjusted mocked folder details to include indexing_status.

@github-actions github-actions Bot added bug Something isn't working frontend good first issue Good for newcomers labels Jul 16, 2026
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 89ace2be-5367-4fb7-a01d-7fb191465371

📥 Commits

Reviewing files that changed from the base of the PR and between 4b35128 and 1c7c924.

📒 Files selected for processing (2)
  • backend/app/database/folders.py
  • backend/app/routes/folders.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • backend/app/routes/folders.py
  • backend/app/database/folders.py

Walkthrough

The PR adds persistent folder indexing states, exposes them through the backend and OpenAPI schema, updates folder-add workflow transitions, and adds frontend polling with an indexing indicator. It also adds a reusable spinner and adjusts ZoomableImage destructuring formatting.

Changes

Folder indexing status flow

Layer / File(s) Summary
Status contracts and persistence
backend/app/database/folders.py, backend/app/schemas/folders.py, frontend/src/types/Folder.ts, docs/backend/backend_python/openapi.json
Adds indexing_status storage, update logic, response fields, typed values, and OpenAPI documentation.
Processing status transitions
backend/app/routes/folders.py
Marks affected folders in_progress during image processing and completed after success or exception handling.
API and frontend progress display
backend/app/routes/folders.py, backend/tests/test_folders.py, frontend/src/hooks/useFolderOperations.tsx, frontend/src/pages/SettingsPage/components/FolderManagementCard.tsx, frontend/src/components/ui/spinner.tsx
Maps indexing status through folder responses, polls active indexing folders, and displays an accessible spinner badge while indexing is in progress.

Frontend cleanup

Layer / File(s) Summary
ZoomableImage destructuring cleanup
frontend/src/components/Media/ZoomableImage.tsx
Adds trailing-comma formatting to the useZoomTransform result destructuring.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant FolderManagementCard
  participant foldersQuery
  participant get_all_folders
  participant db_get_all_folder_details
  FolderManagementCard->>foldersQuery: request folder details
  foldersQuery->>get_all_folders: fetch folders
  get_all_folders->>db_get_all_folder_details: read indexing_status
  db_get_all_folder_details-->>get_all_folders: return folder status
  get_all_folders-->>foldersQuery: return FolderDetails
  foldersQuery-->>FolderManagementCard: refresh displayed status
  FolderManagementCard->>FolderManagementCard: show indexing spinner when in_progress
Loading

Possibly related PRs

Suggested labels: Python, TypeScript/JavaScript, Documentation

Poem

I’m a rabbit with folders to tend,
Watching each index begin and then end.
A spinner hops round,
While statuses abound—
“Completed!” says the burrowed-up friend.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main fix: preventing folders from appearing empty during instant AI tagging.
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

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
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
backend/app/database/folders.py (1)

460-461: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove redundant comment.

As per path instructions, point out redundant obvious comments that do not add clarity to the code. The function name and its docstring clearly explain its purpose.

♻️ Proposed fix
-#for tracking indexing status of folders
 def db_update_folder_indexing_status(folder_id: str, status: str) -> None:
🤖 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 `@backend/app/database/folders.py` around lines 460 - 461, Remove the redundant
“for tracking indexing status of folders” comment immediately above
db_update_folder_indexing_status; retain the function and its existing docstring
unchanged.

Source: Path instructions

🤖 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.

Inline comments:
In `@frontend/src/pages/SettingsPage/components/FolderManagementCard.tsx`:
- Line 97: Update the Badge className in FolderManagementCard to use valid
Tailwind arbitrary-value syntax for the OKLCH background color, replacing spaces
within the bracketed value with underscores, or use an equivalent predefined
background utility. Preserve the existing text and hover styling.

---

Nitpick comments:
In `@backend/app/database/folders.py`:
- Around line 460-461: Remove the redundant “for tracking indexing status of
folders” comment immediately above db_update_folder_indexing_status; retain the
function and its existing docstring unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e113a8ba-c532-4cb8-b144-26ff635fd468

📥 Commits

Reviewing files that changed from the base of the PR and between dbc1434 and d78b5f8.

📒 Files selected for processing (10)
  • backend/app/database/folders.py
  • backend/app/routes/folders.py
  • backend/app/schemas/folders.py
  • backend/tests/test_folders.py
  • docs/backend/backend_python/openapi.json
  • frontend/src/components/Media/ZoomableImage.tsx
  • frontend/src/components/ui/spinner.tsx
  • frontend/src/hooks/useFolderOperations.tsx
  • frontend/src/pages/SettingsPage/components/FolderManagementCard.tsx
  • frontend/src/types/Folder.ts

Comment thread frontend/src/pages/SettingsPage/components/FolderManagementCard.tsx Outdated
@Takitxt

Takitxt commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

@rohan-pandeyy can you review this PR and tell me if you need any changes. I did run the black app/database/folder.py but it still shows error and on my local machines it dosen't show any problem.

@Takitxt

Takitxt commented Jul 18, 2026

Copy link
Copy Markdown
Contributor Author

@rohan-pandeyy can you please again review this PR and suggest changes.

@rohan-pandeyy rohan-pandeyy Jul 19, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we not use "import { Loader2 } from 'lucide-react';" rather than creating this spinner component?

@Takitxt Takitxt Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i mean we can but the project already uses shadCN so i did it using shadCN. if you want me to update i can.?? ( i have not created a spinner component i have taken it from shadCN library just like other components badge for example ).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working frontend good first issue Good for newcomers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: Temporary empty folder state during AI Tagging just after uploading a Folder.

2 participants