Skip to content

Commit

Permalink
add pretty display in command bar
Browse files Browse the repository at this point in the history
  • Loading branch information
ddecrulle committed Nov 28, 2024
1 parent f27bde7 commit c9a48eb
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 104 deletions.
21 changes: 21 additions & 0 deletions web/src/core/tools/timeFormat/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const SECOND = 1000;

export const TIME_UNITS = {
SECOND,
MINUTE: 60 * SECOND,
HOUR: 60 * 60 * SECOND,
DAY: 24 * 60 * 60 * SECOND,
WEEK: 7 * 24 * 60 * 60 * SECOND,
MONTH: 30 * 24 * 60 * 60 * SECOND,
YEAR: 365 * 24 * 60 * 60 * SECOND
};

export const DURATION_DIVISOR_KEYS = [
"second",
"minute",
"hour",
"day",
"week",
"month",
"year"
] as const;
100 changes: 100 additions & 0 deletions web/src/core/tools/timeFormat/formatDuration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { assert } from "tsafe/assert";
import { DurationTranslationFunction } from "./type";
import { TIME_UNITS, DURATION_DIVISOR_KEYS } from "./constants";

export const { formatDuration } = (() => {
const { getDurationUnits } = (() => {
type DurationUnit = {
max: number;
divisor: number;
singular: string;
plural: string;
};

function getDurationUnits(t: DurationTranslationFunction): DurationUnit[] {
return DURATION_DIVISOR_KEYS.map(divisorKey => ({
divisor: (() => {
switch (divisorKey) {
case "second":
return TIME_UNITS.SECOND;
case "minute":
return TIME_UNITS.MINUTE;
case "hour":
return TIME_UNITS.HOUR;
case "day":
return TIME_UNITS.DAY;
case "week":
return TIME_UNITS.WEEK;
case "month":
return TIME_UNITS.MONTH;
case "year":
return TIME_UNITS.YEAR;
}
})(),
max: (() => {
switch (divisorKey) {
case "second":
return TIME_UNITS.MINUTE;
case "minute":
return TIME_UNITS.HOUR;
case "hour":
return 3 * TIME_UNITS.DAY;
case "day":
return TIME_UNITS.WEEK + TIME_UNITS.DAY;
case "week":
return TIME_UNITS.MONTH;
case "month":
return TIME_UNITS.YEAR;
case "year":
return Infinity;
}
})(),
singular: t("singular", { divisorKey }),
plural: t("plural", { divisorKey })
}));
}

return { getDurationUnits };
})();

function formatDuration(params: {
durationSeconds: number;
t: DurationTranslationFunction;
}): string {
const { durationSeconds, t } = params;

for (const unit of getDurationUnits(t)) {
if (durationSeconds * 1000 < unit.max) {
const x = Math.round(durationSeconds / (unit.divisor / 1000));
return x === 1 ? unit.singular : unit.plural.replace("#", `${x}`);
}
}
assert(false);
}

return { formatDuration };
})();

export const englishDurationFormatter: DurationTranslationFunction = (key, params) => {
const en = {
singular: {
second: "1 second",
minute: "1 minute",
hour: "1 hour",
day: "1 day",
week: "1 week",
month: "1 month",
year: "1 year"
},
plural: {
second: "# seconds",
minute: "# minutes",
hour: "# hours",
day: "# days",
week: "# weeks",
month: "# months",
year: "# years"
}
};
return en[key][params.divisorKey];
};
8 changes: 8 additions & 0 deletions web/src/core/tools/timeFormat/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { DURATION_DIVISOR_KEYS } from "./constants";

export type DurationDivisorKey = (typeof DURATION_DIVISOR_KEYS)[number];

export type DurationTranslationFunction = (
key: "singular" | "plural",
params: { divisorKey: DurationDivisorKey }
) => string;
13 changes: 10 additions & 3 deletions web/src/core/usecases/fileExplorer/thunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import { join as pathJoin, basename as pathBasename } from "pathe";
import { crawlFactory } from "core/tools/crawl";
import * as s3ConfigManagement from "core/usecases/s3ConfigManagement";
import { S3Object } from "core/ports/S3Client";
import {
formatDuration,
englishDurationFormatter
} from "core/tools/timeFormat/formatDuration";

export type ExplorersCreateParams =
| ExplorersCreateParams.Directory
Expand Down Expand Up @@ -708,10 +712,14 @@ export const thunks = {

const cmdId = Date.now();

const prettyDurationValue = formatDuration({
durationSeconds: validityDurationSecond,
t: englishDurationFormatter
});
dispatch(
actions.commandLogIssued({
cmdId,
cmd: `mc share download --expire ${validityDurationSecond}s ${pathJoin("s3", path)}`
cmd: `mc share download --expire ${prettyDurationValue} ${pathJoin("s3", path)}`
})
);

Expand All @@ -732,8 +740,7 @@ export const thunks = {
cmdId,
resp: [
`URL: ${downloadUrl.split("?")[0]}`,
// TODO: Pretty print
`Expire: ${validityDurationSecond} seconds`,
`Expire: ${prettyDurationValue}`,
`Share: ${downloadUrl}`
].join("\n")
})
Expand Down
123 changes: 22 additions & 101 deletions web/src/ui/shared/formattedDate/dateTimeFormatter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { getTranslation } from "ui/i18n";
import { durationDivisorKeys, fromNowDivisorKeys } from "./type";
import { fromNowDivisorKeys } from "./type";
import { formatDuration as coreFormatDuration } from "core/tools/timeFormat/formatDuration";
import { TIME_UNITS } from "core/tools/timeFormat/constants";
import { assert } from "tsafe/assert";

