diff --git a/supabase-replicator/supabase/seed.sql b/supabase-replicator/supabase/seed.sql
index 67d4c154fe..150ecab7ff 100644
--- a/supabase-replicator/supabase/seed.sql
+++ b/supabase-replicator/supabase/seed.sql
@@ -493,6 +493,14 @@ as $$
where user_seen_markets.user_id = uid
and user_seen_markets.contract_id = crf.contract_id
)
+ -- That has not been viewed as a card recently.
+ and not exists (
+ select 1 from user_events
+ where user_events.user_id = uid
+ and user_events.data->>'name' = 'view market card'
+ and user_events.data->>'contractId' = crf.contract_id
+ and user_events.ts > now() - interval '1 day'
+ )
order by dot(urf, crf) desc
$$;
@@ -501,12 +509,15 @@ returns JSONB[]
immutable parallel safe
language sql
as $$
- select array_agg(data) as data_array
- from get_recommended_contract_ids(uid, count)
- left join contracts
- on contracts.id = contract_id
- -- Not resolved.
- where not (data->>'isResolved')::boolean
- -- Not closed: closeTime is greater than now.
- and (data->>'closeTime')::bigint > extract(epoch from now()) * 1000
+ select array_agg(data) from (
+ select data
+ from get_recommended_contract_ids(uid)
+ left join contracts
+ on contracts.id = contract_id
+ -- Not resolved.
+ where not (data->>'isResolved')::boolean
+ -- Not closed: closeTime is greater than now.
+ and (data->>'closeTime')::bigint > extract(epoch from now()) * 1000
+ limit count
+ ) as rec_contracts
$$;
diff --git a/web/hooks/use-feed.ts b/web/hooks/use-feed.ts
index 8f8c20e6db..f8f5d3d8e4 100644
--- a/web/hooks/use-feed.ts
+++ b/web/hooks/use-feed.ts
@@ -1,29 +1,40 @@
+import { uniqBy } from 'lodash'
import { Contract } from 'common/contract'
import { User } from 'common/user'
-import { useEffect } from 'react'
+import { useCallback, useEffect } from 'react'
import { usePersistentState, inMemoryStore } from './use-persistent-state'
import { db } from 'web/lib/supabase/db'
+import { buildArray } from 'common/util/array'
-export const useFeed = (user: User | null | undefined, count: number) => {
+const PAGE_SIZE = 10
+
+export const useFeed = (user: User | null | undefined, key: string) => {
const [savedContracts, setSavedContracts] = usePersistentState<
Contract[] | undefined
>(undefined, {
- key: `recommended-contracts-${user?.id}-${count}`,
+ key: `recommended-contracts-${user?.id}-${key}`,
store: inMemoryStore(),
})
const userId = user?.id
- useEffect(() => {
+ const loadMore = useCallback(() => {
if (userId) {
- db.rpc('get_recommended_contracts' as any, { uid: userId, count }).then(
- (res) => {
- const contracts = res.data as Contract[]
- setSavedContracts(contracts)
- }
- )
+ db.rpc('get_recommended_contracts' as any, {
+ uid: userId,
+ count: PAGE_SIZE,
+ }).then((res) => {
+ const newContracts = res.data as Contract[] | undefined
+ setSavedContracts((contracts) =>
+ uniqBy(buildArray(contracts, newContracts), (c) => c.id)
+ )
+ })
}
- }, [setSavedContracts, userId, count])
+ }, [userId, setSavedContracts])
+
+ useEffect(() => {
+ loadMore()
+ }, [loadMore])
- return savedContracts
+ return { contracts: savedContracts, loadMore }
}
diff --git a/web/pages/home/index.tsx b/web/pages/home/index.tsx
index 754520a32b..8bff60a01f 100644
--- a/web/pages/home/index.tsx
+++ b/web/pages/home/index.tsx
@@ -380,18 +380,14 @@ const YourFeedSection = (props: { user: User }) => {
onVisibilityUpdated={(visible) => visible && setHasViewedBottom(true)}
/>
- {hasViewedBottom ? (
-
- ) : (
-
- )}
+ {hasViewedBottom ? : }
)
}
-export const DiscoverFeed = (props: { user: User; count: number }) => {
- const { user, count } = props
- const contracts = useFeed(user, count)
+export const DiscoverFeed = (props: { user: User }) => {
+ const { user } = props
+ const { contracts, loadMore } = useFeed(user, 'home')
if (!contracts) return
return (
@@ -399,6 +395,7 @@ export const DiscoverFeed = (props: { user: User; count: number }) => {
contracts={contracts}
showImageOnTopContract
trackCardViews={true}
+ loadMore={loadMore}
/>
)
}
diff --git a/web/pages/swipe/index.tsx b/web/pages/swipe/index.tsx
index a5cb3b09cd..d1a9ccb2b4 100644
--- a/web/pages/swipe/index.tsx
+++ b/web/pages/swipe/index.tsx
@@ -37,7 +37,8 @@ export default function Swipe() {
})
const user = useUser()
- const feed = useFeed(user, 400)?.filter((c) => c.outcomeType === 'BINARY') as
+ const { contracts, loadMore } = useFeed(user, 'swipe')
+ const feed = contracts?.filter((c) => c.outcomeType === 'BINARY') as
| BinaryContract[]
| undefined
@@ -45,6 +46,13 @@ export default function Swipe() {
key: 'swipe-index',
store: inMemoryStore(),
})
+
+ useEffect(() => {
+ if (feed && index + 2 >= feed.length) {
+ loadMore()
+ }
+ }, [feed, index, loadMore])
+
const contract = feed ? feed[index] : undefined
const cards = useMemo(() => {