Various fixes and enhancements on updater, header bar and tts (#203)
* Show 0% as valid reading progress * Add check update button in the about window * Fix title overflow, fix tts won't continue at chapter end
This commit is contained in:
@@ -20,7 +20,7 @@ const ReadingProgress: React.FC<ReadingProgressProps> = memo(
|
||||
({ book }) => {
|
||||
const progressPercentage = useMemo(() => getProgressPercentage(book), [book]);
|
||||
|
||||
if (!progressPercentage) {
|
||||
if (progressPercentage === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,16 +60,16 @@ const HeaderBar: React.FC<HeaderBarProps> = ({
|
||||
onMouseEnter={() => setHoveredBookKey(bookKey)}
|
||||
onMouseLeave={() => setHoveredBookKey('')}
|
||||
>
|
||||
<div className='sidebar-bookmark-toggler flex h-full items-center space-x-2 sm:space-x-4'>
|
||||
<div className='sidebar-bookmark-toggler bg-base-100 z-20 flex h-full items-center space-x-2 sm:space-x-4'>
|
||||
<SidebarToggler bookKey={bookKey} />
|
||||
<BookmarkToggler bookKey={bookKey} />
|
||||
</div>
|
||||
|
||||
<div className='header-title pointer-events-none absolute inset-0 hidden items-center justify-center sm:flex'>
|
||||
<h2 className='line-clamp-1 max-w-[80%] text-center text-xs font-semibold'>{bookTitle}</h2>
|
||||
<div className='header-title z-15 pointer-events-none absolute inset-0 hidden items-center justify-center sm:flex'>
|
||||
<h2 className='line-clamp-1 max-w-[50%] text-center text-xs font-semibold'>{bookTitle}</h2>
|
||||
</div>
|
||||
|
||||
<div className='ml-auto flex h-full items-center space-x-2 sm:space-x-4'>
|
||||
<div className='bg-base-100 z-20 ml-auto flex h-full items-center space-x-2 sm:space-x-4'>
|
||||
<SettingsToggler />
|
||||
<NotebookToggler bookKey={bookKey} />
|
||||
<Dropdown
|
||||
|
||||
@@ -3,6 +3,8 @@ import Image from 'next/image';
|
||||
import packageJson from '../../package.json';
|
||||
import WindowButtons from './WindowButtons';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import { hasUpdater } from '@/services/environment';
|
||||
import { checkForAppUpdates } from '@/helpers/updater';
|
||||
|
||||
export const setAboutDialogVisible = (visible: boolean) => {
|
||||
const dialog = document.getElementById('about_window');
|
||||
@@ -15,6 +17,15 @@ export const setAboutDialogVisible = (visible: boolean) => {
|
||||
|
||||
export const AboutWindow = () => {
|
||||
const _ = useTranslation();
|
||||
const [isUpdated, setIsUpdated] = React.useState(false);
|
||||
|
||||
const handleCheckUpdate = async () => {
|
||||
const update = await checkForAppUpdates(_);
|
||||
if (!update) {
|
||||
setIsUpdated(true);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<dialog id='about_window' className='modal'>
|
||||
<form method='dialog' className='modal-box w-96 max-w-lg p-4'>
|
||||
@@ -31,10 +42,17 @@ export const AboutWindow = () => {
|
||||
<Image src='/icon.png' alt='App Logo' className='h-24 w-24' width={64} height={64} />
|
||||
</div>
|
||||
<h2 className='text-2xl font-bold'>Readest</h2>
|
||||
<p className='text-neutral-content text-sm'>Bilingify LLC</p>
|
||||
<span className='badge badge-primary mt-2'>
|
||||
<p className='text-neutral-content text-sm'>
|
||||
{_('Version {{version}}', { version: packageJson.version })}
|
||||
</span>
|
||||
</p>
|
||||
{hasUpdater() && !isUpdated && (
|
||||
<span className='badge badge-primary mt-2' onClick={handleCheckUpdate}>
|
||||
{_('Check update')}
|
||||
</span>
|
||||
)}
|
||||
{isUpdated && (
|
||||
<p className='text-neutral-content mt-2 text-xs'>{_('Already the latest version')}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className='divider'></div>
|
||||
|
||||
@@ -7,8 +7,6 @@ import { TranslationFunc } from '@/hooks/useTranslation';
|
||||
const LAST_CHECK_KEY = 'lastAppUpdateCheck';
|
||||
|
||||
export const checkForAppUpdates = async (_: TranslationFunc) => {
|
||||
if (process.env['NEXT_PUBLIC_DISABLE_UPDATER']) return;
|
||||
|
||||
const lastCheck = localStorage.getItem(LAST_CHECK_KEY);
|
||||
const now = Date.now();
|
||||
if (lastCheck && now - parseInt(lastCheck, 10) < CHECK_UPDATE_INTERVAL_SEC * 1000) return;
|
||||
@@ -57,4 +55,5 @@ export const checkForAppUpdates = async (_: TranslationFunc) => {
|
||||
await relaunch();
|
||||
}
|
||||
}
|
||||
return update;
|
||||
};
|
||||
|
||||
@@ -10,7 +10,8 @@ declare global {
|
||||
|
||||
export const isTauriAppPlatform = () => process.env['NEXT_PUBLIC_APP_PLATFORM'] === 'tauri';
|
||||
export const isWebAppPlatform = () => process.env['NEXT_PUBLIC_APP_PLATFORM'] === 'web';
|
||||
export const hasUpdater = () => window.__READEST_UPDATER_ACCESS === true;
|
||||
export const hasUpdater = () =>
|
||||
window.__READEST_UPDATER_ACCESS === true && !process.env['NEXT_PUBLIC_DISABLE_UPDATER'];
|
||||
export const hasCli = () => window.__READEST_CLI_ACCESS === true;
|
||||
|
||||
// Dev API only in development mode and web platform
|
||||
|
||||
@@ -91,6 +91,7 @@ export class TTSController extends EventTarget {
|
||||
this.#nossmlCnt++;
|
||||
// FIXME: in case we are at the end of the book, need a better way to handle this
|
||||
if (this.#nossmlCnt < 10 && this.state === 'playing') {
|
||||
resolve();
|
||||
await this.view.next(1);
|
||||
await this.forward();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user