-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #40 from animeshchaudhri/main
Fix: Import and type errors
- Loading branch information
Showing
10 changed files
with
840 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,286 @@ | ||
# Gallery View | ||
|
||
The Gallery View is a core feature of our Tauri application, providing users with an intuitive interface to browse, sort, and interact with their media items (images and videos). | ||
|
||
## Components Overview | ||
|
||
1. MediaGallery | ||
2. MediaGrid | ||
3. MediaCard | ||
4. MediaView | ||
5. SortingControls | ||
6. PaginationControls | ||
|
||
## MediaGallery | ||
|
||
The main container component for the gallery view. | ||
|
||
### Key Features | ||
- Manages sorting and pagination state | ||
- Renders the grid of media items | ||
- Handles opening and closing of full-screen media view | ||
|
||
### Usage | ||
|
||
```jsx | ||
import MediaGallery from './MediaGallery'; | ||
|
||
<MediaGallery | ||
mediaItems={items} | ||
title="My Gallery" | ||
type="image" | ||
/> | ||
``` | ||
|
||
### Implementation Details | ||
|
||
```jsx | ||
export default function MediaGallery({ | ||
mediaItems, | ||
title, | ||
type, | ||
}: MediaGalleryProps) { | ||
const [sortBy, setSortBy] = useState<string>("date"); | ||
const [currentPage, setCurrentPage] = useState<number>(1); | ||
const [showMediaViewer, setShowMediaViewer] = useState<boolean>(false); | ||
const [selectedMediaIndex, setSelectedMediaIndex] = useState<number>(0); | ||
|
||
// Memoized sorted and paginated media items | ||
const sortedMedia = useMemo(() => sortMedia(mediaItems, sortBy), [mediaItems, sortBy]); | ||
const currentItems = useMemo(() => { | ||
const indexOfLastItem = currentPage * itemsPerPage; | ||
const indexOfFirstItem = indexOfLastItem - itemsPerPage; | ||
return sortedMedia.slice(indexOfFirstItem, indexOfLastItem); | ||
}, [sortedMedia, currentPage]); | ||
|
||
// ... other memoized values and callback functions | ||
|
||
return ( | ||
<div className="container"> | ||
<div className="dark:bg-background dark:text-foreground max-w-6xl mx-auto px-4 md:px-6 py-8"> | ||
{/* Title and SortingControls */} | ||
<MediaGrid | ||
mediaItems={currentItems} | ||
itemsPerRow={itemsPerRow} | ||
openMediaViewer={openMediaViewer} | ||
type={type} | ||
/> | ||
<PaginationControls | ||
currentPage={currentPage} | ||
totalPages={totalPages} | ||
onPageChange={setCurrentPage} | ||
/> | ||
{showMediaViewer && ( | ||
<MediaView | ||
initialIndex={selectedMediaIndex} | ||
onClose={closeMediaViewer} | ||
allMedia={sortedMedia.map((item) => item.src)} | ||
currentPage={currentPage} | ||
itemsPerPage={itemsPerPage} | ||
type={type} | ||
/> | ||
)} | ||
</div> | ||
</div> | ||
); | ||
} | ||
``` | ||
|
||
## MediaGrid | ||
|
||
Renders a grid of MediaCard components. | ||
|
||
### Usage | ||
|
||
```jsx | ||
<MediaGrid | ||
mediaItems={currentItems} | ||
itemsPerRow={3} | ||
openMediaViewer={openMediaViewer} | ||
type="image" | ||
/> | ||
``` | ||
|
||
### Implementation | ||
|
||
```jsx | ||
export default function MediaGrid({ | ||
mediaItems, | ||
itemsPerRow, | ||
openMediaViewer, | ||
type, | ||
}: MediaGridProps) { | ||
if (mediaItems.length === 0) { | ||
return <div className="flex justify-center items-center h-96"> | ||
<h1 className="text-2xl font-bold">No media found</h1> | ||
</div>; | ||
} | ||
|
||
return ( | ||
<div className={`grid gap-4 md:gap-6 ${/* grid classes based on itemsPerRow */}`}> | ||
{mediaItems.map((item, index) => ( | ||
<div key={index} onClick={() => openMediaViewer(index)} className="cursor-pointer"> | ||
<MediaCard item={item} type={type} /> | ||
</div> | ||
))} | ||
</div> | ||
); | ||
} | ||
``` | ||
|
||
## MediaCard | ||
|
||
Represents an individual media item in the grid. | ||
|
||
### Usage | ||
|
||
```jsx | ||
<MediaCard item={mediaItem} type="image" /> | ||
``` | ||
|
||
### Implementation | ||
|
||
```jsx | ||
export default function MediaCard({ item, type }: MediaCardProps) { | ||
return ( | ||
<div className="relative overflow-hidden rounded-lg shadow-lg group hover:shadow-xl hover:-translate-y-2 transition-transform duration-300 ease-in-out dark:bg-card dark:text-card-foreground"> | ||
<a href="#" className="absolute inset-0 z-10"> | ||
<span className="sr-only">View</span> | ||
</a> | ||
{type === "image" ? ( | ||
<img | ||
src={item.src} | ||
alt={item.title} | ||
className="object-cover w-full h-64 transition-opacity duration-300" | ||
/> | ||
) : ( | ||
<video | ||
controls | ||
src={item.src} | ||
className="object-cover w-full h-64 transition-opacity duration-300" | ||
/> | ||
)} | ||
</div> | ||
); | ||
} | ||
``` | ||
|
||
## MediaView | ||
|
||
Provides a full-screen view of media items with navigation. | ||
|
||
### Usage | ||
|
||
```jsx | ||
<MediaView | ||
initialIndex={selectedMediaIndex} | ||
onClose={closeMediaViewer} | ||
allMedia={sortedMedia.map((item) => item.src)} | ||
currentPage={currentPage} | ||
itemsPerPage={itemsPerPage} | ||
type="image" | ||
/> | ||
``` | ||
|
||
### Implementation | ||
|
||
```jsx | ||
const MediaView: React.FC<MediaViewProps> = ({ | ||
initialIndex, | ||
onClose, | ||
allMedia, | ||
currentPage, | ||
itemsPerPage, | ||
type, | ||
}) => { | ||
const [globalIndex, setGlobalIndex] = useState<number>( | ||
(currentPage - 1) * itemsPerPage + initialIndex | ||
); | ||
|
||
// ... navigation handlers | ||
|
||
return ( | ||
<div className="fixed top-0 left-0 w-full h-full flex justify-center items-center bg-black bg-opacity-90 z-50"> | ||
<button onClick={onClose} className="absolute z-0 top-4 left-4 px-4 py-2 rounded-md border border-black bg-white text-black text-sm hover:shadow-[4px_4px_0px_0px_rgba(0,0,0)] transition duration-200"> | ||
Back | ||
</button> | ||
{type === "image" ? ( | ||
<img | ||
src={allMedia[globalIndex]} | ||
alt={`image-${globalIndex}`} | ||
className="max-h-full" | ||
/> | ||
) : ( | ||
<video | ||
src={allMedia[globalIndex]} | ||
className="max-h-full" | ||
controls | ||
autoPlay | ||
/> | ||
)} | ||
{/* Navigation buttons */} | ||
</div> | ||
); | ||
}; | ||
``` | ||
|
||
## SortingControls | ||
|
||
Provides sorting options for media items. | ||
|
||
### Usage | ||
|
||
```jsx | ||
<SortingControls | ||
sortBy={sortBy} | ||
setSortBy={handleSetSortBy} | ||
mediaItems={mediaItems} | ||
/> | ||
``` | ||
|
||
### Implementation | ||
|
||
```jsx | ||
const SortingControls: React.FC<SortingControlsProps> = ({ | ||
sortBy, | ||
setSortBy, | ||
mediaItems, | ||
}) => { | ||
// ... year options generation logic | ||
|
||
return ( | ||
<DropdownMenu> | ||
<DropdownMenuTrigger asChild> | ||
<Button variant="outline" className="flex items-center gap-2"> | ||
<ListOrderedIcon className="w-4 h-4" /> | ||
Sort by {sortBy} | ||
</Button> | ||
</DropdownMenuTrigger> | ||
<DropdownMenuContent | ||
className="w-[200px] bg-white dark:text-foreground" | ||
align="end" | ||
> | ||
<DropdownMenuRadioGroup value={sortBy} onValueChange={setSortBy}> | ||
<DropdownMenuRadioItem value="date">Date</DropdownMenuRadioItem> | ||
{yearOptions.map((option) => ( | ||
<DropdownMenuRadioItem key={option.value} value={option.value}> | ||
{option.label} | ||
</DropdownMenuRadioItem> | ||
))} | ||
</DropdownMenuRadioGroup> | ||
</DropdownMenuContent> | ||
</DropdownMenu> | ||
); | ||
}; | ||
``` | ||
|
||
## Best Practices | ||
|
||
1. Use TypeScript for type safety and better developer experience. | ||
2. Implement proper error handling and loading states. | ||
3. Optimize performance using React hooks like `useMemo` and `useCallback`. | ||
4. Ensure accessibility in all components, especially in the MediaView for keyboard navigation. | ||
5. Use Tailwind CSS for consistent and responsive styling. | ||
|
||
|
||
This documentation provides an overview of the Gallery View components in your Tauri application. For more detailed information on specific components or functionalities, refer to the individual component files |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,83 @@ | ||
# Frontend Setup | ||
|
||
## Prerequisites | ||
|
||
Before setting up the frontend, ensure you have the following installed: | ||
|
||
- [Node.js](https://nodejs.org/) (LTS version recommended) | ||
- npm (comes with Node.js) | ||
- [Rust](https://www.rust-lang.org/tools/install) (latest stable version) | ||
- [Tauri CLI](https://v2.tauri.app/start/prerequisites/) | ||
|
||
For a comprehensive guide on prerequisites, refer to the [Tauri Prerequisites](https://v2.tauri.app/start/prerequisites/) documentation. | ||
|
||
## Setup Directory | ||
|
||
!!! note "Base Directory" | ||
All commands executed below are with respect to the `frontend/` directory | ||
|
||
### Installing Dependencies | ||
|
||
1. Navigate to the frontend directory: | ||
```bash | ||
cd frontend | ||
``` | ||
|
||
2. Install the project dependencies: | ||
```bash | ||
npm install | ||
``` | ||
|
||
For more information on npm commands, see the [npm documentation](https://docs.npmjs.com/). | ||
|
||
## Running the Application | ||
|
||
To start the Tauri application in development mode, run: | ||
|
||
```bash | ||
npm run tauri dev | ||
``` | ||
|
||
This command will: | ||
- Start the [Vite](https://vitejs.dev/) development server for the frontend | ||
- Compile the Rust backend | ||
- Launch the Tauri application window | ||
|
||
For more details on Tauri commands, check the [Tauri CLI documentation](https://tauri.app/v1/api/cli). | ||
|
||
!!! note "First Run" | ||
The first run might take longer as it needs to compile the Rust code. | ||
|
||
## Building for Production | ||
|
||
To create a production build of your Tauri application: | ||
|
||
```bash | ||
npm run tauri build | ||
``` | ||
|
||
This will create an optimized build of your application in the `src-tauri/target/release` directory. | ||
|
||
Learn more about building Tauri apps in the [Tauri Building Guide](https://tauri.app/v1/guides/building/). | ||
|
||
## Troubleshooting | ||
|
||
If you encounter any issues during setup or running the application: | ||
|
||
1. Ensure all prerequisites are correctly installed. | ||
2. Check that you're in the correct directory (`frontend/`). | ||
3. Try deleting the `node_modules` folder and `package-lock.json` file, then run `npm install` again. | ||
4. If Rust-related errors occur, try running `rustup update` to ensure you have the latest version. | ||
For more detailed troubleshooting, refer to the [Tauri Troubleshooting Guide](https://tauri.app/v1/guides/debugging/debugging/). | ||
## Additional Resources | ||
- [Tauri Documentation](https://tauri.app/v1/guides/) | ||
- [Vite Documentation](https://vitejs.dev/guide/) | ||
- [React Documentation](https://reactjs.org/docs/getting-started.html) | ||
- [TypeScript Documentation](https://www.typescriptlang.org/docs/) | ||
- [Rust Book](https://doc.rust-lang.org/book/) | ||
By following these steps, you should have your Tauri frontend environment set up and ready for development. Remember to run `npm run tauri dev` to start your development environment. | ||
Oops, something went wrong.