feat: localization (#196)

* Started adding locale translations :)

* Added some more translations

* Working on translating even more pages

* More translations

* Added test default locale retrieval

* replace `intl.formatMessage` with custom `t` hook

* add more translations

* improve title syntax

* add more translations

* translate admin config page

* translated error messages

* add language selecter

* minor fixes

* improve language handling

* add upcoming languages

* add `crowdin.yml`

* run formatter

---------

Co-authored-by: Steve Tautonico <stautonico@gmail.com>
This commit is contained in:
Elias Schneider
2023-07-20 15:32:07 +02:00
committed by GitHub
parent 7c5ec8d0ea
commit b9f6e3bd08
68 changed files with 4712 additions and 461 deletions

View File

@@ -1,6 +1,8 @@
import { Button, Stack } from "@mantine/core";
import { useModals } from "@mantine/modals";
import { ModalsContextProps } from "@mantine/modals/lib/context";
import { FormattedMessage } from "react-intl";
import { translateOutsideContext } from "../../../hooks/useTranslate.hook";
import CopyTextField from "../../upload/CopyTextField";
const showCompletedReverseShareModal = (
@@ -8,11 +10,12 @@ const showCompletedReverseShareModal = (
link: string,
getReverseShares: () => void
) => {
const t = translateOutsideContext();
return modals.openModal({
closeOnClickOutside: false,
withCloseButton: false,
closeOnEscape: false,
title: "Reverse share link",
title: t("account.reverseShares.modal.reverse-share-link"),
children: <Body link={link} getReverseShares={getReverseShares} />,
});
};
@@ -36,7 +39,7 @@ const Body = ({
getReverseShares();
}}
>
Done
<FormattedMessage id="common.button.done" />
</Button>
</Stack>
);

View File

@@ -12,6 +12,8 @@ import {
import { useForm } from "@mantine/form";
import { useModals } from "@mantine/modals";
import { ModalsContextProps } from "@mantine/modals/lib/context";
import { FormattedMessage } from "react-intl";
import useTranslate from "../../../hooks/useTranslate.hook";
import shareService from "../../../services/share.service";
import { getExpirationPreview } from "../../../utils/date.util";
import toast from "../../../utils/toast.util";
@@ -42,6 +44,7 @@ const Body = ({
showSendEmailNotificationOption: boolean;
}) => {
const modals = useModals();
const t = useTranslate();
const form = useForm({
initialValues: {
@@ -79,7 +82,7 @@ const Body = ({
max={99999}
precision={0}
variant="filled"
label="Share expiration"
label={t("account.reverseShares.modal.expiration.label")}
{...form.getInputProps("expiration_num")}
/>
</Col>
@@ -91,27 +94,44 @@ const Body = ({
{
value: "-minutes",
label:
"Minute" + (form.values.expiration_num == 1 ? "" : "s"),
form.values.expiration_num == 1
? t("upload.modal.expires.minute-singular")
: t("upload.modal.expires.minute-plural"),
},
{
value: "-hours",
label:
"Hour" + (form.values.expiration_num == 1 ? "" : "s"),
form.values.expiration_num == 1
? t("upload.modal.expires.hour-singular")
: t("upload.modal.expires.hour-plural"),
},
{
value: "-days",
label:
"Day" + (form.values.expiration_num == 1 ? "" : "s"),
form.values.expiration_num == 1
? t("upload.modal.expires.day-singular")
: t("upload.modal.expires.day-plural"),
},
{
value: "-weeks",
label:
"Week" + (form.values.expiration_num == 1 ? "" : "s"),
form.values.expiration_num == 1
? t("upload.modal.expires.week-singular")
: t("upload.modal.expires.week-plural"),
},
{
value: "-months",
label:
"Month" + (form.values.expiration_num == 1 ? "" : "s"),
form.values.expiration_num == 1
? t("upload.modal.expires.month-singular")
: t("upload.modal.expires.month-plural"),
},
{
value: "-years",
label:
form.values.expiration_num == 1
? t("upload.modal.expires.year-singular")
: t("upload.modal.expires.year-plural"),
},
]}
/>
@@ -125,11 +145,17 @@ const Body = ({
color: theme.colors.gray[6],
})}
>
{getExpirationPreview("reverse share", form)}
{getExpirationPreview(
{
expiresOn: t("account.reverseShare.expires-on"),
neverExpires: t("account.reverseShare.never-expires"),
},
form
)}
</Text>
</div>
<FileSizeInput
label="Max share size"
label={t("account.reverseShares.modal.max-size.label")}
value={form.values.maxShareSize}
onChange={(number) => form.setFieldValue("maxShareSize", number)}
/>
@@ -138,16 +164,18 @@ const Body = ({
max={1000}
precision={0}
variant="filled"
label="Max use count"
description="The maximum number of times this reverse share link can be used"
label={t("account.reverseShares.modal.max-use.label")}
description={t("account.reverseShares.modal.max-use.description")}
{...form.getInputProps("maxUseCount")}
/>
{showSendEmailNotificationOption && (
<Switch
mt="xs"
labelPosition="left"
label="Send email notification"
description="Send an email notification when a share is created with this reverse share link"
label={t("account.reverseShares.modal.send-email")}
description={t(
"account.reverseShares.modal.send-email.description"
)}
{...form.getInputProps("sendEmailNotification", {
type: "checkbox",
})}
@@ -155,7 +183,7 @@ const Body = ({
)}
<Button mt="md" type="submit">
Create
<FormattedMessage id="common.button.create" />
</Button>
</Stack>
</form>