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
19 changes: 19 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
### Summary

- **Bullet Point**: - What Changed

#### Added

- What was added

#### Changed

- What was changed

#### Fixed

- What was fixed

#### Removed

- What was removed
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ out
.eslintcache
*.log*
.env
electron.vite.config.*.mjs
electron.vite.config.*.mjs
.cursor/rules/user
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ For now, please know that the security warnings are purely administrative and th
1. **Install and Run**: Start Clipless and it begins monitoring your clipboard automatically
2. **Copy Content**: Any content you copy will appear in the Clipless window
3. **Click to Reuse**: Click on any row number to copy that item back to your clipboard
4. **Lock Important Items**: Right-click clips to lock them and prevent removal
4. **Context Menu Actions**: Right-click clips to access Copy, Scan, Lock, and Delete options

### Quick Clips Workflow

Expand Down
3 changes: 1 addition & 2 deletions electron-builder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ mac:
target:
- target: dmg
arch:
- x64
- arm64
extendInfo:
NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder.
Expand Down Expand Up @@ -62,7 +61,7 @@ dmg:
type: link
path: /Applications
background: null
format: UDRO
format: UDZO
internetEnabled: false
linux:
target:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "clipless",
"version": "1.3.1",
"version": "1.4.0",
"description": "An Electron application with React and TypeScript",
"main": "./out/main/index.js",
"author": "Daniel Essig",
Expand Down
63 changes: 61 additions & 2 deletions src/main/ipc/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { ipcMain } from 'electron';
import { ipcMain, Menu, MenuItemConstructorOptions } from 'electron';
import { autoUpdater } from 'electron-updater';
import { is } from '@electron-toolkit/utils';
import { storage } from '../storage';
import { hotkeyManager } from '../hotkeys';
import { getMainWindow, getSettingsWindow, createSettingsWindow, createToolsLauncherWindow, getToolsLauncherWindow } from '../window/creation';
import {
getMainWindow,
getSettingsWindow,
createSettingsWindow,
createToolsLauncherWindow,
getToolsLauncherWindow,
} from '../window/creation';
import { applyWindowSettings } from '../window/settings';
import { checkForUpdatesWithRetry } from '../updater';

Expand Down Expand Up @@ -96,6 +102,59 @@ export function setupMainIPC(): void {
return null;
});

// Context Menu IPC handler
ipcMain.handle(
'show-clip-context-menu',
async (
event,
options: {
index: number;
isFirstClip: boolean;
isLocked: boolean;
hasPatterns: boolean;
}
) => {
const { index, isFirstClip, isLocked, hasPatterns } = options;

const template: MenuItemConstructorOptions[] = [
{
label: 'Copy to Clipboard',
click: () => {
event.sender.send('context-menu-action', { action: 'copy', index });
},
},
{ type: 'separator' },
{
label: hasPatterns ? 'Scan with Quick Clips ⚡' : 'Scan with Quick Clips',
click: () => {
event.sender.send('context-menu-action', { action: 'scan', index });
},
},
{ type: 'separator' },
{
label: isLocked ? 'Unlock Clip' : 'Lock Clip',
enabled: !isFirstClip,
click: () => {
event.sender.send('context-menu-action', { action: 'lock', index });
},
},
{
label: 'Delete Clip',
enabled: !isFirstClip,
click: () => {
event.sender.send('context-menu-action', { action: 'delete', index });
},
},
];

const contextMenu = Menu.buildFromTemplate(template);
const window = getMainWindow();
if (window) {
contextMenu.popup({ window });
}
}
);

