6 Commits

Author SHA1 Message Date
IndieKKY
b481b8a55a chore: release 1.11.5 2024-10-09 20:17:33 +08:00
IndieKKY
3cede8650d 增加总结:辩论 2024-10-09 20:17:08 +08:00
IndieKKY
69e0497081 chore: release 1.11.4 2024-10-09 08:36:01 +08:00
IndieKKY
8776186486 添加官网链接 2024-10-08 19:27:24 +08:00
IndieKKY
d31c2d7b03 chore: release 1.11.3 2024-10-07 19:10:54 +08:00
IndieKKY
1c5534fc82 fix 2024-10-07 19:10:39 +08:00
12 changed files with 136 additions and 13 deletions

View File

@@ -1,3 +1 @@
VITE_ENV=web-dev
VITE_EXTENSION_ID=nejipfbcnfhckfpmlgibfommbnahchko

View File

@@ -1,4 +1,3 @@
NODE_ENV=production
VITE_ENV=chrome
VITE_EXTENSION_ID=bciglihaegkdhoogebcdblfhppoilclp
VITE_ENV=chrome

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "bilibili-subtitle",
"version": "1.11.2",
"version": "1.11.5",
"type": "module",
"description": "哔哩哔哩字幕列表",
"main": "index.js",

View File

@@ -0,0 +1,43 @@
import { useAppSelector } from '@/hooks/redux';
import React from 'react';
const DebateChat: React.FC<DebateProps> = ({ messages }) => {
const fontSize = useAppSelector(state => state.env.envData.fontSize)
return (
<div className="flex flex-col h-full">
<div className="flex-1 overflow-y-auto p-4">
{messages.map((message, index) => (
<div
key={index}
className={`flex mb-4 ${
message.side === 'pro' ? 'justify-start' : 'justify-end'
}`}
>
<div
className={`max-w-[85%] rounded-2xl p-3 shadow-md relative ${
message.side === 'pro'
? 'bg-blue-100 text-blue-800 ml-2'
: 'bg-green-100 text-green-800 mr-2'
}`}
>
<p className={`${fontSize === 'large' ? 'text-sm' : 'text-xs'} font-bold mb-1`}>
{message.side === 'pro' ? '正方' : '反方'}
</p>
<p className={fontSize === 'large' ? 'text-sm' : 'text-xs'}>{message.content}</p>
<div
className={`absolute w-4 h-4 ${
message.side === 'pro'
? 'bg-blue-100 -left-2 top-2 rounded-bl-full'
: 'bg-green-100 -right-2 top-2 rounded-br-full'
}`}
></div>
</div>
</div>
))}
</div>
</div>
);
};
export default DebateChat;

View File

