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
4 changes: 2 additions & 2 deletions apps/extension/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@bypass/extension",
"type": "module",
"version": "24.2.0",
"version": "24.3.0",
"private": true,
"description": "Bypass links from various sites to required links, with added functionality of Bookmarks Manager, Tagging Panel.",
"scripts": {
Expand All @@ -17,12 +17,12 @@
"@bypass/ui": "workspace:*",
"@hugeicons/core-free-icons": "3.3.0",
"@hugeicons/react": "1.1.5",
"@mantine/hooks": "8.3.15",
"@t3-oss/env-core": "0.13.10",
"@tanstack/react-form": "1.28.3",
"@tanstack/react-virtual": "3.13.18",
"@trpc/client": "11.10.0",
"@trpc/server": "11.10.0",
"ahooks": "3.9.6",
"class-variance-authority": "0.7.1",
"clsx": "2.1.1",
"next-themes": "0.4.6",
Expand Down
4 changes: 2 additions & 2 deletions apps/extension/src/entrypoints/popup/components/Global.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Toaster } from '@bypass/ui';
import { useEventListener } from 'ahooks';
import { useHotkeys } from '@mantine/hooks';
import StoreListener from './StoreListener';

function Global() {
// Prevent extension popup close on Escape click
useEventListener('keydown', (e) => e.key === 'Escape' && e.preventDefault());
useHotkeys([['Escape', (e) => e.preventDefault()]]);
Comment thread
amitsingh-007 marked this conversation as resolved.
Comment thread
amitsingh-007 marked this conversation as resolved.
Comment thread
amitsingh-007 marked this conversation as resolved.

return (
<>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { z } from 'zod/mini';
import { useForm } from '@tanstack/react-form';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useDisclosure } from '@mantine/hooks';
import { useCallback, useEffect, useMemo } from 'react';
import { useLocation } from 'wouter';
import { useShallow } from 'zustand/react/shallow';
import {
Expand Down Expand Up @@ -78,7 +79,7 @@ function BookmarkAddEditDialog({ curFolderId, handleScroll }: Props) {
}))
);
const { operation, url: bmUrl } = bookmarkOperation;
const [openDialog, setOpenDialog] = useState(false);
const [openDialog, dialogHandlers] = useDisclosure(false);

const { folderOptions, defaultFolderId } = useMemo(() => {
const decodedFolderList = getDecodedFolderList(folderList);
Expand Down Expand Up @@ -134,7 +135,7 @@ function BookmarkAddEditDialog({ curFolderId, handleScroll }: Props) {
form.setFieldValue('title', title);
form.setFieldValue('folderId', defaultFolderId ?? ROOT_FOLDER_ID);
form.setFieldValue('taggedPersons', []);
setOpenDialog(true);
dialogHandlers.open();
return;
}

Expand All @@ -153,7 +154,7 @@ function BookmarkAddEditDialog({ curFolderId, handleScroll }: Props) {
form.setFieldValue('title', bookmark.title);
form.setFieldValue('folderId', curFolderId);
form.setFieldValue('taggedPersons', bookmark.taggedPersons);
setOpenDialog(true);
dialogHandlers.open();
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand All @@ -179,7 +180,7 @@ function BookmarkAddEditDialog({ curFolderId, handleScroll }: Props) {
}
form.reset();
resetBookmarkOperation();
setOpenDialog(false);
dialogHandlers.close();
};

const handleDelete = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
FilePasteIcon,
LinkSquare02Icon,
} from '@hugeicons/core-free-icons';
import { useKeyPress } from 'ahooks';
import { useHotkeys } from '@mantine/hooks';
import { memo, useCallback, type PropsWithChildren } from 'react';
import { useShallow } from 'zustand/react/shallow';
import ContextMenu, { type IMenuOption } from '@popup/components/ContextMenu';
Expand Down Expand Up @@ -47,16 +47,22 @@ const BookmarkContextMenu = memo<Props>(
const selectedCount = getSelectedCount(selectedBookmarks);
const cutCount = getCutCount(cutBookmarks);

// Keyboard shortcuts using ahooks useKeyPress
useKeyPress(['meta.x'], (e) => {
e.stopPropagation();
handleCutBookmarks();
});

useKeyPress(['meta.v'], (e) => {
e.stopPropagation();
handlePasteSelectedBookmarks();
});
useHotkeys([
[
'mod+X',
(e) => {
e.stopPropagation();
handleCutBookmarks();
},
],
[
'mod+V',
(e) => {
e.stopPropagation();
handlePasteSelectedBookmarks();
},
],
]);
Comment thread
amitsingh-007 marked this conversation as resolved.

const getBookmark = useCallback(
(id: string) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Header } from '@bypass/shared';
import { Button } from '@bypass/ui';
import { useKeyPress } from 'ahooks';
import { memo, useState } from 'react';
import { useDisclosure, useHotkeys } from '@mantine/hooks';
import { memo } from 'react';
import { BookmarkCheck01Icon, FolderAddIcon } from '@hugeicons/core-free-icons';
import { HugeiconsIcon } from '@hugeicons/react';
import { useShallow } from 'zustand/react/shallow';
Expand Down Expand Up @@ -34,38 +34,42 @@ const BookmarksHeader = memo<Props>(({ onSearchChange, folderId }) => {
handleCreateNewFolder: state.handleCreateNewFolder,
}))
);
const [openFolderDialog, setOpenFolderDialog] = useState(false);
const [openConfirmationDialog, setOpenConfirmationDialog] = useState(false);
const [openFolderDialog, folderDialogHandlers] = useDisclosure(false);
const [openConfirmationDialog, confirmationDialogHandlers] =
useDisclosure(false);

