Skip to content

Commit

Permalink
feat: add different output method choice (#202)
Browse files Browse the repository at this point in the history
* feat: add different output method choice

* refa: push plain elements instead of wrapped with Fragment

* feat: add fake author

* feat: add fake author
  • Loading branch information
MaikoTan authored Mar 23, 2024
1 parent 76f4bd8 commit 4468630
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 55 deletions.
130 changes: 75 additions & 55 deletions packages/core/src/command.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,10 @@ export function apply(ctx: Context, config: Config) {

if (!filtered?.length) return session?.text('.no-result')

const output: Element[] = []
const output: Element[][] = []

for (const image of filtered) {
const children: Element[] = []
let url = ''
for (const size of preferSizes.slice(preferSizes.indexOf(config.preferSize))) {
url = image.urls?.[size]
Expand All @@ -83,7 +84,7 @@ export function apply(ctx: Context, config: Config) {
const tips = getTips(session)
if (tips) {
const tip = Random.pick(tips)
output.unshift(
children.unshift(
<p>
<i18n path='.tips'></i18n>
<i18n path={tip}></i18n>
Expand All @@ -95,83 +96,102 @@ export function apply(ctx: Context, config: Config) {
if (config.asset && ctx.assets) {
url = await ctx.booru.imgUrlToAssetUrl(url)
if (!url) {
output.unshift(<i18n path='.no-image'></i18n>)
children.unshift(<i18n path='.no-image'></i18n>)
continue
}
} else if (config.base64) {
url = await ctx.booru.imgUrlToBase64(url)
if (!url) {
output.unshift(<i18n path='.no-image'></i18n>)
children.unshift(<i18n path='.no-image'></i18n>)
continue
}
}
switch (config.output) {
case OutputType.All:
if (image.tags)
output.unshift(
<message>
<p>
<i18n path='.output.source'>{[source]}</i18n>
</p>
<p>
<i18n path='.output.tags'>{[image.tags.join(', ')]}</i18n>
</p>
</message>,
children.unshift(
<p>
<i18n path='.output.source'>{[source]}</i18n>
</p>,
<p>
<i18n path='.output.tags'>{[image.tags.join(', ')]}</i18n>
</p>,
)
case OutputType.ImageAndLink:
case OutputType.ImageAndInfo:
if (image.title || image.author || image.desc)
output.unshift(
<message>
<p>
{config.output >= OutputType.ImageAndLink && image.pageUrl ? (
<a href={image.pageUrl}>{image.title}</a>
) : (
image.title
)}
</p>
<p>
{config.output >= OutputType.ImageAndLink && image.authorUrl ? (
<a href={image.authorUrl}>
<i18n path='.output.author'>{[image.author]}</i18n>
</a>
) : (
children.unshift(
<p>
{config.output >= OutputType.ImageAndLink && image.pageUrl ? (
<a href={image.pageUrl}>{image.title}</a>
) : (
image.title
)}
</p>,
<p>
{config.output >= OutputType.ImageAndLink && image.authorUrl ? (
<a href={image.authorUrl}>
<i18n path='.output.author'>{[image.author]}</i18n>
)}
</p>
<p>
<i18n path='.output.desc'>{[image.desc]}</i18n>
</p>
</message>,
</a>
) : (
<i18n path='.output.author'>{[image.author]}</i18n>
)}
</p>,
<p>
<i18n path='.output.desc'>{[image.desc]}</i18n>
</p>,
)
case OutputType.ImageOnly:
output.unshift(
children.unshift(
/**
* @TODO waiting for upstream to support spoiler tag
* but is only is attribute, so it's can work now.
*/
<message>
<img
spoiler={(() => {
switch (config.spoiler) {
case SpoilerType.Disabled:
return false
case SpoilerType.All:
return true
case SpoilerType.OnlyNSFW:
return Boolean(image.nsfw)
}
})()}
src={url}
></img>
</message>,

<img
spoiler={(() => {
switch (config.spoiler) {
case SpoilerType.Disabled:
return false
case SpoilerType.All:
return true
case SpoilerType.OnlyNSFW:
return Boolean(image.nsfw)
}
})()}
src={url}
></img>,
)
}
output.push(children)
}

switch (session.resolve(config.outputMethod)) {
case 'one-by-one':
return output.map((children) => <message>{children}</message>)
case 'merge-multiple':
return <message>{output.map((children) => children)}</message>
case 'forward-all':
return (
<message forward>
{/* Use <author> for mimicry Bot itself in forward messages (QQ) */}
<author id={session.userId} name={session.username}></author>
{output.map((children) => (
<message>{children}</message>
))}
</message>
)
case 'forward-multiple':
if (output.length === 1) return <message>{output[0]}</message>
return (
<message forward>
{/* Use <author> for mimicry Bot itself in forward messages (QQ) */}
<author id={session.userId} name={session.username}></author>
{output.map((children) => (
<message>{children}</message>
))}
</message>
)
}
// the qq platform will can merge the all forward message with one element(forward message block).
// so can treat it as a spoiler message.
if (['qq', 'red', 'onebot'].includes(session.platform) && config.spoiler !== SpoilerType.Disabled)
return <message forward>{output}</message>
else return output.length === 1 ? output[0] : <message forward>{output}</message>
})
}
11 changes: 11 additions & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ export interface Config {
confidence: number
maxCount: number
output: OutputType
outputMethod: 'one-by-one' | 'merge-multiple' | 'forward-all' | 'forward-multiple'
preferSize: ImageSource.PreferSize
nsfw: boolean
asset: boolean
Expand Down Expand Up @@ -173,6 +174,16 @@ export const Config = Schema.intersect([
])
.description('输出方式。')
.default(1),
outputMethod: Schema.union([
Schema.const('one-by-one').description('逐条发送每张图片'),
Schema.const('merge-multiple').description('合并多条发送 (部分平台可能不支持)'),
Schema.const('forward-all').description('合并为子话题发送所有图片 (部分平台需求较高权限)'),
Schema.const('forward-multiple').description('仅当多于一张图片使用合并为子话题发送 (部分平台需求较高权限)'),
])
.experimental()
.role('radio')
.default('merge-multiple')
.description('发送方式。'),
preferSize: Schema.union([
Schema.const('original').description('原始尺寸'),
Schema.const('large').description('较大尺寸 (通常为约 1200px)'),
Expand Down

0 comments on commit 4468630

Please sign in to comment.