@@ -245,7 +245,7 @@ const MoreBtn = (props: Props) => {
(m4s)
</a>
</li>
<li className='hover:bg-accent'>
{/* <li className='hover:bg-accent'>
<a className='flex items-center' onClick={(e) => {
e.preventDefault()
e.stopPropagation()
@@ -264,7 +264,7 @@ const MoreBtn = (props: Props) => {
<AiFillWechat className='w-[20px] h-[20px] text-primary/75 bg-white rounded-sm p-0.5'/>
微信公众号(IndieKKY)
</a>
</li>
</li> */}
{/* <li className='hover:bg-accent'> */}
{/* <a className='flex items-center' onClick={(e) => { */}
{/* e.preventDefault() */}
@@ -297,6 +297,17 @@ const MoreBtn = (props: Props) => {
</a>
</li>
{/* 官网 */}
<li className='hover:bg-accent'>
<a className='flex items-center' onClick={(e) => {
e.preventDefault()
e.stopPropagation()
openUrl('https://www.bibijun.cc')
}}>
<img alt='哔哔君' src='/favicon-128x128.png' className='w-[20px] h-[20px] bg-white rounded-sm p-0.5'/>
🏠
</a>
</li>
</ul>
</Popover>}
</>

View File

@@ -2,7 +2,7 @@ import React, {MutableRefObject, useCallback, useEffect, useMemo, useRef} from '
import {useAppDispatch, useAppSelector} from '../hooks/redux'
import {setFloatKeyPointsSegIdx, setSegmentFold, setTempData} from '../redux/envReducer'
import classNames from 'classnames'
import {FaClipboardList} from 'react-icons/fa'
import {FaClipboardList, FaComments} from 'react-icons/fa'
import {PAGE_MAIN, PAGE_SETTINGS, SUMMARIZE_THRESHOLD, SUMMARIZE_TYPES} from '../consts/const'
import useTranslate from '../hooks/useTranslate'
import {BsDashSquare, BsPlusSquare, CgFileDocument, FaQuestion, GrOverview, RiFileCopy2Line} from 'react-icons/all'
@@ -12,6 +12,7 @@ import {useInViewport} from 'ahooks'
import SegmentItem from './SegmentItem'
import {stopPopFunc} from '../utils/util'
import useSubtitle from '../hooks/useSubtitle'
import DebateChat from './DebateChat'
const SummarizeItemOverview = (props: {
segment: Segment
@@ -113,6 +114,8 @@ const Summarize = (props: {
<div className={classNames('font-normal', fontSize === 'large' ? 'text-sm' : 'text-xs')}>{question.a}</div>
</div>)}
</div>}
{summary?.type === 'debate' && (summary.content != null) &&
<DebateChat messages={summary.content} />}
</div>
<div className='flex flex-col justify-center items-center'>
{segment.text.length < SUMMARIZE_THRESHOLD && <div className='desc-lighter text-xs'>.</div>}
@@ -200,6 +203,12 @@ const SegmentCard = (props: {
}))
}, [dispatch])
const onSelDebate = useCallback(() => {
dispatch(setTempData({
curSummaryType: 'debate'
}))
}, [dispatch])
return <div
className={classNames('border border-base-300 bg-base-200/25 rounded flex flex-col m-1.5 p-1.5 gap-1 shadow', showCurrent && 'shadow-primary')}>
<div className='relative flex justify-center min-h-[20px]'>
@@ -215,6 +224,7 @@ const SegmentCard = (props: {
<a className={classNames('tab tab-lifted tab-xs', curSummaryType === 'overview' && 'tab-active')} onClick={onSelOverview}><GrOverview/></a>
<a className={classNames('tab tab-lifted tab-xs', curSummaryType === 'keypoint' && 'tab-active')} onClick={onSelKeypoint}><FaClipboardList/></a>
<a className={classNames('tab tab-lifted tab-xs', curSummaryType === 'question' && 'tab-active')} onClick={onSelQuestion}><FaQuestion/></a>
<a className={classNames('tab tab-lifted tab-xs', curSummaryType === 'debate' && 'tab-active')} onClick={onSelDebate}><FaComments/></a>
<a className="tab tab-lifted tab-xs tab-disabled cursor-default"></a>
</div>}
<div

View File

@@ -11,6 +11,7 @@ export const PROMPT_TYPE_TRANSLATE = 'translate'
export const PROMPT_TYPE_SUMMARIZE_OVERVIEW = 'summarize_overview'
export const PROMPT_TYPE_SUMMARIZE_KEYPOINT = 'summarize_keypoint'
export const PROMPT_TYPE_SUMMARIZE_QUESTION = 'summarize_question'
export const PROMPT_TYPE_SUMMARIZE_DEBATE = 'summarize_debate'
export const PROMPT_TYPE_SUMMARIZE_BRIEF = 'summarize_brief'
export const PROMPT_TYPE_ASK = 'ask'
export const PROMPT_TYPES = [{
@@ -28,6 +29,9 @@ export const PROMPT_TYPES = [{
}, {
name: '问题',
type: PROMPT_TYPE_SUMMARIZE_QUESTION,
}, {
name: '辩论',
type: PROMPT_TYPE_SUMMARIZE_DEBATE,
}, {
name: '提问',
type: PROMPT_TYPE_ASK,
@@ -58,6 +62,12 @@ export const SUMMARIZE_TYPES = {
downloadName: '💡常见问题💡',
promptType: PROMPT_TYPE_SUMMARIZE_QUESTION,
},
debate: {
name: '辩论',
desc: '辩论',
downloadName: '💡辩论💡',
promptType: PROMPT_TYPE_SUMMARIZE_DEBATE,
},
}
export const PROMPT_DEFAULTS = {
@@ -175,6 +185,42 @@ Provide an example to illustrate the expected output:
}
]
\`\`\`
`,
[PROMPT_TYPE_SUMMARIZE_DEBATE]: `You are a helpful assistant skilled at generating debates based on video subtitles.
## Context
The video's title: '''{{title}}'''.
The video's subtitles:
'''
{{segment}}
'''
## Command
Please play the roles of both the affirmative and negative sides to discuss the author's viewpoint.
The conversation should consist of 10 rounds(5 sentences from the affirmative side, 5 sentences from the negative side.).
The tone should be straightforward.
Answer in language '{{language}}'.
## Output format
Provide an example to illustrate the expected output:
\`\`\`json
[
{
"side": "pro",
"content": "xxx"
},
{
"side": "con",
"content": "xxx"
}
]
\`\`\`
`,
[PROMPT_TYPE_ASK]: `You are a helpful assistant who answers question related to video subtitles.
Answer in language '{{language}}'.

View File

@@ -62,7 +62,7 @@ class InjectMessaging<AllExtensionMessagesType extends ExtensionMessage, AllInje
[K in AllInjectMessagesType['method']]: (params: Extract<AllInjectMessagesType, { method: K }>['params'], context: MethodContext) => Promise<any>
}) {
this.methods = methods
this.port = chrome.runtime.connect(import.meta.env.VITE_EXTENSION_ID, {
this.port = chrome.runtime.connect({
name: 'bilibili-inject',
})
this.l1protocol = new Layer1Protocol<L2ReqMsg, L2ResMsg>(this.messageHandler, this.port)

View File

@@ -63,7 +63,7 @@ const useMessagingService = <AllAPPMessagesType extends AppMessage>(methods?: {
}, [methods])
const port = useMemo(() => {
return chrome.runtime.connect(import.meta.env.VITE_EXTENSION_ID, {
return chrome.runtime.connect({
name: 'bilibili-app',
})
}, [])

11
src/typings.d.ts vendored
View File

@@ -151,4 +151,13 @@ interface BriefSummary extends Summary {
}
type SummaryStatus = 'init' | 'pending' | 'done'
type SummaryType = 'overview' | 'keypoint' | 'brief' | 'question'
type SummaryType = 'overview' | 'keypoint' | 'brief' | 'question' | 'debate'
interface DebateMessage {
side: 'pro' | 'con';
content: string;
}
interface DebateProps {
messages: DebateMessage[];
}

View File

@@ -81,6 +81,9 @@ export const isSummaryEmpty = (summary: Summary) => {
} else if (summary.type === 'question') {
const content: any[] = summary.content??[]
return content.length === 0
} else if (summary.type === 'debate') {
const content: Array<{ side: string, content: string }> = summary.content ?? []
return content.length === 0
}
return true
}
@@ -107,7 +110,12 @@ export const getSummaryStr = (summary: Summary) => {
s += content.map(item => {
return item.q + '\n' + item.a + '\n'
}).join('\n')
}
} else if (summary.type === 'debate') {
const content: Array<{ side: string, content: string }> = summary.content ?? []
s += content.map(item => {
return (item.side === 'pro'?'正方:':'反方:') + item.content + '\n'
}).join('\n')
}
return s
}

1
src/vite-env.d.ts vendored
View File

@@ -1,7 +1,6 @@
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_EXTENSION_ID: string
}
interface ImportMeta {