diff --git a/src/components/manga/ChapterCard.tsx b/src/components/manga/ChapterCard.tsx index f75c57126d..8f7db0209a 100644 --- a/src/components/manga/ChapterCard.tsx +++ b/src/components/manga/ChapterCard.tsx @@ -30,8 +30,9 @@ import React from 'react'; import { Link } from 'react-router-dom'; import client from 'util/client'; import { BACK } from 'util/useBackTo'; +import { getUploadDateString } from 'util/date'; -interface IProps{ +interface IProps { chapter: IChapter triggerChaptersUpdate: () => void downloadChapter: IDownloadChapter | undefined @@ -48,8 +49,6 @@ const ChapterCard: React.FC = (props: IProps) => { } = props; const isSelecting = selected !== null; - const dateStr = chapter.uploadDate && new Date(chapter.uploadDate).toLocaleDateString(); - const [anchorEl, setAnchorEl] = React.useState(null); const handleMenuClick = (event: React.MouseEvent) => { @@ -69,7 +68,9 @@ const ChapterCard: React.FC = (props: IProps) => { const formData = new FormData(); formData.append(key, value); - if (key === 'read') { formData.append('lastPageRead', '1'); } + if (key === 'read') { + formData.append('lastPageRead', '1'); + } client.patch(`/api/v1/manga/${chapter.mangaId}/chapter/${chapter.index}`, formData) .then(() => triggerChaptersUpdate()); }; @@ -131,13 +132,13 @@ const ChapterCard: React.FC = (props: IProps) => { {chapter.bookmarked && ( )} - { showChapterNumber ? `Chapter ${chapter.chapterNumber}` : chapter.name} + {showChapterNumber ? `Chapter ${chapter.chapterNumber}` : chapter.name} {chapter.scanlator} - {dateStr} + {getUploadDateString(chapter.uploadDate)} {isDownloaded && ' • Downloaded'} @@ -186,7 +187,7 @@ const ChapterCard: React.FC = (props: IProps) => { Download - ) } + )} sendChange('bookmarked', !chapter.bookmarked)}> {chapter.bookmarked && } diff --git a/src/util/date.ts b/src/util/date.ts new file mode 100644 index 0000000000..4e631fe6e7 --- /dev/null +++ b/src/util/date.ts @@ -0,0 +1,72 @@ +/* + * Copyright (C) Contributors to the Suwayomi project + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +export const isWithinLastXMillis = (date: Date, timeMS: number) => { + const timeDifference = Date.now() - date.getTime(); + return timeDifference <= timeMS; +}; + +export const getElapsedTimeSinceStartOfDay = (date: Date) => { + const startOfDay = new Date(date.getFullYear(), date.getMonth(), date.getDate()); + return date.getTime() - startOfDay.getTime(); +}; + +/** + * Returns a string in localized format for the passed date. + * + * In case the date is from today or yesterday a special string will be returned including "Today" + * or "Yesterday" with the localized time of the passed date. + * + * @example + * const today = new Date(); + * const yesterday = new Date(today.getTime() - 1000 * 60 * 60 * 24); + * const someDate = new Date(1337, 4, 20); + * + * const todayAsString = getDateString(today); // => "Today at 02:50 AM" + * const yesterdayAsString = getDateString(yesterday) // => "Yesterday at 02:50 AM" + * const someDate = getDateString(someDate) // => "04/20/1337" + * + * + * @param date + */ +export const getUploadDateString = (date: Date | number) => { + const uploadDate = date instanceof Date ? date : new Date(date); + + const today = new Date(); + const todayElapsedTime = getElapsedTimeSinceStartOfDay(today); + const yesterday = new Date(today.getTime() - todayElapsedTime - 1000 * 60 * 60 * 24); + const elapsedTimeSinceYesterday = today.getTime() - yesterday.getTime(); + + const wasUploadedToday = isWithinLastXMillis(uploadDate, todayElapsedTime); + const wasUploadedYesterday = isWithinLastXMillis(uploadDate, elapsedTimeSinceYesterday); + + const addTimeString = wasUploadedToday || wasUploadedYesterday; + const timeString = addTimeString + ? uploadDate.toLocaleTimeString( + undefined, + { + hour: '2-digit', + minute: '2-digit', + }, + ) + : ''; + + if (wasUploadedToday) { + return `Today at ${timeString}`; + } + + if (wasUploadedYesterday) { + return `Yesterday at ${timeString}`; + } + + return uploadDate.toLocaleDateString(undefined, { + year: 'numeric', + month: '2-digit', + day: '2-digit', + }); +};