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
25 changes: 13 additions & 12 deletions src/components/bookmarks/BookmarkInlineCard.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { forwardRef, useRef, useEffect, useState } from 'react'
import { forwardRef, useRef, useEffect, useState, useCallback } from 'react'
import { ExternalLink, Check, X } from 'lucide-react'
import { TagInput } from '../ui/TagInput'
import { Tag } from '../ui/Tag'
import { getAllTags, createBookmark, updateBookmark } from '../../services/bookmarks'
import { useHotkeys } from '../../hooks/useHotkeys'

/**
* BookmarkInlineCard - Inline card for adding/editing bookmarks
Expand Down Expand Up @@ -110,7 +111,7 @@ export const BookmarkInlineCard = forwardRef(function BookmarkInlineCard(
}

// Auto-save logic
const saveChanges = () => {
const saveChanges = useCallback(() => {
const normalizedUrl = normalizeUrl(localUrl)

if (!validateUrl(localUrl)) {
Expand Down Expand Up @@ -143,7 +144,7 @@ export const BookmarkInlineCard = forwardRef(function BookmarkInlineCard(
console.error('Failed to save bookmark:', error)
return false
}
}
}, [localUrl, localTitle, localDesc, localTags, localReadLater, isEditing, bookmark, onFieldChange, isNew])

const handleUrlBlur = () => {
if (localUrl !== (bookmark?.url || '')) {
Expand Down Expand Up @@ -198,7 +199,7 @@ export const BookmarkInlineCard = forwardRef(function BookmarkInlineCard(
handleTagsChange(newTags)
}

const handleDone = () => {
const handleDone = useCallback(() => {
if (!validateUrl(localUrl)) {
setUrlError('URL is required')
urlInputRef.current?.focus()
Expand All @@ -208,12 +209,18 @@ export const BookmarkInlineCard = forwardRef(function BookmarkInlineCard(
if (saveChanges()) {
onDone?.()
}
}
}, [localUrl, saveChanges, onDone])

const handleDiscard = () => {
onDiscard?.()
}

// Ctrl/Cmd+Enter to save from any field
useHotkeys(
{ 'mod+enter': handleDone },
{ enableOnInputs: true }
)

const handleKeyDown = (e, currentField) => {
if (e.key === 'Escape') {
e.preventDefault()
Expand All @@ -222,12 +229,6 @@ export const BookmarkInlineCard = forwardRef(function BookmarkInlineCard(
return
}

if (e.key === 'Enter' && currentField !== 'desc') {
e.preventDefault()
handleDone()
return
}

// Tab navigation
if (e.key === 'Tab') {
e.preventDefault()
Expand Down Expand Up @@ -423,7 +424,7 @@ export const BookmarkInlineCard = forwardRef(function BookmarkInlineCard(
</div>

<div className="text-[10px] text-muted-foreground/50 font-medium">
Enter to save · Esc to {isNew ? 'cancel' : 'close'}
Ctrl+Enter to save · Esc to {isNew ? 'cancel' : 'close'}
</div>
</div>
</div>
Expand Down
10 changes: 5 additions & 5 deletions src/components/ui/Toast.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ export function Toast({ message, action, actionLabel = 'Undo', duration = 5000,
return (
<div
className={cn(
'fixed bottom-4 left-1/2 -translate-x-1/2 z-50',
'flex items-center gap-3 px-4 py-3 rounded-lg shadow-lg',
'fixed bottom-4 right-4 z-50',
'flex items-center gap-4 px-4 py-3 rounded-lg shadow-lg',
'bg-card border border-border text-foreground',
'transition-all duration-150',
isLeaving ? 'opacity-0 translate-y-2' : 'opacity-100 translate-y-0'
Expand All @@ -42,14 +42,14 @@ export function Toast({ message, action, actionLabel = 'Undo', duration = 5000,
{action && (
<button
onClick={handleAction}
className="text-sm font-medium text-primary hover:text-primary/80 transition-colors"
className="text-sm font-medium text-primary hover:text-primary/80 transition-colors whitespace-nowrap"
>
{actionLabel}
</button>
)}
<button
onClick={handleClose}
className="ml-1 p-1 rounded hover:bg-muted transition-colors"
className="p-1 rounded hover:bg-muted transition-colors flex-shrink-0"
aria-label="Dismiss"
>
<X className="w-4 h-4 text-muted-foreground" />
Expand All @@ -61,7 +61,7 @@ export function Toast({ message, action, actionLabel = 'Undo', duration = 5000,
// Toast container that manages multiple toasts
export function ToastContainer({ toasts, onRemove }) {
return (
<div className="fixed bottom-4 left-1/2 -translate-x-1/2 z-50 flex flex-col gap-2">
<div className="fixed bottom-4 right-4 z-50 flex flex-col gap-2">
{toasts.map((toast) => (
<Toast
key={toast.id}
Expand Down
Loading