feat(annotator): add page number for annotations, closes #3082 (#3405)

* feat(annotator): add page number in annotation

* feat: add page number for annotations, closes #3082
This commit is contained in:
Huang Xin
2026-02-28 15:08:56 +08:00
committed by GitHub
parent b50bc0b854
commit c533da498d
48 changed files with 777 additions and 57 deletions
@@ -421,6 +421,31 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
const updateBooknotesPage = async () => {
const config = getConfig(bookKey);
const view = getView(bookKey);
if (!config || !view) return;
const { booknotes: annotations = [] } = config;
annotations.sort((a, b) => {
return CFI.compare(a.cfi, b.cfi);
});
for (const annotation of annotations) {
if (annotation.deletedAt || annotation.page || !annotation.cfi) continue;
const progress = await view.getCFIProgress(annotation.cfi);
if (progress) {
annotation.page = progress.location.current + 1;
}
}
const updatedConfig = updateBooknotes(bookKey, annotations);
if (updatedConfig) {
saveConfig(envConfig, bookKey, updatedConfig, settings);
}
};
setTimeout(updateBooknotesPage, 3000);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const handleQuickAction = () => {
const action = viewSettings.annotationQuickAction;
if (appService?.isAndroidApp && !androidTouchEndRef.current) return;
@@ -585,6 +610,7 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => {
cfi,
text: selection.text,
note: '',
page: progress.page,
createdAt: Date.now(),
updatedAt: Date.now(),
};
@@ -625,6 +651,7 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => {
color,
text: selection.text,
note: '',
page: progress.page,
createdAt: Date.now(),
updatedAt: Date.now(),
};
@@ -64,7 +64,7 @@ const ExportMarkdownDialog: React.FC<ExportMarkdownDialogProps> = ({
{% if annotation.note %}
**${_('Note:')}** {{ annotation.note }}
{% endif %}
*${_('Time:')} {{ annotation.timestamp | date('%Y-%m-%d %H:%M') }}*
*${_('Page:')} {{ annotation.page }} · ${_('Time:')} {{ annotation.timestamp | date('%Y-%m-%d %H:%M') }}*
{% endfor %}
---
@@ -122,10 +122,12 @@ const ExportMarkdownDialog: React.FC<ExportMarkdownDialogProps> = ({
chapters: sortedGroups.map((group) => ({
title: group.label || _('Untitled'),
annotations: group.booknotes.map((note) => ({
...note,
text: note.text || '',
note: note.note || '',
style: note.style,
color: note.color,
page: note.page,
timestamp: note.updatedAt,
})),
})),
@@ -182,11 +184,19 @@ const ExportMarkdownDialog: React.FC<ExportMarkdownDialogProps> = ({
lines.push(`**${_('Note')}**: ${note.note}`);
}
// Add timestamp
let pageStr = '';
if (exportConfig.includePageNumber && note.page) {
pageStr = `${_('Page: {{number}}', { number: note.page })}`;
}
let timestampStr = '';
if (exportConfig.includeTimestamp && note.updatedAt) {
const timestamp = new Date(note.updatedAt).toLocaleString();
timestampStr = `${_('Time:')} ${timestamp}`;
}
if (pageStr || timestampStr) {
lines.push('');
lines.push(`*${_('Time:')} ${timestamp}*`);
const infoStr = pageStr ? `${pageStr} · ${timestampStr}`.trim() : timestampStr;
lines.push(`*${infoStr}*`);
}
lines.push(exportConfig.noteSeparator);
@@ -322,6 +332,17 @@ const ExportMarkdownDialog: React.FC<ExportMarkdownDialogProps> = ({
<span className='text-sm'>{_('Notes')}</span>
</label>
<label className='flex cursor-pointer items-center gap-2'>
<input
type='checkbox'
checked={exportConfig.includePageNumber}
onChange={() => handleToggle('includePageNumber')}
className='checkbox checkbox-sm'
disabled={exportConfig.useCustomTemplate}
/>
<span className='text-sm'>{_('Page Number')}</span>
</label>
<label className='flex cursor-pointer items-center gap-2'>
<input
type='checkbox'
@@ -461,6 +482,10 @@ const ExportMarkdownDialog: React.FC<ExportMarkdownDialogProps> = ({
<code className='bg-base-300 rounded px-1'>annotation.color</code> -{' '}
{_('Annotation color')}: yellow | red | green | blue | violet
</li>
<li className='ml-8'>
<code className='bg-base-300 rounded px-1'>annotation.page</code> -{' '}
{_('Annotation page number')}
</li>
<li className='ml-8'>
<code className='bg-base-300 rounded px-1'>annotation.timestamp</code> -{' '}
{_('Annotation time')}