const disableSave = isFetching || !isSaveButtonActive;

const handleSaveClick = () => {
handleSave(folderId);
};

useKeyPress('meta.s', (event) => {
event.preventDefault();
event.stopPropagation();
if (!disableSave) {
handleSaveClick();
}
});
useHotkeys([
[
'mod+S',
(e) => {
e.preventDefault();
e.stopPropagation();
if (!disableSave) {
handleSaveClick();
}
},
],
]);
Comment thread
amitsingh-007 marked this conversation as resolved.
Comment thread
amitsingh-007 marked this conversation as resolved.
Comment thread
amitsingh-007 marked this conversation as resolved.

const onBackClick = () => {
if (isSaveButtonActive) {
setOpenConfirmationDialog(true);
confirmationDialogHandlers.open();
} else {
handleClose();
}
};

const toggleNewFolderDialog = () => setOpenFolderDialog(!openFolderDialog);

const handleConfirmationDialogClose = () => setOpenConfirmationDialog(false);
const handleConfirmationDialogClose = confirmationDialogHandlers.close;

const handleConfirmationDialogOk = () => {
handleClose();
setOpenConfirmationDialog(false);
confirmationDialogHandlers.close();
};

const handleNewFolderSave = (folderName: string) => {
Expand All @@ -83,7 +87,7 @@ const BookmarksHeader = memo<Props>(({ onSearchChange, folderId }) => {
variant="secondary"
className="font-medium"
disabled={isFetching}
onClick={toggleNewFolderDialog}
onClick={folderDialogHandlers.open}
>
<HugeiconsIcon icon={FolderAddIcon} className="mr-1 size-4" />
Add
Expand All @@ -102,7 +106,7 @@ const BookmarksHeader = memo<Props>(({ onSearchChange, folderId }) => {
headerText="Add folder"
handleSave={handleNewFolderSave}
isOpen={openFolderDialog}
onClose={toggleNewFolderDialog}
onClose={folderDialogHandlers.close}
/>
<ConfirmationDialog
isOpen={openConfirmationDialog}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Folder, type FolderProps } from '@bypass/shared';
import { useDisclosure } from '@mantine/hooks';
import { HugeiconsIcon } from '@hugeicons/react';
import {
FolderEditIcon,
FolderRemoveIcon,
StarIcon,
StarOffIcon,
} from '@hugeicons/core-free-icons';
import { memo, useCallback, useMemo, useState } from 'react';
import { memo, useCallback, useMemo } from 'react';
import ContextMenu, { type IMenuOption } from '@popup/components/ContextMenu';
import { FolderAddEditDialog } from './FolderAddEditDialog';

Expand All @@ -28,11 +29,7 @@ const FolderRow = memo<Props>(
toggleDefaultFolder,
...restProps
}) => {
const [openEditDialog, setOpenEditDialog] = useState(false);

const toggleEditDialog = useCallback(() => {
setOpenEditDialog((prev) => !prev);
}, []);
const [openEditDialog, editDialogHandlers] = useDisclosure(false);

const handleDeleteOptionClick = useCallback(() => {
handleRemove(id);
Expand All @@ -49,7 +46,7 @@ const FolderRow = memo<Props>(
const menuOptions = useMemo(() => {
const options: IMenuOption[] = [
{
onClick: toggleEditDialog,
onClick: editDialogHandlers.open,
text: 'Edit',
id: 'edit',
icon: FolderEditIcon,
Expand All @@ -72,8 +69,8 @@ const FolderRow = memo<Props>(
}, [
handleDefaultOptionClick,
handleDeleteOptionClick,
editDialogHandlers.open,
isDefault,
toggleEditDialog,
]);

return (
Expand All @@ -98,7 +95,7 @@ const FolderRow = memo<Props>(
origName={origName}
handleSave={handleFolderSave}
isOpen={openEditDialog}
onClose={toggleEditDialog}
onClose={editDialogHandlers.close}
/>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
Input,
Spinner,
} from '@bypass/ui';
import { useDisclosure } from '@mantine/hooks';
import { useForm, useStore } from '@tanstack/react-form';
import { HugeiconsIcon } from '@hugeicons/react';
import { UserWarning03Icon } from '@hugeicons/core-free-icons';
Expand Down Expand Up @@ -45,7 +46,7 @@ function AddOrEditPersonDialog({
const { resolvePersonImageFromUid } = usePerson();
const initialUid = useRef(crypto.randomUUID());
const [imageUrl, setImageUrl] = useState('');
const [showImagePicker, setShowImagePicker] = useState(false);
const [showImagePicker, imagePickerHandlers] = useDisclosure(false);
const [isLoading, setIsLoading] = useState(false);

const form = useForm({
Expand Down Expand Up @@ -104,8 +105,6 @@ function AddOrEditPersonDialog({
setImageUrl(url);
};

const toggleImagePicker = () => setShowImagePicker(!showImagePicker);

const uid = useStore(form.store, (state) => state.values.uid);

return (
Expand Down Expand Up @@ -147,7 +146,7 @@ function AddOrEditPersonDialog({
data-testid="change-avatar-button"
className="absolute inset-0 rounded-xl border-0"
style={{ width: IMAGE_SIZE, height: IMAGE_SIZE }}
onClick={toggleImagePicker}
onClick={imagePickerHandlers.open}
/>
</div>
</div>
Expand Down Expand Up @@ -181,7 +180,7 @@ function AddOrEditPersonDialog({
uid={uid}
isOpen={showImagePicker}
handleImageSave={handleImageCropSave}
onDialogClose={toggleImagePicker}
onDialogClose={imagePickerHandlers.close}
/>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import {
Slider,
Spinner,
} from '@bypass/ui';
import { useDebounce } from 'ahooks';
import {
type ChangeEventHandler,
type ClipboardEventHandler,
useRef,
useState,
} from 'react';
import { useDebouncedValue } from '@mantine/hooks';
import AvatarEditor from 'react-avatar-editor';
import wretch from 'wretch';
import { uploadFileToFirebase } from '../utils/uploadImage';
Expand All @@ -30,15 +30,16 @@ interface Props {
function ImagePicker({ uid, isOpen, onDialogClose, handleImageSave }: Props) {
const [isUploadingImage, setIsUploadingImage] = useState(false);
const [inputOrFileValue, setInputOrFileValue] = useState<string | File>('');
const inputOrFile = useDebounce(inputOrFileValue, { wait: 500 });
const [debouncedInputUrl] = useDebouncedValue(inputOrFileValue, 500);
const [isLoadingImage, setIsLoadingImage] = useState(false);
const imageCropperRef = useRef<AvatarEditor>(null);
const [zoom, setZoom] = useState(1);
const [rotation, setRotation] = useState(0);

const handleImageUrlChange: ChangeEventHandler<HTMLInputElement> = (e) => {
setIsLoadingImage(true);
setInputOrFileValue(e.target.value ?? '');
const nextValue = e.target.value ?? '';
setInputOrFileValue(nextValue);
setIsLoadingImage(nextValue.trim().length > 0);
};

const handleImagePaste: ClipboardEventHandler<HTMLInputElement> = (e) => {
Expand Down Expand Up @@ -68,7 +69,7 @@ function ImagePicker({ uid, isOpen, onDialogClose, handleImageSave }: Props) {
};

const saveCroppedImage = async () => {
if (!inputOrFile || !imageCropperRef.current) {
if (!debouncedInputUrl || !imageCropperRef.current) {
return;
}
try {
Expand All @@ -87,7 +88,7 @@ function ImagePicker({ uid, isOpen, onDialogClose, handleImageSave }: Props) {
}
};

const disableControls = isLoadingImage || !inputOrFile;
const disableControls = isLoadingImage || !debouncedInputUrl;

return (
<Dialog open={isOpen} onOpenChange={(open) => !open && onDialogClose()}>
Expand Down Expand Up @@ -122,7 +123,7 @@ function ImagePicker({ uid, isOpen, onDialogClose, handleImageSave }: Props) {
)}
<AvatarEditor
ref={imageCropperRef}
image={inputOrFile}
image={debouncedInputUrl}
crossOrigin="anonymous"
// When changing this, change in upload API as well
width={250}
Expand Down
Loading
Loading