diff --git a/components/editor/plugins/mentions.js b/components/editor/plugins/mentions.js
index f273ddc15..b4cb260e7 100644
--- a/components/editor/plugins/mentions.js
+++ b/components/editor/plugins/mentions.js
@@ -1,7 +1,7 @@
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { createPortal } from 'react-dom'
import Dropdown from 'react-bootstrap/Dropdown'
-import { useLazyQuery } from '@apollo/client/react'
+import { useApolloClient } from '@apollo/client/react'
import { LexicalTypeaheadMenuPlugin, MenuOption } from '@lexical/react/LexicalTypeaheadMenuPlugin'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import useDebounceCallback from '@/components/use-debounce-callback'
@@ -18,12 +18,12 @@ const MENTION_PATTERN = /(^|\s|\()([@~]\w{0,75})$/
const MAX_SUGGESTIONS = 5
const SUGGESTION_DEBOUNCE_MS = 150
-function getSuggestionLookup (trigger, getUserSuggestions, getSubSuggestions) {
+function getSuggestionLookup (trigger) {
switch (trigger) {
case '@':
- return { getSuggestions: getUserSuggestions, itemsField: 'userSuggestions' }
+ return { query: USER_SUGGESTIONS, itemsField: 'userSuggestions' }
case '~':
- return { getSuggestions: getSubSuggestions, itemsField: 'subSuggestions' }
+ return { query: SUB_SUGGESTIONS, itemsField: 'subSuggestions' }
default:
return null
}
@@ -31,11 +31,10 @@ function getSuggestionLookup (trigger, getUserSuggestions, getSubSuggestions) {
/** takes the full \@user or \~sub and fetches the suggestions */
function useSuggestions ({ query }) {
+ const client = useApolloClient()
const [suggestions, setSuggestions] = useState([])
const requestIdRef = useRef(0)
- const [getUserSuggestions] = useLazyQuery(USER_SUGGESTIONS)
- const [getSubSuggestions] = useLazyQuery(SUB_SUGGESTIONS)
const setCurrentSuggestions = useCallback((requestId, nextSuggestions = []) => {
if (requestId === requestIdRef.current) {
setSuggestions(nextSuggestions)
@@ -43,7 +42,7 @@ function useSuggestions ({ query }) {
}, [])
const fetchSuggestions = useDebounceCallback(async (nextQuery, requestId) => {
- const lookup = getSuggestionLookup(nextQuery[0], getUserSuggestions, getSubSuggestions)
+ const lookup = getSuggestionLookup(nextQuery[0])
if (!lookup) {
setCurrentSuggestions(requestId)
@@ -51,14 +50,15 @@ function useSuggestions ({ query }) {
}
try {
- const { data } = await lookup.getSuggestions({
+ const { data } = await client.query({
+ query: lookup.query,
variables: { q: nextQuery.slice(1), limit: MAX_SUGGESTIONS }
})
setCurrentSuggestions(requestId, data?.[lookup.itemsField] || [])
} catch {
setCurrentSuggestions(requestId)
}
- }, SUGGESTION_DEBOUNCE_MS, [getUserSuggestions, getSubSuggestions, setCurrentSuggestions])
+ }, SUGGESTION_DEBOUNCE_MS, [client, setCurrentSuggestions])
useEffect(() => {
if (!query) {
diff --git a/components/editor/plugins/upload.js b/components/editor/plugins/upload.js
index ce114f348..7e050a426 100644
--- a/components/editor/plugins/upload.js
+++ b/components/editor/plugins/upload.js
@@ -1,5 +1,4 @@
import { useEffect, useRef, useCallback } from 'react'
-import { isAbortError } from '@/lib/error'
import {
COMMAND_PRIORITY_EDITOR,
$getRoot,
@@ -29,6 +28,7 @@ import styles from '@/lib/lexical/theme/editor.module.css'
import { $insertTextAtSelection } from '@/lib/lexical/utils'
import { isMarkdownMode } from '@/lib/lexical/commands/utils'
import { $createMediaNode, MediaNode } from '@/lib/lexical/nodes/content/media'
+import { isAbortError } from '@/lib/error'
// submit disabled reason for upload
export const UPLOAD_SUBMIT_DISABLED_REASON = 'upload'
@@ -263,8 +263,7 @@ function useLexicalUploadFees (editor) {
const { merge } = useFeeButton()
const [updateUploadFees] = useLazyQuery(UPLOAD_FEES_QUERY, {
- fetchPolicy: 'no-cache',
- nextFetchPolicy: 'no-cache'
+ fetchPolicy: 'no-cache'
})
const handleUploadFeesData = useCallback(({ data }) => {
diff --git a/components/form.js b/components/form.js
index be1bc1244..0e2c88b73 100644
--- a/components/form.js
+++ b/components/form.js
@@ -1,7 +1,6 @@
import Button from 'react-bootstrap/Button'
import InputGroup from 'react-bootstrap/InputGroup'
import BootstrapForm from 'react-bootstrap/Form'
-import { isAbortError } from '@/lib/error'
import { Formik, Form as FormikForm, useFormikContext, useField, FieldArray } from 'formik'
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'
import copy from 'clipboard-copy'
@@ -33,6 +32,7 @@ import dynamic from 'next/dynamic'
import { useIsClient } from './use-client'
import PageLoading from './page-loading'
import { SNEditor } from './editor'
+import { isAbortError } from '@/lib/error'
export { MultiSelect } from './multi-select'
export class SessionRequiredError extends Error {
constructor () {
@@ -489,6 +489,7 @@ export function BaseSuggest ({
resetSuggestions()
}
}, [query, resetSuggestions, getSuggestions])
+
const onKeyDown = useCallback(e => {
switch (e.code) {
case 'ArrowUp':
diff --git a/components/payIn/hooks/use-auto-retry-pay-ins.js b/components/payIn/hooks/use-auto-retry-pay-ins.js
index 11914d7c3..831410c91 100644
--- a/components/payIn/hooks/use-auto-retry-pay-ins.js
+++ b/components/payIn/hooks/use-auto-retry-pay-ins.js
@@ -1,7 +1,6 @@
import { usePreferredSendProtocolId, useWalletPayment } from '@/wallets/client/hooks'
-import { isAbortError } from '@/lib/error'
import usePayInHelper from './use-pay-in-helper'
-import { useLazyQuery } from '@apollo/client/react'
+import { useApolloClient } from '@apollo/client/react'
import { FAILED_PAY_INS } from '@/fragments/payIn'
import { useMe } from '@/components/me'
import { useEffect } from 'react'
@@ -12,7 +11,7 @@ export function useAutoRetryPayIns () {
const waitForWalletPayment = useWalletPayment()
const sendProtocolId = usePreferredSendProtocolId()
const payInHelper = usePayInHelper()
- const [getFailedPayIns] = useLazyQuery(FAILED_PAY_INS, { fetchPolicy: 'network-only', nextFetchPolicy: 'network-only', errorPolicy: 'all' })
+ const client = useApolloClient()
const { me } = useMe()
useEffect(() => {
@@ -39,11 +38,15 @@ export function useAutoRetryPayIns () {
let failedPayIns
try {
- const { data, error } = await getFailedPayIns()
+ const { data, error } = await client.query({
+ query: FAILED_PAY_INS,
+ fetchPolicy: 'network-only',
+ errorPolicy: 'all'
+ })
if (error) throw error
failedPayIns = data.failedPayIns
} catch (err) {
- !isAbortError(err) && console.error('failed to fetch invoices to retry:', err)
+ console.error('failed to fetch invoices to retry:', err)
return
}
@@ -80,7 +83,7 @@ export function useAutoRetryPayIns () {
queuePoll()
return stopPolling
- }, [me?.id, sendProtocolId, getFailedPayIns, payInHelper, waitForWalletPayment])
+ }, [me?.id, sendProtocolId, client, payInHelper, waitForWalletPayment])
}
export function isAutoRetryEligiblePayIn (payIn) {
diff --git a/components/sub-select.js b/components/sub-select.js
index 6e6b36ecb..d0349b54b 100644
--- a/components/sub-select.js
+++ b/components/sub-select.js
@@ -1,10 +1,9 @@
import { useEffect, useState } from 'react'
-import { isAbortError } from '@/lib/error'
import { useRouter } from 'next/router'
import { MultiSelect, Select } from './form'
import { EXTRA_LONG_POLL_INTERVAL_MS, SSR } from '@/lib/constants'
import { ACTIVE_SUBS, SUB_FULL } from '@/fragments/subs'
-import { useLazyQuery, useQuery } from '@apollo/client/react'
+import { useApolloClient, useQuery } from '@apollo/client/react'
import styles from './sub-select.module.css'
import { useMe } from './me'
import { useShowModal } from './modal'
@@ -141,6 +140,7 @@ export default function SubSelect ({ prependSubs, sub, onChange, size, appendSub
export function SubMultiSelect ({ prependSubs, subs, onChange, size, appendSubs, filterSubs, className, ...props }) {
const router = useRouter()
+ const client = useApolloClient()
const activeSubs = useSubs({ prependSubs, subs, filterSubs, appendSubs })
const valueProps = props.noForm
? {
@@ -151,16 +151,18 @@ export function SubMultiSelect ({ prependSubs, subs, onChange, size, appendSubs,
}
const showModal = useShowModal()
- const [getSub] = useLazyQuery(SUB_FULL)
const handleTerritoryClick = async (subName) => {
try {
- const { data } = await getSub({ variables: { sub: subName } })
+ const { data } = await client.query({
+ query: SUB_FULL,
+ variables: { sub: subName }
+ })
if (data?.sub) {
showModal(() => )
}
} catch (err) {
- !isAbortError(err) && console.error(err)
+ console.error(err)
}
}
diff --git a/components/territory-form.js b/components/territory-form.js
index f1d81edfe..216a692ce 100644
--- a/components/territory-form.js
+++ b/components/territory-form.js
@@ -1,5 +1,4 @@
import AccordianItem from './accordian-item'
-import { isAbortError } from '@/lib/error'
import { Col, InputGroup, Row, Form as BootstrapForm, Badge } from 'react-bootstrap'
import { Checkbox, CheckboxGroup, Form, Input, SNInput, Range } from './form'
import { useFormikContext } from 'formik'
@@ -20,6 +19,7 @@ import Link from 'next/link'
import usePayInMutation from '@/components/payIn/hooks/use-pay-in-mutation'
import { UNARCHIVE_TERRITORY, UPSERT_SUB } from '@/fragments/payIn'
import LinkExternal from '@/svgs/link-external.svg'
+import { isAbortError } from '@/lib/error'
function SatFilterRanges () {
const { values } = useFormikContext()
diff --git a/components/use-crossposter.js b/components/use-crossposter.js
index fa06492f0..20792f4f0 100644
--- a/components/use-crossposter.js
+++ b/components/use-crossposter.js
@@ -1,10 +1,9 @@
import { useCallback } from 'react'
-import { isAbortError } from '@/lib/error'
import { useToast } from './toast'
import { Button } from 'react-bootstrap'
import Nostr, { DEFAULT_CROSSPOSTING_RELAYS } from '@/lib/nostr'
import { gql } from '@apollo/client'
-import { useLazyQuery, useMutation, useQuery } from '@apollo/client/react'
+import { useApolloClient, useMutation, useQuery } from '@apollo/client/react'
import { SETTINGS } from '@/fragments/users'
import { ITEM_FULL_FIELDS, POLL_FIELDS } from '@/fragments/items'
@@ -85,24 +84,11 @@ function bountyToEvent (item) {
export default function useCrossposter () {
const toaster = useToast()
+ const client = useApolloClient()
const { data } = useQuery(SETTINGS)
const userRelays = data?.settings?.privates?.nostrRelays || []
const relays = [...DEFAULT_CROSSPOSTING_RELAYS, ...userRelays]
- const [fetchItem] = useLazyQuery(
- gql`
- ${ITEM_FULL_FIELDS}
- ${POLL_FIELDS}
- query Item($id: ID!) {
- item(id: $id) {
- ...ItemFullFields
- ...PollFields
- }
- }`, {
- fetchPolicy: 'no-cache'
- }
- )
-
const [updateNoteId] = useMutation(
gql`
mutation updateNoteId($id: ID!, $noteId: String!) {
@@ -186,11 +172,23 @@ export default function useCrossposter () {
const fetchItemData = async (itemId) => {
try {
- const { data } = await fetchItem({ variables: { id: itemId } })
+ const { data } = await client.query({
+ query: gql`
+ ${ITEM_FULL_FIELDS}
+ ${POLL_FIELDS}
+ query Item($id: ID!) {
+ item(id: $id) {
+ ...ItemFullFields
+ ...PollFields
+ }
+ }`,
+ variables: { id: itemId },
+ fetchPolicy: 'no-cache'
+ })
return data?.item
} catch (e) {
- !isAbortError(e) && console.error(e)
+ console.error(e)
return null
}
}
diff --git a/pages/items/[id]/edit.js b/pages/items/[id]/edit.js
index 045712a4b..83d43aa2d 100644
--- a/pages/items/[id]/edit.js
+++ b/pages/items/[id]/edit.js
@@ -1,5 +1,4 @@
import { ITEM } from '@/fragments/items'
-import { isAbortError } from '@/lib/error'
import { getGetServerSideProps } from '@/api/ssrApollo'
import { DiscussionForm } from '@/components/discussion-form'
import { LinkForm } from '@/components/link-form'
@@ -7,8 +6,8 @@ import { CenterLayout } from '@/components/layout'
import JobForm from '@/components/job-form'
import { PollForm } from '@/components/poll-form'
import { BountyForm } from '@/components/bounty-form'
-import { useEffect, useState } from 'react'
-import { useLazyQuery, useQuery } from '@apollo/client/react'
+import { useMemo, useState } from 'react'
+import { useQuery } from '@apollo/client/react'
import { useRouter } from 'next/router'
import PageLoading from '@/components/page-loading'
import { FeeButtonProvider } from '@/components/fee-button'
@@ -26,49 +25,29 @@ export const getServerSideProps = getGetServerSideProps({
export default function PostEdit ({ ssrData }) {
const router = useRouter()
const { data } = useQuery(ITEM, { variables: { id: router.query.id } })
- const [fetchSubs] = useLazyQuery(SUBS)
if (!data && !ssrData) return
const { item } = data || ssrData
const [subs, setSubs] = useState(item.subNames)
- const [baseLineItems, setBaseLineItems] = useState({})
- useEffect(() => {
- const territoryAddPrefix = 'territory-add-'
- const addedSubs = subsDiff(subs, item.subNames)
- if (!addedSubs.length) {
- setBaseLineItems(prev => Object.entries(prev).reduce((acc, [key, value]) => {
- if (!key.startsWith(territoryAddPrefix)) {
- acc[key] = value
- }
- return acc
- }, {}))
- return
- }
- fetchSubs({ variables: { subNames: addedSubs } }).then(res => {
- setBaseLineItems(prev => {
- const newBaseLineItems = Object.entries(prev).reduce((acc, [key, value]) => {
- if (!key.startsWith(territoryAddPrefix)) {
- acc[key] = value
- }
- return acc
- }, {})
- const territoryAdds = res.data.subs.reduce((acc, sub) => ({
- ...acc,
- [`${territoryAddPrefix}${sub.name}`]: {
- label: `~${sub.name} post`,
- term: `+ ${sub.baseCost}`,
- op: '+',
- modifier: cost => cost + sub.baseCost
- }
- }), {})
- return {
- ...newBaseLineItems,
- ...territoryAdds
- }
- })
- }).catch(err => !isAbortError(err) && console.error(err))
- }, [subs, fetchSubs])
+ const addedSubs = useMemo(() => subsDiff(subs, item.subNames), [subs, item.subNames])
+ const { data: subsData } = useQuery(SUBS, {
+ variables: { subNames: addedSubs },
+ skip: !addedSubs.length
+ })
+
+ const baseLineItems = useMemo(() => {
+ if (!addedSubs.length || !subsData?.subs) return {}
+ return subsData.subs.reduce((acc, sub) => ({
+ ...acc,
+ [`territory-add-${sub.name}`]: {
+ label: `~${sub.name} post`,
+ term: `+ ${sub.baseCost}`,
+ op: '+',
+ modifier: cost => cost + sub.baseCost
+ }
+ }), {})
+ }, [addedSubs, subsData])
const [,, editThreshold] = useCanEdit(item)
const EditInfo = editThreshold && item.payIn?.payInState === 'PAID'