From 4bb33da27f6246f572bd86d04516ef81d70a2f4b Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Thu, 30 May 2024 13:43:12 +0800 Subject: [PATCH 01/10] add just added section to home --- packages/api/src/generated/graphql.ts | 4 +- packages/api/src/generated/schema.graphql | 2 +- packages/api/src/jobs/update_home.ts | 158 +++++++++++++++------- packages/api/src/schema.ts | 2 +- 4 files changed, 110 insertions(+), 56 deletions(-) diff --git a/packages/api/src/generated/graphql.ts b/packages/api/src/generated/graphql.ts index 158adacca..23b96e9fa 100644 --- a/packages/api/src/generated/graphql.ts +++ b/packages/api/src/generated/graphql.ts @@ -1324,7 +1324,7 @@ export type HomeItemSource = { __typename?: 'HomeItemSource'; icon?: Maybe; id?: Maybe; - name: Scalars['String']; + name?: Maybe; type: HomeItemSourceType; url?: Maybe; }; @@ -6117,7 +6117,7 @@ export type HomeItemResolvers = { icon?: Resolver, ParentType, ContextType>; id?: Resolver, ParentType, ContextType>; - name?: Resolver; + name?: Resolver, ParentType, ContextType>; type?: Resolver; url?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; diff --git a/packages/api/src/generated/schema.graphql b/packages/api/src/generated/schema.graphql index 18a8fca83..ab28f495b 100644 --- a/packages/api/src/generated/schema.graphql +++ b/packages/api/src/generated/schema.graphql @@ -1192,7 +1192,7 @@ type HomeItem { type HomeItemSource { icon: String id: ID - name: String! + name: String type: HomeItemSourceType! url: String } diff --git a/packages/api/src/jobs/update_home.ts b/packages/api/src/jobs/update_home.ts index 5b5e46aa8..29d1ca477 100644 --- a/packages/api/src/jobs/update_home.ts +++ b/packages/api/src/jobs/update_home.ts @@ -104,19 +104,55 @@ const publicItemToCandidate = (item: PublicItem): Candidate => ({ score: 0, }) -const selectCandidates = async (user: User): Promise> => { - const userId = user.id - // get last 100 library items saved and not seen by user +const getJustAddedCandidates = async ( + userId: string, + limit = 100 +): Promise> => { const libraryItems = await searchLibraryItems( { - size: 100, + size: limit, includeContent: false, - query: `-is:seen wordsCount:>0`, + query: `in:inbox saved:last24hrs -is:seen`, }, userId ) - logger.info(`Found ${libraryItems.length} library items`) + logger.info(`Found ${libraryItems.length} just added library items`) + + // get subscriptions for the library items + const subscriptionNames = libraryItems + .filter((item) => !!item.subscription) + .map((item) => item.subscription as string) + + const subscriptions = await findSubscriptionsByNames( + userId, + subscriptionNames + ) + + // map library items to candidates + const justAddedCandidates: Array = libraryItems.map((item) => + libraryItemToCandidate(item, subscriptions) + ) + + return justAddedCandidates +} + +const selectCandidates = async ( + user: User, + limit = 100 +): Promise> => { + const userId = user.id + // get last 100 library items saved and not seen by user + const libraryItems = await searchLibraryItems( + { + size: limit, + includeContent: false, + query: `in:inbox -saved:last24hrs -is:seen`, + }, + userId + ) + + logger.info(`Found ${libraryItems.length} not just added library items`) // get subscriptions for the library items const subscriptionNames = libraryItems @@ -290,27 +326,10 @@ const appendSectionsToHome = async ( await pipeline.exec() } -const mixHomeItems = (rankedHomeItems: Array): Array
=> { - // find the median word count - const wordCounts = rankedHomeItems.map((item) => item.wordCount) - wordCounts.sort((a, b) => a - b) - const medianWordCount = wordCounts[Math.floor(wordCounts.length / 2)] - // separate items into two groups based on word count - const shortItems: Array = [] - const longItems: Array = [] - for (const item of rankedHomeItems) { - if (item.wordCount < medianWordCount) { - shortItems.push(item) - } else { - longItems.push(item) - } - } - // initialize empty batches - const batches: Array> = Array.from( - { length: Math.floor(rankedHomeItems.length / 10) }, - () => [] - ) - +const mixHomeItems = ( + justAddedCandidates: Array, + rankedHomeItems: Array +): Array
=> { const checkConstraints = (batch: Array, item: Candidate) => { const titleCount = batch.filter((i) => i.title === item.title).length const authorCount = batch.filter((i) => i.author === item.author).length @@ -328,14 +347,22 @@ const mixHomeItems = (rankedHomeItems: Array): Array
=> { ) } + const candidateToItem = (candidate: Candidate): Item => ({ + id: candidate.id, + type: candidate.type, + score: candidate.score, + }) + const distributeItems = ( items: Array, batches: Array> ) => { + const batchSize = Math.ceil(items.length / batches.length) + for (const item of items) { let added = false for (const batch of batches) { - if (batch.length < 5 && checkConstraints(batch, item)) { + if (batch.length < batchSize && checkConstraints(batch, item)) { batch.push(item) added = true break @@ -344,7 +371,7 @@ const mixHomeItems = (rankedHomeItems: Array): Array
=> { if (!added) { for (const batch of batches) { - if (batch.length < 10) { + if (batch.length < batchSize) { batch.push(item) break } @@ -353,31 +380,51 @@ const mixHomeItems = (rankedHomeItems: Array): Array
=> { } } - // distribute quick link items first - distributeItems(shortItems, batches) - distributeItems(longItems, batches) + // find the median word count + const wordCounts = rankedHomeItems.map((item) => item.wordCount) + wordCounts.sort((a, b) => a - b) + const medianWordCount = wordCounts[Math.floor(wordCounts.length / 2)] + // separate items into two groups based on word count + const shortItems: Array = [] + const longItems: Array = [] + for (const item of rankedHomeItems) { + if (item.wordCount < medianWordCount) { + shortItems.push(item) + } else { + longItems.push(item) + } + } + + // initialize empty batches + const numOfBatches = 10 + const batches = { + short: Array.from({ length: numOfBatches }, () => []) as Array< + Array + >, + long: Array.from({ length: numOfBatches }, () => []) as Array< + Array + >, + } + + distributeItems(shortItems, batches.short) + distributeItems(longItems, batches.long) // convert batches to sections const sections = [] - for (const batch of batches) { - // create a section for all quick links - sections.push({ - items: batch.slice(0, 5).map((item) => ({ - id: item.id, - type: item.type, - score: item.score, - })), - layout: 'quick links', - }) + sections.push({ + items: batches.short.flat().map(candidateToItem), + layout: 'quick links', + }) - // create a section for each long item - sections.push( - ...batch.slice(5).map((item) => ({ - items: [{ id: item.id, type: item.type, score: item.score }], - layout: 'long', - })) - ) - } + sections.push({ + items: batches.long.flat().map(candidateToItem), + layout: 'long', + }) + + sections.push({ + items: justAddedCandidates.map(candidateToItem), + layout: 'just added', + }) return sections } @@ -395,6 +442,13 @@ export const updateHome = async (data: UpdateHomeJobData) => { logger.info(`Updating home for user ${userId}`) + logger.profile('justAdded') + const justAddedCandidates = await getJustAddedCandidates(userId) + logger.profile('justAdded', { + level: 'info', + message: `Found ${justAddedCandidates.length} just added candidates`, + }) + logger.profile('selecting') const candidates = await selectCandidates(user) logger.profile('selecting', { @@ -402,7 +456,7 @@ export const updateHome = async (data: UpdateHomeJobData) => { message: `Found ${candidates.length} candidates`, }) - if (candidates.length === 0) { + if (!justAddedCandidates.length && !candidates.length) { logger.info('No candidates found') return } @@ -419,7 +473,7 @@ export const updateHome = async (data: UpdateHomeJobData) => { // TODO: filter candidates logger.profile('mixing') - const rankedSections = mixHomeItems(rankedCandidates) + const rankedSections = mixHomeItems(justAddedCandidates, rankedCandidates) logger.profile('mixing', { level: 'info', message: `Created ${rankedSections.length} sections`, diff --git a/packages/api/src/schema.ts b/packages/api/src/schema.ts index 329961d37..1821ab37a 100755 --- a/packages/api/src/schema.ts +++ b/packages/api/src/schema.ts @@ -3121,7 +3121,7 @@ const schema = gql` type HomeItemSource { id: ID - name: String! + name: String url: String icon: String type: HomeItemSourceType! From 4a54fa31af2345fe0ed312e50ab7775dc06bc650 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Thu, 30 May 2024 13:51:43 +0800 Subject: [PATCH 02/10] show just added section in home page --- packages/web/pages/justread/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/web/pages/justread/index.tsx b/packages/web/pages/justread/index.tsx index 62355e78c..f62884e89 100644 --- a/packages/web/pages/justread/index.tsx +++ b/packages/web/pages/justread/index.tsx @@ -58,6 +58,7 @@ export default function Home(): JSX.Element { > {homeData.sections?.map((homeSection, idx) => { switch (homeSection.layout) { + case 'just added': case 'long': return ( Date: Thu, 30 May 2024 14:34:08 +0800 Subject: [PATCH 03/10] trigger update home job once a new item is scored --- packages/api/src/jobs/score_library_item.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/api/src/jobs/score_library_item.ts b/packages/api/src/jobs/score_library_item.ts index 7080d0ea0..d5f44ce9b 100644 --- a/packages/api/src/jobs/score_library_item.ts +++ b/packages/api/src/jobs/score_library_item.ts @@ -3,6 +3,7 @@ import { updateLibraryItem, } from '../services/library_item' import { Feature, getScores } from '../services/score' +import { enqueueUpdateHomeJob } from '../utils/createTask' import { lanaugeToCode } from '../utils/helpers' import { logger } from '../utils/logger' @@ -81,4 +82,9 @@ export const scoreLibraryItem = async ( true ) logger.info('Library item scored', data) + + await enqueueUpdateHomeJob({ + userId, + cursor: Date.now(), + }) } From bc4951f376f8fbfebebe1939a87ee787e333207d Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Thu, 30 May 2024 15:39:04 +0800 Subject: [PATCH 04/10] do not fail score job if failed to enqueue updating home job --- packages/api/src/jobs/score_library_item.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/api/src/jobs/score_library_item.ts b/packages/api/src/jobs/score_library_item.ts index d5f44ce9b..0dc3152dc 100644 --- a/packages/api/src/jobs/score_library_item.ts +++ b/packages/api/src/jobs/score_library_item.ts @@ -83,8 +83,11 @@ export const scoreLibraryItem = async ( ) logger.info('Library item scored', data) - await enqueueUpdateHomeJob({ - userId, - cursor: Date.now(), - }) + try { + await enqueueUpdateHomeJob({ + userId, + }) + } catch (error) { + logger.error('Failed to enqueue update home job', error) + } } From 8dfd8763925952f26bcd202a0a261fd40f2dcc52 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Thu, 30 May 2024 15:48:28 +0800 Subject: [PATCH 05/10] limit to 5 just added items --- packages/api/src/jobs/update_home.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/api/src/jobs/update_home.ts b/packages/api/src/jobs/update_home.ts index 29d1ca477..ac28ffcac 100644 --- a/packages/api/src/jobs/update_home.ts +++ b/packages/api/src/jobs/update_home.ts @@ -106,7 +106,7 @@ const publicItemToCandidate = (item: PublicItem): Candidate => ({ const getJustAddedCandidates = async ( userId: string, - limit = 100 + limit = 5 // limit to 5 just added candidates ): Promise> => { const libraryItems = await searchLibraryItems( { From d349c1867f95df78e93f00ce8fb6cbe33096f26d Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Thu, 30 May 2024 15:48:57 +0800 Subject: [PATCH 06/10] add section title --- packages/api/src/resolvers/function_resolvers.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/api/src/resolvers/function_resolvers.ts b/packages/api/src/resolvers/function_resolvers.ts index d4692561f..524c70a58 100644 --- a/packages/api/src/resolvers/function_resolvers.ts +++ b/packages/api/src/resolvers/function_resolvers.ts @@ -635,6 +635,20 @@ export const functionResolvers = { }, }, HomeSection: { + title: (section: { title?: string; layout: string }) => { + if (section.title) return section.title + + switch (section.layout) { + case 'just added': + return 'Just Added' + case 'long': + return 'Long Reads' + case 'quick links': + return 'Quick Links' + default: + return '' + } + }, async items( section: { items: Array<{ From 633a022825adc4cd7b936c15f4a96ffdcf17cb7a Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Thu, 30 May 2024 17:36:18 +0800 Subject: [PATCH 07/10] add client side pagination --- packages/api/src/jobs/update_home.ts | 4 +- .../web/components/elements/Pagination.tsx | 48 ++++ packages/web/pages/justread/index.tsx | 213 ++++++++++++++++-- 3 files changed, 245 insertions(+), 20 deletions(-) create mode 100644 packages/web/components/elements/Pagination.tsx diff --git a/packages/api/src/jobs/update_home.ts b/packages/api/src/jobs/update_home.ts index ac28ffcac..bf2ccc7ea 100644 --- a/packages/api/src/jobs/update_home.ts +++ b/packages/api/src/jobs/update_home.ts @@ -319,8 +319,8 @@ const appendSectionsToHome = async ( const ttl = 86_400_000 pipeline.zremrangebyscore(key, '-inf', Date.now() - ttl) - // keep only the top MAX_FEED_ITEMS items - pipeline.zremrangebyrank(key, 0, -(MAX_FEED_ITEMS + 1)) + // keep only the new sections and remove the oldest ones + pipeline.zremrangebyrank(key, 0, -(sections.length + 1)) logger.info('Adding home sections to redis') await pipeline.exec() diff --git a/packages/web/components/elements/Pagination.tsx b/packages/web/components/elements/Pagination.tsx new file mode 100644 index 000000000..595f130ec --- /dev/null +++ b/packages/web/components/elements/Pagination.tsx @@ -0,0 +1,48 @@ +import React, { useState } from 'react' +import { Button } from './Button' +import { HStack, VStack } from './LayoutPrimitives' + +type PaginationProps = { + items: T[] + itemsPerPage: number + render: (item: T) => React.ReactNode +} + +const Pagination = ({ + items, + itemsPerPage, + render, +}: PaginationProps) => { + const [currentPage, setCurrentPage] = useState(1) + const maxPage = Math.ceil(items.length / itemsPerPage) + + function createChangePageHandler(page: number) { + return function handlePageChange() { + setCurrentPage(page) + } + } + + const itemsToShow = items.slice( + (currentPage - 1) * itemsPerPage, + currentPage * itemsPerPage + ) + + return ( + + {itemsToShow.map(render)} + + {Array.from({ length: maxPage }, (_, i) => i + 1).map((pageNum) => ( + + ))} + + + ) +} + +export default Pagination diff --git a/packages/web/pages/justread/index.tsx b/packages/web/pages/justread/index.tsx index f62884e89..45c767a38 100644 --- a/packages/web/pages/justread/index.tsx +++ b/packages/web/pages/justread/index.tsx @@ -1,18 +1,17 @@ +import * as HoverCard from '@radix-ui/react-hover-card' import { styled } from '@stitches/react' +import { useRouter } from 'next/router' +import { useMemo } from 'react' +import { Button } from '../../components/elements/Button' import { AddToLibraryActionIcon } from '../../components/elements/icons/home/AddToLibraryActionIcon' import { ArchiveActionIcon } from '../../components/elements/icons/home/ArchiveActionIcon' import { CommentActionIcon } from '../../components/elements/icons/home/CommentActionIcon' import { RemoveActionIcon } from '../../components/elements/icons/home/RemoveActionIcon' import { ShareActionIcon } from '../../components/elements/icons/home/ShareActionIcon' +import Pagination from '../../components/elements/Pagination' +import { timeAgo } from '../../components/patterns/LibraryCards/LibraryCardStyles' +import { theme } from '../../components/tokens/stitches.config' import { useApplyLocalTheme } from '../../lib/hooks/useApplyLocalTheme' -import { - HStack, - SpanBox, - VStack, -} from './../../components/elements/LayoutPrimitives' - -import * as HoverCard from '@radix-ui/react-hover-card' -import { Button } from '../../components/elements/Button' import { HomeItem, HomeItemSource, @@ -20,14 +19,15 @@ import { HomeSection, useGetHomeItems, } from '../../lib/networking/queries/useGetHome' -import { timeAgo } from '../../components/patterns/LibraryCards/LibraryCardStyles' -import { theme } from '../../components/tokens/stitches.config' -import { useRouter } from 'next/router' import { SubscriptionType, useGetSubscriptionsQuery, } from '../../lib/networking/queries/useGetSubscriptionsQuery' -import { useMemo } from 'react' +import { + HStack, + SpanBox, + VStack, +} from './../../components/elements/LayoutPrimitives' export default function Home(): JSX.Element { const homeData = useGetHomeItems() @@ -59,6 +59,12 @@ export default function Home(): JSX.Element { {homeData.sections?.map((homeSection, idx) => { switch (homeSection.layout) { case 'just added': + return ( + + ) case 'long': return ( ) + case 'quick links': + return ( + + ) } })} @@ -77,13 +90,92 @@ type HomeSectionProps = { homeSection: HomeSection } +const JustReadHomeSection = (props: HomeSectionProps): JSX.Element => { + return ( + + + {props.homeSection.title} + + + {props.homeSection.items.map((homeItem) => { + return + })} + + ) +} + const LongHomeSection = (props: HomeSectionProps): JSX.Element => { return ( - - {props.homeSection.items.map((homeItem) => { - return - })} - + + + {props.homeSection.title} + + + ( + + )} + /> + + ) +} + +const QuickLinksHomeSection = (props: HomeSectionProps): JSX.Element => { + return ( + + + {props.homeSection.title} + + + ( + + )} + /> + ) } @@ -130,7 +222,59 @@ const Title = (props: HomeItemViewProps): JSX.Element => { ) } -const HomeItemView = (props: HomeItemViewProps): JSX.Element => { +const JustReadItemView = (props: HomeItemViewProps): JSX.Element => { + const router = useRouter() + + return ( + { + if (event.metaKey || event.ctrlKey) { + window.open(props.homeItem.url, '_blank') + } else { + router.push(props.homeItem.url) + } + }} + > + + + + + + + + </VStack> + <SpanBox css={{ ml: 'auto' }}> + {props.homeItem.thumbnail && ( + <CoverImage + css={{ + mt: '6px', + width: '120px', + height: '70px', + borderRadius: '4px', + }} + src={props.homeItem.thumbnail} + ></CoverImage> + )} + </SpanBox> + </HStack> + </VStack> + ) +} + +const LongHomeItemView = (props: HomeItemViewProps): JSX.Element => { const router = useRouter() return ( @@ -204,6 +348,39 @@ const HomeItemView = (props: HomeItemViewProps): JSX.Element => { ) } +const QuickLinkHomeItemView = (props: HomeItemViewProps): JSX.Element => { + const router = useRouter() + + return ( + <VStack + css={{ + width: '100%', + padding: '10px', + borderRadius: '5px', + '&:hover': { + bg: '$thBackground', + borderRadius: '0px', + }, + }} + onClick={(event) => { + if (event.metaKey || event.ctrlKey) { + window.open(props.homeItem.url, '_blank') + } else { + router.push(props.homeItem.url) + } + }} + > + <TimeAgo homeItem={props.homeItem} /> + <Title homeItem={props.homeItem} /> + <SpanBox + css={{ fontFamily: '$inter', fontSize: '13px', lineHeight: '23px' }} + > + {props.homeItem.previewContent} + </SpanBox> + </VStack> + ) +} + const SiteIconSmall = styled('img', { width: '16px', height: '16px', From 1af6cfa54917e8d6f004843ee1314d1e172abe19 Mon Sep 17 00:00:00 2001 From: Hongbo Wu <hongbo@omnivore.app> Date: Fri, 31 May 2024 11:51:30 +0800 Subject: [PATCH 08/10] rename long section to for you --- packages/api/src/jobs/update_home.ts | 7 ++++--- packages/api/src/resolvers/function_resolvers.ts | 4 ++-- packages/web/pages/justread/index.tsx | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/api/src/jobs/update_home.ts b/packages/api/src/jobs/update_home.ts index bf2ccc7ea..be4bf36b3 100644 --- a/packages/api/src/jobs/update_home.ts +++ b/packages/api/src/jobs/update_home.ts @@ -112,7 +112,8 @@ const getJustAddedCandidates = async ( { size: limit, includeContent: false, - query: `in:inbox saved:last24hrs -is:seen`, + useFolders: true, // only show items in inbox folder + query: `in:inbox saved:"this week" -is:seen`, }, userId ) @@ -147,7 +148,7 @@ const selectCandidates = async ( { size: limit, includeContent: false, - query: `in:inbox -saved:last24hrs -is:seen`, + query: `in:inbox -is:seen`, }, userId ) @@ -418,7 +419,7 @@ const mixHomeItems = ( sections.push({ items: batches.long.flat().map(candidateToItem), - layout: 'long', + layout: 'for you', }) sections.push({ diff --git a/packages/api/src/resolvers/function_resolvers.ts b/packages/api/src/resolvers/function_resolvers.ts index 524c70a58..c938ac90c 100644 --- a/packages/api/src/resolvers/function_resolvers.ts +++ b/packages/api/src/resolvers/function_resolvers.ts @@ -641,8 +641,8 @@ export const functionResolvers = { switch (section.layout) { case 'just added': return 'Just Added' - case 'long': - return 'Long Reads' + case 'for you': + return 'For You' case 'quick links': return 'Quick Links' default: diff --git a/packages/web/pages/justread/index.tsx b/packages/web/pages/justread/index.tsx index 45c767a38..6dee8f785 100644 --- a/packages/web/pages/justread/index.tsx +++ b/packages/web/pages/justread/index.tsx @@ -65,9 +65,9 @@ export default function Home(): JSX.Element { homeSection={homeSection} /> ) - case 'long': + case 'for you': return ( - <LongHomeSection + <ForYouHomeSection key={`section-${idx}`} homeSection={homeSection} /> @@ -117,7 +117,7 @@ const JustReadHomeSection = (props: HomeSectionProps): JSX.Element => { ) } -const LongHomeSection = (props: HomeSectionProps): JSX.Element => { +const ForYouHomeSection = (props: HomeSectionProps): JSX.Element => { return ( <VStack distribution="start" From aa4e091c4b3112cf2d28b9a775e0556be94e82e1 Mon Sep 17 00:00:00 2001 From: Hongbo Wu <hongbo@omnivore.app> Date: Fri, 31 May 2024 12:00:30 +0800 Subject: [PATCH 09/10] exclude just added items from for you and quick links section --- packages/api/src/jobs/update_home.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/api/src/jobs/update_home.ts b/packages/api/src/jobs/update_home.ts index be4bf36b3..ab58a8077 100644 --- a/packages/api/src/jobs/update_home.ts +++ b/packages/api/src/jobs/update_home.ts @@ -140,6 +140,7 @@ const getJustAddedCandidates = async ( const selectCandidates = async ( user: User, + excludes: Array<string> = [], limit = 100 ): Promise<Array<Candidate>> => { const userId = user.id @@ -148,7 +149,7 @@ const selectCandidates = async ( { size: limit, includeContent: false, - query: `in:inbox -is:seen`, + query: `in:inbox -is:seen -includes:${excludes.join(',')}`, }, userId ) @@ -239,7 +240,6 @@ const rankCandidates = async ( } const redisKey = (userId: string) => `home:${userId}` -const MAX_FEED_ITEMS = 500 export const getHomeSections = async ( userId: string, @@ -451,7 +451,10 @@ export const updateHome = async (data: UpdateHomeJobData) => { }) logger.profile('selecting') - const candidates = await selectCandidates(user) + const candidates = await selectCandidates( + user, + justAddedCandidates.map((c) => c.id) + ) logger.profile('selecting', { level: 'info', message: `Found ${candidates.length} candidates`, From a6d27bea8dceb9bbdb29d402999a899ea30cb7a9 Mon Sep 17 00:00:00 2001 From: Hongbo Wu <hongbo@omnivore.app> Date: Fri, 31 May 2024 12:23:11 +0800 Subject: [PATCH 10/10] rename for you to top picks --- packages/api/src/jobs/update_home.ts | 8 ++++---- packages/api/src/resolvers/function_resolvers.ts | 8 ++++---- packages/web/pages/justread/index.tsx | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/api/src/jobs/update_home.ts b/packages/api/src/jobs/update_home.ts index ab58a8077..b94fed91a 100644 --- a/packages/api/src/jobs/update_home.ts +++ b/packages/api/src/jobs/update_home.ts @@ -113,7 +113,7 @@ const getJustAddedCandidates = async ( size: limit, includeContent: false, useFolders: true, // only show items in inbox folder - query: `in:inbox saved:"this week" -is:seen`, + query: `in:inbox saved:"this week"`, }, userId ) @@ -414,17 +414,17 @@ const mixHomeItems = ( const sections = [] sections.push({ items: batches.short.flat().map(candidateToItem), - layout: 'quick links', + layout: 'quick_links', }) sections.push({ items: batches.long.flat().map(candidateToItem), - layout: 'for you', + layout: 'top_picks', }) sections.push({ items: justAddedCandidates.map(candidateToItem), - layout: 'just added', + layout: 'just_added', }) return sections diff --git a/packages/api/src/resolvers/function_resolvers.ts b/packages/api/src/resolvers/function_resolvers.ts index c938ac90c..b9e7a4976 100644 --- a/packages/api/src/resolvers/function_resolvers.ts +++ b/packages/api/src/resolvers/function_resolvers.ts @@ -639,11 +639,11 @@ export const functionResolvers = { if (section.title) return section.title switch (section.layout) { - case 'just added': + case 'just_added': return 'Just Added' - case 'for you': - return 'For You' - case 'quick links': + case 'top_picks': + return 'Top Picks' + case 'quick_links': return 'Quick Links' default: return '' diff --git a/packages/web/pages/justread/index.tsx b/packages/web/pages/justread/index.tsx index 6dee8f785..baf33dedb 100644 --- a/packages/web/pages/justread/index.tsx +++ b/packages/web/pages/justread/index.tsx @@ -58,21 +58,21 @@ export default function Home(): JSX.Element { > {homeData.sections?.map((homeSection, idx) => { switch (homeSection.layout) { - case 'just added': + case 'just_added': return ( <JustReadHomeSection key={`section-${idx}`} homeSection={homeSection} /> ) - case 'for you': + case 'top_picks': return ( - <ForYouHomeSection + <TopPicksHomeSection key={`section-${idx}`} homeSection={homeSection} /> ) - case 'quick links': + case 'quick_links': return ( <QuickLinksHomeSection key={`section-${idx}`} @@ -117,7 +117,7 @@ const JustReadHomeSection = (props: HomeSectionProps): JSX.Element => { ) } -const ForYouHomeSection = (props: HomeSectionProps): JSX.Element => { +const TopPicksHomeSection = (props: HomeSectionProps): JSX.Element => { return ( <VStack distribution="start"