summaryrefslogtreecommitdiffstats
path: root/ui/src/components
diff options
context:
space:
mode:
authorDessalines <dessalines@users.noreply.github.com>2019-08-09 17:14:43 -0700
committerGitHub <noreply@github.com>2019-08-09 17:14:43 -0700
commit536c3f491546b4546f43a46e7a1a699ca9ac2934 (patch)
treef080c86e51b9660560ac493cb7f6d9676ea12fbe /ui/src/components
parent5a1e8aa645c9f0898e765b45c2f362308292db26 (diff)
Adding support for internationalization / i18n (#189)
* Still not working * Starting to work on internationalization * Main done. * i18n translations first pass. * Localization testing mostly done. * Second front end pass. * Added a few more translations. * Adding back end translations.
Diffstat (limited to 'ui/src/components')
-rw-r--r--ui/src/components/comment-form.tsx10
-rw-r--r--ui/src/components/comment-node.tsx51
-rw-r--r--ui/src/components/comment-nodes.tsx2
-rw-r--r--ui/src/components/communities.tsx36
-rw-r--r--ui/src/components/community-form.tsx23
-rw-r--r--ui/src/components/community.tsx25
-rw-r--r--ui/src/components/create-community.tsx6
-rw-r--r--ui/src/components/create-post.tsx6
-rw-r--r--ui/src/components/footer.tsx9
-rw-r--r--ui/src/components/home.tsx0
-rw-r--r--ui/src/components/inbox.tsx36
-rw-r--r--ui/src/components/login.tsx27
-rw-r--r--ui/src/components/main.tsx120
-rw-r--r--ui/src/components/modlog.tsx2
-rw-r--r--ui/src/components/moment-time.tsx6
-rw-r--r--ui/src/components/navbar.tsx21
-rw-r--r--ui/src/components/post-form.tsx22
-rw-r--r--ui/src/components/post-listing.tsx36
-rw-r--r--ui/src/components/post-listings.tsx7
-rw-r--r--ui/src/components/post.tsx12
-rw-r--r--ui/src/components/search.tsx42
-rw-r--r--ui/src/components/setup.tsx22
-rw-r--r--ui/src/components/sidebar.tsx38
-rw-r--r--ui/src/components/site-form.tsx13
-rw-r--r--ui/src/components/sponsors.tsx20
-rw-r--r--ui/src/components/user.tsx48
26 files changed, 357 insertions, 283 deletions
diff --git a/ui/src/components/comment-form.tsx b/ui/src/components/comment-form.tsx
index 5181e45e..ed62fcf5 100644
--- a/ui/src/components/comment-form.tsx
+++ b/ui/src/components/comment-form.tsx
@@ -1,7 +1,10 @@
import { Component, linkEvent } from 'inferno';
import { CommentNode as CommentNodeI, CommentForm as CommentFormI } from '../interfaces';
+import { capitalizeFirstLetter } from '../utils';
import { WebSocketService, UserService } from '../services';
import * as autosize from 'autosize';
+import { i18n } from '../i18next';
+import { T } from 'inferno-i18next';
interface CommentFormProps {
postId?: number;
@@ -25,12 +28,13 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
post_id: this.props.node ? this.props.node.comment.post_id : this.props.postId,
creator_id: UserService.Instance.user ? UserService.Instance.user.id : null,
},
- buttonTitle: !this.props.node ? "Post" : this.props.edit ? "Edit" : "Reply",
+ buttonTitle: !this.props.node ? capitalizeFirstLetter(i18n.t('post')) : this.props.edit ? capitalizeFirstLetter(i18n.t('edit')) : capitalizeFirstLetter(i18n.t('reply')),
}
constructor(props: any, context: any) {
super(props, context);
+
this.state = this.emptyState;
if (this.props.node) {
@@ -62,7 +66,7 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
<div class="row">
<div class="col-sm-12">
<button type="submit" class="btn btn-sm btn-secondary mr-2" disabled={this.props.disabled}>{this.state.buttonTitle}</button>
- {this.props.node && <button type="button" class="btn btn-sm btn-secondary" onClick={linkEvent(this, this.handleReplyCancel)}>Cancel</button>}
+ {this.props.node && <button type="button" class="btn btn-sm btn-secondary" onClick={linkEvent(this, this.handleReplyCancel)}><T i18nKey="cancel">#</T></button>}
</div>
</div>
</form>
@@ -84,7 +88,7 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
if (i.props.node) {
i.props.onReplyCancel();
}
-
+
autosize.update(document.querySelector('textarea'));
}
diff --git a/ui/src/components/comment-node.tsx b/ui/src/components/comment-node.tsx
index a201ddd6..a1ac93b3 100644
--- a/ui/src/components/comment-node.tsx
+++ b/ui/src/components/comment-node.tsx
@@ -7,6 +7,8 @@ import * as moment from 'moment';
import { MomentTime } from './moment-time';
import { CommentForm } from './comment-form';
import { CommentNodes } from './comment-nodes';
+import { i18n } from '../i18next';
+import { T } from 'inferno-i18next';
enum BanType {Community, Site};
@@ -74,10 +76,10 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
<Link className="text-info" to={`/u/${node.comment.creator_name}`}>{node.comment.creator_name}</Link>
</li>
{this.isMod &&
- <li className="list-inline-item badge badge-light">mod</li>
+ <li className="list-inline-item badge badge-light"><T i18nKey="mod">#</T></li>
}
{this.isAdmin &&
- <li className="list-inline-item badge badge-light">admin</li>
+ <li className="list-inline-item badge badge-light"><T i18nKey="admin">#</T></li>
}
<li className="list-inline-item">
<span>(
@@ -97,24 +99,24 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
{this.state.showEdit && <CommentForm node={node} edit onReplyCancel={this.handleReplyCancel} disabled={this.props.locked} />}
{!this.state.showEdit && !this.state.collapsed &&
<div>
- <div className="md-div" dangerouslySetInnerHTML={mdToHtml(node.comment.removed ? '*removed*' : node.comment.deleted ? '*deleted*' : node.comment.content)} />
+ <div className="md-div" dangerouslySetInnerHTML={mdToHtml(node.comment.removed ? `*${i18n.t('removed')}*` : node.comment.deleted ? `*${i18n.t('deleted')}*` : node.comment.content)} />
<ul class="list-inline mb-1 text-muted small font-weight-bold">
{UserService.Instance.user && !this.props.viewOnly &&
<>
<li className="list-inline-item">
- <span class="pointer" onClick={linkEvent(this, this.handleReplyClick)}>reply</span>
+ <span class="pointer" onClick={linkEvent(this, this.handleReplyClick)}><T i18nKey="reply">#</T></span>
</li>
<li className="list-inline-item mr-2">
- <span class="pointer" onClick={linkEvent(this, this.handleSaveCommentClick)}>{node.comment.saved ? 'unsave' : 'save'}</span>
+ <span class="pointer" onClick={linkEvent(this, this.handleSaveCommentClick)}>{node.comment.saved ? i18n.t('unsave') : i18n.t('save')}</span>
</li>
{this.myComment &&
<>
<li className="list-inline-item">
- <span class="pointer" onClick={linkEvent(this, this.handleEditClick)}>edit</span>
+ <span class="pointer" onClick={linkEvent(this, this.handleEditClick)}><T i18nKey="edit">#</T></span>
</li>
<li className="list-inline-item">
<span class="pointer" onClick={linkEvent(this, this.handleDeleteClick)}>
- {!this.props.node.comment.deleted ? 'delete' : 'restore'}
+ {!this.props.node.comment.deleted ? i18n.t('delete') : i18n.t('restore')}
</span>
</li>
</>
@@ -123,8 +125,8 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
{this.canMod &&
<li className="list-inline-item">
{!this.props.node.comment.removed ?
- <span class="pointer" onClick={linkEvent(this, this.handleModRemoveShow)}>remove</span> :
- <span class="pointer" onClick={linkEvent(this, this.handleModRemoveSubmit)}>restore</span>
+ <span class="pointer" onClick={linkEvent(this, this.handleModRemoveShow)}><T i18nKey="remove">#</T></span> :
+ <span class="pointer" onClick={linkEvent(this, this.handleModRemoveSubmit)}><T i18nKey="restore">#</T></span>
}
</li>
}
@@ -134,14 +136,14 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
{!this.isMod &&
<li className="list-inline-item">
{!this.props.node.comment.banned_from_community ?
- <span class="pointer" onClick={linkEvent(this, this.handleModBanFromCommunityShow)}>ban</span> :
- <span class="pointer" onClick={linkEvent(this, this.handleModBanFromCommunitySubmit)}>unban</span>
+ <span class="pointer" onClick={linkEvent(this, this.handleModBanFromCommunityShow)}><T i18nKey="ban">#</T></span> :
+ <span class="pointer" onClick={linkEvent(this, this.handleModBanFromCommunitySubmit)}><T i18nKey="unban">#</T></span>
}
</li>
}
{!this.props.node.comment.banned_from_community &&
<li className="list-inline-item">
- <span class="pointer" onClick={linkEvent(this, this.handleAddModToCommunity)}>{`${this.isMod ? 'remove' : 'appoint'} as mod`}</span>
+ <span class="pointer" onClick={linkEvent(this, this.handleAddModToCommunity)}>{this.isMod ? i18n.t('remove_as_mod') : i18n.t('appoint_as_mod')}</span>
</li>
}
</>
@@ -152,14 +154,14 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
{!this.isAdmin &&
<li className="list-inline-item">
{!this.props.node.comment.banned ?
- <span class="pointer" onClick={linkEvent(this, this.handleModBanShow)}>ban from site</span> :
- <span class="pointer" onClick={linkEvent(this, this.handleModBanSubmit)}>unban from site</span>
+ <span class="pointer" onClick={linkEvent(this, this.handleModBanShow)}><T i18nKey="ban_from_site">#</T></span> :
+ <span class="pointer" onClick={linkEvent(this, this.handleModBanSubmit)}><T i18nKey="unban_from_site">#</T></span>
}
</li>
}
{!this.props.node.comment.banned &&
<li className="list-inline-item">
- <span class="pointer" onClick={linkEvent(this, this.handleAddAdmin)}>{`${this.isAdmin ? 'remove' : 'appoint'} as admin`}</span>
+ <span class="pointer" onClick={linkEvent(this, this.handleAddAdmin)}>{this.isAdmin ? i18n.t('remove_as_admin') : i18n.t('appoint_as_admin')}</span>
</li>
}
</>
@@ -167,11 +169,11 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
</>
}
<li className="list-inline-item">
- <Link className="text-muted" to={`/post/${node.comment.post_id}/comment/${node.comment.id}`}>link</Link>
+ <Link className="text-muted" to={`/post/${node.comment.post_id}/comment/${node.comment.id}`}><T i18nKey="link">#</T></Link>
</li>
{this.props.markable &&
<li className="list-inline-item">
- <span class="pointer" onClick={linkEvent(this, this.handleMarkRead)}>{`mark as ${node.comment.read ? 'unread' : 'read'}`}</span>
+ <span class="pointer" onClick={linkEvent(this, this.handleMarkRead)}>{node.comment.read ? i18n.t('mark_as_unread') : i18n.t('mark_as_read')}</span>
</li>
}
</ul>
@@ -180,23 +182,23 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
</div>
{this.state.showRemoveDialog &&
<form class="form-inline" onSubmit={linkEvent(this, this.handleModRemoveSubmit)}>
- <input type="text" class="form-control mr-2" placeholder="Reason" value={this.state.removeReason} onInput={linkEvent(this, this.handleModRemoveReasonChange)} />
- <button type="submit" class="btn btn-secondary">Remove Comment</button>
+ <input type="text" class="form-control mr-2" placeholder={i18n.t('reason')} value={this.state.removeReason} onInput={linkEvent(this, this.handleModRemoveReasonChange)} />
+ <button type="submit" class="btn btn-secondary"><T i18nKey="remove_comment">#</T></button>
</form>
}
{this.state.showBanDialog &&
<form onSubmit={linkEvent(this, this.handleModBanBothSubmit)}>
<div class="form-group row">
- <label class="col-form-label">Reason</label>
- <input type="text" class="form-control mr-2" placeholder="Optional" value={this.state.banReason} onInput={linkEvent(this, this.handleModBanReasonChange)} />
+ <label class="col-form-label"><T i18nKey="reason">#</T></label>
+ <input type="text" class="form-control mr-2" placeholder={i18n.t('reason')} value={this.state.banReason} onInput={linkEvent(this, this.handleModBanReasonChange)} />
</div>
{/* TODO hold off on expires until later */}
{/* <div class="form-group row"> */}
{/* <label class="col-form-label">Expires</label> */}
- {/* <input type="date" class="form-control mr-2" placeholder="Expires" value={this.state.banExpires} onInput={linkEvent(this, this.handleModBanExpiresChange)} /> */}
+ {/* <input type="date" class="form-control mr-2" placeholder={i18n.t('expires')} value={this.state.banExpires} onInput={linkEvent(this, this.handleModBanExpiresChange)} /> */}
{/* </div> */}
<div class="form-group row">
- <button type="submit" class="btn btn-secondary">Ban {this.props.node.comment.creator_name}</button>
+ <button type="submit" class="btn btn-secondary">{i18n.t('ban')} {this.props.node.comment.creator_name}</button>
</div>
</form>
}
@@ -387,9 +389,6 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
handleModBanBothSubmit(i: CommentNode) {
event.preventDefault();
- console.log(BanType[i.state.banType]);
- console.log(i.props.node.comment.banned);
-
if (i.state.banType == BanType.Community) {
let form: BanFromCommunityForm = {
user_id: i.props.node.comment.creator_id,
diff --git a/ui/src/components/comment-nodes.tsx b/ui/src/components/comment-nodes.tsx
index da67bbc7..fca323e3 100644
--- a/ui/src/components/comment-nodes.tsx
+++ b/ui/src/components/comment-nodes.tsx
@@ -32,7 +32,7 @@ export class CommentNodes extends Component<CommentNodesProps, CommentNodesState
moderators={this.props.moderators}
admins={this.props.admins}
markable={this.props.markable}
- />
+ />
)}
</div>
)
diff --git a/ui/src/components/communities.tsx b/ui/src/components/communities.tsx
index c4efe1fb..49b982dc 100644
--- a/ui/src/components/communities.tsx
+++ b/ui/src/components/communities.tsx
@@ -5,6 +5,8 @@ import { retryWhen, delay, take } from 'rxjs/operators';
import { UserOperation, Community, ListCommunitiesResponse, CommunityResponse, FollowCommunityForm, ListCommunitiesForm, SortType } from '../interfaces';
import { WebSocketService } from '../services';
import { msgOp } from '../utils';
+import { i18n } from '../i18next';
+import { T } from 'inferno-i18next';
declare const Sortable: any;
@@ -26,12 +28,12 @@ export class Communities extends Component<any, CommunitiesState> {
super(props, context);
this.state = this.emptyState;
this.subscription = WebSocketService.Instance.subject
- .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
- .subscribe(
- (msg) => this.parseMessage(msg),
+ .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
+ .subscribe(
+ (msg) => this.parseMessage(msg),
(err) => console.error(err),
() => console.log('complete')
- );
+ );
this.refetch();
@@ -46,7 +48,7 @@ export class Communities extends Component<any, CommunitiesState> {
}
componentDidMount() {
- document.title = `Communities - ${WebSocketService.Instance.site.name}`;
+ document.title = `${i18n.t('communities')} - ${WebSocketService.Instance.site.name}`;
}
// Necessary for back button for some reason
@@ -64,17 +66,17 @@ export class Communities extends Component<any, CommunitiesState> {
{this.state.loading ?
<h5 class=""><svg class="icon icon-spinner spin"><use xlinkHref="#icon-spinner"></use></svg></h5> :
<div>
- <h5>List of communities</h5>
+ <h5><T i18nKey="list_of_communities">#</T></h5>
<div class="table-responsive">
<table id="community_table" class="table table-sm table-hover">
<thead class="pointer">
<tr>
- <th>Name</th>
- <th class="d-none d-lg-table-cell">Title</th>
- <th>Category</th>
- <th class="text-right">Subscribers</th>
- <th class="text-right d-none d-lg-table-cell">Posts</th>
- <th class="text-right d-none d-lg-table-cell">Comments</th>
+ <th><T i18nKey="name">#</T></th>
+ <th class="d-none d-lg-table-cell"><T i18nKey="title">#</T></th>
+ <th><T i18nKey="category">#</T></th>
+ <th class="text-right"><T i18nKey="subscribers">#</T></th>
+ <th class="text-right d-none d-lg-table-cell"><T i18nKey="posts">#</T></th>
+ <th class="text-right d-none d-lg-table-cell"><T i18nKey="comments">#</T></th>
<th></th>
</tr>
</thead>
@@ -89,8 +91,8 @@ export class Communities extends Component<any, CommunitiesState> {
<td class="text-right d-none d-lg-table-cell">{community.number_of_comments}</td>
<td class="text-right">
{community.subscribed ?
- <span class="pointer btn-link" onClick={linkEvent(community.id, this.handleUnsubscribe)}>Unsubscribe</span> :
- <span class="pointer btn-link" onClick={linkEvent(community.id, this.handleSubscribe)}>Subscribe</span>
+ <span class="pointer btn-link" onClick={linkEvent(community.id, this.handleUnsubscribe)}><T i18nKey="unsubscribe">#</T></span> :
+ <span class="pointer btn-link" onClick={linkEvent(community.id, this.handleSubscribe)}><T i18nKey="subscribe">#</T></span>
}
</td>
</tr>
@@ -109,9 +111,9 @@ export class Communities extends Component<any, CommunitiesState> {
return (
<div class="mt-2">
{this.state.page > 1 &&
- <button class="btn btn-sm btn-secondary mr-1" onClick={linkEvent(this, this.prevPage)}>Prev</button>
+ <button class="btn btn-sm btn-secondary mr-1" onClick={linkEvent(this, this.prevPage)}><T i18nKey="prev">#</T></button>
}
- <button class="btn btn-sm btn-secondary" onClick={linkEvent(this, this.nextPage)}>Next</button>
+ <button class="btn btn-sm btn-secondary" onClick={linkEvent(this, this.nextPage)}><T i18nKey="next">#</T></button>
</div>
);
}
@@ -165,7 +167,7 @@ export class Communities extends Component<any, CommunitiesState> {
console.log(msg);
let op: UserOperation = msgOp(msg);
if (msg.error) {
- alert(msg.error);
+ alert(i18n.t(msg.error));
return;
} else if (op == UserOperation.ListCommunities) {
let res: ListCommunitiesResponse = msg;
diff --git a/ui/src/components/community-form.tsx b/ui/src/components/community-form.tsx
index e295dcbe..b039fb4d 100644
--- a/ui/src/components/community-form.tsx
+++ b/ui/src/components/community-form.tsx
@@ -3,8 +3,10 @@ import { Subscription } from "rxjs";
import { retryWhen, delay, take } from 'rxjs/operators';
import { CommunityForm as CommunityFormI, UserOperation, Category, ListCategoriesResponse, CommunityResponse } from '../interfaces';
import { WebSocketService } from '../services';
-import { msgOp } from '../utils';
+import { msgOp, capitalizeFirstLetter } from '../utils';
import * as autosize from 'autosize';
+import { i18n } from '../i18next';
+import { T } from 'inferno-i18next';
import { Community } from '../interfaces';
@@ -74,25 +76,25 @@ export class CommunityForm extends Component<CommunityFormProps, CommunityFormSt
return (
<form onSubmit={linkEvent(this, this.handleCreateCommunitySubmit)}>
<div class="form-group row">
- <label class="col-12 col-form-label">Name</label>
+ <label class="col-12 col-form-label"><T i18nKey="name">#</T></label>
<div class="col-12">
- <input type="text" class="form-control" value={this.state.communityForm.name} onInput={linkEvent(this, this.handleCommunityNameChange)} required minLength={3} maxLength={20} pattern="[a-z0-9_]+" title="lowercase, underscores, and no spaces."/>
+ <input type="text" class="form-control" value={this.state.communityForm.name} onInput={linkEvent(this, this.handleCommunityNameChange)} required minLength={3} maxLength={20} pattern="[a-z0-9_]+" title={i18n.t('community_reqs')}/>
</div>
</div>
<div class="form-group row">
- <label class="col-12 col-form-label">Title</label>
+ <label class="col-12 col-form-label"><T i18nKey="title">#</T></label>
<div class="col-12">
<input type="text" value={this.state.communityForm.title} onInput={linkEvent(this, this.handleCommunityTitleChange)} class="form-control" required minLength={3} maxLength={100} />
</div>
</div>
<div class="form-group row">
- <label class="col-12 col-form-label">Sidebar</label>
+ <label class="col-12 col-form-label"><T i18nKey="sidebar">#</T></label>
<div class="col-12">
<textarea value={this.state.communityForm.description} onInput={linkEvent(this, this.handleCommunityDescriptionChange)} class="form-control" rows={3} maxLength={10000} />
</div>
</div>
<div class="form-group row">
- <label class="col-12 col-form-label">Category</label>
+ <label class="col-12 col-form-label"><T i18nKey="category">#</T></label>
<div class="col-12">
<select class="form-control" value={this.state.communityForm.category_id} onInput={linkEvent(this, this.handleCommunityCategoryChange)}>
{this.state.categories.map(category =>
@@ -106,8 +108,8 @@ export class CommunityForm extends Component<CommunityFormProps, CommunityFormSt
<button type="submit" class="btn btn-secondary mr-2">
{this.state.loading ?
<svg class="icon icon-spinner spin"><use xlinkHref="#icon-spinner"></use></svg> :
- this.props.community ? 'Save' : 'Create'}</button>
- {this.props.community && <button type="button" class="btn btn-secondary" onClick={linkEvent(this, this.handleCancel)}>Cancel</button>}
+ this.props.community ? capitalizeFirstLetter(i18n.t('save')) : capitalizeFirstLetter(i18n.t('create'))}</button>
+ {this.props.community && <button type="button" class="btn btn-secondary" onClick={linkEvent(this, this.handleCancel)}><T i18nKey="cancel">#</T></button>}
</div>
</div>
</form>
@@ -153,7 +155,7 @@ export class CommunityForm extends Component<CommunityFormProps, CommunityFormSt
let op: UserOperation = msgOp(msg);
console.log(msg);
if (msg.error) {
- alert(msg.error);
+ alert(i18n.t(msg.error));
this.state.loading = false;
this.setState(this.state);
return;
@@ -169,8 +171,7 @@ export class CommunityForm extends Component<CommunityFormProps, CommunityFormSt
this.state.loading = false;
this.props.onCreate(res.community);
}
-
- // TODO is this necessary?
+ // TODO is ths necessary
else if (op == UserOperation.EditCommunity) {
let res: CommunityResponse = msg;
this.state.loading = false;
diff --git a/ui/src/components/community.tsx b/ui/src/components/community.tsx
index 6a1f5da2..480b909e 100644
--- a/ui/src/components/community.tsx
+++ b/ui/src/components/community.tsx
@@ -6,6 +6,7 @@ import { WebSocketService } from '../services';
import { PostListings } from './post-listings';
import { Sidebar } from './sidebar';
import { msgOp, routeSortTypeToEnum, fetchLimit } from '../utils';
+import { T } from 'inferno-i18next';
interface State {
community: CommunityI;
@@ -102,7 +103,7 @@ export class Community extends Component<any, State> {
<div class="col-12 col-md-8">
<h5>{this.state.community.title}
{this.state.community.removed &&
- <small className="ml-2 text-muted font-italic">removed</small>
+ <small className="ml-2 text-muted font-italic"><T i18nKey="removed">#</T></small>
}
</h5>
{this.selects()}
@@ -126,15 +127,15 @@ export class Community extends Component<any, State> {
return (
<div className="mb-2">
<select value={this.state.sort} onChange={linkEvent(this, this.handleSortChange)} class="custom-select custom-select-sm w-auto">
- <option disabled>Sort Type</option>
- <option value={SortType.Hot}>Hot</option>
- <option value={SortType.New}>New</option>
+ <option disabled><T i18nKey="sort_type">#</T></option>
+ <option value={SortType.Hot}><T i18nKey="hot">#</T></option>
+ <option value={SortType.New}><T i18nKey="new">#</T></option>
<option disabled>──────────</option>
- <option value={SortType.TopDay}>Top Day</option>
- <option value={SortType.TopWeek}>Week</option>
- <option value={SortType.TopMonth}>Month</option>
- <option value={SortType.TopYear}>Year</option>
- <option value={SortType.TopAll}>All</option>
+ <option value={SortType.TopDay}><T i18nKey="top_day">#</T></option>
+ <option value={SortType.TopWeek}><T i18nKey="week">#</T></option>
+ <option value={SortType.TopMonth}><T i18nKey="month">#</T></option>
+ <option value={SortType.TopYear}><T i18nKey="year">#</T></option>
+ <option value={SortType.TopAll}><T i18nKey="all">#</T></option>
</select>
</div>
)
@@ -144,9 +145,9 @@ export class Community extends Component<any, State> {
return (
<div class="mt-2">
{this.state.page > 1 &&
- <button class="btn btn-sm btn-secondary mr-1" onClick={linkEvent(this, this.prevPage)}>Prev</button>
+ <button class="btn btn-sm btn-secondary mr-1" onClick={linkEvent(this, this.prevPage)}><T i18nKey="prev">#</T></button>
}
- <button class="btn btn-sm btn-secondary" onClick={linkEvent(this, this.nextPage)}>Next</button>
+ <button class="btn btn-sm btn-secondary" onClick={linkEvent(this, this.nextPage)}><T i18nKey="next">#</T></button>
</div>
);
}
@@ -193,7 +194,7 @@ export class Community extends Component<any, State> {
console.log(msg);
let op: UserOperation = msgOp(msg);
if (msg.error) {
- alert(msg.error);
+ alert(i18n.t(msg.error));
return;
} else if (op == UserOperation.GetCommunity) {
let res: GetCommunityResponse = msg;
diff --git a/ui/src/components/create-community.tsx b/ui/src/components/create-community.tsx
index c2f89eef..61245e73 100644
--- a/ui/src/components/create-community.tsx
+++ b/ui/src/components/create-community.tsx
@@ -2,6 +2,8 @@ import { Component } from 'inferno';
import { CommunityForm } from './community-form';
import { Community } from '../interfaces';
import { WebSocketService } from '../services';
+import { i18n } from '../i18next';
+import { T } from 'inferno-i18next';
export class CreateCommunity extends Component<any, any> {
@@ -11,7 +13,7 @@ export class CreateCommunity extends Component<any, any> {
}
componentDidMount() {
- document.title = `Create Community - ${WebSocketService.Instance.site.name}`;
+ document.title = `${i18n.t('create_community')} - ${WebSocketService.Instance.site.name}`;
}
render() {
@@ -19,7 +21,7 @@ export class CreateCommunity extends Component<any, any> {
<div class="container">
<div class="row">
<div class="col-12 col-lg-6 offset-lg-3 mb-4">
- <h5>Create Community</h5>
+ <h5><T i18nKey="create_community">#</T></h5>
<CommunityForm onCreate={this.handleCommunityCreate}/>
</div>
</div>
diff --git a/ui/src/components/create-post.tsx b/ui/src/components/create-post.tsx
index e09bcf70..dd93a3c5 100644
--- a/ui/src/components/create-post.tsx
+++ b/ui/src/components/create-post.tsx
@@ -1,6 +1,8 @@
import { Component } from 'inferno';
import { PostForm } from './post-form';
import { WebSocketService } from '../services';
+import { i18n } from '../i18next';
+import { T } from 'inferno-i18next';
export class CreatePost extends Component<any, any> {
@@ -10,7 +12,7 @@ export class CreatePost extends Component<any, any> {
}
componentDidMount() {
- document.title = `Create Post - ${WebSocketService.Instance.site.name}`;
+ document.title = `${i18n.t('create_post')} - ${WebSocketService.Instance.site.name}`;
}
render() {
@@ -18,7 +20,7 @@ export class CreatePost extends Component<any, any> {
<div class="container">
<div class="row">
<div class="col-12 col-lg-6 offset-lg-3 mb-4">
- <h5>Create a Post</h5>
+ <h5><T i18nKey="create_post">#</T></h5>
<PostForm onCreate={this.handlePostCreate} prevCommunityName={this.prevCommunityName} />
</div>
</div>
diff --git a/ui/src/components/footer.tsx b/ui/src/components/footer.tsx
index 31403d7c..87d7097e 100644
--- a/ui/src/components/footer.tsx
+++ b/ui/src/components/footer.tsx
@@ -2,6 +2,7 @@ import { Component } from 'inferno';
import { Link } from 'inferno-router';
import { repoUrl } from '../utils';
import { version } from '../version';
+import { T } from 'inferno-i18next';
export class Footer extends Component<any, any> {
@@ -19,16 +20,16 @@ export class Footer extends Component<any, any> {
<span class="navbar-text">{version}</span>
</li>
<li class="nav-item">
- <Link class="nav-link" to="/modlog">Modlog</Link>
+ <Link class="nav-link" to="/modlog"><T i18nKey="modlog">#</T></Link>
</li>
<li class="nav-item">
- <a class="nav-link" href={`${repoUrl}/blob/master/docs/api.md`}>API</a>
+ <a class="nav-link" href={`${repoUrl}/blob/master/docs/api.md`}><T i18nKey="api">#</T></a>
</li>
<li class="nav-item">
- <Link class="nav-link" to="/sponsors">Sponsors</Link>
+ <Link class="nav-link" to="/sponsors"><T i18nKey="sponsors">#</T></Link>
</li>
<li class="nav-item">
- <a class="nav-link" href={repoUrl}>Code</a>
+ <a class="nav-link" href={repoUrl}><T i18nKey="code">#</T></a>
</li>
</ul>
</div>
diff --git a/ui/src/components/home.tsx b/ui/src/components/home.tsx
deleted file mode 100644
index e69de29b..00000000
--- a/ui/src/components/home.tsx
+++ /dev/null
diff --git a/ui/src/components/inbox.tsx b/ui/src/components/inbox.tsx
index 5fb7f874..c9f46b36 100644
--- a/ui/src/components/inbox.tsx
+++ b/ui/src/components/inbox.tsx
@@ -6,6 +6,8 @@ import { UserOperation, Comment, SortType, GetRepliesForm, GetRepliesResponse, C
import { WebSocketService, UserService } f