fix keyboard shortcut not working in add dialog
This commit is contained in:
@@ -1,11 +1,7 @@
|
|||||||
import { Outlet, createFileRoute } from "@tanstack/react-router"
|
import { Outlet, createFileRoute } from "@tanstack/react-router"
|
||||||
import { useEffect } from "react"
|
import { useEffect } from "react"
|
||||||
import { useDeleteBookmark } from "~/bookmark/api"
|
|
||||||
import { Button } from "~/components/button"
|
|
||||||
import { Dialog, DialogActionRow, DialogBody, DialogTitle } from "~/components/dialog"
|
|
||||||
import { LoadingSpinner } from "~/components/loading-spinner"
|
|
||||||
import { useMnemonics } from "~/hooks/use-mnemonics"
|
|
||||||
import { AddBookmarkDialog } from "./bookmarks/-dialogs/add-bookmark-dialog"
|
import { AddBookmarkDialog } from "./bookmarks/-dialogs/add-bookmark-dialog"
|
||||||
|
import { DeleteBookmarkDialog } from "./bookmarks/-dialogs/delete-bookmark-dialog"
|
||||||
import { ActiveDialog, LayoutMode, useBookmarkPageStore } from "./bookmarks/-store"
|
import { ActiveDialog, LayoutMode, useBookmarkPageStore } from "./bookmarks/-store"
|
||||||
|
|
||||||
export const Route = createFileRoute("/bookmarks")({
|
export const Route = createFileRoute("/bookmarks")({
|
||||||
@@ -53,84 +49,3 @@ function PageDialog() {
|
|||||||
return <DeleteBookmarkDialog />
|
return <DeleteBookmarkDialog />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function DeleteBookmarkDialog() {
|
|
||||||
// biome-ignore lint/style/noNonNullAssertion: this cannot be null when delete bookmark dialog is visible
|
|
||||||
const bookmark = useBookmarkPageStore((state) => state.bookmarkToBeDeleted!)
|
|
||||||
const setActiveDialog = useBookmarkPageStore((state) => state.setActiveDialog)
|
|
||||||
const deleteBookmarkMutation = useDeleteBookmark()
|
|
||||||
|
|
||||||
useMnemonics(
|
|
||||||
{
|
|
||||||
y: proceed,
|
|
||||||
n: cancel,
|
|
||||||
},
|
|
||||||
{ ignore: () => false },
|
|
||||||
)
|
|
||||||
|
|
||||||
async function proceed() {
|
|
||||||
try {
|
|
||||||
await deleteBookmarkMutation.mutateAsync({ bookmark })
|
|
||||||
setActiveDialog(ActiveDialog.None)
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function cancel() {
|
|
||||||
setActiveDialog(ActiveDialog.None)
|
|
||||||
}
|
|
||||||
|
|
||||||
function body() {
|
|
||||||
switch (deleteBookmarkMutation.status) {
|
|
||||||
case "pending":
|
|
||||||
return (
|
|
||||||
<p>
|
|
||||||
Deleting <LoadingSpinner />
|
|
||||||
</p>
|
|
||||||
)
|
|
||||||
case "idle":
|
|
||||||
return (
|
|
||||||
<p>
|
|
||||||
The bookmark titled:
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<strong>
|
|
||||||
<em>"{bookmark.title}"</em>
|
|
||||||
</strong>
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
will be deleted. Proceed?
|
|
||||||
</p>
|
|
||||||
)
|
|
||||||
case "error":
|
|
||||||
return <p className="text-red-500">Failed to delete the bookmark!</p>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function title() {
|
|
||||||
switch (deleteBookmarkMutation.status) {
|
|
||||||
case "pending":
|
|
||||||
return "PLEASE WAIT"
|
|
||||||
case "idle":
|
|
||||||
return "CONFIRM"
|
|
||||||
case "error":
|
|
||||||
return "ERROR OCCURRED"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dialog>
|
|
||||||
<DialogTitle>{title()}</DialogTitle>
|
|
||||||
<DialogBody>{body()}</DialogBody>
|
|
||||||
<DialogActionRow>
|
|
||||||
<Button disabled={deleteBookmarkMutation.isPending} onClick={proceed}>
|
|
||||||
{deleteBookmarkMutation.isError ? "Retry" : "Proceed"} (y)
|
|
||||||
</Button>
|
|
||||||
<Button disabled={deleteBookmarkMutation.isPending} onClick={cancel}>
|
|
||||||
Cancel (n)
|
|
||||||
</Button>
|
|
||||||
</DialogActionRow>
|
|
||||||
</Dialog>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
@@ -3,7 +3,7 @@ import type { BookmarkTag } from "@markone/core/bookmark"
|
|||||||
import clsx from "clsx"
|
import clsx from "clsx"
|
||||||
import { atom, useAtom } from "jotai"
|
import { atom, useAtom } from "jotai"
|
||||||
import { useAtomCallback } from "jotai/utils"
|
import { useAtomCallback } from "jotai/utils"
|
||||||
import { useCallback, useEffect, useId, useRef, useState } from "react"
|
import { useCallback, useEffect, useId, useImperativeHandle, useRef, useState } from "react"
|
||||||
import { ApiErrorCode, BadRequestError } from "~/api"
|
import { ApiErrorCode, BadRequestError } from "~/api"
|
||||||
import { useCreateBookmark, useTags } from "~/bookmark/api"
|
import { useCreateBookmark, useTags } from "~/bookmark/api"
|
||||||
import { Button } from "~/components/button"
|
import { Button } from "~/components/button"
|
||||||
@@ -36,6 +36,7 @@ function AddBookmarkDialog() {
|
|||||||
const setActiveDialog = useBookmarkPageStore((state) => state.setActiveDialog)
|
const setActiveDialog = useBookmarkPageStore((state) => state.setActiveDialog)
|
||||||
const formId = useId()
|
const formId = useId()
|
||||||
const linkInputRef = useRef<HTMLInputElement | null>(null)
|
const linkInputRef = useRef<HTMLInputElement | null>(null)
|
||||||
|
const tagsInputRef = useRef<HTMLInputElement | null>(null)
|
||||||
const getTags = useAtomCallback(
|
const getTags = useAtomCallback(
|
||||||
useCallback((get) => {
|
useCallback((get) => {
|
||||||
const value = get(tagsInputValueAtom)
|
const value = get(tagsInputValueAtom)
|
||||||
@@ -46,7 +47,7 @@ function AddBookmarkDialog() {
|
|||||||
useMnemonics(
|
useMnemonics(
|
||||||
{
|
{
|
||||||
c: () => {
|
c: () => {
|
||||||
if (!document.activeElement) {
|
if (linkInputRef.current !== document.activeElement && tagsInputRef.current !== document.activeElement) {
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -127,7 +128,7 @@ function AddBookmarkDialog() {
|
|||||||
className="w-full"
|
className="w-full"
|
||||||
labelClassName="bg-stone-300 dark:bg-stone-800"
|
labelClassName="bg-stone-300 dark:bg-stone-800"
|
||||||
/>
|
/>
|
||||||
<TagsInput />
|
<TagsInput ref={tagsInputRef} />
|
||||||
</form>
|
</form>
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogActionRow>
|
<DialogActionRow>
|
||||||
@@ -142,11 +143,11 @@ function AddBookmarkDialog() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function TagsInput() {
|
function TagsInput({ ref }: { ref: React.Ref<HTMLInputElement | null> }) {
|
||||||
const [value, setValue] = useAtom(tagsInputValueAtom)
|
const [value, setValue] = useAtom(tagsInputValueAtom)
|
||||||
const [isInputFocused, setIsInputFocused] = useState(false)
|
const [isInputFocused, setIsInputFocused] = useState(false)
|
||||||
const [lastTag] = useAtom(lastTagAtom)
|
const [lastTag] = useAtom(lastTagAtom)
|
||||||
const { refs, floatingStyles } = useFloating({
|
const { refs, floatingStyles } = useFloating<HTMLInputElement>({
|
||||||
whileElementsMounted: autoUpdate,
|
whileElementsMounted: autoUpdate,
|
||||||
middleware: [
|
middleware: [
|
||||||
size({
|
size({
|
||||||
@@ -160,6 +161,8 @@ function TagsInput() {
|
|||||||
open: isInputFocused && lastTag !== "",
|
open: isInputFocused && lastTag !== "",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(ref, () => refs.reference.current)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FormField
|
<FormField
|
||||||
|
@@ -0,0 +1,89 @@
|
|||||||
|
import { useDeleteBookmark } from "~/bookmark/api"
|
||||||
|
import { Button } from "~/components/button"
|
||||||
|
import { Dialog, DialogTitle, DialogBody, DialogActionRow } from "~/components/dialog"
|
||||||
|
import { LoadingSpinner } from "~/components/loading-spinner"
|
||||||
|
import { useMnemonics } from "~/hooks/use-mnemonics"
|
||||||
|
import { useBookmarkPageStore, ActiveDialog } from "../-store"
|
||||||
|
|
||||||
|
function DeleteBookmarkDialog() {
|
||||||
|
// biome-ignore lint/style/noNonNullAssertion: this cannot be null when delete bookmark dialog is visible
|
||||||
|
const bookmark = useBookmarkPageStore((state) => state.bookmarkToBeDeleted!)
|
||||||
|
const setActiveDialog = useBookmarkPageStore((state) => state.setActiveDialog)
|
||||||
|
const deleteBookmarkMutation = useDeleteBookmark()
|
||||||
|
|
||||||
|
useMnemonics(
|
||||||
|
{
|
||||||
|
y: proceed,
|
||||||
|
n: cancel,
|
||||||
|
},
|
||||||
|
{ ignore: () => false },
|
||||||
|
)
|
||||||
|
|
||||||
|
async function proceed() {
|
||||||
|
try {
|
||||||
|
await deleteBookmarkMutation.mutateAsync({ bookmark })
|
||||||
|
setActiveDialog(ActiveDialog.None)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancel() {
|
||||||
|
setActiveDialog(ActiveDialog.None)
|
||||||
|
}
|
||||||
|
|
||||||
|
function body() {
|
||||||
|
switch (deleteBookmarkMutation.status) {
|
||||||
|
case "pending":
|
||||||
|
return (
|
||||||
|
<p>
|
||||||
|
Deleting <LoadingSpinner />
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
case "idle":
|
||||||
|
return (
|
||||||
|
<p>
|
||||||
|
The bookmark titled:
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<strong>
|
||||||
|
<em>"{bookmark.title}"</em>
|
||||||
|
</strong>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
will be deleted. Proceed?
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
case "error":
|
||||||
|
return <p className="text-red-500">Failed to delete the bookmark!</p>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function title() {
|
||||||
|
switch (deleteBookmarkMutation.status) {
|
||||||
|
case "pending":
|
||||||
|
return "PLEASE WAIT"
|
||||||
|
case "idle":
|
||||||
|
return "CONFIRM"
|
||||||
|
case "error":
|
||||||
|
return "ERROR OCCURRED"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog>
|
||||||
|
<DialogTitle>{title()}</DialogTitle>
|
||||||
|
<DialogBody>{body()}</DialogBody>
|
||||||
|
<DialogActionRow>
|
||||||
|
<Button disabled={deleteBookmarkMutation.isPending} onClick={proceed}>
|
||||||
|
{deleteBookmarkMutation.isError ? "Retry" : "Proceed"} (y)
|
||||||
|
</Button>
|
||||||
|
<Button disabled={deleteBookmarkMutation.isPending} onClick={cancel}>
|
||||||
|
Cancel (n)
|
||||||
|
</Button>
|
||||||
|
</DialogActionRow>
|
||||||
|
</Dialog>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { DeleteBookmarkDialog }
|
Reference in New Issue
Block a user