ipcMain.handle('download-update', async () => {
if (!is.dev) {
try {
Expand Down
9 changes: 9 additions & 0 deletions src/preload/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ declare global {
toolsLauncherReady: () => Promise<void>;
onToolsLauncherInitialize: (callback: (clipContent: string) => void) => void;
removeAllListeners?: (channel: string) => void;
// Native Context Menu APIs
showClipContextMenu: (options: {
index: number;
isFirstClip: boolean;
isLocked: boolean;
hasPatterns: boolean;
}) => Promise<void>;
onContextMenuAction: (callback: (data: { action: string; index: number }) => void) => void;
removeContextMenuListeners: () => void;
};
}
}
12 changes: 12 additions & 0 deletions src/preload/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,18 @@ const api = {
callback(clipContent)
),
removeAllListeners: (channel: string) => electronAPI.ipcRenderer.removeAllListeners(channel),

// Native Context Menu APIs
showClipContextMenu: (options: {
index: number;
isFirstClip: boolean;
isLocked: boolean;
hasPatterns: boolean;
}) => electronAPI.ipcRenderer.invoke('show-clip-context-menu', options),
onContextMenuAction: (callback: (data: { action: string; index: number }) => void) =>
electronAPI.ipcRenderer.on('context-menu-action', (_event, data) => callback(data)),
removeContextMenuListeners: () =>
electronAPI.ipcRenderer.removeAllListeners('context-menu-action'),
};

// Use `contextBridge` APIs to expose Electron APIs to
Expand Down
28 changes: 16 additions & 12 deletions src/renderer/src/Settings.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@
.container {
width: 100%;
height: 100%;
background-color: #111827;
background-color: #1a1a1a;
display: flex;
flex-direction: column;
}

.container.light {
background-color: #f9fafb;
background-color: #eaeaea;
}

/* Tab Navigation */
.tabsContainer {
border-bottom: 1px solid #374151;
background-color: #1f2937;
border-bottom: 1px solid #3a3a3a;
background-color: #262626;
}

.tabsContainer.light {
border-bottom-color: #e5e7eb;
background-color: #f9fafb;
border-bottom-color: #e5e5e5;
background-color: #fafafa;
}

.tabs {
Expand All @@ -34,7 +34,7 @@
padding: 0.75rem 1rem;
background: none;
border: none;
color: #9ca3af;
color: #a0a0a0;
font-size: 0.875rem;
font-weight: 500;
cursor: pointer;
Expand All @@ -43,7 +43,7 @@
}

.tab:hover {
color: #d1d5db;
color: #ffffff;
}

.tab.light {
Expand All @@ -55,8 +55,12 @@
}

.tabActive {
color: #3b82f6 !important;
border-bottom-color: #3b82f6;
color: #ffffff !important;
border-bottom-color: #10b981;
}

.tabActive.light {
color: #1a1a1a !important;
}

.scrollContainer {
Expand All @@ -80,7 +84,7 @@
}

.section {
background-color: #1f2937;
background-color: #262626;
border-radius: 0.5rem;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
padding: 1rem;
Expand All @@ -95,7 +99,7 @@
margin: 0 0 0.75rem 0;
font-size: 1.125rem;
font-weight: 600;
color: #f9fafb;
color: #fafafa;
}

.container.light .sectionTitle {
Expand Down
34 changes: 17 additions & 17 deletions src/renderer/src/assets/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
--bg-secondary: #262626;
--bg-tertiary: #333333;
--bg-quaternary: #1a1a1a;
--bg-accent: rgba(74, 144, 226, 0.1);
--bg-accent-hover: rgba(74, 144, 226, 0.15);
--bg-accent: rgba(107, 114, 128, 0.1);
--bg-accent-hover: rgba(107, 114, 128, 0.15);
--bg-success: rgba(16, 185, 129, 0.1);
--bg-error: rgba(239, 68, 68, 0.1);
--bg-disabled: #333333;
Expand All @@ -51,16 +51,16 @@

--border-primary: #444444;
--border-secondary: #333333;
--border-accent: #4a90e2;
--border-accent: #6b7280;
--border-success: #10b981;
--border-error: #ef4444;
--border-warning: #f59e0b;

--accent-primary: #4a90e2;
--accent-secondary: #6366f1;
--accent-tertiary: #8b5cf6;
--accent-gradient: linear-gradient(135deg, #4a90e2, #6366f1);
--accent-gradient-hover: linear-gradient(135deg, #4f46e5, #7c3aed);
--accent-primary: #6b7280;
--accent-secondary: #9ca3af;
--accent-tertiary: #d1d5db;
--accent-gradient: linear-gradient(135deg, #6b7280, #9ca3af);
--accent-gradient-hover: linear-gradient(135deg, #4b5563, #6b7280);

--success-color: #10b981;
--success-hover: #059669;
Expand All @@ -72,12 +72,12 @@
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 2px 4px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 4px 8px rgba(0, 0, 0, 0.15);
--shadow-accent: 0 2px 4px rgba(59, 130, 246, 0.3);
--shadow-accent-hover: 0 4px 8px rgba(59, 130, 246, 0.4);
--shadow-accent: 0 2px 4px rgba(107, 114, 128, 0.3);
--shadow-accent-hover: 0 4px 8px rgba(107, 114, 128, 0.4);
--shadow-success: 0 1px 2px rgba(16, 185, 129, 0.3);
--shadow-error: 0 1px 2px rgba(239, 68, 68, 0.3);

--focus-ring: 0 0 0 2px rgba(59, 130, 246, 0.1);
--focus-ring: 0 0 0 2px rgba(107, 114, 128, 0.1);
--focus-ring-success: 0 0 0 2px rgba(16, 185, 129, 0.1);
--focus-ring-error: 0 0 0 2px rgba(239, 68, 68, 0.1);
}
Expand Down Expand Up @@ -132,8 +132,8 @@ body.light {
--bg-secondary: #f8f8f8;
--bg-tertiary: #e8e8e8;
--bg-quaternary: #ffffff;
--bg-accent: rgba(74, 144, 226, 0.05);
--bg-accent-hover: rgba(74, 144, 226, 0.08);
--bg-accent: rgba(107, 114, 128, 0.05);
--bg-accent-hover: rgba(107, 114, 128, 0.08);
--bg-success: rgba(16, 185, 129, 0.08);
--bg-error: rgba(239, 68, 68, 0.08);
--bg-disabled: #e8e8e8;
Expand All @@ -146,18 +146,18 @@ body.light {
--text-on-accent: #ffffff;
--text-disabled: #999999;

--border-primary: #d0d0d0;
--border-primary: #a0a0a0;
--border-secondary: #e0e0e0;
--border-accent: #4a90e2;
--border-accent: #6b7280;
--border-success: #10b981;
--border-error: #ef4444;
--border-warning: #f59e0b;

--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.03);
--shadow-md: 0 2px 4px rgba(0, 0, 0, 0.05);
--shadow-lg: 0 4px 8px rgba(0, 0, 0, 0.08);
--shadow-accent: 0 2px 4px rgba(59, 130, 246, 0.3);
--shadow-accent-hover: 0 4px 8px rgba(59, 130, 246, 0.4);
--shadow-accent: 0 2px 4px rgba(107, 114, 128, 0.3);
--shadow-accent-hover: 0 4px 8px rgba(107, 114, 128, 0.4);
--shadow-success: 0 1px 2px rgba(16, 185, 129, 0.3);
--shadow-error: 0 1px 2px rgba(239, 68, 68, 0.3);
}
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/assets/settings.css
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ body {
}

.toggle-switch.active {
background: #3b82f6; /* Blue color */
background: #10b981; /* Green color */
}

.toggle-slider {
Expand Down
19 changes: 18 additions & 1 deletion src/renderer/src/components/clips/clip/Clip.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,24 @@
}

.clipRow.light:hover {
background-color: #e8e8e8;
background-color: #e0e0e0;
}

/* Zebra striping for even rows */
.clip:nth-child(even) .clipRow {
background-color: #383838;
}

.clip:nth-child(even) .clipRow.light {
background-color: #f0f0f0;
}

.clip:nth-child(even) .clipRow:hover {
background-color: #505050;
}

.clip:nth-child(even) .clipRow.light:hover {
background-color: #e0e0e0;
}

.clipRow.expanded {
Expand Down
Loading
Loading