Skip to content

Commit 9330fa3

Browse files
authored
Merge pull request #230 from PasteBar/163/customize-db-storage-location
163/customize db storage location
2 parents 4f7d2aa + d656eb2 commit 9330fa3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+4513
-1286
lines changed

.changeset/calm-bags-learn.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'pastebar-app-ui': patch
3+
---
4+
5+
Added option to disable capturing and storing images from clipboard

.changeset/tasty-walls-pull.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'pastebar-app-ui': minor
3+
---
4+
5+
Added custom data location to store application data in a folder of your choice instead of the default location.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ safelist.txt
1212
clipboard-images/**/*
1313
clip-images/**/*
1414
src-tauri/http-cacache/**/*
15+
pastebar_settings.yaml
1516

1617
node_modules
1718
packages/dist-ui/**/*

CLAUDE.md

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
PasteBar is a cross-platform clipboard manager built with Tauri (Rust + TypeScript/React). It provides unlimited clipboard history, custom clip management, collections, and advanced features like programming language detection and web scraping.
8+
9+
**Technology Stack:**
10+
- **Backend**: Rust with Tauri framework, Diesel ORM (SQLite), Reqwest, Serde, Tokio
11+
- **Frontend**: TypeScript, React, React Query, Vite, TailwindCSS, Jotai, Zustand
12+
- **Platforms**: macOS and Windows (including Apple Silicon M1, Intel, AMD, and ARM)
13+
14+
## Development Commands
15+
16+
### Prerequisites
17+
First install the Diesel CLI:
18+
```bash
19+
cargo install diesel_cli --no-default-features --features sqlite
20+
```
21+
22+
### Main Development Commands
23+
```bash
24+
# Development (starts both frontend and backend in dev mode)
25+
npm start
26+
# or
27+
npm run dev
28+
29+
# Build for production
30+
npm run build
31+
32+
# Build debug version
33+
npm run app:build:debug
34+
35+
# Platform-specific builds
36+
npm run app:build:osx:universal
37+
npm run app:build:osx:x86_64
38+
npm run app:build:windows:arm
39+
40+
# Database migrations
41+
npm run diesel:migration:run
42+
43+
# Code formatting
44+
npm run format
45+
46+
# Version management
47+
npm run version:sync
48+
```
49+
50+
### Frontend Development (packages/pastebar-app-ui/)
51+
The frontend is a workspace package that builds separately:
52+
```bash
53+
cd packages/pastebar-app-ui
54+
npm run dev # Development server on port 4422
55+
npm run build # Build to dist-ui/
56+
```
57+
58+
### Rust/Tauri Development (src-tauri/)
59+
```bash
60+
cd src-tauri
61+
cargo run --no-default-features # Development mode
62+
cargo build --release # Production build
63+
```
64+
65+
## Architecture Overview
66+
67+
### High-Level Structure
68+
69+
**Tauri Architecture**: The app uses Tauri's hybrid architecture where:
70+
- Rust backend handles core functionality (clipboard monitoring, database operations, system integration)
71+
- TypeScript/React frontend provides the UI
72+
- Communication happens via Tauri commands and events
73+
74+
**Core Components:**
75+
76+
1. **Clipboard Monitoring** (`src-tauri/src/clipboard/mod.rs`)
77+
- Real-time clipboard monitoring using `clipboard-master`
78+
- Automatic image capture and text processing
79+
- Language detection for code snippets
80+
- Configurable exclusion lists and masking
81+
82+
2. **Database Layer** (`src-tauri/src/db.rs` + Diesel)
83+
- SQLite database with migrations in `migrations/`
84+
- Custom data location support with path transformation
85+
- Connection pooling with r2d2
86+
87+
3. **System Integration** (`src-tauri/src/main.rs`)
88+
- System tray menu with dynamic content
89+
- Global hotkeys and window management
90+
- Platform-specific features (macOS accessibility, Windows compatibility)
91+
92+
4. **State Management** (Frontend)
93+
- Jotai for atomic state management
94+
- Zustand stores for settings, collections, clipboard history
95+
- React Query for server state and caching
96+
97+
### Key Patterns
98+
99+
**Path Transformation System**:
100+
- Images are stored with `{{base_folder}}` placeholders for relative paths
101+
- `to_relative_image_path()` and `to_absolute_image_path()` handle conversion
102+
- Enables custom database locations without breaking image references
103+
104+
**Event-Driven Communication**:
105+
- Tauri events for real-time updates between backend and frontend
106+
- Settings synchronization across multiple windows
107+
- Menu rebuilding on state changes
108+
109+
**Multi-Window Architecture**:
110+
- Main window (primary interface)
111+
- History window (clipboard history view)
112+
- QuickPaste window (contextual paste menu)
113+
114+
### Database Schema
115+
116+
Main entities:
117+
- `items` - Custom clips and menu items
118+
- `clipboard_history` - Automatic clipboard captures
119+
- `collections` - Organization containers
120+
- `tabs` - Sub-organization within collections
121+
- `link_metadata` - Web scraping and link preview data
122+
- `settings` - User preferences and configuration
123+
124+
### Frontend Structure
125+
126+
```
127+
packages/pastebar-app-ui/src/
128+
├── components/ # Reusable UI components
129+
├── pages/ # Main application pages
130+
├── store/ # State management (Jotai + Zustand)
131+
├── hooks/ # Custom React hooks
132+
├── lib/ # Utilities and helpers
133+
├── locales/ # Internationalization
134+
└── assets/ # Static assets
135+
```
136+
137+
### Backend Structure
138+
139+
```
140+
src-tauri/src/
141+
├── commands/ # Tauri command handlers
142+
├── services/ # Business logic layer
143+
├── models/ # Database models
144+
├── clipboard/ # Clipboard monitoring
145+
├── menu.rs # System tray menu
146+
├── db.rs # Database configuration
147+
└── main.rs # Application entry point
148+
```
149+
150+
## Important Development Notes
151+
152+
### Settings Management
153+
- Settings are stored as generic key-value pairs in the database
154+
- Frontend uses `settingsStore.ts` with automatic synchronization
155+
- Use `updateSetting()` function and include `invoke('build_system_menu')` for settings that affect the system tray
156+
157+
### Custom Data Locations
158+
- The app supports custom database locations via user settings
159+
- All file operations must use `get_data_dir()`, `get_clip_images_dir()`, etc.
160+
- Path transformation ensures image references work across location changes
161+
162+
### Image Handling
163+
- Images are stored in both thumbnail and full resolution
164+
- Use path transformation helpers when storing/retrieving image paths
165+
- Images support relative paths with `{{base_folder}}` placeholders
166+
167+
### Internationalization
168+
- Backend translations in `src-tauri/src/services/translations/translations.yaml`
169+
- Frontend translations in `packages/pastebar-app-ui/src/locales/lang/`
170+
- Use `t()` function in React components and `Translations::get()` in Rust
171+
172+
### Debug Logging
173+
- Use `debug_output(|| { println!("message") })` in Rust for debug-only logging
174+
- Debug messages only appear in debug builds, keeping release builds clean
175+
176+
### System Tray Menu
177+
- Dynamic menu built from database items and settings
178+
- Rebuild required when items or relevant settings change
179+
- Use `invoke('build_system_menu')` after operations that affect menu content
180+
181+
### Database Migrations
182+
- Use Diesel migrations for schema changes
183+
- Place migration files in `migrations/` directory
184+
- Run migrations with `npm run diesel:migration:run`