export const { fromNow } = (() => {
Expand All @@ -13,14 +15,6 @@ export const { fromNow } = (() => {
futureN: string;
};

const SECOND = 1000;
const MINUTE = 60 * SECOND;
const HOUR = 60 * MINUTE;
const DAY = 24 * HOUR;
const WEEK = 7 * DAY;
const MONTH = 30 * DAY;
const YEAR = 365 * DAY;

function getFromNowUnits(): FromNowUnit[] {
const { t } = getTranslation("formattedDate");

Expand All @@ -30,37 +24,37 @@ export const { fromNow } = (() => {
case "now":
return 1;
case "second":
return SECOND;
return TIME_UNITS.SECOND;
case "minute":
return MINUTE;
return TIME_UNITS.MINUTE;
case "hour":
return HOUR;
return TIME_UNITS.HOUR;
case "day":
return DAY;
return TIME_UNITS.DAY;
case "week":
return WEEK;
return TIME_UNITS.WEEK;
case "month":
return MONTH;
return TIME_UNITS.MONTH;
case "year":
return YEAR;
return TIME_UNITS.YEAR;
}
})(),
max: (() => {
switch (divisorKey) {
case "now":
return 4 * SECOND;
return 4 * TIME_UNITS.SECOND;
case "second":
return MINUTE;
return TIME_UNITS.MINUTE;
case "minute":
return HOUR;
return TIME_UNITS.HOUR;
case "hour":
return DAY;
return TIME_UNITS.DAY;
case "day":
return WEEK;
return TIME_UNITS.WEEK;
case "week":
return MONTH;
return TIME_UNITS.MONTH;
case "month":
return YEAR;
return TIME_UNITS.YEAR;
case "year":
return Infinity;
}
Expand Down Expand Up @@ -93,81 +87,8 @@ export const { fromNow } = (() => {
return { fromNow };
})();

export const { formatDuration } = (() => {
const { getDurationUnits } = (() => {
type DurationUnit = {
max: number;
divisor: number;
singular: string;
plural: string;
};
const SECOND = 1000;
const MINUTE = 60 * SECOND;
const HOUR = 60 * MINUTE;
const DAY = 24 * HOUR;
const WEEK = 7 * DAY;
const MONTH = 30 * DAY;
const YEAR = 365 * DAY;

function getDurationUnits(): DurationUnit[] {
const { t } = getTranslation("formattedDate");

return durationDivisorKeys.map(divisorKey => ({
divisor: (() => {
switch (divisorKey) {
case "second":
return SECOND;
case "minute":
return MINUTE;
case "hour":
return HOUR;
case "day":
return DAY;
case "week":
return WEEK;
case "month":
return MONTH;
case "year":
return YEAR;
}
})(),
max: (() => {
switch (divisorKey) {
case "second":
return MINUTE;
case "minute":
return HOUR;
case "hour":
return 3 * DAY;
case "day":
return WEEK + DAY;
case "week":
return MONTH;
case "month":
return YEAR;
case "year":
return Infinity;
}
})(),
singular: t("singular", { divisorKey }),
plural: t("plural", { divisorKey })
}));
}

return { getDurationUnits };
})();

function formatDuration(params: { durationSeconds: number }): string {
const { durationSeconds } = params;

for (const unit of getDurationUnits()) {
if (durationSeconds * 1000 < unit.max) {
const x = Math.round(durationSeconds / (unit.divisor / 1000));
return x === 1 ? unit.singular : unit.plural.replace("#", `${x}`);
}
}
assert(false);
}

return { formatDuration };
})();
export const formatDuration = (params: { durationSeconds: number }) => {
const { t } = getTranslation("formattedDate");
const { durationSeconds } = params;
return coreFormatDuration({ durationSeconds, t });
};
5 changes: 5 additions & 0 deletions web/src/ui/shared/formattedDate/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export const durationDivisorKeys = [
] as const;
export type DurationDivisorKey = (typeof durationDivisorKeys)[number];

export type DurationTranslationFunction = (
key: "singular" | "plural",
params: { divisorKey: DurationDivisorKey }
) => string;

export const fromNowDivisorKeys = [...durationDivisorKeys, "now"] as const;
export type FromNowDivisorKey = (typeof fromNowDivisorKeys)[number];

Expand Down

0 comments on commit c9a48eb

Please sign in to comment.