This commit is contained in:
Курнат Андрей
2026-02-16 05:52:43 +03:00
parent ac6d9e84c6
commit 45382570d9
4 changed files with 61 additions and 10 deletions

View File

@@ -154,6 +154,7 @@
isBookLoaded: false,
fb2CurrentPage: 0,
fb2TotalPages: 1,
toc: []
};
// ========== УТИЛИТЫ ==========
@@ -287,16 +288,17 @@
try {
const toc = state.book.navigation.toc || [];
const chapters = toc.map(ch => ({
state.toc = toc.map(ch => ({
label: (ch.label || '').trim(),
href: ch.href || ''
}));
sendMessage('chaptersLoaded', { chapters });
sendMessage('chaptersLoaded', { chapters: state.toc });
} catch (e) {
debugLog('TOC error: ' + e.message);
}
const charsPerScreen = Math.max(600, Math.floor((window.innerWidth * window.innerHeight) / 400));
return state.book.locations.generate(1600);
return state.book.locations.generate(charsPerScreen);
})
.then(() => {
state.totalPages = state.book.locations.length();
@@ -309,13 +311,29 @@
state.rendition.on('relocated', location => {
if (!location || !location.start) return;
state.currentCfi = location.start.cfi;
// 1. Достаем страницы ВНУТРИ главы
// Если epub.js не успел посчитать (бывает на долю секунды), ставим 1
const chapterPage = location.start.displayed ? location.start.displayed.page : 1;
const chapterTotal = location.start.displayed ? location.start.displayed.total : 1;
// 2. Ищем красивое название главы по её href
const currentHref = location.start.href || '';
let chapterName = currentHref; // По умолчанию системное имя
// Пытаемся найти точное совпадение в сохраненном оглавлении
const foundChapter = state.toc.find(ch => currentHref.includes(ch.href));
if (foundChapter) {
chapterName = foundChapter.label;
}
try {
sendMessage('progressUpdate', {
progress: state.book.locations.percentageFromCfi(state.currentCfi) || 0,
cfi: state.currentCfi,
currentPage: location.start.location || 0,
totalPages: state.totalPages,
chapter: location.start.href || ''
currentPage: location.start.location || 0, // Глобальная страница
totalPages: state.totalPages, // Всего глобальных страниц
chapterCurrentPage: chapterPage, // <--- Страница в главе!
chapterTotalPages: chapterTotal, // <--- Всего страниц в главе!
chapter: chapterName // <--- Красивое имя главы
});
} catch (e) {
debugLog('Relocated error: ' + e.message);

View File

@@ -33,6 +33,19 @@ public partial class ReaderViewModel : BaseViewModel
[ObservableProperty]
private string? _selectedChapter;
[ObservableProperty]
private int _chapterCurrentPage = 1;
[ObservableProperty]
private int _chapterTotalPages = 1;
// Это свойство будет обновляться автоматически при изменении любого из полей выше
public string ChapterProgressText => $"{ChapterCurrentPage} из {ChapterTotalPages}";
// Чтобы ChapterProgressText уведомлял интерфейс, добавим частичные методы (особенность Toolkit)
partial void OnChapterCurrentPageChanged(int value) => OnPropertyChanged(nameof(ChapterProgressText));
partial void OnChapterTotalPagesChanged(int value) => OnPropertyChanged(nameof(ChapterProgressText));
public List<string> AvailableFonts { get; } = new()
{
"serif",

View File

@@ -20,6 +20,21 @@
DefaultFile="index.html"
HorizontalOptions="Fill"
VerticalOptions="Fill" />
<VerticalStackLayout VerticalOptions="End"
HorizontalOptions="Center"
Padding="10"
InputTransparent="True">
<Frame BackgroundColor="#AA000000"
CornerRadius="15"
Padding="10,2"
BorderColor="Transparent"
HasShadow="False">
<Label Text="{Binding ChapterProgressText}"
TextColor="White"
FontSize="12"
HorizontalTextAlignment="Center" />
</Frame>
</VerticalStackLayout>
<!-- Overlay Menu -->
<Grid IsVisible="{Binding IsMenuVisible}"

View File

@@ -18,10 +18,6 @@ public partial class ReaderPage : ContentPage
_viewModel = viewModel;
BindingContext = viewModel;
_viewModel.OnJavaScriptRequested += OnJavaScriptRequested;
//Microsoft.Maui.Controls.Application.Current.Deactivated += async (s, e) =>
//{
// if (_isActive) await SaveCurrentProgress();
//};
}
protected override async void OnAppearing()
@@ -207,6 +203,15 @@ public partial class ReaderPage : ContentPage
var chapter = data["chapter"]?.ToString();
var currentPage = data["currentPage"]?.Value<int>() ?? 0;
var totalPages = data["totalPages"]?.Value<int>() ?? 0;
// Ловим новые данные по главе
var chapterPage = data["chapterCurrentPage"]?.Value<int>() ?? 1;
var chapterTotal = data["chapterTotalPages"]?.Value<int>() ?? 1;
// Обновляем ViewModel на главном потоке
MainThread.BeginInvokeOnMainThread(() => {
_viewModel.ChapterCurrentPage = chapterPage;
_viewModel.ChapterTotalPages = chapterTotal;
});
await _viewModel.SaveProgressAsync(progress, cfi, chapter, currentPage, totalPages);
}
break;