Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,12 @@ You can find the API route here `pages/api/immich-proxy/[...path].ts`
Since the `thumbnailPath` of Immich API doesnt give us a direct link to the image, I've created a proxy api that fetches the image and sends it back as a response.

**For Person's Thumbnail**
You can find the API route here `pages/api/immich-proxy/thumbnail/[id].ts`
You can find the API route here `pages/api/immich-proxy/thumbnail/[id].ts`

### Branching Strategy

- Always create a new branch for your changes
- Always rebase your branch before creating a PR
- Always squash your commits before merging
- Always merge your branch into the `prerelease` branch
- Always delete your branch after merging
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,26 @@ services:
- .env
```

Add the Immich API Key and immich url's to the env file (which you already have for the immich)
Add the Immich API Key and immich url's to the env file (which you already have for the immich).
You also need to add `DB_PORT` (Default 5432) and `DB_HOST`, which has to be set to the name of the immich database
container (Default `immich_postgres`).

```bash
IMMICH_API_KEY= # your_immich_api_key
IMMICH_URL = "http://local-ip-of-immich:port" # Your immich instace ip address and port
EXTERNAL_IMMICH_URL = "https://external-address" # External address of immich

DB_PORT = "5432"
DB_HOST = "immich_postgres"

# Optional
GOOGLE_MAPS_API_KEY= # Google Maps API Key
GEMINI_API_KEY= # Gemini API Key
```
Refer here for obtaining Immich API Key: https://immich.app/docs/features/command-line-interface#obtain-the-api-key

> [!NOTE] When creating the API key, make sure you select all the permissions for the API key.

#### Method 2 - Portainer

If you're using portainer, run the docker using `docker run` and add the power tools to the same network as immich.
Expand Down Expand Up @@ -149,4 +156,4 @@ Google Gemini 1.5 Flash model is used for parsing your search query in "Find" pa

## Contributing

Feel free to contribute to this project, I'm open to any suggestions and improvements. Please read the [CONTRIBUTING.md](./CONTRIBUTING.md) for more details.
Feel free to contribute to this project, I'm open to any suggestions and improvements. Please read the [CONTRIBUTING.md](./CONTRIBUTING.md) for more details.
Binary file modified bun.lockb
Binary file not shown.
155 changes: 155 additions & 0 deletions docs/VIRTUALIZED_ASSET_GRID.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# Virtualized Asset Grid Components

This document explains how to use the new React Window-based virtualized asset grid components for better performance with large datasets.

## Overview

The virtualized asset grid components provide significant performance improvements when displaying large numbers of assets by only rendering the items that are currently visible in the viewport. This is especially useful for photo galleries with thousands of images.

## Components

### 1. VirtualizedAssetGrid

A basic virtualized grid with fixed dimensions.

```tsx
import VirtualizedAssetGrid from '@/components/shared/VirtualizedAssetGrid';

<VirtualizedAssetGrid
assets={assets}
selectable={true}
onSelectionChange={handleSelectionChange}
columnCount={5}
itemSize={200}
height={600}
/>
```

**Props:**
- `assets`: Array of IAsset objects
- `selectable`: Whether assets can be selected (default: false)
- `onSelectionChange`: Callback when selection changes
- `columnCount`: Number of columns (default: 5)
- `itemSize`: Size of each item in pixels (default: 200)
- `height`: Height of the grid container (default: 600)

### 2. ResponsiveVirtualizedAssetGrid

A responsive virtualized grid that automatically adjusts to container size.

```tsx
import ResponsiveVirtualizedAssetGrid from '@/components/shared/ResponsiveVirtualizedAssetGrid';

