Extracting translation strings
parent
0ec9a4c89b
commit
893701c07b
|
@ -1,3 +1,8 @@
|
||||||
{
|
{
|
||||||
|
"nav_topics_title": "Abonnierte Themen",
|
||||||
|
"nav_button_all_notifications": "Alle Benachrichtigungen",
|
||||||
|
"nav_button_settings": "Einstellungen",
|
||||||
|
"nav_button_documentation": "Dokumentation",
|
||||||
|
"nav_button_publish_message": "Nachricht senden",
|
||||||
"nav_button_subscribe": "Thema abonnieren"
|
"nav_button_subscribe": "Thema abonnieren"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,35 @@
|
||||||
{
|
{
|
||||||
"nav_button_subscribe": "Subscribe to topic"
|
"nav_topics_title": "Subscribed topics",
|
||||||
|
"nav_button_all_notifications": "All notifications",
|
||||||
|
"nav_button_settings": "Settings",
|
||||||
|
"nav_button_documentation": "Documentation",
|
||||||
|
"nav_button_publish_message": "Publish message",
|
||||||
|
"nav_button_subscribe": "Subscribe to topic",
|
||||||
|
"alert_grant_title": "Notifications are disabled",
|
||||||
|
"alert_grant_description": "Grant your browser permission to display desktop notifications.",
|
||||||
|
"alert_grant_button": "Grant now",
|
||||||
|
"alert_not_supported_title": "Notifications not supported",
|
||||||
|
"alert_not_supported_description": "Notifications are not supported in your browser.",
|
||||||
|
"notifications_copied_to_clipboard": "Copied to clipboard",
|
||||||
|
"notifications_tags": "Tags",
|
||||||
|
"notifications_attachment_copy_url_title": "Copy attachment URL to clipboard",
|
||||||
|
"notifications_attachment_copy_url_button": "Copy URL",
|
||||||
|
"notifications_attachment_open_title": "Go to {{url}}",
|
||||||
|
"notifications_attachment_open_button": "Open attachment",
|
||||||
|
"notifications_attachment_link_expires": "link expires {{date}}",
|
||||||
|
"notifications_attachment_link_expired": "download link expired",
|
||||||
|
"notifications_click_copy_url_title": "Copy link URL to clipboard",
|
||||||
|
"notifications_click_copy_url_button": "Copy link",
|
||||||
|
"notifications_click_open_title": "Go to {{url}}",
|
||||||
|
"notifications_click_open_button": "Open link",
|
||||||
|
"notifications_none_for_topic_title": "You haven't received any notifications for this topic yet.",
|
||||||
|
"notifications_none_for_topic_description": "To send notifications to this topic, simply PUT or POST to the topic URL.",
|
||||||
|
"notifications_none_for_any_title": "You haven't received any notifications.",
|
||||||
|
"notifications_none_for_any_description": "To send notifications to a topic, simply PUT or POST to the topic URL. Here's an example using one of your topics.",
|
||||||
|
"notifications_no_subscriptions_title": "It looks like you don't have any subscriptions yet.",
|
||||||
|
"notifications_no_subscriptions_description": "Click the \"Add subscription\" link to create or subscribe to a topic. After that, you can send messages via PUT or POST and you'll receive notifications here.",
|
||||||
|
"notifications_example": "Example",
|
||||||
|
"notifications_more_details": "For more information, check out the <websiteLink>website</websiteLink> or <docsLink>documentation</docsLink>.",
|
||||||
|
"notifications_loading": "Loading notifications ...",
|
||||||
|
"emoji_picker_search_placeholder": "Search emoji"
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import IconButton from "@mui/material/IconButton";
|
||||||
import {Close} from "@mui/icons-material";
|
import {Close} from "@mui/icons-material";
|
||||||
import Popper from "@mui/material/Popper";
|
import Popper from "@mui/material/Popper";
|
||||||
import {splitNoEmpty} from "../app/utils";
|
import {splitNoEmpty} from "../app/utils";
|
||||||
|
import {useTranslation} from "react-i18next";
|
||||||
|
|
||||||
// Create emoji list by category and create a search base (string with all search words)
|
// Create emoji list by category and create a search base (string with all search words)
|
||||||
//
|
//
|
||||||
|
@ -36,6 +37,7 @@ rawEmojis.forEach(emoji => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const EmojiPicker = (props) => {
|
const EmojiPicker = (props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const open = Boolean(props.anchorEl);
|
const open = Boolean(props.anchorEl);
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
const searchRef = useRef(null);
|
const searchRef = useRef(null);
|
||||||
|
@ -71,7 +73,7 @@ const EmojiPicker = (props) => {
|
||||||
inputRef={searchRef}
|
inputRef={searchRef}
|
||||||
margin="dense"
|
margin="dense"
|
||||||
size="small"
|
size="small"
|
||||||
placeholder="Search emoji"
|
placeholder={t("emoji_picker_search_placeholder")}
|
||||||
value={search}
|
value={search}
|
||||||
onChange={ev => setSearch(ev.target.value)}
|
onChange={ev => setSearch(ev.target.value)}
|
||||||
type="text"
|
type="text"
|
||||||
|
|
|
@ -97,14 +97,14 @@ const NavList = (props) => {
|
||||||
{!showSubscriptionsList &&
|
{!showSubscriptionsList &&
|
||||||
<ListItemButton onClick={() => navigate(routes.root)} selected={location.pathname === config.appRoot}>
|
<ListItemButton onClick={() => navigate(routes.root)} selected={location.pathname === config.appRoot}>
|
||||||
<ListItemIcon><ChatBubble/></ListItemIcon>
|
<ListItemIcon><ChatBubble/></ListItemIcon>
|
||||||
<ListItemText primary="All notifications"/>
|
<ListItemText primary={t("nav_button_all_notifications")}/>
|
||||||
</ListItemButton>}
|
</ListItemButton>}
|
||||||
{showSubscriptionsList &&
|
{showSubscriptionsList &&
|
||||||
<>
|
<>
|
||||||
<ListSubheader>Subscribed topics</ListSubheader>
|
<ListSubheader>{t("nav_topics_title")}</ListSubheader>
|
||||||
<ListItemButton onClick={() => navigate(routes.root)} selected={location.pathname === config.appRoot}>
|
<ListItemButton onClick={() => navigate(routes.root)} selected={location.pathname === config.appRoot}>
|
||||||
<ListItemIcon><ChatBubble/></ListItemIcon>
|
<ListItemIcon><ChatBubble/></ListItemIcon>
|
||||||
<ListItemText primary="All notifications"/>
|
<ListItemText primary={t("nav_button_all_notifications")}/>
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
<SubscriptionList
|
<SubscriptionList
|
||||||
subscriptions={props.subscriptions}
|
subscriptions={props.subscriptions}
|
||||||
|
@ -114,15 +114,15 @@ const NavList = (props) => {
|
||||||
</>}
|
</>}
|
||||||
<ListItemButton onClick={() => navigate(routes.settings)} selected={location.pathname === routes.settings}>
|
<ListItemButton onClick={() => navigate(routes.settings)} selected={location.pathname === routes.settings}>
|
||||||
<ListItemIcon><SettingsIcon/></ListItemIcon>
|
<ListItemIcon><SettingsIcon/></ListItemIcon>
|
||||||
<ListItemText primary="Settings"/>
|
<ListItemText primary={t("nav_button_settings")}/>
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
<ListItemButton onClick={() => openUrl("/docs")}>
|
<ListItemButton onClick={() => openUrl("/docs")}>
|
||||||
<ListItemIcon><ArticleIcon/></ListItemIcon>
|
<ListItemIcon><ArticleIcon/></ListItemIcon>
|
||||||
<ListItemText primary="Documentation"/>
|
<ListItemText primary={t("nav_button_documentation")}/>
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
<ListItemButton onClick={() => props.onPublishMessageClick()}>
|
<ListItemButton onClick={() => props.onPublishMessageClick()}>
|
||||||
<ListItemIcon><Send/></ListItemIcon>
|
<ListItemIcon><Send/></ListItemIcon>
|
||||||
<ListItemText primary="Publish message"/>
|
<ListItemText primary={t("nav_button_publish_message")}/>
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
<ListItemButton onClick={() => setSubscribeDialogOpen(true)}>
|
<ListItemButton onClick={() => setSubscribeDialogOpen(true)}>
|
||||||
<ListItemIcon><AddIcon/></ListItemIcon>
|
<ListItemIcon><AddIcon/></ListItemIcon>
|
||||||
|
@ -181,20 +181,19 @@ const SubscriptionItem = (props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const NotificationGrantAlert = (props) => {
|
const NotificationGrantAlert = (props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Alert severity="warning" sx={{paddingTop: 2}}>
|
<Alert severity="warning" sx={{paddingTop: 2}}>
|
||||||
<AlertTitle>Notifications are disabled</AlertTitle>
|
<AlertTitle>{t("alert_grant_title")}</AlertTitle>
|
||||||
<Typography gutterBottom>
|
<Typography gutterBottom>{t("alert_grant_description")}</Typography>
|
||||||
Grant your browser permission to display desktop notifications.
|
|
||||||
</Typography>
|
|
||||||
<Button
|
<Button
|
||||||
sx={{float: 'right'}}
|
sx={{float: 'right'}}
|
||||||
color="inherit"
|
color="inherit"
|
||||||
size="small"
|
size="small"
|
||||||
onClick={props.onRequestPermissionClick}
|
onClick={props.onRequestPermissionClick}
|
||||||
>
|
>
|
||||||
Grant now
|
{t("alert_grant_button")}
|
||||||
</Button>
|
</Button>
|
||||||
</Alert>
|
</Alert>
|
||||||
<Divider/>
|
<Divider/>
|
||||||
|
@ -203,13 +202,12 @@ const NotificationGrantAlert = (props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const NotificationNotSupportedAlert = () => {
|
const NotificationNotSupportedAlert = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Alert severity="warning" sx={{paddingTop: 2}}>
|
<Alert severity="warning" sx={{paddingTop: 2}}>
|
||||||
<AlertTitle>Notifications not supported</AlertTitle>
|
<AlertTitle>{t("alert_not_supported_title")}</AlertTitle>
|
||||||
<Typography gutterBottom>
|
<Typography gutterBottom>{t("alert_not_supported_description")}</Typography>
|
||||||
Notifications are not supported in your browser.
|
|
||||||
</Typography>
|
|
||||||
</Alert>
|
</Alert>
|
||||||
<Divider/>
|
<Divider/>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -39,6 +39,7 @@ import priority4 from "../img/priority-4.svg";
|
||||||
import priority5 from "../img/priority-5.svg";
|
import priority5 from "../img/priority-5.svg";
|
||||||
import logoOutline from "../img/ntfy-outline.svg";
|
import logoOutline from "../img/ntfy-outline.svg";
|
||||||
import AttachmentIcon from "./AttachmentIcon";
|
import AttachmentIcon from "./AttachmentIcon";
|
||||||
|
import {Trans, useTranslation} from "react-i18next";
|
||||||
|
|
||||||
const Notifications = (props) => {
|
const Notifications = (props) => {
|
||||||
if (props.mode === "all") {
|
if (props.mode === "all") {
|
||||||
|
@ -72,6 +73,7 @@ const SingleSubscription = (props) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const NotificationList = (props) => {
|
const NotificationList = (props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const pageSize = 20;
|
const pageSize = 20;
|
||||||
const notifications = props.notifications;
|
const notifications = props.notifications;
|
||||||
const [snackOpen, setSnackOpen] = useState(false);
|
const [snackOpen, setSnackOpen] = useState(false);
|
||||||
|
@ -112,7 +114,7 @@ const NotificationList = (props) => {
|
||||||
open={snackOpen}
|
open={snackOpen}
|
||||||
autoHideDuration={3000}
|
autoHideDuration={3000}
|
||||||
onClose={() => setSnackOpen(false)}
|
onClose={() => setSnackOpen(false)}
|
||||||
message="Copied to clipboard"
|
message={t("notifications_copied_to_clipboard")}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Container>
|
</Container>
|
||||||
|
@ -121,6 +123,7 @@ const NotificationList = (props) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const NotificationItem = (props) => {
|
const NotificationItem = (props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const notification = props.notification;
|
const notification = props.notification;
|
||||||
const attachment = notification.attachment;
|
const attachment = notification.attachment;
|
||||||
const date = formatShortDateTime(notification.time);
|
const date = formatShortDateTime(notification.time);
|
||||||
|
@ -160,24 +163,24 @@ const NotificationItem = (props) => {
|
||||||
{notification.title && <Typography variant="h5" component="div">{formatTitle(notification)}</Typography>}
|
{notification.title && <Typography variant="h5" component="div">{formatTitle(notification)}</Typography>}
|
||||||
<Typography variant="body1" sx={{ whiteSpace: 'pre-line' }}>{autolink(formatMessage(notification))}</Typography>
|
<Typography variant="body1" sx={{ whiteSpace: 'pre-line' }}>{autolink(formatMessage(notification))}</Typography>
|
||||||
{attachment && <Attachment attachment={attachment}/>}
|
{attachment && <Attachment attachment={attachment}/>}
|
||||||
{tags && <Typography sx={{ fontSize: 14 }} color="text.secondary">Tags: {tags}</Typography>}
|
{tags && <Typography sx={{ fontSize: 14 }} color="text.secondary">{t("notifications_tags")}: {tags}</Typography>}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
{showActions &&
|
{showActions &&
|
||||||
<CardActions sx={{paddingTop: 0}}>
|
<CardActions sx={{paddingTop: 0}}>
|
||||||
{showAttachmentActions && <>
|
{showAttachmentActions && <>
|
||||||
<Tooltip title="Copy attachment URL to clipboard">
|
<Tooltip title={t("notifications_attachment_copy_url_title")}>
|
||||||
<Button onClick={() => handleCopy(attachment.url)}>Copy URL</Button>
|
<Button onClick={() => handleCopy(attachment.url)}>{t("notifications_attachment_copy_url_button")}</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title={`Go to ${attachment.url}`}>
|
<Tooltip title={t("notifications_attachment_open_title", { url: attachment.url })}>
|
||||||
<Button onClick={() => openUrl(attachment.url)}>Open attachment</Button>
|
<Button onClick={() => openUrl(attachment.url)}>{t("notifications_attachment_open_button")}</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</>}
|
</>}
|
||||||
{showClickAction && <>
|
{showClickAction && <>
|
||||||
<Tooltip title="Copy link URL to clipboard">
|
<Tooltip title={t("notifications_click_copy_url_title")}>
|
||||||
<Button onClick={() => handleCopy(notification.click)}>Copy link</Button>
|
<Button onClick={() => handleCopy(notification.click)}>{t("notifications_click_copy_url_button")}</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title={`Go to ${notification.click}`}>
|
<Tooltip title={t("notifications_click_open_title", { url: notification.click })}>
|
||||||
<Button onClick={() => openUrl(notification.click)}>Open link</Button>
|
<Button onClick={() => openUrl(notification.click)}>{t("notifications_click_open_button")}</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</>}
|
</>}
|
||||||
</CardActions>}
|
</CardActions>}
|
||||||
|
@ -208,6 +211,7 @@ const priorityFiles = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const Attachment = (props) => {
|
const Attachment = (props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const attachment = props.attachment;
|
const attachment = props.attachment;
|
||||||
const expired = attachment.expires && attachment.expires < Date.now()/1000;
|
const expired = attachment.expires && attachment.expires < Date.now()/1000;
|
||||||
const expires = attachment.expires && attachment.expires > Date.now()/1000;
|
const expires = attachment.expires && attachment.expires > Date.now()/1000;
|
||||||
|
@ -224,10 +228,10 @@ const Attachment = (props) => {
|
||||||
infos.push(formatBytes(attachment.size));
|
infos.push(formatBytes(attachment.size));
|
||||||
}
|
}
|
||||||
if (expires) {
|
if (expires) {
|
||||||
infos.push(`link expires ${formatShortDateTime(attachment.expires)}`);
|
infos.push(t("notifications_attachment_link_expires", { date: formatShortDateTime(attachment.expires) }));
|
||||||
}
|
}
|
||||||
if (expired) {
|
if (expired) {
|
||||||
infos.push(`download link expired`);
|
infos.push(t("notifications_attachment_link_expired"));
|
||||||
}
|
}
|
||||||
const maybeInfoText = (infos.length > 0) ? <><br/>{infos.join(", ")}</> : null;
|
const maybeInfoText = (infos.length > 0) ? <><br/>{infos.join(", ")}</> : null;
|
||||||
|
|
||||||
|
@ -326,82 +330,93 @@ const Image = (props) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const NoNotifications = (props) => {
|
const NoNotifications = (props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const shortUrl = topicShortUrl(props.subscription.baseUrl, props.subscription.topic);
|
const shortUrl = topicShortUrl(props.subscription.baseUrl, props.subscription.topic);
|
||||||
return (
|
return (
|
||||||
<VerticallyCenteredContainer maxWidth="xs">
|
<VerticallyCenteredContainer maxWidth="xs">
|
||||||
<Typography variant="h5" align="center" sx={{ paddingBottom: 1 }}>
|
<Typography variant="h5" align="center" sx={{ paddingBottom: 1 }}>
|
||||||
<img src={logoOutline} height="64" width="64" alt="No notifications"/><br />
|
<img src={logoOutline} height="64" width="64"/><br />
|
||||||
You haven't received any notifications for this topic yet.
|
{t("notifications_none_for_topic_title")}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Paragraph>
|
<Paragraph>
|
||||||
To send notifications to this topic, simply PUT or POST to the topic URL.
|
{t("notifications_none_for_topic_description")}
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
<Paragraph>
|
<Paragraph>
|
||||||
Example:<br/>
|
{t("notifications_example")}:<br/>
|
||||||
<tt>
|
<tt>
|
||||||
$ curl -d "Hi" {shortUrl}
|
$ curl -d "Hi" {shortUrl}
|
||||||
</tt>
|
</tt>
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
<Paragraph>
|
<Paragraph>
|
||||||
For more detailed instructions, check out the <Link href="https://ntfy.sh" target="_blank" rel="noopener">website</Link> or
|
<ForMoreDetails/>
|
||||||
{" "}<Link href="https://ntfy.sh/docs" target="_blank" rel="noopener">documentation</Link>.
|
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
</VerticallyCenteredContainer>
|
</VerticallyCenteredContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const NoNotificationsWithoutSubscription = (props) => {
|
const NoNotificationsWithoutSubscription = (props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const subscription = props.subscriptions[0];
|
const subscription = props.subscriptions[0];
|
||||||
const shortUrl = topicShortUrl(subscription.baseUrl, subscription.topic);
|
const shortUrl = topicShortUrl(subscription.baseUrl, subscription.topic);
|
||||||
return (
|
return (
|
||||||
<VerticallyCenteredContainer maxWidth="xs">
|
<VerticallyCenteredContainer maxWidth="xs">
|
||||||
<Typography variant="h5" align="center" sx={{ paddingBottom: 1 }}>
|
<Typography variant="h5" align="center" sx={{ paddingBottom: 1 }}>
|
||||||
<img src={logoOutline} height="64" width="64" alt="No notifications"/><br />
|
<img src={logoOutline} height="64" width="64"/><br />
|
||||||
You haven't received any notifications.
|
{t("notifications_none_for_any_title")}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Paragraph>
|
<Paragraph>
|
||||||
To send notifications to a topic, simply PUT or POST to the topic URL. Here's
|
{t("notifications_none_for_any_description")}
|
||||||
an example using one of your topics.
|
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
<Paragraph>
|
<Paragraph>
|
||||||
Example:<br/>
|
{t("notifications_example")}:<br/>
|
||||||
<tt>
|
<tt>
|
||||||
$ curl -d "Hi" {shortUrl}
|
$ curl -d "Hi" {shortUrl}
|
||||||
</tt>
|
</tt>
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
<Paragraph>
|
<Paragraph>
|
||||||
For more detailed instructions, check out the <Link href="https://ntfy.sh" target="_blank" rel="noopener">website</Link> or
|
<ForMoreDetails/>
|
||||||
{" "}<Link href="https://ntfy.sh/docs" target="_blank" rel="noopener">documentation</Link>.
|
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
</VerticallyCenteredContainer>
|
</VerticallyCenteredContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const NoSubscriptions = () => {
|
const NoSubscriptions = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<VerticallyCenteredContainer maxWidth="xs">
|
<VerticallyCenteredContainer maxWidth="xs">
|
||||||
<Typography variant="h5" align="center" sx={{ paddingBottom: 1 }}>
|
<Typography variant="h5" align="center" sx={{ paddingBottom: 1 }}>
|
||||||
<img src={logoOutline} height="64" width="64" alt="No topics"/><br />
|
<img src={logoOutline} height="64" width="64"/><br />
|
||||||
It looks like you don't have any subscriptions yet.
|
{t("notifications_no_subscriptions_title")}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Paragraph>
|
<Paragraph>
|
||||||
Click the "Add subscription" link to create or subscribe to a topic. After that, you can send messages
|
{t("notifications_no_subscriptions_description")}
|
||||||
via PUT or POST and you'll receive notifications here.
|
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
<Paragraph>
|
<Paragraph>
|
||||||
For more information, check out the <Link href="https://ntfy.sh" target="_blank" rel="noopener">website</Link> or
|
<ForMoreDetails/>
|
||||||
{" "}<Link href="https://ntfy.sh/docs" target="_blank" rel="noopener">documentation</Link>.
|
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
</VerticallyCenteredContainer>
|
</VerticallyCenteredContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ForMoreDetails = () => {
|
||||||
|
return (
|
||||||
|
<Trans
|
||||||
|
i18nKey="notifications_more_details"
|
||||||
|
components={{
|
||||||
|
websiteLink: <Link href="https://ntfy.sh" target="_blank" rel="noopener"/>,
|
||||||
|
docsLink: <Link href="https://ntfy.sh/docs" target="_blank" rel="noopener"/>
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const Loading = () => {
|
const Loading = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<VerticallyCenteredContainer>
|
<VerticallyCenteredContainer>
|
||||||
<Typography variant="h5" color="text.secondary" align="center" sx={{ paddingBottom: 1 }}>
|
<Typography variant="h5" color="text.secondary" align="center" sx={{ paddingBottom: 1 }}>
|
||||||
<CircularProgress disableShrink sx={{marginBottom: 1}}/><br />
|
<CircularProgress disableShrink sx={{marginBottom: 1}}/><br />
|
||||||
Loading notifications ...
|
{t("notifications_loading")}
|
||||||
</Typography>
|
</Typography>
|
||||||
</VerticallyCenteredContainer>
|
</VerticallyCenteredContainer>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue