mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-23 21:38:44 +08:00
refactor(i18n): i18n utils tools (#7251)
This commit is contained in:
@@ -1,12 +1,9 @@
|
||||
import { useDocMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta';
|
||||
import { useDocCollectionPage } from '@affine/core/hooks/use-block-suite-workspace-page';
|
||||
import {
|
||||
type CalendarTranslation,
|
||||
timestampToCalendarDate,
|
||||
} from '@affine/core/utils';
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import type { ListHistoryQuery } from '@affine/graphql';
|
||||
import { listHistoryQuery, recoverDocMutation } from '@affine/graphql';
|
||||
import { i18nTime } from '@affine/i18n';
|
||||
import { assertEquals } from '@blocksuite/global/utils';
|
||||
import { DocCollection } from '@blocksuite/store';
|
||||
import { globalBlockSuiteSchema } from '@toeverything/infra';
|
||||
@@ -175,13 +172,20 @@ export const useSnapshotPage = (
|
||||
return page;
|
||||
};
|
||||
|
||||
export const historyListGroupByDay = (
|
||||
histories: DocHistory[],
|
||||
translation: CalendarTranslation
|
||||
) => {
|
||||
export const historyListGroupByDay = (histories: DocHistory[]) => {
|
||||
const map = new Map<string, DocHistory[]>();
|
||||
for (const history of histories) {
|
||||
const day = timestampToCalendarDate(history.timestamp, translation);
|
||||
const day = i18nTime(history.timestamp, {
|
||||
relative: {
|
||||
max: [1, 'week'],
|
||||
accuracy: 'day',
|
||||
weekday: true,
|
||||
},
|
||||
absolute: {
|
||||
accuracy: 'day',
|
||||
noYear: true,
|
||||
},
|
||||
});
|
||||
const list = map.get(day) ?? [];
|
||||
list.push(history);
|
||||
map.set(day, list);
|
||||
|
||||
@@ -6,7 +6,7 @@ import { openSettingModalAtom } from '@affine/core/atoms';
|
||||
import { useDocCollectionPageTitle } from '@affine/core/hooks/use-block-suite-workspace-page-title';
|
||||
import { WorkspacePermissionService } from '@affine/core/modules/permissions';
|
||||
import { WorkspaceQuotaService } from '@affine/core/modules/quota';
|
||||
import { Trans } from '@affine/i18n';
|
||||
import { i18nTime, Trans } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { CloseIcon, ToggleCollapseIcon } from '@blocksuite/icons/rc';
|
||||
import type { Doc as BlockSuiteDoc, DocCollection } from '@blocksuite/store';
|
||||
@@ -33,11 +33,7 @@ import {
|
||||
import { encodeStateAsUpdate } from 'yjs';
|
||||
|
||||
import { pageHistoryModalAtom } from '../../../atoms/page-history';
|
||||
import {
|
||||
type CalendarTranslation,
|
||||
mixpanel,
|
||||
timestampToLocalTime,
|
||||
} from '../../../utils';
|
||||
import { mixpanel } from '../../../utils';
|
||||
import { BlockSuiteEditor } from '../../blocksuite/block-suite-editor';
|
||||
import { StyledEditorModeSwitch } from '../../blocksuite/block-suite-mode-switch/style';
|
||||
import {
|
||||
@@ -144,7 +140,11 @@ const HistoryEditorPreview = ({
|
||||
</StyledEditorModeSwitch>
|
||||
<div className={styles.previewHeaderTitle}>{title}</div>
|
||||
<div className={styles.previewHeaderTimestamp}>
|
||||
{ts ? timestampToLocalTime(ts) : null}
|
||||
{ts
|
||||
? i18nTime(ts, {
|
||||
absolute: { accuracy: 'minute', noDate: true },
|
||||
})
|
||||
: null}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -317,14 +317,8 @@ const PageHistoryList = ({
|
||||
}) => {
|
||||
const t = useAFFiNEI18N();
|
||||
const historyListByDay = useMemo(() => {
|
||||
const translation: CalendarTranslation = {
|
||||
yesterday: t['com.affine.yesterday'],
|
||||
today: t['com.affine.today'],
|
||||
tomorrow: t['com.affine.tomorrow'],
|
||||
nextWeek: t['com.affine.nextWeek'],
|
||||
};
|
||||
return historyListGroupByDay(historyList, translation);
|
||||
}, [historyList, t]);
|
||||
return historyListGroupByDay(historyList);
|
||||
}, [historyList]);
|
||||
|
||||
const [collapsedMap, setCollapsedMap] = useState<Record<number, boolean>>({});
|
||||
|
||||
@@ -382,7 +376,9 @@ const PageHistoryList = ({
|
||||
data-active={activeVersion === history.timestamp}
|
||||
>
|
||||
<button>
|
||||
{timestampToLocalTime(history.timestamp)}
|
||||
{i18nTime(history.timestamp, {
|
||||
absolute: { noDate: true, accuracy: 'minute' },
|
||||
})}
|
||||
</button>
|
||||
</div>
|
||||
{idx > list.length - 1 ? (
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@ import type {
|
||||
PageInfoCustomPropertyMeta,
|
||||
PagePropertyType,
|
||||
} from '@affine/core/modules/properties/services/schema';
|
||||
import { timestampToLocalDate } from '@affine/core/utils';
|
||||
import { i18nTime } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { DocService, useService } from '@toeverything/infra';
|
||||
import { noop } from 'lodash-es';
|
||||
@@ -22,7 +22,7 @@ interface PropertyRowValueProps {
|
||||
|
||||
export const DateValue = ({ property }: PropertyRowValueProps) => {
|
||||
const displayValue = property.value
|
||||
? timestampToLocalDate(property.value)
|
||||
? i18nTime(property.value, { absolute: { accuracy: 'day' } })
|
||||
: undefined;
|
||||
const manager = useContext(managerContext);
|
||||
|
||||
|
||||
@@ -14,11 +14,7 @@ import type {
|
||||
PageInfoCustomPropertyMeta,
|
||||
PagePropertyType,
|
||||
} from '@affine/core/modules/properties/services/schema';
|
||||
import {
|
||||
timestampToHumanTime,
|
||||
timestampToLocalDate,
|
||||
timestampToLocalDateTime,
|
||||
} from '@affine/core/utils';
|
||||
import { i18nTime } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import {
|
||||
@@ -617,7 +613,7 @@ export const PagePropertiesTableHeader = ({
|
||||
|
||||
const timestampElement = useMemo(() => {
|
||||
const localizedCreateTime = manager.createDate
|
||||
? timestampToLocalDate(manager.createDate)
|
||||
? i18nTime(manager.createDate)
|
||||
: null;
|
||||
|
||||
const createTimeElement = (
|
||||
@@ -632,11 +628,11 @@ export const PagePropertiesTableHeader = ({
|
||||
content={
|
||||
<>
|
||||
<div className={styles.tableHeaderTimestamp}>
|
||||
{t['Updated']()} {timestampToLocalDateTime(serverClock)}
|
||||
{t['Updated']()} {i18nTime(serverClock)}
|
||||
</div>
|
||||
{manager.createDate && (
|
||||
<div className={styles.tableHeaderTimestamp}>
|
||||
{t['Created']()} {timestampToLocalDateTime(manager.createDate)}
|
||||
{t['Created']()} {i18nTime(manager.createDate)}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
@@ -645,7 +641,16 @@ export const PagePropertiesTableHeader = ({
|
||||
<div className={styles.tableHeaderTimestamp}>
|
||||
{!syncing && !retrying ? (
|
||||
<>
|
||||
{t['Updated']()} {timestampToHumanTime(serverClock)}
|
||||
{t['Updated']()}{' '}
|
||||
{i18nTime(serverClock, {
|
||||
relative: {
|
||||
max: [1, 'day'],
|
||||
accuracy: 'minute',
|
||||
},
|
||||
absolute: {
|
||||
accuracy: 'day',
|
||||
},
|
||||
})}
|
||||
</>
|
||||
) : (
|
||||
<>{t['com.affine.syncing']()}</>
|
||||
@@ -655,7 +660,7 @@ export const PagePropertiesTableHeader = ({
|
||||
) : manager.updatedDate ? (
|
||||
<Tooltip side="right" content={createTimeElement}>
|
||||
<div className={styles.tableHeaderTimestamp}>
|
||||
{t['Updated']()} {timestampToLocalDate(manager.updatedDate)}
|
||||
{t['Updated']()} {i18nTime(manager.updatedDate)}
|
||||
</div>
|
||||
</Tooltip>
|
||||
) : (
|
||||
|
||||
+6
-8
@@ -18,7 +18,7 @@ import {
|
||||
SubscriptionRecurring,
|
||||
SubscriptionStatus,
|
||||
} from '@affine/graphql';
|
||||
import { Trans } from '@affine/i18n';
|
||||
import { i18nTime, Trans } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { ArrowRightSmallIcon } from '@blocksuite/icons/rc';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
@@ -29,11 +29,7 @@ import { openSettingModalAtom } from '../../../../../atoms';
|
||||
import { useMutation } from '../../../../../hooks/use-mutation';
|
||||
import { useQuery } from '../../../../../hooks/use-query';
|
||||
import { SubscriptionService } from '../../../../../modules/cloud';
|
||||
import {
|
||||
mixpanel,
|
||||
popupWindow,
|
||||
timestampToLocalDate,
|
||||
} from '../../../../../utils';
|
||||
import { mixpanel, popupWindow } from '../../../../../utils';
|
||||
import { SWRErrorBoundary } from '../../../../pure/swr-error-bundary';
|
||||
import { CancelAction, ResumeAction } from '../plans/actions';
|
||||
import { AICancel, AIResume, AISubscribe } from '../plans/ai/actions';
|
||||
@@ -282,11 +278,13 @@ const AIPlanCard = ({ onClick }: { onClick: () => void }) => {
|
||||
/>
|
||||
) : subscription?.nextBillAt ? (
|
||||
t['com.affine.payment.ai.billing-tip.next-bill-at']({
|
||||
due: timestampToLocalDate(subscription.nextBillAt),
|
||||
due: i18nTime(subscription.nextBillAt, {
|
||||
absolute: { accuracy: 'day' },
|
||||
}),
|
||||
})
|
||||
) : subscription?.canceledAt && subscription.end ? (
|
||||
t['com.affine.payment.ai.billing-tip.end-at']({
|
||||
end: timestampToLocalDate(subscription.end),
|
||||
end: i18nTime(subscription.end, { absolute: { accuracy: 'day' } }),
|
||||
})
|
||||
) : null;
|
||||
|
||||
|
||||
+7
-3
@@ -1,6 +1,6 @@
|
||||
import { Button } from '@affine/component';
|
||||
import { AuthService, SubscriptionService } from '@affine/core/modules/cloud';
|
||||
import { timestampToLocalDate } from '@affine/core/utils';
|
||||
import { i18nTime } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
import { useEffect } from 'react';
|
||||
@@ -32,11 +32,15 @@ export const AIPlan = () => {
|
||||
|
||||
const billingTip = subscription?.nextBillAt
|
||||
? t['com.affine.payment.ai.billing-tip.next-bill-at']({
|
||||
due: timestampToLocalDate(subscription.nextBillAt),
|
||||
due: i18nTime(subscription.nextBillAt, {
|
||||
absolute: { accuracy: 'day' },
|
||||
}),
|
||||
})
|
||||
: subscription?.canceledAt && subscription.end
|
||||
? t['com.affine.payment.ai.billing-tip.end-at']({
|
||||
end: timestampToLocalDate(subscription.end),
|
||||
end: i18nTime(subscription.end, {
|
||||
absolute: { accuracy: 'day' },
|
||||
}),
|
||||
})
|
||||
: null;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Checkbox } from '@affine/component';
|
||||
import { Checkbox, Tooltip } from '@affine/component';
|
||||
import { getDNDId } from '@affine/core/hooks/affine/use-global-dnd-helper';
|
||||
import { TagService } from '@affine/core/modules/tag';
|
||||
import { i18nTime } from '@affine/i18n';
|
||||
import { useDraggable } from '@dnd-kit/core';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
@@ -15,7 +16,7 @@ import {
|
||||
} from '../scoped-atoms';
|
||||
import type { DraggableTitleCellData, PageListItemProps } from '../types';
|
||||
import { useAllDocDisplayProperties } from '../use-all-doc-display-properties';
|
||||
import { ColWrapper, formatDate, stopPropagation } from '../utils';
|
||||
import { ColWrapper, stopPropagation } from '../utils';
|
||||
import * as styles from './page-list-item.css';
|
||||
import { PageTags } from './page-tags';
|
||||
|
||||
@@ -97,13 +98,17 @@ const PageCreateDateCell = ({
|
||||
createDate,
|
||||
}: Pick<PageListItemProps, 'createDate'>) => {
|
||||
return (
|
||||
<div
|
||||
data-testid="page-list-item-date"
|
||||
data-date-raw={createDate}
|
||||
className={styles.dateCell}
|
||||
>
|
||||
{formatDate(createDate)}
|
||||
</div>
|
||||
<Tooltip content={i18nTime(createDate)}>
|
||||
<div
|
||||
data-testid="page-list-item-date"
|
||||
data-date-raw={createDate}
|
||||
className={styles.dateCell}
|
||||
>
|
||||
{i18nTime(createDate, {
|
||||
relative: true,
|
||||
})}
|
||||
</div>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -111,13 +116,19 @@ const PageUpdatedDateCell = ({
|
||||
updatedDate,
|
||||
}: Pick<PageListItemProps, 'updatedDate'>) => {
|
||||
return (
|
||||
<div
|
||||
data-testid="page-list-item-date"
|
||||
data-date-raw={updatedDate}
|
||||
className={styles.dateCell}
|
||||
>
|
||||
{updatedDate ? formatDate(updatedDate) : '-'}
|
||||
</div>
|
||||
<Tooltip content={updatedDate ? i18nTime(updatedDate) : undefined}>
|
||||
<div
|
||||
data-testid="page-list-item-date"
|
||||
data-date-raw={updatedDate}
|
||||
className={styles.dateCell}
|
||||
>
|
||||
{updatedDate
|
||||
? i18nTime(updatedDate, {
|
||||
relative: true,
|
||||
})
|
||||
: '-'}
|
||||
</div>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -5,70 +5,6 @@ import { forwardRef } from 'react';
|
||||
import * as styles from './list.css';
|
||||
import type { ColWrapperProps } from './types';
|
||||
|
||||
export function isToday(date: Date): boolean {
|
||||
const today = new Date();
|
||||
return (
|
||||
date.getDate() === today.getDate() &&
|
||||
date.getMonth() === today.getMonth() &&
|
||||
date.getFullYear() === today.getFullYear()
|
||||
);
|
||||
}
|
||||
|
||||
export function isYesterday(date: Date): boolean {
|
||||
const yesterday = new Date();
|
||||
yesterday.setDate(yesterday.getDate() - 1);
|
||||
return (
|
||||
date.getFullYear() === yesterday.getFullYear() &&
|
||||
date.getMonth() === yesterday.getMonth() &&
|
||||
date.getDate() === yesterday.getDate()
|
||||
);
|
||||
}
|
||||
|
||||
export function isLastWeek(date: Date): boolean {
|
||||
const today = new Date();
|
||||
const lastWeek = new Date(
|
||||
today.getFullYear(),
|
||||
today.getMonth(),
|
||||
today.getDate() - 7
|
||||
);
|
||||
return date >= lastWeek && date < today;
|
||||
}
|
||||
|
||||
export function isLastMonth(date: Date): boolean {
|
||||
const today = new Date();
|
||||
const lastMonth = new Date(
|
||||
today.getFullYear(),
|
||||
today.getMonth() - 1,
|
||||
today.getDate()
|
||||
);
|
||||
return date >= lastMonth && date < today;
|
||||
}
|
||||
|
||||
export function isLastYear(date: Date): boolean {
|
||||
const today = new Date();
|
||||
const lastYear = new Date(
|
||||
today.getFullYear() - 1,
|
||||
today.getMonth(),
|
||||
today.getDate()
|
||||
);
|
||||
return date >= lastYear && date < today;
|
||||
}
|
||||
|
||||
export const formatDate = (date: Date): string => {
|
||||
// yyyy-mm-dd MM-DD HH:mm
|
||||
// const year = date.getFullYear();
|
||||
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
||||
const day = date.getDate().toString().padStart(2, '0');
|
||||
const hours = date.getHours().toString().padStart(2, '0');
|
||||
const minutes = date.getMinutes().toString().padStart(2, '0');
|
||||
if (isToday(date)) {
|
||||
// HH:mm
|
||||
return `${hours}:${minutes}`;
|
||||
}
|
||||
// MM-DD HH:mm
|
||||
return `${month}-${day} ${hours}:${minutes}`;
|
||||
};
|
||||
|
||||
export const ColWrapper = forwardRef<HTMLDivElement, ColWrapperProps>(
|
||||
function ColWrapper(
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user