Draft: Mark strings for translation. (#3458)

* Mark strings for translation.

* Mark up strings for translation

* fix(web): fix linter warnings

---------

Co-authored-by: Le fractal <17422-fractal@users.noreply.framagit.org>
Co-authored-by: Gabe Kangas <gabek@real-ity.com>
This commit is contained in:
taintedcypher 2024-04-23 03:56:02 +02:00 committed by GitHub
parent e2b9db1e66
commit 7013c214d6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 80 additions and 52 deletions

View file

@ -1,3 +1,4 @@
import { useTranslation } from 'next-export-i18n';
import { Card, Col, Row, Typography } from 'antd';
import Link from 'next/link';
import { FC, useContext } from 'react';
@ -43,6 +44,7 @@ export type OfflineProps = {
export const Offline: FC<OfflineProps> = ({ logs = [], config }) => {
const serverStatusData = useContext(ServerStatusContext);
const { t } = useTranslation();
const { serverConfig } = serverStatusData || {};
const { rtmpServerPort, streamKeyOverridden } = serverConfig;
const instanceUrl = global.window?.location.hostname || '';
@ -55,7 +57,7 @@ export const Offline: FC<OfflineProps> = ({ logs = [], config }) => {
const data = [
{
icon: <BookTwoTone twoToneColor="#6f42c1" />,
title: 'Use your broadcasting software',
title: t('Use your broadcasting software'),
content: (
<div>
<a
@ -63,12 +65,13 @@ export const Offline: FC<OfflineProps> = ({ logs = [], config }) => {
target="_blank"
rel="noopener noreferrer"
>
Learn how to point your existing software to your new server and start streaming your
content.
{t(
'Learn how to point your existing software to your new server and start streaming your content.',
)}
</a>
<div className="stream-info-container">
<Text strong className="stream-info-label">
Streaming URL:
{t('Streaming URL:')}
</Text>
{rtmpURL && (
<Paragraph className="stream-info-box" copyable>
@ -76,14 +79,14 @@ export const Offline: FC<OfflineProps> = ({ logs = [], config }) => {
</Paragraph>
)}
<Text strong className="stream-info-label">
Streaming Keys:
{t('Streaming Keys:')}
</Text>
<Text strong className="stream-info-box">
{!streamKeyOverridden ? (
<Link href="/admin/config/server"> View </Link>
<Link href="/admin/config/server"> {t('View')} </Link>
) : (
<span style={{ paddingLeft: '10px', fontWeight: 'normal' }}>
Overridden via command line.
{t('Overridden via command line.')}
</span>
)}
</Text>
@ -93,7 +96,7 @@ export const Offline: FC<OfflineProps> = ({ logs = [], config }) => {
},
{
icon: <PlaySquareTwoTone twoToneColor="#f9826c" />,
title: 'Embed your video onto other sites',
title: t('Embed your video onto other sites'),
content: (
<div>
<a
@ -101,7 +104,7 @@ export const Offline: FC<OfflineProps> = ({ logs = [], config }) => {
target="_blank"
rel="noopener noreferrer"
>
Learn how you can add your Owncast stream to other sites you control.
{t('Learn how you can add your Owncast stream to other sites you control.')}
</a>
</div>
),
@ -111,19 +114,19 @@ export const Offline: FC<OfflineProps> = ({ logs = [], config }) => {
if (!config?.chatDisabled) {
data.push({
icon: <MessageTwoTone twoToneColor="#0366d6" />,
title: 'Chat is disabled',
content: <span>Chat will continue to be disabled until you begin a live stream.</span>,
title: t('Chat is disabled'),
content: <span>{t('Chat will continue to be disabled until you begin a live stream.')}</span>,
});
}
if (!config?.yp?.enabled) {
data.push({
icon: <ProfileTwoTone twoToneColor="#D18BFE" />,
title: 'Find an audience on the Owncast Directory',
title: t('Find an audience on the Owncast Directory'),
content: (
<div>
List yourself in the Owncast Directory and show off your stream. Enable it in{' '}
<Link href="/admin/config/general/">settings.</Link>
{t('List yourself in the Owncast Directory and show off your stream. Enable it in')}{' '}
<Link href="/admin/config/general/">{t('settings.')}</Link>
</div>
),
});
@ -132,12 +135,13 @@ export const Offline: FC<OfflineProps> = ({ logs = [], config }) => {
if (!config?.federation?.enabled) {
data.push({
icon: <img alt="fediverse" width="20px" src="/img/fediverse-color.png" />,
title: 'Add your Owncast instance to the Fediverse',
title: t('Add your Owncast instance to the Fediverse'),
content: (
<div>
<Link href="/admin/config-federation/">Enable Owncast social</Link> features to have your
instance join the Fediverse, allowing people to follow, share and engage with your live
stream.
<Link href="/admin/config-federation/">{t('Enable Owncast social features')}</Link>{' '}
{t(
'to have your instance join the Fediverse, allowing people to follow, share and engage with your live stream.',
)}
</div>
),
});
@ -152,8 +156,8 @@ export const Offline: FC<OfflineProps> = ({ logs = [], config }) => {
<OwncastLogo variant="simple" />
</span>
<div>
<Title level={2}>No stream is active</Title>
<p>You should start one.</p>
<Title level={2}>{t('No stream is active')}</Title>
<p>{t('You should start one.')}</p>
</div>
</div>
</Col>

View file

@ -5,6 +5,7 @@ import { ColumnsType } from 'antd/es/table';
import { format } from 'date-fns';
import dynamic from 'next/dynamic';
import { useTranslation } from 'next-export-i18n';
import { MessageType } from '../../../types/chat';
import {
CHAT_HISTORY,
@ -61,6 +62,7 @@ export default function Chat() {
const [bulkProcessing, setBulkProcessing] = useState(false);
const [bulkOutcome, setBulkOutcome] = useState(null);
const [bulkAction, setBulkAction] = useState('');
const { t } = useTranslation();
let outcomeTimeout = null;
let chatReloadInterval = null;
@ -153,7 +155,7 @@ export default function Chat() {
const chatColumns: ColumnsType<MessageType> = [
{
title: 'Time',
title: t('Time'),
dataIndex: 'timestamp',
key: 'timestamp',
className: 'timestamp-col',
@ -166,7 +168,7 @@ export default function Chat() {
width: 90,
},
{
title: 'User',
title: t('User'),
dataIndex: 'user',
key: 'user',
className: 'name-col',
@ -182,7 +184,7 @@ export default function Chat() {
width: 110,
},
{
title: 'Message',
title: t('Message'),
dataIndex: 'body',
key: 'body',
className: 'message-col',
@ -201,8 +203,8 @@ export default function Chat() {
key: 'hiddenAt',
className: 'toggle-col',
filters: [
{ text: 'Visible messages', value: true },
{ text: 'Hidden messages', value: false },
{ text: t('Visible messages'), value: true },
{ text: t('Hidden messages'), value: false },
],
onFilter: (value, record) => record.visible === value,
render: (hiddenAt, record) => (
@ -219,10 +221,12 @@ export default function Chat() {
return (
<div className="chat-messages">
<Title>Chat Messages</Title>
<p>Manage the messages from viewers that show up on your stream.</p>
<Title>{t('Chat Messages')}</Title>
<p>{t('Manage the messages from viewers that show up on your stream.')}</p>
<div className={bulkDivClasses}>
<span className="label">Check multiple messages to change their visibility to: </span>
<span className="label">
{t('Check multiple messages to change their visibility to:')}{' '}
</span>
<Button
type="primary"
@ -234,7 +238,7 @@ export default function Chat() {
disabled={!selectedRowKeys.length || (bulkAction && bulkAction !== 'show')}
onClick={handleSubmitBulkShow}
>
Show
{t('Show')}
</Button>
<Button
type="primary"
@ -246,7 +250,7 @@ export default function Chat() {
disabled={!selectedRowKeys.length || (bulkAction && bulkAction !== 'hide')}
onClick={handleSubmitBulkHide}
>
Hide
{t('Hide')}
</Button>
</div>
<Table

View file

@ -1,5 +1,6 @@
import React, { useState, useEffect, useContext, ReactElement } from 'react';
import { Tabs } from 'antd';
import { useTranslation } from 'next-export-i18n';
import { ServerStatusContext } from '../../../utils/server-status-context';
import {
CONNECTED_CLIENTS,
@ -24,6 +25,7 @@ export default function ChatUsers() {
const [ipBans, setIPBans] = useState([]);
const [clients, setClients] = useState([]);
const [moderators, setModerators] = useState([]);
const { t } = useTranslation();
const getInfo = async () => {
try {
@ -71,34 +73,50 @@ export default function ChatUsers() {
<>
<ClientTable data={clients} />
<p className="description">
Visit the{' '}
{t('Visit the')}{' '}
<a
href="https://owncast.online/docs/viewers/?source=admin"
target="_blank"
rel="noopener noreferrer"
>
documentation
{t('documentation')}
</a>{' '}
to configure additional details about your viewers.
{t('to configure additional details about your viewers.')}
</p>
</>
) : (
<p className="description">
When a stream is active and chat is enabled, connected chat clients will be displayed here.
{t(
'When a stream is active and chat is enabled, connected chat clients will be displayed here.',
)}
</p>
);
const connectedUserTabTitle = (
<span>Connected {online ? `(${clients.length})` : '(offline)'}</span>
<span>
{t('Connected')} ({online ? clients.length : t('offline')})
</span>
);
const bannedUsersTabTitle = <span>Banned Users ({disabledUsers.length})</span>;
const bannedUsersTabTitle = (
<span>
{t('Banned Users')} ({disabledUsers.length})
</span>
);
const bannedUsersTable = <UserTable data={disabledUsers} />;
const bannedIPTabTitle = <span>IP Bans ({ipBans.length})</span>;
const bannedIPTabTitle = (
<span>
{t('IP Bans')} ({ipBans.length})
</span>
);
const bannedIpTable = <BannedIPsTable data={ipBans} />;
const moderatorUsersTabTitle = <span>Moderators ({moderators.length})</span>;
const moderatorUsersTabTitle = (
<span>
{t('Moderators')} ({moderators.length})
</span>
);
const moderatorTable = <UserTable data={moderators} />;
const items = [

View file

@ -2,6 +2,7 @@ import React, { useState, useEffect, useContext, ReactElement } from 'react';
import { Row, Col, Typography, MenuProps, Dropdown, Spin, Alert } from 'antd';
import { getUnixTime, sub } from 'date-fns';
import dynamic from 'next/dynamic';
import { useTranslation } from 'next-export-i18n';
import { Chart } from '../../components/admin/Chart';
import { StatisticItem } from '../../components/admin/StatisticItem';
import { ViewerTable } from '../../components/admin/ViewerTable';
@ -26,6 +27,7 @@ const FETCH_INTERVAL = 60 * 1000; // 1 min
export default function ViewersOverTime() {
const context = useContext(ServerStatusContext);
const { t } = useTranslation();
const { online, broadcaster, viewerCount, overallPeakViewerCount, sessionPeakViewerCount } =
context || {};
let streamStart;
@ -34,13 +36,13 @@ export default function ViewersOverTime() {
}
const times = [
{ title: 'Current stream', start: streamStart },
{ title: 'Last 12 hours', start: sub(new Date(), { hours: 12 }) },
{ title: 'Last 24 hours', start: sub(new Date(), { hours: 24 }) },
{ title: 'Last 7 days', start: sub(new Date(), { days: 7 }) },
{ title: 'Last 30 days', start: sub(new Date(), { days: 30 }) },
{ title: 'Last 3 months', start: sub(new Date(), { months: 3 }) },
{ title: 'Last 6 months', start: sub(new Date(), { months: 6 }) },
{ title: t('Current stream'), start: streamStart },
{ title: t('Last 12 hours'), start: sub(new Date(), { hours: 12 }) },
{ title: t('Last 24 hours'), start: sub(new Date(), { hours: 24 }) },
{ title: t('Last 7 days'), start: sub(new Date(), { days: 7 }) },
{ title: t('Last 30 days'), start: sub(new Date(), { days: 30 }) },
{ title: t('Last 3 months'), start: sub(new Date(), { months: 3 }) },
{ title: t('Last 6 months'), start: sub(new Date(), { months: 6 }) },
];
const [loadingChart, setLoadingChart] = useState(true);
@ -94,13 +96,13 @@ export default function ViewersOverTime() {
return (
<>
<Typography.Title>Viewer Info</Typography.Title>
<Typography.Title>{t('Viewer Info')}</Typography.Title>
<br />
<Row gutter={[16, 16]} justify="space-around">
{online && (
<Col span={8} md={8}>
<StatisticItem
title="Current viewers"
title={t('Current viewers')}
value={viewerCount.toString()}
prefix={<UserOutlined />}
/>
@ -108,14 +110,14 @@ export default function ViewersOverTime() {
)}
<Col md={online ? 8 : 12}>
<StatisticItem
title={online ? 'Max viewers this stream' : 'Max viewers last stream'}
title={online ? t('Max viewers this stream') : t('Max viewers last stream')}
value={sessionPeakViewerCount.toString()}
prefix={<UserOutlined />}
/>
</Col>
<Col md={online ? 8 : 12}>
<StatisticItem
title="All-time max viewers"
title={t('max viewers')}
value={overallPeakViewerCount.toString()}
prefix={<UserOutlined />}
/>
@ -125,8 +127,8 @@ export default function ViewersOverTime() {
<Alert
style={{ marginTop: '10px' }}
banner
message="Please wait"
description="No viewer data has been collected yet."
message={t('Please wait')}
description={t('No viewer data has been collected yet.')}
type="info"
/>
)}
@ -134,7 +136,7 @@ export default function ViewersOverTime() {
<Spin spinning={!viewerInfo.length || loadingChart}>
{viewerInfo.length > 0 && (
<Chart
title="Viewers"
title={t('Viewers')}
data={viewerInfo}
color="#2087E2"
unit="viewers"