add RSS label to the following feed items

This commit is contained in:
Hongbo Wu
2023-11-17 18:26:00 +08:00
parent c5a97c7a41
commit e26ed0b6f0
7 changed files with 79 additions and 27 deletions

View File

@ -32,7 +32,10 @@ const convertToLabel = (label: CreateLabelInput, userId: string) => {
return {
user: { id: userId },
name: label.name,
color: label.color || generateRandomColor(), // assign a random color if not provided
color:
label.color ||
getInternalLabelWithColor(label.name)?.color ||
generateRandomColor(), // assign a random color if not provided
description: label.description,
internal: isLabelInternal(label.name),
}

View File

@ -1,5 +1,9 @@
/* eslint-disable @typescript-eslint/no-misused-promises */
import express from 'express'
import {
findOrCreateLabels,
saveLabelsInLibraryItem,
} from '../../services/labels'
import { saveFeedItemInFollowing } from '../../services/library_item'
import { logger } from '../../utils/logger'
@ -49,16 +53,40 @@ export function followingServiceRouter() {
return res.status(400).send('INVALID_REQUEST_BODY')
}
if (req.body.addedToFollowingFrom === 'feed') {
logger.info('saving feed item')
if (
req.body.addedToFollowingFrom === 'feed' &&
req.body.userIds.length > 0
) {
const userId = req.body.userIds[0]
logger.info('saving feed item', userId)
const result = await saveFeedItemInFollowing(req.body)
const result = await saveFeedItemInFollowing(req.body, userId)
if (result.identifiers.length === 0) {
logger.error('error saving feed item in following')
return res.status(500).send('ERROR_SAVING_FEED_ITEM')
}
logger.info('feed item saved in following')
// add RSS label to the item
const labels = await findOrCreateLabels(
[
{
name: 'RSS',
},
],
userId
)
await saveLabelsInLibraryItem(
labels,
result.identifiers[0].id,
userId,
undefined,
true
)
logger.info('RSS label added to the item')
return res.sendStatus(200)
}

View File

@ -69,7 +69,8 @@ export const saveLabelsInLibraryItem = async (
labels: Label[],
libraryItemId: string,
userId: string,
pubsub = createPubSubClient()
pubsub = createPubSubClient(),
skipPubSub = false
) => {
await authTrx(
async (tx) => {
@ -92,6 +93,10 @@ export const saveLabelsInLibraryItem = async (
userId
)
if (skipPubSub) {
return
}
// create pubsub event
await pubsub.entityCreated<AddLabelsToLibraryItemEvent>(
EntityType.LABEL,
@ -104,7 +109,8 @@ export const addLabelsToLibraryItem = async (
labels: Label[],
libraryItemId: string,
userId: string,
pubsub = createPubSubClient()
pubsub = createPubSubClient(),
skipPubSub = false
) => {
await authTrx(
async (tx) => {
@ -128,6 +134,10 @@ export const addLabelsToLibraryItem = async (
userId
)
if (skipPubSub) {
return
}
// create pubsub event
await pubsub.entityCreated<AddLabelsToLibraryItemEvent>(
EntityType.LABEL,

View File

@ -9,7 +9,6 @@ import { createPubSubClient, EntityType } from '../pubsub'
import { authTrx, getColumns } from '../repository'
import { libraryItemRepository } from '../repository/library_item'
import { SaveFollowingItemRequest } from '../routers/svc/following'
import { SetClaimsRole } from '../utils/dictionary'
import { generateSlug, wordsCount } from '../utils/helpers'
import {
DateFilter,
@ -248,7 +247,7 @@ const buildWhereClause = (
if (args.noFilters) {
args.noFilters.forEach((filter) => {
queryBuilder.andWhere(
`library_item.${filter.field} = '{}' OR library_item.${filter.field} IS NULL`
`(library_item.${filter.field} = '{}' OR library_item.${filter.field} IS NULL)`
)
})
}
@ -397,7 +396,6 @@ export const updateLibraryItem = async (
const updatedLibraryItem = await authTrx(
async (tx) => {
const itemRepo = tx.withRepository(libraryItemRepository)
await itemRepo.update(id, libraryItem)
// reset deletedAt and archivedAt
switch (libraryItem.state) {
@ -413,6 +411,7 @@ export const updateLibraryItem = async (
libraryItem.deletedAt = null
break
}
await itemRepo.update(id, libraryItem)
return itemRepo.findOneByOrFail({ id })
},
@ -551,31 +550,32 @@ export const createLibraryItem = async (
return newLibraryItem
}
export const saveFeedItemInFollowing = (input: SaveFollowingItemRequest) => {
export const saveFeedItemInFollowing = (
input: SaveFollowingItemRequest,
userId: string
) => {
return authTrx(
async (tx) => {
const libraryItems: QueryDeepPartialEntity<LibraryItem>[] =
input.userIds.map((userId) => ({
...input,
user: { id: userId },
originalUrl: input.url,
subscription: input.addedToFollowingBy,
folder: InFilter.FOLLOWING,
slug: generateSlug(input.title),
}))
const itemToSave: QueryDeepPartialEntity<LibraryItem> = {
...input,
user: { id: userId },
originalUrl: input.url,
subscription: input.addedToFollowingBy,
folder: InFilter.FOLLOWING,
slug: generateSlug(input.title),
}
return tx
.getRepository(LibraryItem)
.createQueryBuilder()
.insert()
.values(libraryItems)
.values(itemToSave)
.orIgnore() // ignore if the item already exists
.returning('*')
.execute()
},
undefined,
undefined,
SetClaimsRole.ADMIN
userId
)
}

View File

@ -273,5 +273,7 @@ export const parsedContentToLibraryItem = ({
contentReader: contentReaderForLibraryItem(itemType, uploadFileId),
subscription: rssFeedUrl,
folder: 'inbox',
archivedAt:
state === ArticleSavingRequestStatus.Archived ? new Date() : null,
}
}

View File

@ -692,7 +692,7 @@ describe('Article API', () => {
200
)
const item = await findLibraryItemById(itemId, user.id)
expect(item?.folder).to.eql('trash')
expect(item?.state).to.eql(LibraryItemState.Deleted)
})
})
@ -1153,12 +1153,12 @@ describe('Article API', () => {
})
})
context("when in:inbox label:test' is in the query", () => {
context('when in:inbox no:subscription label:test is in the query', () => {
let items: LibraryItem[] = []
let label: Label
before(async () => {
keyword = 'in:inbox label:test'
keyword = 'in:inbox no:subscription label:test'
// Create some test items
label = await createLabel('test', '', user.id)
items = await createLibraryItems(
@ -1170,6 +1170,14 @@ describe('Article API', () => {
slug: 'test slug 1',
originalUrl: `${url}/test1`,
},
{
user,
title: 'test title 2',
readableContent: '<p>test 2</p>',
slug: 'test slug 2',
originalUrl: `${url}/test2`,
subscription: 'test subscription',
},
{
user,
title: 'test title 3',
@ -1184,6 +1192,7 @@ describe('Article API', () => {
)
await saveLabelsInLibraryItem([label], items[0].id, user.id)
await saveLabelsInLibraryItem([label], items[1].id, user.id)
await saveLabelsInLibraryItem([label], items[2].id, user.id)
})
after(async () => {

View File

@ -242,9 +242,9 @@ function Subscriptions(
{!collapsed ? (
<>
<FilterButton filterTerm="in:inbox has:subscriptions" text="All" {...props} />
<FilterButton filterTerm={`label:RSS`} text="Feeds" {...props} />
<FilterButton filterTerm={`in:inbox label:RSS`} text="Feeds" {...props} />
<FilterButton
filterTerm={`label:Newsletter`}
filterTerm={`in:inbox label:Newsletter`}
text="Newsletters"
{...props}
/>