+
+ Google Drive
+
@@ -390,10 +403,13 @@ function GalleryAndDownload({ files }: GalleryAndDownloadProps) {
{[
`${bytesToHumanReadableFileSize(progress.loaded)}${progress.total !== undefined ? ` / ${bytesToHumanReadableFileSize(progress.total)}` : ''}`,
- progress.estimated !== undefined ? `${Math.ceil( progress.estimated)} sekunden` : undefined,
+ progress.estimated !== undefined ? `${dayjs.duration(progress.estimated, 'seconds').humanize()} übrig` : undefined,
progress.rate !== undefined ? `${bytesToHumanReadableFileSize(progress.rate)}/s` : undefined,
].filter(Boolean).join(' | ')}
+
+
+
)}
@@ -452,6 +468,8 @@ function AsyncDownload({ hash, onFinish }: { hash: string; onFinish: () => void
return t('homepage.gallery.downloadAsyncCreateZip');
case 'downloading':
return t('homepage.gallery.downloadAsyncDownloading', {current: data.context.countDone, total: data.fileCount})
+ case 'save_zip':
+ return t('homepage.gallery.downloadAsyncSaveZip');
case 'caching':
return t('homepage.gallery.downloadAsyncCaching');
default:
@@ -468,8 +486,10 @@ function AsyncDownload({ hash, onFinish }: { hash: string; onFinish: () => void
return 0.05;
case 'downloading':
const imageProgressDone = data.context.countDone / data.fileCount;
- return 0.05 + Math.round(imageProgressDone * (90 - 5)) / 100;
- case 'caching':
+ return 0.05 + Math.round(imageProgressDone * (80 - 5)) / 100;
+ case 'save_zip':
+ return 0.85;
+ case 'caching':
return 0.95;
default:
return 1;
@@ -479,10 +499,10 @@ function AsyncDownload({ hash, onFinish }: { hash: string; onFinish: () => void
return (
<>
-
{getMessageForState(downloadState.data)}
{Math.ceil(progress * 100 * 100) / 100}%
+
{getMessageForState(downloadState.data)}
>
);
}
diff --git a/pwa/src/main.tsx b/pwa/src/main.tsx
index c8d19f8..5337dbd 100644
--- a/pwa/src/main.tsx
+++ b/pwa/src/main.tsx
@@ -3,6 +3,10 @@ import App from './App';
import './index.css';
import { init as initI18n, currentLanguage } from './utils/i18n';
import axios from 'axios';
+import dayjs from 'dayjs';
+import duration from 'dayjs/plugin/duration';
+import relativeTime from 'dayjs/plugin/relativeTime';
+import 'dayjs/locale/de';
(async () => {
// Set different base URLs for client and server
@@ -10,6 +14,10 @@ import axios from 'axios';
await initI18n(currentLanguage());
+ dayjs.locale(currentLanguage());
+ dayjs.extend(duration);
+ dayjs.extend(relativeTime);
+
const rootElement = document.getElementById('root');
if (!rootElement) throw new Error('Failed to find the root element');
ReactDOM.createRoot(rootElement).render(
diff --git a/pwa/src/translations/app.de.json b/pwa/src/translations/app.de.json
index f9eaf22..641e08b 100644
--- a/pwa/src/translations/app.de.json
+++ b/pwa/src/translations/app.de.json
@@ -89,8 +89,11 @@
"homepage.gallery.downloadAsyncPending": "Download wird bald erstellt ...",
"homepage.gallery.downloadAsyncCreateZip": "ZIP wird erstellt ...",
"homepage.gallery.downloadAsyncDownloading": "Datei {{current}} von {{total}} wurde der ZIP Datei hinzugefügt ...",
+ "homepage.gallery.downloadAsyncSaveZip": "ZIP Datei wird gespeichert ...",
"homepage.gallery.downloadAsyncCaching": "Erstellte ZIP Datei wird zwischengespeichert für den nächsten ...",
"homepage.gallery.downloadAsyncReady": "ZIP Datei ist bereit zum Download und wird in kürze automatisch heruntergeladen",
+ "homepage.gallery.downloadAlternative": "Falls der Download stehen bleibt, klicke
hier um die Datei direkt zu downloaden.",
+ "homepage.gallery.downloadGDriveInstead": "Falls ihr Probleme mit dem herunterladen habt, könnt ihr unten auch auf den \"Google Drive\" Knopf drücken. Dann könnt ihr die Fotos stattdessen über Google Drive herunterladen. Nachteil ist einfach, dass die Fotos nicht sortiert sind.",
"admin.login.title": "Admin Login",
"admin.login.username": "Benutzername",
"admin.login.password": "Passwort",