<ResponsiveVirtualizedAssetGrid
assets={assets}
selectable={true}
onSelectionChange={handleSelectionChange}
targetItemSize={200}
gap={8}
minColumns={2}
maxColumns={8}
className="w-full h-full"
/>
```

**Props:**
- `assets`: Array of IAsset objects
- `selectable`: Whether assets can be selected (default: false)
- `onSelectionChange`: Callback when selection changes
- `targetItemSize`: Target size for each item (default: 200)
- `gap`: Gap between items in pixels (default: 8)
- `minColumns`: Minimum number of columns (default: 2)
- `maxColumns`: Maximum number of columns (default: 8)
- `className`: Additional CSS classes

## Features

### Selection
Both components support asset selection with the following features:
- Click to select/deselect individual assets
- Shift+click for range selection
- ESC key to clear all selections
- Visual indicators for selected items

### Lightbox Integration
Both components integrate with the existing lightbox for full-screen viewing:
- Click on an asset to open in lightbox
- Video support with duration display
- Download functionality

### Performance Optimizations
- Only renders visible items
- Lazy loading of images
- Efficient memory usage
- Smooth scrolling performance

## Migration from AssetGrid

To migrate from the existing `AssetGrid` component:

### Before:
```tsx
import AssetGrid from '@/components/shared/AssetGrid';

<AssetGrid
assets={assets}
selectable={true}
onSelectionChange={handleSelectionChange}
/>
```

### After:
```tsx
import ResponsiveVirtualizedAssetGrid from '@/components/shared/ResponsiveVirtualizedAssetGrid';

<div style={{ height: '600px', width: '100%' }}>
<ResponsiveVirtualizedAssetGrid
assets={assets}
selectable={true}
onSelectionChange={handleSelectionChange}
targetItemSize={200}
gap={8}
minColumns={2}
maxColumns={8}
/>
</div>
```

**Important:** The virtualized components require a container with a defined height. Make sure to wrap them in a div with appropriate height styling.

## Custom Hook: useGridDimensions

The `useGridDimensions` hook can be used to calculate optimal grid dimensions:

```tsx
import { useGridDimensions } from '@/hooks';

const gridDimensions = useGridDimensions({
containerWidth: 800,
containerHeight: 600,
itemSize: 200,
gap: 8,
minColumns: 2,
maxColumns: 8
});
```

## Example Usage

See `src/components/shared/AssetGridExample.tsx` for a complete example showing different configurations of the virtualized grid components.

## Performance Considerations

- Use `ResponsiveVirtualizedAssetGrid` for most use cases as it automatically adapts to container size
- Set appropriate `targetItemSize` based on your design requirements
- Consider using smaller `gap` values for dense layouts
- The components work best with containers that have a defined height

## Browser Support

The components use modern browser APIs:
- ResizeObserver (for responsive behavior)
- IntersectionObserver (for lazy loading)
- CSS Grid and Flexbox

For older browsers, consider using polyfills or the basic `VirtualizedAssetGrid` with fixed dimensions.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@radix-ui/react-alert-dialog": "^1.1.4",
"@radix-ui/react-avatar": "^1.1.0",
"@radix-ui/react-checkbox": "^1.1.2",
"@radix-ui/react-context-menu": "^2.2.16",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-hover-card": "^1.1.1",
Expand All @@ -35,11 +36,12 @@
"@remotion/cli": "4.0.232",
"@remotion/eslint-plugin": "^4.0.232",
"@tanstack/react-query": "^5.69.0",
"@tanstack/react-table": "^8.20.1",
"@tanstack/react-table": "^8.21.3",
"@types/cookie": "^0.6.0",
"@types/qs": "^6.9.15",
"@types/react-autosuggest": "^10.1.11",
"@types/react-calendar-heatmap": "^1.6.7",
"@types/react-window": "^1.8.8",
"@vis.gl/react-google-maps": "^1.4.2",
"axios": "^1.7.4",
"chrono-node": "^1.4.9",
Expand All @@ -66,6 +68,7 @@
"react-hot-toast": "^2.5.1",
"react-leaflet": "^4.2.1",
"react-mentions": "^4.4.10",
"react-window": "^1.8.11",
"recharts": "^2.12.7",
"remotion": "4.0.232",
"sass": "^1.77.8",
Expand Down
Loading
Loading