feat: add feed event url support

This commit is contained in:
moonrailgun 2024-09-02 23:42:34 +08:00
parent 01d774d395
commit 8534ab7ba0
9 changed files with 42 additions and 19 deletions

View File

@ -110,7 +110,7 @@ export const FeedArchivePageButton: React.FC<FeedArchivePageButtonProps> =
<Button <Button
size="icon" size="icon"
variant="secondary" variant="secondary"
className="absolute right-0 top-0 h-6 w-6 overflow-hidden" className="h-6 w-6 overflow-hidden"
onClick={() => handleUnArchive(item)} onClick={() => handleUnArchive(item)}
> >
<LuArchiveRestore size={12} /> <LuArchiveRestore size={12} />

View File

@ -33,7 +33,7 @@ export const FeedEventItem: React.FC<{
</div> </div>
</div> </div>
{actions} <div className="absolute right-0 top-0 flex gap-1">{actions}</div>
<div className="flex justify-between"> <div className="flex justify-between">
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">

View File

@ -12,7 +12,13 @@ import { useTranslation } from '@i18next-toolkit/react';
import { createFileRoute, useNavigate } from '@tanstack/react-router'; import { createFileRoute, useNavigate } from '@tanstack/react-router';
import { useEvent } from '@/hooks/useEvent'; import { useEvent } from '@/hooks/useEvent';
import { AlertConfirm } from '@/components/AlertConfirm'; import { AlertConfirm } from '@/components/AlertConfirm';
import { LuArchive, LuPencil, LuTrash, LuWebhook } from 'react-icons/lu'; import {
LuArchive,
LuLink,
LuPencil,
LuTrash,
LuWebhook,
} from 'react-icons/lu';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { FeedApiGuide } from '@/components/feed/FeedApiGuide'; import { FeedApiGuide } from '@/components/feed/FeedApiGuide';
import { FeedEventItem } from '@/components/feed/FeedEventItem'; import { FeedEventItem } from '@/components/feed/FeedEventItem';
@ -156,14 +162,27 @@ function PageComponent() {
className="animate-fade-in mb-2" className="animate-fade-in mb-2"
event={item} event={item}
actions={ actions={
<>
{item.url && (
<Button <Button
size="icon" size="icon"
variant="secondary" variant="secondary"
className="absolute right-0 top-0 h-6 w-6 overflow-hidden" className="h-6 w-6 overflow-hidden"
onClick={() => window.open(item.url)}
>
<LuLink size={12} />
</Button>
)}
<Button
size="icon"
variant="secondary"
className="h-6 w-6 overflow-hidden"
onClick={() => handleArchive(item)} onClick={() => handleArchive(item)}
> >
<LuArchive size={12} /> <LuArchive size={12} />
</Button> </Button>
</>
} }
/> />
)} )}

View File

@ -12,6 +12,7 @@ import {
} from '../../prisma/zod/index.js'; } from '../../prisma/zod/index.js';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { z } from 'zod'; import { z } from 'zod';
import { compact } from 'lodash-es';
const { get: getFeedEventNotify, del: delFeedEventNotifyCache } = const { get: getFeedEventNotify, del: delFeedEventNotifyCache } =
buildQueryWithCache(async (channelId: string) => { buildQueryWithCache(async (channelId: string) => {
@ -80,9 +81,12 @@ export async function sendFeedEventsNotify(
const eventTokens: ContentToken[] = [ const eventTokens: ContentToken[] = [
token.list( token.list(
events.map((event) => events.map((event) =>
compact([
token.text( token.text(
`[${event.source}:${event.eventName}] ${event.senderName ?? ''}: ${event.eventContent}` `[${event.source}:${event.eventName}] ${event.senderName ?? ''}: ${event.eventContent}`
) ),
event.url && token.url(event.url, '[→]'),
])
) )
), ),
]; ];

View File

@ -41,7 +41,7 @@ export const token = {
url, url,
title, title,
}), }),
list: (items: ContentToken[]): ListContentToken => ({ list: (items: ContentToken[][]): ListContentToken => ({
type: 'list', type: 'list',
items, items,
}), }),

View File

@ -35,7 +35,7 @@ export class BaseContentTokenizer {
} }
parseList(token: ListContentToken) { parseList(token: ListContentToken) {
return token.items.map((item) => this.parse([item])).join('\n'); return token.items.map((tokens) => this.parse(tokens)).join('\n');
} }
parse(tokens: ContentToken[]): string { parse(tokens: ContentToken[]): string {

View File

@ -40,6 +40,6 @@ export class HTMLContentTokenizer extends BaseContentTokenizer {
} }
parseList(token: ListContentToken) { parseList(token: ListContentToken) {
return `<ul>${token.items.map((item) => `<li>${this.parse([item])}</li>`).join('')}</ul>`; return `<ul>${token.items.map((tokens) => `<li>${this.parse(tokens)}</li>`).join('')}</ul>`;
} }
} }

View File

@ -37,7 +37,7 @@ export class MarkdownContentTokenizer extends BaseContentTokenizer {
parseList(token: ListContentToken) { parseList(token: ListContentToken) {
return ( return (
'\n' + '\n' +
token.items.map((item) => `- ${this.parse([item])}`).join('\n') + token.items.map((tokens) => `- ${this.parse(tokens)}`).join('\n') +
'\n' '\n'
); );
} }

View File

@ -31,7 +31,7 @@ export type UrlContentToken = {
export type ListContentToken = { export type ListContentToken = {
type: 'list'; type: 'list';
items: ContentToken[]; items: ContentToken[][];
}; };
export type ContentToken = export type ContentToken =