custom_db_location_plan.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Plan: Implement Custom Data Location Feature
2+
3+
This document outlines the plan to implement the feature allowing users to specify a custom location for the PasteBar application's data.
4+
5+
## 1. Goals
6+
7+
* Allow users to specify a custom parent directory for application data via the settings UI.
8+
* The application will create and manage a `pastebar-data` subdirectory within the user-specified location.
9+
* This `pastebar-data` directory will contain the database file (`pastebar-db.data`), the `clip-images` folder, and the `clipboard-images` folder.
10+
* Provide options to either **move** the existing data, **copy** it, or **use the new location without moving/copying**.
11+
* Ensure the application uses the data from the new location after a restart.
12+
* Handle potential errors gracefully and inform the user.
13+
* Update the application state and backend configuration accordingly.
14+
15+
## 2. Backend (Rust - `src-tauri`)
16+
17+
### 2.1. Configuration (`user_settings_service.rs`)
18+
19+
* The `UserConfig` struct's `custom_db_path: Option<String>` will now be repurposed to store the path to the **user-selected parent directory**. The application logic will handle appending the `/pastebar-data/` segment. This requires no change to the struct itself, only to how the path is interpreted.
20+
21+
### 2.2. Path Logic (`db.rs` and new helpers)
22+
23+
* We will introduce new helper functions to consistently resolve data paths, whether default or custom.
24+
* `get_data_dir() -> PathBuf`: This will be the core helper. It checks for a `custom_db_path` in the settings.
25+
* If present, it returns `PathBuf::from(custom_path)`.
26+
* If `None`, it returns the default application data directory.
27+
* `get_db_path()`: This function will be refactored to use `get_data_dir().join("pastebar-db.data")`.
28+
* `get_clip_images_dir()`: A new helper that returns `get_data_dir().join("clip-images")`.
29+
* `get_clipboard_images_dir()`: A new helper that returns `get_data_dir().join("clipboard-images")`.
30+
31+
### 2.3. New & Updated Tauri Commands (`user_settings_command.rs`)
32+
33+
* **`cmd_validate_custom_db_path(path: String) -> Result<bool, String>`**
34+
* **No change in purpose.** This command will still check if the user-selected directory is valid and writable.
35+
* **`cmd_check_custom_data_path(path: String) -> Result<PathStatus, String>`**
36+
* A new command to check the status of a selected directory. It returns one of the following statuses: `Empty`, `NotEmpty`, `IsPastebarDataAndNotEmpty`.
37+
* **`cmd_set_and_relocate_data(new_parent_dir_path: String, operation: String) -> Result<String, String>`** (renamed from `set_and_relocate_db`)
38+
* `new_parent_dir_path`: The new directory path selected by the user.
39+
* `operation`: Either "move", "copy", or "none".
40+
* **Updated Steps:**
41+
1. Get the source paths:
42+
* Current DB file path.
43+
* Current `clip-images` directory path.
44+
* Current `clipboard-images` directory path.
45+
2. Define the new data directory: `let new_data_dir = Path::new(&new_parent_dir_path);`
46+
3. Create the new data directory: `fs::create_dir_all(&new_data_dir)`.
47+
4. Perform file/directory operations for each item (DB file, `clip-images` dir, `clipboard-images` dir):
48+
* If "move": `fs::rename(source, destination)`.
49+
* If "copy": `fs::copy` for the file, and a recursive copy function for the directories.
50+
* If "none", do nothing.
51+
* Handle cases where source items might not exist (e.g., `clip-images` folder hasn't been created yet) by skipping them gracefully.
52+
5. If successful, call `user_settings_service::set_custom_db_path(&new_parent_dir_path)`.
53+
6. Return a success or error message.
54+
55+
* **`cmd_revert_to_default_data_location() -> Result<String, String>`** (renamed and simplified)
56+
* **Updated Steps:**
57+
1. Call `user_settings_service::remove_custom_db_path()` to clear the custom data path setting.
58+
2. Return a success message indicating the setting has been removed.
59+
60+
## 3. Frontend (React)
61+
62+
* The UI has been updated to refer to "Custom Application Data Location" instead of "Custom Database Location".
63+
* A third radio button option, "Use new location", has been added.
64+
* The `handleBrowse` function now calls the `cmd_check_custom_data_path` command to analyze the selected directory and prompts the user accordingly.
65+
* The `settingsStore.ts` has been updated to support the "none" operation.
66+
67+
## 4. User Interaction Flow (Mermaid Diagram)
68+
69+
```mermaid
70+
graph TD
71+
subgraph User Flow
72+
A[User navigates to User Preferences] --> B{Custom Data Path Set?};
73+
B -- Yes --> C[Display Current Custom Path];
74+
B -- No --> D[Display Current Path: Default];
75+
76+
C --> E[Show "Revert to Default" Button];
77+
D --> F[User Selects New Parent Directory];
78+
F --> G{Path Status?};
79+
G -- Empty --> H[Set Path];
80+
G -- Not Empty --> I{Confirm "pastebar-data" subfolder};
81+
I -- Yes --> J[Append "pastebar-data" to path];
82+
J --> H;
83+
I -- No --> H;
84+
G -- Is 'pastebar-data' and Not Empty --> K[Alert user existing data will be used];
85+
K --> H;
86+
H --> L[User Selects Operation: Move/Copy/None];
87+
L --> M[User Clicks "Apply and Restart"];
88+
end
89+
90+
subgraph Backend Logic
91+
M --> N[Frontend calls `cmd_set_and_relocate_data`];
92+
N -- Success --> O[1. Create new data dir if needed];
93+
O --> P[2. Move/Copy/Skip data];
94+
P --> Q[3. Update `custom_db_path` in settings];
95+
Q --> R[Show Success Toast & Relaunch App];
96+
N -- Error --> S[Show Error Toast];
97+
98+
E --> T[User Clicks "Revert"];
99+
T --> U[Frontend calls `cmd_revert_to_default_data_location`];
100+
U -- Success --> V[Move/Copy data back to default app dir & clear setting];
101+
V --> W[Show Success Toast & Relaunch App];
102+
U -- Error --> X[Show Error Toast];
103+
end
104+
105+
D -- "Browse..." --> F;
106+
```
107+
108+
## 5. Implementation Summary
109+
110+
The following changes have been implemented:
111+
112+
* **`packages/pastebar-app-ui/src/pages/settings/UserPreferences.tsx`**:
113+
* Renamed "Custom Database Location" to "Custom Application Data Location".
114+
* Added a third radio button for the "Use new location" option.
115+
* Updated the `handleBrowse` function to call the new `cmd_check_custom_data_path` command and handle the different path statuses with user prompts.
116+
* **`packages/pastebar-app-ui/src/store/settingsStore.ts`**:
117+
* Updated the `applyCustomDbPath` function to accept the "none" operation.
118+
* Updated the `revertToDefaultDbPath` function to call the renamed backend command.
119+
* **`src-tauri/src/commands/user_settings_command.rs`**:
120+
* Added the `cmd_check_custom_data_path` command.
121+
* Renamed `cmd_set_and_relocate_db` to `cmd_set_and_relocate_data` and updated its logic to handle the "none" operation and the new data directory structure.
122+
* Renamed `cmd_revert_to_default_db_location` to `cmd_revert_to_default_data_location` and updated its logic.
123+
* **`src-tauri/src/db.rs`**:
124+
* Refactored the `get_data_dir` function to no longer automatically append `pastebar-data`.
125+
* Added `get_clip_images_dir` and `get_clipboard_images_dir` helper functions.
126+
* **`src-tauri/src/main.rs`**:
127+
* Registered the new and renamed commands in the `invoke_handler`.
128+
* **`src-tauri/Cargo.toml`**:
129+
* Added the `fs_extra` dependency for recursive directory copying.
130+
* **`src-tauri/src/services/items_service.rs`** and **`src-tauri/src/services/history_service.rs`**:
131+
* Updated to use the new `get_clip_images_dir` and `get_clipboard_images_dir` helper functions.

0 commit comments

Comments
 (0)