Hey is a decentralized and permissionless social media app built with Lens Protocol 🌿

feat: Migrate to sonner (#5565)

authored by

Bigint and committed by
GitHub
0b212ed7 12535925

+90 -96
+1 -1
apps/web/package.json
··· 46 46 "react-dom": "^19.1.0", 47 47 "react-easy-crop": "^5.4.1", 48 48 "react-hook-form": "^7.55.0", 49 - "react-hot-toast": "^2.5.2", 50 49 "react-markdown": "^10.1.0", 51 50 "react-router": "^7.5.0", 52 51 "react-tracked": "^2.0.1", ··· 58 57 "remark-linkify-regex": "^1.2.1", 59 58 "remark-parse": "^11.0.0", 60 59 "remark-stringify": "^11.0.0", 60 + "sonner": "^2.0.3", 61 61 "strip-markdown": "^6.0.0", 62 62 "tailwind-merge": "^3.2.0", 63 63 "tailwindcss": "^4.1.3",
+1 -1
apps/web/src/components/Account/Menu/CopyLink.tsx
··· 4 4 import getAccount from "@hey/helpers/getAccount"; 5 5 import stopEventPropagation from "@hey/helpers/stopEventPropagation"; 6 6 import type { AccountFragment } from "@hey/indexer"; 7 - import toast from "react-hot-toast"; 7 + import { toast } from "sonner"; 8 8 9 9 interface CopyLinkProps { 10 10 account: AccountFragment;
+13 -4
apps/web/src/components/Common/Layout.tsx
··· 4 4 import Navbar from "@/components/Shared/Navbar"; 5 5 import BottomNavigation from "@/components/Shared/Navbar/BottomNavigation"; 6 6 import getCurrentSession from "@/helpers/getCurrentSession"; 7 - import getToastOptions from "@/helpers/getToastOptions"; 8 7 import { useTheme } from "@/hooks/useTheme"; 9 8 import { useAccountStatus } from "@/store/non-persisted/useAccountStatus"; 10 9 import { useAccountStore } from "@/store/persisted/useAccountStore"; 11 10 import { signOut } from "@/store/persisted/useAuthStore"; 12 11 import { usePreferencesStore } from "@/store/persisted/usePreferencesStore"; 12 + import { CheckCircleIcon, XCircleIcon } from "@heroicons/react/24/solid"; 13 13 import { useMeQuery } from "@hey/indexer"; 14 14 import { useIsClient } from "@uidotdev/usehooks"; 15 15 import { useEffect } from "react"; 16 - import { Toaster } from "react-hot-toast"; 17 16 import { Outlet, useLocation } from "react-router"; 17 + import { Toaster, type ToasterProps } from "sonner"; 18 + import { Spinner } from "../Shared/UI"; 18 19 19 20 const Layout = () => { 20 21 const { pathname } = useLocation(); ··· 60 61 return ( 61 62 <> 62 63 <Toaster 63 - containerStyle={{ wordBreak: "break-word" }} 64 64 position="bottom-right" 65 - toastOptions={getToastOptions(theme)} 65 + theme={theme as ToasterProps["theme"]} 66 + toastOptions={{ 67 + className: "font-sofia-pro", 68 + style: { boxShadow: "none" } 69 + }} 70 + icons={{ 71 + success: <CheckCircleIcon />, 72 + error: <XCircleIcon />, 73 + loading: <Spinner size="xs" /> 74 + }} 66 75 /> 67 76 <GlobalModals /> 68 77 <GlobalAlerts />
+1 -1
apps/web/src/components/Composer/Actions/Attachment.tsx
··· 16 16 import { useClickAway } from "@uidotdev/usehooks"; 17 17 import type { ChangeEvent, JSX, MutableRefObject } from "react"; 18 18 import { useId, useState } from "react"; 19 - import toast from "react-hot-toast"; 19 + import { toast } from "sonner"; 20 20 21 21 const ImageMimeType = Object.values(MediaImageMimeType); 22 22 const AudioMimeType = Object.values(MediaAudioMimeType);
+1 -1
apps/web/src/components/Composer/Actions/LivestreamSettings/LivestreamEditor.tsx
··· 14 14 import { useMutation } from "@tanstack/react-query"; 15 15 import type { ReactNode } from "react"; 16 16 import { useState } from "react"; 17 - import toast from "react-hot-toast"; 17 + import { toast } from "sonner"; 18 18 19 19 interface WrapperProps { 20 20 children: ReactNode;
+1 -1
apps/web/src/components/Composer/ChooseThumbnail.tsx
··· 8 8 import getFileFromDataURL from "@hey/helpers/getFileFromDataURL"; 9 9 import type { ChangeEvent } from "react"; 10 10 import { useEffect, useState } from "react"; 11 - import { toast } from "react-hot-toast"; 11 + import { toast } from "sonner"; 12 12 13 13 const DEFAULT_THUMBNAIL_INDEX = 0; 14 14 export const THUMBNAIL_GENERATE_COUNT = 4;
+1 -1
apps/web/src/components/Composer/NewPublication.tsx
··· 33 33 import type { IGif } from "@hey/types/giphy"; 34 34 import type { NewAttachment } from "@hey/types/misc"; 35 35 import { useEffect, useState } from "react"; 36 - import toast from "react-hot-toast"; 36 + import { toast } from "sonner"; 37 37 import Attachment from "./Actions/Attachment"; 38 38 import CollectSettings from "./Actions/CollectSettings"; 39 39 import Gif from "./Actions/Gif";
+1 -1
apps/web/src/components/Group/Settings/Monetize/SuperJoin.tsx
··· 27 27 useUpdateGroupRulesMutation 28 28 } from "@hey/indexer"; 29 29 import { type RefObject, useEffect, useRef, useState } from "react"; 30 - import toast from "react-hot-toast"; 30 + import { toast } from "sonner"; 31 31 32 32 interface SuperJoinProps { 33 33 group: GroupFragment;
+1 -1
apps/web/src/components/Group/Settings/Personalize/Form.tsx
··· 20 20 import { type GroupFragment, useSetGroupMetadataMutation } from "@hey/indexer"; 21 21 import { group as groupMetadata } from "@lens-protocol/metadata"; 22 22 import { useState } from "react"; 23 - import toast from "react-hot-toast"; 23 + import { toast } from "sonner"; 24 24 import { z } from "zod"; 25 25 26 26 const ValidationSchema = z.object({
+1 -1
apps/web/src/components/Group/Settings/Rules/ApprovalRule.tsx
··· 10 10 useUpdateGroupRulesMutation 11 11 } from "@hey/indexer"; 12 12 import { useState } from "react"; 13 - import toast from "react-hot-toast"; 13 + import { toast } from "sonner"; 14 14 15 15 interface ApprovalRuleProps { 16 16 group: GroupFragment;
+1 -1
apps/web/src/components/Groups/Sidebar/Create/CreateGroupModal.tsx
··· 15 15 import { useCreateGroupMutation } from "@hey/indexer"; 16 16 import { group } from "@lens-protocol/metadata"; 17 17 import { useState } from "react"; 18 - import toast from "react-hot-toast"; 18 + import { toast } from "sonner"; 19 19 import { z } from "zod"; 20 20 import { useCreateGroupStore } from "./CreateGroup"; 21 21
+1 -1
apps/web/src/components/Post/Actions/Like.tsx
··· 15 15 } from "@hey/indexer"; 16 16 import { useCounter, useToggle } from "@uidotdev/usehooks"; 17 17 import { AnimateNumber } from "motion-plus-react"; 18 - import toast from "react-hot-toast"; 18 + import { toast } from "sonner"; 19 19 20 20 interface LikeProps { 21 21 post: PostFragment;
+1 -1
apps/web/src/components/Post/Actions/Menu/Bookmark.tsx
··· 10 10 useBookmarkPostMutation, 11 11 useUndoBookmarkPostMutation 12 12 } from "@hey/indexer"; 13 - import { toast } from "react-hot-toast"; 14 13 import { useLocation } from "react-router"; 14 + import { toast } from "sonner"; 15 15 16 16 interface BookmarkProps { 17 17 post: PostFragment;
+1 -1
apps/web/src/components/Post/Actions/Menu/CopyPostText.tsx
··· 4 4 import getPostData from "@hey/helpers/getPostData"; 5 5 import stopEventPropagation from "@hey/helpers/stopEventPropagation"; 6 6 import type { PostFragment } from "@hey/indexer"; 7 - import toast from "react-hot-toast"; 7 + import { toast } from "sonner"; 8 8 9 9 interface CopyPostTextProps { 10 10 post: PostFragment;
+1 -1
apps/web/src/components/Post/Actions/Menu/HideComment.tsx
··· 11 11 useHideReplyMutation, 12 12 useUnhideReplyMutation 13 13 } from "@hey/indexer"; 14 - import { toast } from "react-hot-toast"; 14 + import { toast } from "sonner"; 15 15 16 16 interface HideCommentProps { 17 17 post: PostFragment;
+1 -1
apps/web/src/components/Post/Actions/Menu/NotInterested.tsx
··· 10 10 useAddPostNotInterestedMutation, 11 11 useUndoPostNotInterestedMutation 12 12 } from "@hey/indexer"; 13 - import { toast } from "react-hot-toast"; 13 + import { toast } from "sonner"; 14 14 15 15 interface NotInterestedProps { 16 16 post: PostFragment;
+1 -1
apps/web/src/components/Post/Actions/Menu/Share.tsx
··· 3 3 import { ClipboardDocumentIcon } from "@heroicons/react/24/outline"; 4 4 import stopEventPropagation from "@hey/helpers/stopEventPropagation"; 5 5 import type { PostFragment } from "@hey/indexer"; 6 - import toast from "react-hot-toast"; 6 + import { toast } from "sonner"; 7 7 8 8 interface ShareProps { 9 9 post: PostFragment;
+1 -1
apps/web/src/components/Post/Actions/Share/Quote.tsx
··· 7 7 import { ChatBubbleBottomCenterTextIcon } from "@heroicons/react/24/outline"; 8 8 import { Errors } from "@hey/data/errors"; 9 9 import type { PostFragment } from "@hey/indexer"; 10 - import toast from "react-hot-toast"; 10 + import { toast } from "sonner"; 11 11 12 12 interface QuoteProps { 13 13 post: PostFragment;
+1 -1
apps/web/src/components/Post/Actions/Share/Repost.tsx
··· 10 10 import { type PostFragment, useRepostMutation } from "@hey/indexer"; 11 11 import { useCounter } from "@uidotdev/usehooks"; 12 12 import type { Dispatch, SetStateAction } from "react"; 13 - import { toast } from "react-hot-toast"; 13 + import { toast } from "sonner"; 14 14 15 15 interface RepostProps { 16 16 isSubmitting: boolean;
+1 -1
apps/web/src/components/Post/Actions/Share/UndoRepost.tsx
··· 9 9 import { isRepost } from "@hey/helpers/postHelpers"; 10 10 import { type AnyPostFragment, useDeletePostMutation } from "@hey/indexer"; 11 11 import type { Dispatch, SetStateAction } from "react"; 12 - import { toast } from "react-hot-toast"; 12 + import { toast } from "sonner"; 13 13 14 14 interface UndoRepostProps { 15 15 post: AnyPostFragment;
+1 -1
apps/web/src/components/Post/OpenAction/CollectAction/CollectActionButton.tsx
··· 16 16 useExecutePostActionMutation 17 17 } from "@hey/indexer"; 18 18 import { useState } from "react"; 19 - import toast from "react-hot-toast"; 19 + import { toast } from "sonner"; 20 20 21 21 interface CollectActionButtonProps { 22 22 collects: number;
+1 -1
apps/web/src/components/Post/OpenAction/TipAction/Action.tsx
··· 21 21 } from "@hey/indexer"; 22 22 import type { ChangeEvent, RefObject } from "react"; 23 23 import { useRef, useState } from "react"; 24 - import toast from "react-hot-toast"; 24 + import { toast } from "sonner"; 25 25 26 26 const submitButtonClassName = "w-full py-1.5 text-sm font-semibold"; 27 27
+1 -1
apps/web/src/components/Settings/Danger/Delete.tsx
··· 12 12 import { NULL_ADDRESS } from "@hey/data/constants"; 13 13 import { Errors } from "@hey/data/errors"; 14 14 import { useState } from "react"; 15 - import toast from "react-hot-toast"; 16 15 import { Link } from "react-router"; 16 + import { toast } from "sonner"; 17 17 18 18 const DeleteSettings = () => { 19 19 const { currentAccount } = useAccountStore();
+1 -1
apps/web/src/components/Settings/Developer/Tokens.tsx
··· 6 6 import { Errors } from "@hey/data/errors"; 7 7 import { useAuthenticateMutation, useChallengeMutation } from "@hey/indexer"; 8 8 import { useState } from "react"; 9 - import toast from "react-hot-toast"; 9 + import { toast } from "sonner"; 10 10 import { useAccount, useSignMessage } from "wagmi"; 11 11 12 12 const Tokens = () => {
+1 -1
apps/web/src/components/Settings/Funds/Unwrap.tsx
··· 5 5 import { NATIVE_TOKEN_SYMBOL } from "@hey/data/constants"; 6 6 import { useUnwrapTokensMutation } from "@hey/indexer"; 7 7 import { useState } from "react"; 8 - import toast from "react-hot-toast"; 8 + import { toast } from "sonner"; 9 9 10 10 interface UnwrapProps { 11 11 value: string;
+1 -1
apps/web/src/components/Settings/Funds/Withdraw.tsx
··· 4 4 import useTransactionLifecycle from "@/hooks/useTransactionLifecycle"; 5 5 import { useWithdrawMutation } from "@hey/indexer"; 6 6 import { useState } from "react"; 7 - import toast from "react-hot-toast"; 7 + import { toast } from "sonner"; 8 8 import type { Address } from "viem"; 9 9 10 10 interface WithdrawProps {
+1 -1
apps/web/src/components/Settings/Funds/Wrap.tsx
··· 5 5 import { WRAPPED_NATIVE_TOKEN_SYMBOL } from "@hey/data/constants"; 6 6 import { useWrapTokensMutation } from "@hey/indexer"; 7 7 import { useState } from "react"; 8 - import toast from "react-hot-toast"; 8 + import { toast } from "sonner"; 9 9 10 10 interface WrapProps { 11 11 value: string;
+1 -1
apps/web/src/components/Settings/Manager/AccountManager/AddAccountManager.tsx
··· 9 9 import { useAddAccountManagerMutation } from "@hey/indexer"; 10 10 import type { Dispatch, SetStateAction } from "react"; 11 11 import { useState } from "react"; 12 - import toast from "react-hot-toast"; 12 + import { toast } from "sonner"; 13 13 import { isAddress } from "viem"; 14 14 15 15 interface AddAccountManagerProps {
+1 -1
apps/web/src/components/Settings/Manager/AccountManager/Management/List.tsx
··· 12 12 useUnhideManagedAccountMutation 13 13 } from "@hey/indexer"; 14 14 import { useEffect } from "react"; 15 - import toast from "react-hot-toast"; 16 15 import { Virtuoso } from "react-virtuoso"; 16 + import { toast } from "sonner"; 17 17 import { useAccount } from "wagmi"; 18 18 19 19 interface ListProps {
+1 -1
apps/web/src/components/Settings/Manager/AccountManager/Managers/List.tsx
··· 16 16 useRemoveAccountManagerMutation 17 17 } from "@hey/indexer"; 18 18 import { useState } from "react"; 19 - import toast from "react-hot-toast"; 20 19 import { Virtuoso } from "react-virtuoso"; 20 + import { toast } from "sonner"; 21 21 import Permission from "./Permission"; 22 22 23 23 const List = () => {
+1 -1
apps/web/src/components/Settings/Manager/AccountManager/Managers/Permission.tsx
··· 11 11 useUpdateAccountManagerMutation 12 12 } from "@hey/indexer"; 13 13 import { useState } from "react"; 14 - import toast from "react-hot-toast"; 14 + import { toast } from "sonner"; 15 15 16 16 interface PermissionsProps { 17 17 title: string;
+1 -1
apps/web/src/components/Settings/Manager/Signless.tsx
··· 5 5 import { Errors } from "@hey/data/errors"; 6 6 import { useEnableSignlessMutation } from "@hey/indexer"; 7 7 import { useState } from "react"; 8 - import toast from "react-hot-toast"; 8 + import { toast } from "sonner"; 9 9 10 10 const Signless = () => { 11 11 const { isSuspended } = useAccountStatus();
+1 -1
apps/web/src/components/Settings/Monetize/SuperFollow.tsx
··· 29 29 useUpdateAccountFollowRulesMutation 30 30 } from "@hey/indexer"; 31 31 import { type RefObject, useEffect, useRef, useState } from "react"; 32 - import toast from "react-hot-toast"; 32 + import { toast } from "sonner"; 33 33 34 34 const SuperFollow = () => { 35 35 const { currentAccount, setCurrentAccount } = useAccountStore();
+1 -1
apps/web/src/components/Settings/Personalize/Form.tsx
··· 30 30 account as accountMetadata 31 31 } from "@lens-protocol/metadata"; 32 32 import { useState } from "react"; 33 - import toast from "react-hot-toast"; 33 + import { toast } from "sonner"; 34 34 import { z } from "zod"; 35 35 36 36 const ValidationSchema = z.object({
+1 -1
apps/web/src/components/Settings/Preferences/AppIcon.tsx
··· 6 6 import { CheckCircleIcon as CheckCircleIconSolid } from "@heroicons/react/24/solid"; 7 7 import { STATIC_IMAGES_URL } from "@hey/data/constants"; 8 8 import { useMutation } from "@tanstack/react-query"; 9 - import toast from "react-hot-toast"; 9 + import { toast } from "sonner"; 10 10 11 11 const icons = [ 12 12 { id: 0, name: "Default" },
+1 -1
apps/web/src/components/Settings/Preferences/IncludeLowScore.tsx
··· 4 4 import { usePreferencesStore } from "@/store/persisted/usePreferencesStore"; 5 5 import { SwatchIcon } from "@heroicons/react/24/outline"; 6 6 import { useMutation } from "@tanstack/react-query"; 7 - import toast from "react-hot-toast"; 7 + import { toast } from "sonner"; 8 8 9 9 const IncludeLowScore = () => { 10 10 const { includeLowScore, setIncludeLowScore } = usePreferencesStore();
+1 -1
apps/web/src/components/Settings/Sessions/List.tsx
··· 13 13 useRevokeAuthenticationMutation 14 14 } from "@hey/indexer"; 15 15 import { useState } from "react"; 16 - import toast from "react-hot-toast"; 17 16 import { Virtuoso } from "react-virtuoso"; 17 + import { toast } from "sonner"; 18 18 19 19 const List = () => { 20 20 const { currentAccount } = useAccountStore();
+1 -1
apps/web/src/components/Settings/Username/LinkUsername.tsx
··· 13 13 useUsernamesQuery 14 14 } from "@hey/indexer"; 15 15 import { useState } from "react"; 16 - import toast from "react-hot-toast"; 16 + import { toast } from "sonner"; 17 17 18 18 const LinkUsername = () => { 19 19 const { currentAccount } = useAccountStore();
+1 -1
apps/web/src/components/Settings/Username/UnlinkUsername.tsx
··· 7 7 import getAccount from "@hey/helpers/getAccount"; 8 8 import { useUnassignUsernameFromAccountMutation } from "@hey/indexer"; 9 9 import { useState } from "react"; 10 - import toast from "react-hot-toast"; 10 + import { toast } from "sonner"; 11 11 12 12 const UnlinkUsername = () => { 13 13 const { currentAccount } = useAccountStore();
+1 -1
apps/web/src/components/Shared/Account/Follow.tsx
··· 8 8 import { Errors } from "@hey/data/errors"; 9 9 import { type AccountFragment, useFollowMutation } from "@hey/indexer"; 10 10 import { useState } from "react"; 11 - import toast from "react-hot-toast"; 11 + import { toast } from "sonner"; 12 12 13 13 interface FollowProps { 14 14 onFollow?: () => void;
+1 -1
apps/web/src/components/Shared/Account/Fund/FundAccount/Fund.tsx
··· 10 10 import { NATIVE_TOKEN_SYMBOL } from "@hey/data/constants"; 11 11 import { useDepositMutation } from "@hey/indexer"; 12 12 import { type ChangeEvent, type RefObject, useRef, useState } from "react"; 13 - import toast from "react-hot-toast"; 13 + import { toast } from "sonner"; 14 14 import { formatUnits } from "viem"; 15 15 import { useAccount, useBalance } from "wagmi"; 16 16
+1 -1
apps/web/src/components/Shared/Account/Suspend.tsx
··· 2 2 import { trpc } from "@/helpers/trpc"; 3 3 import { Permission, PermissionId } from "@hey/data/permissions"; 4 4 import { useMutation, useQuery } from "@tanstack/react-query"; 5 - import toast from "react-hot-toast"; 5 + import { toast } from "sonner"; 6 6 import ToggleWithHelper from "../ToggleWithHelper"; 7 7 8 8 interface SuspendProps {
+1 -1
apps/web/src/components/Shared/Account/Unfollow.tsx
··· 8 8 import { Errors } from "@hey/data/errors"; 9 9 import { type AccountFragment, useUnfollowMutation } from "@hey/indexer"; 10 10 import { useState } from "react"; 11 - import toast from "react-hot-toast"; 11 + import { toast } from "sonner"; 12 12 13 13 interface UnfollowProps { 14 14 buttonClassName: string;
+1 -1
apps/web/src/components/Shared/Alert/BlockOrUnblockAccount.tsx
··· 9 9 import getAccount from "@hey/helpers/getAccount"; 10 10 import { useBlockMutation, useUnblockMutation } from "@hey/indexer"; 11 11 import { useState } from "react"; 12 - import { toast } from "react-hot-toast"; 12 + import { toast } from "sonner"; 13 13 14 14 const BlockOrUnblockAccount = () => { 15 15 const { currentAccount } = useAccountStore();
+1 -1
apps/web/src/components/Shared/Alert/DeletePost.tsx
··· 6 6 import { useApolloClient } from "@apollo/client"; 7 7 import { Errors } from "@hey/data/errors"; 8 8 import { useDeletePostMutation } from "@hey/indexer"; 9 - import { toast } from "react-hot-toast"; 9 + import { toast } from "sonner"; 10 10 11 11 const DeletePost = () => { 12 12 const { deletingPost, setShowPostDeleteAlert, showPostDeleteAlert } =
+1 -1
apps/web/src/components/Shared/Alert/MuteOrUnmuteAccount.tsx
··· 8 8 import getAccount from "@hey/helpers/getAccount"; 9 9 import { useMuteMutation, useUnmuteMutation } from "@hey/indexer"; 10 10 import { useState } from "react"; 11 - import { toast } from "react-hot-toast"; 11 + import { toast } from "sonner"; 12 12 13 13 const MuteOrUnmuteAccount = () => { 14 14 const { currentAccount } = useAccountStore();
+1 -1
apps/web/src/components/Shared/Auth/Login.tsx
··· 12 12 } from "@hey/indexer"; 13 13 import type { Dispatch, SetStateAction } from "react"; 14 14 import { useState } from "react"; 15 - import toast from "react-hot-toast"; 15 + import { toast } from "sonner"; 16 16 import { useAccount, useDisconnect, useSignMessage } from "wagmi"; 17 17 import SingleAccount from "../Account/SingleAccount"; 18 18 import Loader from "../Loader";
+1 -1
apps/web/src/components/Shared/Auth/Signup/ChooseUsername.tsx
··· 19 19 } from "@hey/indexer"; 20 20 import { account as accountMetadata } from "@lens-protocol/metadata"; 21 21 import { useState } from "react"; 22 - import toast from "react-hot-toast"; 22 + import { toast } from "sonner"; 23 23 import { useAccount, useSignMessage } from "wagmi"; 24 24 import { z } from "zod"; 25 25 import { useSignupStore } from ".";
+1 -1
apps/web/src/components/Shared/AvatarUpload.tsx
··· 11 11 import type { ChangeEvent } from "react"; 12 12 import { useState } from "react"; 13 13 import Cropper, { type Area } from "react-easy-crop"; 14 - import toast from "react-hot-toast"; 14 + import { toast } from "sonner"; 15 15 16 16 interface AvatarUploadProps { 17 17 src: string;
+1 -1
apps/web/src/components/Shared/CoverUpload.tsx
··· 11 11 import type { ChangeEvent } from "react"; 12 12 import { useState } from "react"; 13 13 import Cropper, { type Area } from "react-easy-crop"; 14 - import toast from "react-hot-toast"; 14 + import { toast } from "sonner"; 15 15 16 16 interface CoverUploadProps { 17 17 src: string;
+1 -1
apps/web/src/components/Shared/Group/Join.tsx
··· 6 6 import { Errors } from "@hey/data/errors"; 7 7 import { type GroupFragment, useJoinGroupMutation } from "@hey/indexer"; 8 8 import { useState } from "react"; 9 - import toast from "react-hot-toast"; 9 + import { toast } from "sonner"; 10 10 11 11 interface JoinProps { 12 12 group: GroupFragment;
+1 -1
apps/web/src/components/Shared/Group/Leave.tsx
··· 6 6 import { Errors } from "@hey/data/errors"; 7 7 import { type GroupFragment, useLeaveGroupMutation } from "@hey/indexer"; 8 8 import { useState } from "react"; 9 - import toast from "react-hot-toast"; 9 + import { toast } from "sonner"; 10 10 11 11 interface LeaveProps { 12 12 group: GroupFragment;
+1 -1
apps/web/src/components/Shared/MetaDetails.tsx
··· 1 1 import { H6 } from "@/components/Shared/UI"; 2 2 import cn from "@/helpers/cn"; 3 3 import type { ReactNode } from "react"; 4 - import { toast } from "react-hot-toast"; 4 + import { toast } from "sonner"; 5 5 6 6 interface MetaDetailsProps { 7 7 children: ReactNode;
+1 -1
apps/web/src/components/Shared/Modal/ReportAccount/index.tsx
··· 21 21 useReportAccountMutation 22 22 } from "@hey/indexer"; 23 23 import { useState } from "react"; 24 - import toast from "react-hot-toast"; 24 + import { toast } from "sonner"; 25 25 import { z } from "zod"; 26 26 27 27 const ValidationSchema = z.object({
+1 -1
apps/web/src/components/Shared/Modal/ReportPost/index.tsx
··· 15 15 import stopEventPropagation from "@hey/helpers/stopEventPropagation"; 16 16 import { PostReportReason, useReportPostMutation } from "@hey/indexer"; 17 17 import { useState } from "react"; 18 - import toast from "react-hot-toast"; 18 + import { toast } from "sonner"; 19 19 import { z } from "zod"; 20 20 21 21 const ValidationSchema = z.object({
+1 -1
apps/web/src/components/Shared/Navbar/NavItems/Logout.tsx
··· 6 6 import { ArrowRightStartOnRectangleIcon } from "@heroicons/react/24/outline"; 7 7 import { useRevokeAuthenticationMutation } from "@hey/indexer"; 8 8 import { useState } from "react"; 9 - import toast from "react-hot-toast"; 9 + import { toast } from "sonner"; 10 10 11 11 interface LogoutProps { 12 12 className?: string;
+1 -1
apps/web/src/components/Staff/Account/Tool/Permissions.tsx
··· 5 5 import { AdjustmentsHorizontalIcon } from "@heroicons/react/24/solid"; 6 6 import { Permission, PermissionId } from "@hey/data/permissions"; 7 7 import { useMutation, useQuery } from "@tanstack/react-query"; 8 - import toast from "react-hot-toast"; 8 + import { toast } from "sonner"; 9 9 10 10 interface PermissionsProps { 11 11 address: string;
+1 -1
apps/web/src/helpers/errorToast.ts
··· 1 1 import { Errors } from "@hey/data/errors"; 2 - import { toast } from "react-hot-toast"; 2 + import { toast } from "sonner"; 3 3 4 4 const FORBIDDEN_ERROR = 5 5 "Forbidden - Failed to generate source stamp: App rejected verification request:";
+1 -1
apps/web/src/hooks/prosekit/usePaste.tsx
··· 4 4 import { type Editor, defineDOMEventHandler, union } from "prosekit/core"; 5 5 import { useExtension } from "prosekit/react"; 6 6 import { useCallback, useEffect, useMemo, useRef } from "react"; 7 - import toast from "react-hot-toast"; 7 + import { toast } from "sonner"; 8 8 9 9 const handleFiles = ( 10 10 event: Event,
+3 -6
apps/web/src/hooks/useCreatePost.tsx
··· 5 5 useCreatePostMutation, 6 6 usePostLazyQuery 7 7 } from "@hey/indexer"; 8 - import toast from "react-hot-toast"; 8 + import { toast } from "sonner"; 9 9 import usePollTransactionStatus from "./usePollTransactionStatus"; 10 10 import useTransactionLifecycle from "./useTransactionLifecycle"; 11 11 ··· 26 26 const { cache } = useApolloClient(); 27 27 const isComment = Boolean(commentOn); 28 28 29 - const updateCache = async (txHash: string, toastId: string) => { 29 + const updateCache = async (txHash: string) => { 30 30 const { data } = await getPost({ variables: { request: { txHash } } }); 31 31 if (!data?.post) { 32 32 return; 33 33 } 34 34 35 - toast.dismiss(toastId); 36 35 toast.success(`${isComment ? "Comment" : "Post"} created successfully!`); 37 - 38 36 cache.modify({ 39 37 fields: { 40 38 [isComment ? "postReferences" : "posts"]: () => { ··· 45 43 }; 46 44 47 45 const onCompletedWithTransaction = (hash: string) => { 48 - const toastId = toast.loading("Processing..."); 49 - pollTransactionStatus(hash, () => updateCache(hash, toastId)); 46 + pollTransactionStatus(hash, () => updateCache(hash)); 50 47 return onCompleted(); 51 48 }; 52 49
+1 -1
apps/web/src/hooks/useUploadAttachments.tsx
··· 4 4 import type { NewAttachment } from "@hey/types/misc"; 5 5 import imageCompression from "browser-image-compression"; 6 6 import { useCallback } from "react"; 7 - import { toast } from "react-hot-toast"; 7 + import { toast } from "sonner"; 8 8 9 9 const useUploadAttachments = () => { 10 10 const {
+1 -1
apps/web/vite.config.mjs
··· 32 32 "react-virtuoso", 33 33 "react-easy-crop", 34 34 "react-hook-form", 35 - "react-hot-toast", 36 35 "react-router", 37 36 "react-tracked" 38 37 ], ··· 55 54 "@radix-ui/react-slider", 56 55 "@radix-ui/react-tooltip", 57 56 "@uidotdev/usehooks", 57 + "sonner", 58 58 "motion" 59 59 ], 60 60 aws: ["@aws-sdk/client-s3", "@aws-sdk/lib-storage"],
+14 -26
pnpm-lock.yaml
··· 235 235 react-hook-form: 236 236 specifier: ^7.55.0 237 237 version: 7.55.0(react@19.1.0) 238 - react-hot-toast: 239 - specifier: ^2.5.2 240 - version: 2.5.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) 241 238 react-markdown: 242 239 specifier: ^10.1.0 243 240 version: 10.1.0(@types/react@19.1.0)(react@19.1.0) ··· 271 268 remark-stringify: 272 269 specifier: ^11.0.0 273 270 version: 11.0.0 271 + sonner: 272 + specifier: ^2.0.3 273 + version: 2.0.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) 274 274 strip-markdown: 275 275 specifier: ^6.0.0 276 276 version: 6.0.0 ··· 4110 4110 globrex@0.1.2: 4111 4111 resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} 4112 4112 4113 - goober@2.1.16: 4114 - resolution: {integrity: sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==} 4115 - peerDependencies: 4116 - csstype: ^3.0.10 4117 - 4118 4113 gopd@1.2.0: 4119 4114 resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} 4120 4115 engines: {node: '>= 0.4'} ··· 5420 5415 peerDependencies: 5421 5416 react: ^16.8.0 || ^17 || ^18 || ^19 5422 5417 5423 - react-hot-toast@2.5.2: 5424 - resolution: {integrity: sha512-Tun3BbCxzmXXM7C+NI4qiv6lT0uwGh4oAfeJyNOjYUejTsm35mK9iCaYLGv8cBz9L5YxZLx/2ii7zsIwPtPUdw==} 5425 - engines: {node: '>=10'} 5426 - peerDependencies: 5427 - react: '>=16' 5428 - react-dom: '>=16' 5429 - 5430 5418 react-is@16.13.1: 5431 5419 resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} 5432 5420 ··· 5755 5743 sonic-boom@2.8.0: 5756 5744 resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} 5757 5745 5746 + sonner@2.0.3: 5747 + resolution: {integrity: sha512-njQ4Hht92m0sMqqHVDL32V2Oun9W1+PHO9NDv9FHfJjT3JT22IG4Jpo3FPQy+mouRKCXFWO+r67v6MrHX2zeIA==} 5748 + peerDependencies: 5749 + react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc 5750 + react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc 5751 + 5758 5752 source-map-js@1.2.1: 5759 5753 resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} 5760 5754 engines: {node: '>=0.10.0'} ··· 11607 11601 11608 11602 globrex@0.1.2: {} 11609 11603 11610 - goober@2.1.16(csstype@3.1.3): 11611 - dependencies: 11612 - csstype: 3.1.3 11613 - 11614 11604 gopd@1.2.0: {} 11615 11605 11616 11606 graceful-fs@4.2.11: {} ··· 13125 13115 dependencies: 13126 13116 react: 19.1.0 13127 13117 13128 - react-hot-toast@2.5.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0): 13129 - dependencies: 13130 - csstype: 3.1.3 13131 - goober: 2.1.16(csstype@3.1.3) 13132 - react: 19.1.0 13133 - react-dom: 19.1.0(react@19.1.0) 13134 - 13135 13118 react-is@16.13.1: {} 13136 13119 13137 13120 react-markdown@10.1.0(@types/react@19.1.0)(react@19.1.0): ··· 13583 13566 sonic-boom@2.8.0: 13584 13567 dependencies: 13585 13568 atomic-sleep: 1.0.0 13569 + 13570 + sonner@2.0.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0): 13571 + dependencies: 13572 + react: 19.1.0 13573 + react-dom: 19.1.0(react@19.1.0) 13586 13574 13587 13575 source-map-js@1.2.1: {} 13588 13576