feat: fix frontend ci (#2)

This commit is contained in:
yehong 2023-08-12 14:38:31 +08:00 committed by GitHub
parent cb1f8b84b1
commit 9c1b187809
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 12904 additions and 14160 deletions

View File

@ -14,4 +14,25 @@ module.exports = {
},
},
],
module: {
rules: [
{
test: /\.less$/,
use: [
"style-loader",
"css-loader",
"less-loader",
],
},
],
},
webpack: {
configure: {
resolve: {
fallback: {
"path": false,
},
},
},
},
};

View File

@ -13,6 +13,7 @@
"braft-editor": "^2.3.9",
"browser-image-size": "^1.1.0",
"casdoor-js-sdk": "^0.5.1",
"classnames": "^2.3.2",
"codemirror": "^5.54.0",
"craco-less": "^2.0.0",
"i18next": "^19.6.0",
@ -49,7 +50,7 @@
"crowdin:sync": "crowdin upload && crowdin download",
"preinstall": "node -e \"if (process.env.npm_execpath.indexOf('yarn') === -1) throw new Error('Use yarn for installing: https://yarnpkg.com/en/docs/install')\"",
"fix": "eslint --fix src/**/*.{js,jsx,ts,tsx}",
"lint:css": "stylelint src/**/*.{css,less} --fix"
"lintcss": "stylelint src/**/*.{css,scss} --fix --custom-syntax postcss-scss"
},
"eslintConfig": {
"extends": "react-app"
@ -69,12 +70,14 @@
"devDependencies": {
"@babel/core": "^7.18.13",
"@babel/eslint-parser": "^7.18.9",
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@babel/preset-react": "^7.18.6",
"eslint": "8.22.0",
"eslint": "^8.47.0",
"eslint-plugin-react": "^7.31.1",
"eslint-plugin-unused-imports": "^2.0.0",
"husky": "^4.3.8",
"lint-staged": "^13.0.3",
"postcss-scss": "^4.0.6",
"stylelint": "^14.11.0",
"stylelint-config-recommended-less": "^1.0.4",
"stylelint-config-standard": "^28.0.0"

View File

@ -14,9 +14,9 @@
import React, {Component} from "react";
import classNames from "classnames";
import "./App.less";
import "codemirror/lib/codemirror.css";
import {BackTop, Spin} from "antd";
import "./App.less";
import * as Setting from "./Setting";
import {Route, Switch} from "react-router-dom";
import TopicPage from "./TopicPage";

View File

@ -1,5 +1,5 @@
/*@import "~antd/lib/back-top/style/index.css";*/
@import "~antd/dist/antd.less";
@import "~antd/dist/reset.css";
#logo {
width: 94px;

View File

@ -28,18 +28,18 @@ class Avatar extends React.Component {
render() {
let style;
switch (this.props.size) {
case "small":
style = {width: "24px", height: "24px"};
break;
case "middle":
style = {width: "36px", height: "36px"};
break;
case "large":
style = {width: "73px", height: "73px"};
break;
default:
style = {width: "48px", height: "48px"};
break;
case "small":
style = {width: "24px", height: "24px"};
break;
case "middle":
style = {width: "36px", height: "36px"};
break;
case "large":
style = {width: "73px", height: "73px"};
break;
default:
style = {width: "48px", height: "48px"};
break;
}
let src;

View File

@ -316,20 +316,20 @@ class Header extends React.Component {
renderSearchEngine() {
let searchUrl;
switch (Conf.DefaultSearchSite) {
case "google":
case "Google":
searchUrl = `https://www.google.com/search?q=site:${Conf.Domain}/t ${this.state.searchValue}`;
break;
case "bing":
case "Bing":
searchUrl = `https://cn.bing.com/search?q=site:${Conf.Domain}/t ${this.state.searchValue}`;
break;
case "baidu":
case "Baidu":
searchUrl = `https://www.baidu.com/s?q6=${Conf.Domain}&q3=${this.state.searchValue}`;
break;
default:
searchUrl = "/search?keyword=" + this.state.searchValue;
case "google":
case "Google":
searchUrl = `https://www.google.com/search?q=site:${Conf.Domain}/t ${this.state.searchValue}`;
break;
case "bing":
case "Bing":
searchUrl = `https://cn.bing.com/search?q=site:${Conf.Domain}/t ${this.state.searchValue}`;
break;
case "baidu":
case "Baidu":
searchUrl = `https://www.baidu.com/s?q6=${Conf.Domain}&q3=${this.state.searchValue}`;
break;
default:
searchUrl = "/search?keyword=" + this.state.searchValue;
}
return (

View File

@ -51,7 +51,6 @@ class AdminFrontConf extends React.Component {
getContent(id) {
ConfBackend.getFrontConfById(id).then((res) => {
console.log(res.data.value);
this.setState({
content: res.data.value,
});
@ -77,6 +76,7 @@ class AdminFrontConf extends React.Component {
getFrontConf(id) {
ConfBackend.getFrontConfById(id).then((res) => {
// eslint-disable-next-line no-console
console.log(res.data[0]);
});
}

View File

@ -138,30 +138,30 @@ class AdminFrontConf extends React.Component {
convert(s) {
let str;
switch (s) {
case "forumName":
str = i18next.t("frontConf:Forum name");
break;
case "logoImage":
str = i18next.t("frontConf:Logo image");
break;
case "footerLogoImage":
str = i18next.t("frontConf:Footer Logo image");
break;
case "footerLogoUrl":
str = i18next.t("frontConf:Footer Logo URL");
break;
case "signinBoxStrong":
str = i18next.t("frontConf:Right title");
break;
case "signinBoxSpan":
str = i18next.t("frontConf:Right subtitle");
break;
case "footerDeclaration":
str = i18next.t("frontConf:Footer title");
break;
case "footerAdvise":
str = i18next.t("frontConf:Footer subtitle");
break;
case "forumName":
str = i18next.t("frontConf:Forum name");
break;
case "logoImage":
str = i18next.t("frontConf:Logo image");
break;
case "footerLogoImage":
str = i18next.t("frontConf:Footer Logo image");
break;
case "footerLogoUrl":
str = i18next.t("frontConf:Footer Logo URL");
break;
case "signinBoxStrong":
str = i18next.t("frontConf:Right title");
break;
case "signinBoxSpan":
str = i18next.t("frontConf:Right subtitle");
break;
case "footerDeclaration":
str = i18next.t("frontConf:Footer title");
break;
case "footerAdvise":
str = i18next.t("frontConf:Footer subtitle");
break;
}
return str;
}

View File

@ -441,26 +441,26 @@ class AdminNode extends React.Component {
let value, data;
switch (item) {
case "node":
value = this.getIndexFromNodeId(this.state.form.parentNode);
data = this.state.nodes.map((node, i) => {
return {text: `${node.nodeInfo.name} / ${node.nodeInfo.id}`, id: i};
});
break;
case "tab":
value = this.getIndexFromTabId(this.state.form.tab);
data = this.state.tabs.map((tab, i) => {
return {text: `${tab.name} / ${tab.id}`, id: i};
});
break;
case "plane":
value = this.getIndexFromPlaneId(this.state.form.planeId);
data = this.state.planes.map((plane, i) => {
return {text: `${plane.name} / ${plane.id}`, id: i};
});
break;
default:
break;
case "node":
value = this.getIndexFromNodeId(this.state.form.parentNode);
data = this.state.nodes.map((node, i) => {
return {text: `${node.nodeInfo.name} / ${node.nodeInfo.id}`, id: i};
});
break;
case "tab":
value = this.getIndexFromTabId(this.state.form.tab);
data = this.state.tabs.map((tab, i) => {
return {text: `${tab.name} / ${tab.id}`, id: i};
});
break;
case "plane":
value = this.getIndexFromPlaneId(this.state.form.planeId);
data = this.state.planes.map((plane, i) => {
return {text: `${plane.name} / ${plane.id}`, id: i};
});
break;
default:
break;
}
return (
@ -479,20 +479,20 @@ class AdminNode extends React.Component {
const index = parseInt(s);
switch (item) {
case "node":
const nodeId = this.state.nodes[index].nodeInfo.id;
this.updateFormField("parentNode", nodeId);
break;
case "tab":
const tab = this.state.tabs[index].id;
this.updateFormField("tab", tab);
break;
case "plane":
const planeId = this.state.planes[index].id;
this.updateFormField("planeId", planeId);
break;
default:
break;
case "node":
const nodeId = this.state.nodes[index].nodeInfo.id;
this.updateFormField("parentNode", nodeId);
break;
case "tab":
const tab = this.state.tabs[index].id;
this.updateFormField("tab", tab);
break;
case "plane":
const planeId = this.state.planes[index].id;
this.updateFormField("planeId", planeId);
break;
default:
break;
}
}}
options={{

View File

@ -215,70 +215,70 @@ class AdminTopic extends React.Component {
renderRadioButton(type) {
switch (type) {
case "sdt":
return (
<span>
<input type="radio" onClick={() => this.setState({sdt: 1})} checked={this.state.sdt === 1} name="sdt" />
{i18next.t("admin:Show")} <input type="radio" onClick={() => this.setState({sdt: 0})} checked={this.state.sdt === 0} name="sdt" />
{i18next.t("admin:Hidden")}
</span>
);
case "us":
return (
<span>
<input type="radio" onClick={() => this.setState({us: 1})} checked={this.state.us === 1} name="us" />
{i18next.t("admin:Asc")} <input type="radio" onClick={() => this.setState({us: 2})} checked={this.state.us === 2} name="us" />
{i18next.t("admin:Desc")} <input type="radio" onClick={() => this.setState({us: 0})} checked={this.state.us === 0} name="us" />
{i18next.t("admin:Ignore")}
</span>
);
case "cs":
return (
<span>
<input type="radio" onClick={() => this.setState({cs: 1})} checked={this.state.cs === 1} name="cs" />
{i18next.t("admin:Asc")} <input type="radio" onClick={() => this.setState({cs: 2})} checked={this.state.cs === 2} name="cs" />
{i18next.t("admin:Desc")} <input type="radio" onClick={() => this.setState({cs: 0})} checked={this.state.cs === 0} name="cs" />
{i18next.t("admin:Ignore")}
</span>
);
case "lrs":
return (
<span>
<input type="radio" onClick={() => this.setState({lrs: 1})} checked={this.state.lrs === 1} name="lrs" />
{i18next.t("admin:Asc")} <input type="radio" onClick={() => this.setState({lrs: 2})} checked={this.state.lrs === 2} name="lrs" />
{i18next.t("admin:Desc")} <input type="radio" onClick={() => this.setState({lrs: 0})} checked={this.state.lrs === 0} name="lrs" />
{i18next.t("admin:Ignore")}
</span>
);
case "rcs":
return (
<span>
<input type="radio" onClick={() => this.setState({rcs: 1})} checked={this.state.rcs === 1} name="rcs" />
{i18next.t("admin:Asc")} <input type="radio" onClick={() => this.setState({rcs: 2})} checked={this.state.rcs === 2} name="rcs" />
{i18next.t("admin:Desc")} <input type="radio" onClick={() => this.setState({rcs: 0})} checked={this.state.rcs === 0} name="rcs" />
{i18next.t("admin:Ignore")}
</span>
);
case "hs":
return (
<span>
<input type="radio" onClick={() => this.setState({hs: 1})} checked={this.state.hs === 1} name="hs" />
{i18next.t("admin:Asc")} <input type="radio" onClick={() => this.setState({hs: 2})} checked={this.state.hs === 2} name="hs" />
{i18next.t("admin:Desc")} <input type="radio" onClick={() => this.setState({hs: 0})} checked={this.state.hs === 0} name="hs" />
{i18next.t("admin:Ignore")}
</span>
);
case "fcs":
return (
<span>
<input type="radio" onClick={() => this.setState({fcs: 1})} checked={this.state.fcs === 1} name="fcs" />
{i18next.t("admin:Asc")} <input type="radio" onClick={() => this.setState({fcs: 2})} checked={this.state.fcs === 2} name="fcs" />
{i18next.t("admin:Desc")} <input type="radio" onClick={() => this.setState({fcs: 0})} checked={this.state.fcs === 0} name="fcs" />
{i18next.t("admin:Ignore")}
</span>
);
default:
return null;
case "sdt":
return (
<span>
<input type="radio" onClick={() => this.setState({sdt: 1})} checked={this.state.sdt === 1} name="sdt" />
{i18next.t("admin:Show")} <input type="radio" onClick={() => this.setState({sdt: 0})} checked={this.state.sdt === 0} name="sdt" />
{i18next.t("admin:Hidden")}
</span>
);
case "us":
return (
<span>
<input type="radio" onClick={() => this.setState({us: 1})} checked={this.state.us === 1} name="us" />
{i18next.t("admin:Asc")} <input type="radio" onClick={() => this.setState({us: 2})} checked={this.state.us === 2} name="us" />
{i18next.t("admin:Desc")} <input type="radio" onClick={() => this.setState({us: 0})} checked={this.state.us === 0} name="us" />
{i18next.t("admin:Ignore")}
</span>
);
case "cs":
return (
<span>
<input type="radio" onClick={() => this.setState({cs: 1})} checked={this.state.cs === 1} name="cs" />
{i18next.t("admin:Asc")} <input type="radio" onClick={() => this.setState({cs: 2})} checked={this.state.cs === 2} name="cs" />
{i18next.t("admin:Desc")} <input type="radio" onClick={() => this.setState({cs: 0})} checked={this.state.cs === 0} name="cs" />
{i18next.t("admin:Ignore")}
</span>
);
case "lrs":
return (
<span>
<input type="radio" onClick={() => this.setState({lrs: 1})} checked={this.state.lrs === 1} name="lrs" />
{i18next.t("admin:Asc")} <input type="radio" onClick={() => this.setState({lrs: 2})} checked={this.state.lrs === 2} name="lrs" />
{i18next.t("admin:Desc")} <input type="radio" onClick={() => this.setState({lrs: 0})} checked={this.state.lrs === 0} name="lrs" />
{i18next.t("admin:Ignore")}
</span>
);
case "rcs":
return (
<span>
<input type="radio" onClick={() => this.setState({rcs: 1})} checked={this.state.rcs === 1} name="rcs" />
{i18next.t("admin:Asc")} <input type="radio" onClick={() => this.setState({rcs: 2})} checked={this.state.rcs === 2} name="rcs" />
{i18next.t("admin:Desc")} <input type="radio" onClick={() => this.setState({rcs: 0})} checked={this.state.rcs === 0} name="rcs" />
{i18next.t("admin:Ignore")}
</span>
);
case "hs":
return (
<span>
<input type="radio" onClick={() => this.setState({hs: 1})} checked={this.state.hs === 1} name="hs" />
{i18next.t("admin:Asc")} <input type="radio" onClick={() => this.setState({hs: 2})} checked={this.state.hs === 2} name="hs" />
{i18next.t("admin:Desc")} <input type="radio" onClick={() => this.setState({hs: 0})} checked={this.state.hs === 0} name="hs" />
{i18next.t("admin:Ignore")}
</span>
);
case "fcs":
return (
<span>
<input type="radio" onClick={() => this.setState({fcs: 1})} checked={this.state.fcs === 1} name="fcs" />
{i18next.t("admin:Asc")} <input type="radio" onClick={() => this.setState({fcs: 2})} checked={this.state.fcs === 2} name="fcs" />
{i18next.t("admin:Desc")} <input type="radio" onClick={() => this.setState({fcs: 0})} checked={this.state.fcs === 0} name="fcs" />
{i18next.t("admin:Ignore")}
</span>
);
default:
return null;
}
}
@ -405,6 +405,7 @@ class AdminTopic extends React.Component {
}
renderTopicStatus(status, homePageTopTime, tabTopTime, nodeTopTime) {
// eslint-disable-next-line no-console
console.log(status);
if (status === false) {
status = 1;
@ -422,18 +423,18 @@ class AdminTopic extends React.Component {
}
switch (status) {
case 1:
return <span className="gray">{i18next.t("topic:Normal")}</span>;
case 2:
return <span className="negative">{i18next.t("topic:Deleted")}</span>;
case 3:
return <span className="positive">{i18next.t("topic:Node Topping")}</span>;
case 4:
return <span className="positive">{i18next.t("topic:Tab Topping")}</span>;
case 5:
return <span className="positive">{i18next.t("topic:Homepage Topping")}</span>;
default:
return <span className="gray">{i18next.t("topic:Unknown status")}</span>;
case 1:
return <span className="gray">{i18next.t("topic:Normal")}</span>;
case 2:
return <span className="negative">{i18next.t("topic:Deleted")}</span>;
case 3:
return <span className="positive">{i18next.t("topic:Node Topping")}</span>;
case 4:
return <span className="positive">{i18next.t("topic:Tab Topping")}</span>;
case 5:
return <span className="positive">{i18next.t("topic:Homepage Topping")}</span>;
default:
return <span className="gray">{i18next.t("topic:Unknown status")}</span>;
}
}

View File

@ -275,26 +275,26 @@ class AdminTranslation extends React.Component {
changeEvent(event) {
switch (event) {
case "config":
this.getAll();
break;
case "create":
this.setState({
form: {
id: "",
name: "",
translator: "",
key: "",
enable: false,
visible: false,
},
});
break;
case "manage":
this.getAll();
break;
default:
break;
case "config":
this.getAll();
break;
case "create":
this.setState({
form: {
id: "",
name: "",
translator: "",
key: "",
enable: false,
visible: false,
},
});
break;
case "manage":
this.getAll();
break;
default:
break;
}
this.setState({
@ -391,232 +391,232 @@ class AdminTranslation extends React.Component {
render() {
switch (this.state.event) {
case "config":
return this.renderFormBox(
<div className="box">
{this.renderProblem()}
{this.state.message !== "" ? (
<div className="message" onClick={() => this.clearMessage()}>
<li className="fa fa-exclamation-triangle" />
case "config":
return this.renderFormBox(
<div className="box">
{this.renderProblem()}
{this.state.message !== "" ? (
<div className="message" onClick={() => this.clearMessage()}>
<li className="fa fa-exclamation-triangle" />
&nbsp; {this.state.message}
</div>
) : null}
<div className="inner">
<table cellPadding="5" cellSpacing="0" border="0" width="100%">
<tbody>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right">
{i18next.t("translator:Translation Platform")}
</td>
<td width="auto" align="left">
{this.renderSelectPlatform()}
</td>
</tr>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right">
{i18next.t("translator:Key")}
</td>
<td width="auto" align="left">
<input
onChange={(event) => {
const targetVal = event.target.value;
this.setState((prevState) => {
prevState.form.key = targetVal;
return prevState;
});
}}
value={this.state.form?.key}
style={{width: 300}}
/>
</td>
</tr>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right">
{i18next.t("translator:Visible")}
</td>
<td width="auto" align="left">
<input
type="radio"
onClick={() => {
this.setState((prevState) => {
prevState.form.visible = true;
return prevState;
});
}}
checked={this.state.form?.visible}
name="visible"
/>
{i18next.t("tab:show")}{" "}
<input
type="radio"
onClick={() => {
this.setState((prevState) => {
prevState.form.visible = false;
return prevState;
});
}}
checked={!this.state.form?.visible}
name="visible"
/>
{i18next.t("tab:hidden")}
</td>
</tr>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right"></td>
<td width="auto" align="left">
<input type="submit" className="super normal button" value={i18next.t("translator:Save")} onClick={() => this.updateTranslator()} />
</td>
</tr>
</tbody>
</table>
</div>
) : null}
<div className="inner">
<table cellPadding="5" cellSpacing="0" border="0" width="100%">
<tbody>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right">
{i18next.t("translator:Translation Platform")}
</td>
<td width="auto" align="left">
{this.renderSelectPlatform()}
</td>
</tr>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right">
{i18next.t("translator:Key")}
</td>
<td width="auto" align="left">
<input
onChange={(event) => {
const targetVal = event.target.value;
this.setState((prevState) => {
prevState.form.key = targetVal;
return prevState;
});
}}
value={this.state.form?.key}
style={{width: 300}}
/>
</td>
</tr>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right">
{i18next.t("translator:Visible")}
</td>
<td width="auto" align="left">
<input
type="radio"
onClick={() => {
this.setState((prevState) => {
prevState.form.visible = true;
return prevState;
});
}}
checked={this.state.form?.visible}
name="visible"
/>
{i18next.t("tab:show")}{" "}
<input
type="radio"
onClick={() => {
this.setState((prevState) => {
prevState.form.visible = false;
return prevState;
});
}}
checked={!this.state.form?.visible}
name="visible"
/>
{i18next.t("tab:hidden")}
</td>
</tr>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right"></td>
<td width="auto" align="left">
<input type="submit" className="super normal button" value={i18next.t("translator:Save")} onClick={() => this.updateTranslator()} />
</td>
</tr>
</tbody>
</table>
</div>
);
case "create":
return this.renderFormBox(
<div className="box">
{this.renderProblem()}
{this.state.message !== "" ? (
<div className="message" onClick={() => this.clearMessage()}>
<li className="fa fa-exclamation-triangle" />
</div>
);
case "create":
return this.renderFormBox(
<div className="box">
{this.renderProblem()}
{this.state.message !== "" ? (
<div className="message" onClick={() => this.clearMessage()}>
<li className="fa fa-exclamation-triangle" />
&nbsp; {this.state.message}
</div>
) : null}
<div className="inner">
<table cellPadding="5" cellSpacing="0" border="0" width="100%">
<tbody>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right">
{i18next.t("translator:Translation Platform ID")}
</td>
<td width="auto" align="left">
<input
onChange={(event) => {
const targetVal = event.target.value;
this.setState((prevState) => {
prevState.form.id = targetVal;
return prevState;
});
}}
value={this.state.form.id}
style={{width: 300}}
/>
</td>
</tr>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right">
{i18next.t("translator:Translation Platform Name")}
</td>
<td width="auto" align="left">
<input
onChange={(event) => {
const targetVal = event.target.value;
this.setState((prevState) => {
prevState.form.name = targetVal;
return prevState;
});
}}
value={this.state.form.name}
style={{width: 300}}
/>
</td>
</tr>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right">
{i18next.t("translator:Translation API")}
</td>
<td width="auto" align="left">
{this.renderSelectAPI()}
</td>
</tr>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right">
{i18next.t("translator:Key")}
</td>
<td width="auto" align="left">
<input
onChange={(event) => {
const targetVal = event.target.value;
this.setState((prevState) => {
prevState.form.key = targetVal;
return prevState;
});
}}
value={this.state.form.key}
style={{width: 300}}
/>
</td>
</tr>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right">
{i18next.t("translator:Visible")}
</td>
<td width="auto" align="left">
<input
type="radio"
onClick={() => {
this.setState((prevState) => {
prevState.form.visible = true;
return prevState;
});
}}
checked={this.state.form.visible}
name="visible"
/>
{i18next.t("tab:show")}{" "}
<input
type="radio"
onClick={() => {
this.setState((prevState) => {
prevState.form.visible = false;
return prevState;
});
}}
checked={!this.state.form.visible}
name="visible"
/>
{i18next.t("tab:hidden")}
</td>
</tr>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right"></td>
<td width="auto" align="left">
<input type="submit" className="super normal button" value={i18next.t("translator:Save")} onClick={() => this.addTranslator()} />
</td>
</tr>
</tbody>
</table>
</div>
) : null}
<div className="inner">
<table cellPadding="5" cellSpacing="0" border="0" width="100%">
<tbody>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right">
{i18next.t("translator:Translation Platform ID")}
</td>
<td width="auto" align="left">
<input
onChange={(event) => {
const targetVal = event.target.value;
this.setState((prevState) => {
prevState.form.id = targetVal;
return prevState;
});
}}
value={this.state.form.id}
style={{width: 300}}
/>
</td>
</tr>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right">
{i18next.t("translator:Translation Platform Name")}
</td>
<td width="auto" align="left">
<input
onChange={(event) => {
const targetVal = event.target.value;
this.setState((prevState) => {
prevState.form.name = targetVal;
return prevState;
});
}}
value={this.state.form.name}
style={{width: 300}}
/>
</td>
</tr>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right">
{i18next.t("translator:Translation API")}
</td>
<td width="auto" align="left">
{this.renderSelectAPI()}
</td>
</tr>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right">
{i18next.t("translator:Key")}
</td>
<td width="auto" align="left">
<input
onChange={(event) => {
const targetVal = event.target.value;
this.setState((prevState) => {
prevState.form.key = targetVal;
return prevState;
});
}}
value={this.state.form.key}
style={{width: 300}}
/>
</td>
</tr>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right">
{i18next.t("translator:Visible")}
</td>
<td width="auto" align="left">
<input
type="radio"
onClick={() => {
this.setState((prevState) => {
prevState.form.visible = true;
return prevState;
});
}}
checked={this.state.form.visible}
name="visible"
/>
{i18next.t("tab:show")}{" "}
<input
type="radio"
onClick={() => {
this.setState((prevState) => {
prevState.form.visible = false;
return prevState;
});
}}
checked={!this.state.form.visible}
name="visible"
/>
{i18next.t("tab:hidden")}
</td>
</tr>
<tr>
<td width={Setting.PcBrowser ? "120" : "90"} align="right"></td>
<td width="auto" align="left">
<input type="submit" className="super normal button" value={i18next.t("translator:Save")} onClick={() => this.addTranslator()} />
</td>
</tr>
</tbody>
</table>
</div>
);
case "manage":
return this.renderFormBox(
<div className="box">
{this.renderProblem()}
{this.state.message !== "" ? (
<div className="message" onClick={() => this.clearMessage()}>
<li className="fa fa-exclamation-triangle" />
</div>
);
case "manage":
return this.renderFormBox(
<div className="box">
{this.renderProblem()}
{this.state.message !== "" ? (
<div className="message" onClick={() => this.clearMessage()}>
<li className="fa fa-exclamation-triangle" />
&nbsp; {this.state.message}
</div>
) : null}
<div id="all-translators">
{this.state.translators !== null && this.state.translators.length !== 0 ? (
this.state.translators.map((translator) => this.renderTranslators(translator))
) : (
<div
className="cell"
style={{
textAlign: "center",
height: "100px",
lineHeight: "100px",
}}
>
{this.state.translators === null ? i18next.t("loading:Data is loading...") : i18next.t("translator:No translator yet")}
</div>
)}
</div>
) : null}
<div id="all-translators">
{this.state.translators !== null && this.state.translators.length !== 0 ? (
this.state.translators.map((translator) => this.renderTranslators(translator))
) : (
<div
className="cell"
style={{
textAlign: "center",
height: "100px",
lineHeight: "100px",
}}
>
{this.state.translators === null ? i18next.t("loading:Data is loading...") : i18next.t("translator:No translator yet")}
</div>
)}
</div>
);
</div>
);
}
}
}

View File

@ -64,7 +64,7 @@ function getBrowserLanguage() {
function initLanguage() {
let language = localStorage.getItem("language");
if (language === undefined || language == null) {
if (language === undefined || language === null) {
if (Conf.ForceLanguage !== "") {
language = Conf.ForceLanguage;
} else {

View File

@ -25,6 +25,7 @@ const theme = localStorage.getItem("CASNODE_THEME");
loadTheme(theme);
// eslint-disable-next-line react/no-deprecated
ReactDOM.render(
<BrowserRouter>
<App />

View File

@ -89,250 +89,250 @@ class BalanceBox extends React.Component {
renderRecord(record) {
switch (record?.consumptionType) {
case 1:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Checkin bonus")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="positive">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{record?.createdTime.replace(/-/g, "").substring(0, 8)} {i18next.t("balance:'s daily checkin bonus")} {record?.amount} {i18next.t("balance:copper")}
</span>
</td>
</tr>
);
case 2:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Received thanks")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="positive">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
<Link to={`/member/${record?.consumerId}`}>{record?.consumerId}</Link> {i18next.t("balance:Thanks your topic")} <Link to={`/t/${record?.objectId}`}>{pangu.spacing(record?.title)}</Link>
</span>
</td>
</tr>
);
case 3:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Received thanks")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="positive">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
<Link to={`/member/${record?.consumerId}`}>{record?.consumerId}</Link> {i18next.t("balance:Thanks your reply in")} <Link to={`/t/${record?.objectId}`}>{pangu.spacing(record?.title)}</Link> {i18next.t("balance:Reply in")}
</span>
</td>
</tr>
);
case 4:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Send thanks")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="negative">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{i18next.t("balance:Thanks")} <Link to={`/member/${record?.consumerId}`}>{record?.consumerId}</Link> {i18next.t("balance:'s topic")} <Link to={`/t/${record?.objectId}`}>{pangu.spacing(record?.title)}</Link>
</span>
</td>
</tr>
);
case 5:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Send thanks")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="negative">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{i18next.t("balance:Thanks")} <Link to={`/member/${record?.consumerId}`}>{record?.consumerId}</Link> {i18next.t("balance:'s reply")} <Link to={`t/${record?.objectId}`}>{pangu.spacing(record?.title)}</Link>
</span>
</td>
</tr>
);
case 6:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Create reply")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="negative">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{i18next.t("balance:Created a")} {record?.length} {i18next.t("balance:characters reply")} <Link to={`t/${record?.objectId}`}>{pangu.spacing(record?.title)}</Link>
</span>
</td>
</tr>
);
case 7:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Topic response bonus")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="positive">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{i18next.t("balance:receive")} <Link to={`/member/${record?.consumerId}`}>{record?.consumerId}</Link> {i18next.t("balance:'s reply")} <Link to={`t/${record?.objectId}`}>{pangu.spacing(record?.title)}</Link>
</span>
</td>
</tr>
);
case 8:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Create topic")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="negative">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{i18next.t("balance:Created a")} {record?.length} {i18next.t("balance:characters topic")} <Link to={`t/${record?.objectId}`}>{pangu.spacing(record?.title)}</Link>
</span>
</td>
</tr>
);
case 9:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Top topic")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="negative">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{i18next.t("balance:Topped topic")} <Link to={`t/${record?.objectId}`}>{pangu.spacing(record?.title)}</Link> {i18next.t("balance:Pin it to the top")}
</span>
</td>
</tr>
);
case 10:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Admin revision")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="positive">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{i18next.t("balance:Admin")} <Link to={`/member/${record?.consumerId}`}>{record?.consumerId}</Link> {i18next.t("balance:Add balance")} {Math.abs(record?.amount)} {i18next.t("balance:copper")}
</span>
</td>
</tr>
);
case 11:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Admin revision")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="negative">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{i18next.t("balance:Admin")} <Link to={`/member/${record?.consumerId}`}>{record?.consumerId}</Link> {i18next.t("balance:Reduce balance")} {Math.abs(record?.amount)} {i18next.t("balance:copper")}
</span>
</td>
</tr>
);
default:
return null;
case 1:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Checkin bonus")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="positive">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{record?.createdTime.replace(/-/g, "").substring(0, 8)} {i18next.t("balance:'s daily checkin bonus")} {record?.amount} {i18next.t("balance:copper")}
</span>
</td>
</tr>
);
case 2:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Received thanks")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="positive">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
<Link to={`/member/${record?.consumerId}`}>{record?.consumerId}</Link> {i18next.t("balance:Thanks your topic")} <Link to={`/t/${record?.objectId}`}>{pangu.spacing(record?.title)}</Link>
</span>
</td>
</tr>
);
case 3:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Received thanks")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="positive">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
<Link to={`/member/${record?.consumerId}`}>{record?.consumerId}</Link> {i18next.t("balance:Thanks your reply in")} <Link to={`/t/${record?.objectId}`}>{pangu.spacing(record?.title)}</Link> {i18next.t("balance:Reply in")}
</span>
</td>
</tr>
);
case 4:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Send thanks")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="negative">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{i18next.t("balance:Thanks")} <Link to={`/member/${record?.consumerId}`}>{record?.consumerId}</Link> {i18next.t("balance:'s topic")} <Link to={`/t/${record?.objectId}`}>{pangu.spacing(record?.title)}</Link>
</span>
</td>
</tr>
);
case 5:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Send thanks")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="negative">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{i18next.t("balance:Thanks")} <Link to={`/member/${record?.consumerId}`}>{record?.consumerId}</Link> {i18next.t("balance:'s reply")} <Link to={`t/${record?.objectId}`}>{pangu.spacing(record?.title)}</Link>
</span>
</td>
</tr>
);
case 6:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Create reply")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="negative">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{i18next.t("balance:Created a")} {record?.length} {i18next.t("balance:characters reply")} <Link to={`t/${record?.objectId}`}>{pangu.spacing(record?.title)}</Link>
</span>
</td>
</tr>
);
case 7:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Topic response bonus")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="positive">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{i18next.t("balance:receive")} <Link to={`/member/${record?.consumerId}`}>{record?.consumerId}</Link> {i18next.t("balance:'s reply")} <Link to={`t/${record?.objectId}`}>{pangu.spacing(record?.title)}</Link>
</span>
</td>
</tr>
);
case 8:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Create topic")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="negative">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{i18next.t("balance:Created a")} {record?.length} {i18next.t("balance:characters topic")} <Link to={`t/${record?.objectId}`}>{pangu.spacing(record?.title)}</Link>
</span>
</td>
</tr>
);
case 9:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Top topic")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="negative">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{i18next.t("balance:Topped topic")} <Link to={`t/${record?.objectId}`}>{pangu.spacing(record?.title)}</Link> {i18next.t("balance:Pin it to the top")}
</span>
</td>
</tr>
);
case 10:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Admin revision")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="positive">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{i18next.t("balance:Admin")} <Link to={`/member/${record?.consumerId}`}>{record?.consumerId}</Link> {i18next.t("balance:Add balance")} {Math.abs(record?.amount)} {i18next.t("balance:copper")}
</span>
</td>
</tr>
);
case 11:
return (
<tr>
<td className="d">
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
</td>
<td className="d">{i18next.t("balance:Admin revision")}</td>
<td className="d" style={{textAlign: "right"}}>
<span className="negative">
<strong>{record?.amount + ".0"}</strong>
</span>
</td>
<td className="d" style={{textAlign: "right"}}>
{record?.balance + ".0"}
</td>
<td className="d" style={{borderRight: "none"}}>
<span className="gray">
{i18next.t("balance:Admin")} <Link to={`/member/${record?.consumerId}`}>{record?.consumerId}</Link> {i18next.t("balance:Reduce balance")} {Math.abs(record?.amount)} {i18next.t("balance:copper")}
</span>
</td>
</tr>
);
default:
return null;
}
}

View File

@ -63,7 +63,7 @@ class EditBox extends React.Component {
if (this.state.editType === "topic") {
form["title"] = this.state.editObject?.title;
form["nodeId"] = this.state.editObject?.nodeId;
if (this.state.editObject?.tags != null) {
if (this.state.editObject?.tags !== null) {
this.setState({
tags: this.state.editObject?.tags,
});

View File

@ -73,17 +73,17 @@ class FavoritesBox extends React.Component {
getFavoritesInfo() {
let favoritesType;
switch (this.state.favoritesType) {
case "topics":
favoritesType = "favor_topic";
break;
case "following":
favoritesType = "follow_user";
break;
case "nodes":
favoritesType = "favor_node";
break;
default:
return;
case "topics":
favoritesType = "favor_topic";
break;
case "following":
favoritesType = "follow_user";
break;
case "nodes":
favoritesType = "favor_node";
break;
default:
return;
}
FavoritesBackend.getFavorites(favoritesType, this.state.limit, this.state.page).then((res) => {
if (res.status === "ok") {
@ -107,7 +107,7 @@ class FavoritesBox extends React.Component {
}
renderNodes(node) {
if (node.nodeInfo == null) {
if (node.nodeInfo === null) {
return;
}
@ -145,66 +145,66 @@ class FavoritesBox extends React.Component {
render() {
switch (this.state.favoritesType) {
case "nodes":
return (
<div className="box">
<div className="header">
<Link to="/">{Setting.getForumName()}</Link>
<span className="chevron">&nbsp;&nbsp;</span> {i18next.t("fav:My Favorite Nodes")}
<div className="fr f12">
<span className="snow">{i18next.t("fav:Total nodes")} &nbsp;</span>
<strong className="gray">{this.state.favoritesNum}</strong>
</div>
</div>
<div id="my-nodes">
{this.state.favorites.map((node) => {
return this.renderNodes(node);
})}
case "nodes":
return (
<div className="box">
<div className="header">
<Link to="/">{Setting.getForumName()}</Link>
<span className="chevron">&nbsp;&nbsp;</span> {i18next.t("fav:My Favorite Nodes")}
<div className="fr f12">
<span className="snow">{i18next.t("fav:Total nodes")} &nbsp;</span>
<strong className="gray">{this.state.favoritesNum}</strong>
</div>
</div>
);
case "topics":
return (
<div className="box">
<div className="header">
<Link to="/">{Setting.getForumName()}</Link>
<span className="chevron">&nbsp;&nbsp;</span> {i18next.t("fav:My favorite topics")}
<div className="fr f12">
<span className="snow">{i18next.t("fav:Total topics")} &nbsp;</span>
<strong className="gray">{this.state.favoritesNum}</strong>
</div>
</div>
<TopicList topics={this.state.favorites} showNodeName={true} showAvatar={true} />
<div className="sep20" />
<div className="header">
<Link to="/">{Setting.getForumName()}</Link>
<span className="chevron">&nbsp;&nbsp;</span> {i18next.t("fav:My subscribe topics")}
<div className="fr f12">
<span className="snow">{i18next.t("fav:Total topics")} &nbsp;</span>
<strong className="gray">{this.state.subscribesNum}</strong>
</div>
</div>
<TopicList topics={this.state.subscribes} showNodeName={true} showAvatar={true} />
<div id="my-nodes">
{this.state.favorites.map((node) => {
return this.renderNodes(node);
})}
</div>
);
case "following":
return (
<div className="box">
<div className="header">
<Link to="/">{Setting.getForumName()}</Link>
<span className="chevron">&nbsp;&nbsp;</span> {i18next.t("fav:Latest topics from people I followed")}
<div className="fr f12">
<span className="snow">{i18next.t("fav:Total topics")} &nbsp;</span>
<strong className="gray">{this.state.favoritesNum}</strong>
</div>
</div>
);
case "topics":
return (
<div className="box">
<div className="header">
<Link to="/">{Setting.getForumName()}</Link>
<span className="chevron">&nbsp;&nbsp;</span> {i18next.t("fav:My favorite topics")}
<div className="fr f12">
<span className="snow">{i18next.t("fav:Total topics")} &nbsp;</span>
<strong className="gray">{this.state.favoritesNum}</strong>
</div>
{Setting.PcBrowser ? this.showPageColumn() : null}
<TopicList topics={this.state.favorites} showNodeName={true} showAvatar={true} />
{this.showPageColumn()}
</div>
);
default:
return <div className="box">{this.state.favoritesType}</div>;
<TopicList topics={this.state.favorites} showNodeName={true} showAvatar={true} />
<div className="sep20" />
<div className="header">
<Link to="/">{Setting.getForumName()}</Link>
<span className="chevron">&nbsp;&nbsp;</span> {i18next.t("fav:My subscribe topics")}
<div className="fr f12">
<span className="snow">{i18next.t("fav:Total topics")} &nbsp;</span>
<strong className="gray">{this.state.subscribesNum}</strong>
</div>
</div>
<TopicList topics={this.state.subscribes} showNodeName={true} showAvatar={true} />
</div>
);
case "following":
return (
<div className="box">
<div className="header">
<Link to="/">{Setting.getForumName()}</Link>
<span className="chevron">&nbsp;&nbsp;</span> {i18next.t("fav:Latest topics from people I followed")}
<div className="fr f12">
<span className="snow">{i18next.t("fav:Total topics")} &nbsp;</span>
<strong className="gray">{this.state.favoritesNum}</strong>
</div>
</div>
{Setting.PcBrowser ? this.showPageColumn() : null}
<TopicList topics={this.state.favorites} showNodeName={true} showAvatar={true} />
{this.showPageColumn()}
</div>
);
default:
return <div className="box">{this.state.favoritesType}</div>;
}
}
}

View File

@ -274,6 +274,7 @@ class NodeBox extends React.Component {
<Link to="/">{Setting.getForumName()}</Link> <span className="chevron">&nbsp;&nbsp;</span> {this.state.nodeInfo?.name}
<div className="sep5"></div>
{this.props.account !== null ? (
// eslint-disable-next-line react/no-unknown-property
<div align="right">
<input type="button" className="super normal button" value={i18next.t("node:new topic")} onClick={() => this.props.history.push(`/new/${this.state.nodeId}`)} style={{width: "100%", lineHeight: "20px"}} />
</div>
@ -415,6 +416,7 @@ class NodeBox extends React.Component {
{Setting.PcBrowser ? this.showPageColumn() : null}
<TopicList nodeId={this.state.nodeId} topics={this.state.topics} showNodeName={false} showAvatar={true} topType={"node"} />
{this.showPageColumn()}
{/* eslint-disable-next-line react/no-unknown-property */}
<div className="cell" align="center">
<div className="fr">{`${this.state.favoritesNum} ${i18next.t("node:members have added this node to favorites")}`}</div>
<span className="gray">{`${i18next.t("node:Topic")} ${from} ${i18next.t("node:to")} ${end} ${i18next.t("node:of all")} ${this.state.topicNum} ${i18next.t("node:topics")}`}</span>

View File

@ -148,73 +148,73 @@ class NotificationBox extends React.Component {
renderNotificationContent(notification) {
switch (notification?.notificationType) {
case 1:
return (
<td valign="middle">
<span className="fade">
{this.renderMember(notification?.senderId)} {i18next.t("notification:Replied to you in")} <Link to={`/t/${notification?.objectId}?from=${encodeURIComponent(window.location.href)}`}>{pangu.spacing(notification?.title)}</Link>{" "}
{i18next.t("notification:Replied to you in")}
</span>
{this.renderDelete(notification?.createdTime, notification?.objectId)}
<div className="sep5"></div>
<div className="payload">{this.renderContent(notification?.content)}</div>
</td>
);
case 2:
return (
<td valign="middle">
<span className="fade">
{this.renderMember(notification?.senderId)} {i18next.t("notification:Mentioned you in")} <Link to={`/t/${notification?.objectId}?from=${encodeURIComponent(window.location.href)}`}>{pangu.spacing(notification?.title)}</Link>{" "}
{i18next.t("notification:Mentioned you in")}
</span>
{this.renderDelete(notification?.createdTime, notification?.objectId)}
<div className="sep5"></div>
<div className="payload">{this.renderContent(notification?.content)}</div>
</td>
);
case 3:
return (
<td valign="middle">
<span className="fade">
{this.renderMember(notification?.senderId)} {i18next.t("notification:Mentioned you in topic")} <Link to={`/t/${notification?.objectId}?from=${encodeURIComponent(window.location.href)}`}>{pangu.spacing(notification?.title)}</Link>{" "}
{i18next.t("notification:Mentioned you in")}
</span>
{this.renderDelete(notification?.createdTime, notification?.objectId)}
</td>
);
case 4:
return (
<td valign="middle">
<span className="fade">
{this.renderMember(notification?.senderId)} {i18next.t("notification:Favorite you topic")} <Link to={`/t/${notification?.objectId}?from=${encodeURIComponent(window.location.href)}`}>{pangu.spacing(notification?.title)}</Link>
</span>
{this.renderDelete(notification?.createdTime, notification?.objectId)}
</td>
);
case 5:
return (
<td valign="middle">
<span className="fade">
{this.renderMember(notification?.senderId)} {i18next.t("notification:Thanks for you topic")} <Link to={`/t/${notification?.objectId}?from=${encodeURIComponent(window.location.href)}`}>{pangu.spacing(notification?.title)}</Link>
</span>{" "}
case 1:
return (
<td valign="middle">
<span className="fade">
{this.renderMember(notification?.senderId)} {i18next.t("notification:Replied to you in")} <Link to={`/t/${notification?.objectId}?from=${encodeURIComponent(window.location.href)}`}>{pangu.spacing(notification?.title)}</Link>{" "}
{i18next.t("notification:Replied to you in")}
</span>
{this.renderDelete(notification?.createdTime, notification?.objectId)}
<div className="sep5"></div>
<div className="payload">{this.renderContent(notification?.content)}</div>
</td>
);
case 2:
return (
<td valign="middle">
<span className="fade">
{this.renderMember(notification?.senderId)} {i18next.t("notification:Mentioned you in")} <Link to={`/t/${notification?.objectId}?from=${encodeURIComponent(window.location.href)}`}>{pangu.spacing(notification?.title)}</Link>{" "}
{i18next.t("notification:Mentioned you in")}
</span>
{this.renderDelete(notification?.createdTime, notification?.objectId)}
<div className="sep5"></div>
<div className="payload">{this.renderContent(notification?.content)}</div>
</td>
);
case 3:
return (
<td valign="middle">
<span className="fade">
{this.renderMember(notification?.senderId)} {i18next.t("notification:Mentioned you in topic")} <Link to={`/t/${notification?.objectId}?from=${encodeURIComponent(window.location.href)}`}>{pangu.spacing(notification?.title)}</Link>{" "}
{i18next.t("notification:Mentioned you in")}
</span>
{this.renderDelete(notification?.createdTime, notification?.objectId)}
</td>
);
case 4:
return (
<td valign="middle">
<span className="fade">
{this.renderMember(notification?.senderId)} {i18next.t("notification:Favorite you topic")} <Link to={`/t/${notification?.objectId}?from=${encodeURIComponent(window.location.href)}`}>{pangu.spacing(notification?.title)}</Link>
</span>
{this.renderDelete(notification?.createdTime, notification?.objectId)}
</td>
);
case 5:
return (
<td valign="middle">
<span className="fade">
{this.renderMember(notification?.senderId)} {i18next.t("notification:Thanks for you topic")} <Link to={`/t/${notification?.objectId}?from=${encodeURIComponent(window.location.href)}`}>{pangu.spacing(notification?.title)}</Link>
</span>{" "}
&nbsp;
{this.renderDelete(notification?.createdTime, notification?.objectId)}
</td>
);
case 6:
return (
<td valign="middle">
<span className="fade">
{this.renderMember(notification?.senderId)} {i18next.t("notification:Thanks for your reply in topic")} {""}
<Link to={`/t/${notification?.objectId}?from=${encodeURIComponent(window.location.href)}`}>{pangu.spacing(notification?.title)}</Link> {i18next.t("notification:Replies in")}
</span>
{this.renderDelete(notification?.createdTime, notification?.objectId)}
<div className="sep5"></div>
<div className="payload">{this.renderContent(notification?.content)}</div>
</td>
);
default:
return null;
{this.renderDelete(notification?.createdTime, notification?.objectId)}
</td>
);
case 6:
return (
<td valign="middle">
<span className="fade">
{this.renderMember(notification?.senderId)} {i18next.t("notification:Thanks for your reply in topic")} {""}
<Link to={`/t/${notification?.objectId}?from=${encodeURIComponent(window.location.href)}`}>{pangu.spacing(notification?.title)}</Link> {i18next.t("notification:Replies in")}
</span>
{this.renderDelete(notification?.createdTime, notification?.objectId)}
<div className="sep5"></div>
<div className="payload">{this.renderContent(notification?.content)}</div>
</td>
);
default:
return null;
}
}

View File

@ -56,6 +56,7 @@ class SearchTag extends React.Component {
renderTag() {
return (
<div className={`box ${this.state.tagId}`}>
{/* eslint-disable-next-line react/no-unknown-property */}
<div className="cell" align="center" style={{border: 0}}>
<div className="header">
<Link to="/">{Setting.getForumName()}</Link> <span className="chevron">&nbsp;&nbsp;</span>

View File

@ -28,6 +28,7 @@ class SelectLanguageBox extends React.Component {
render() {
return (
// eslint-disable-next-line react/no-unknown-property
<div align="center">
<div className="box" style={{width: Setting.PcBrowser ? "600px" : "auto"}}>
<Helmet>

View File

@ -38,6 +38,7 @@ class SelectLanguageBox extends React.Component {
render() {
return (
// eslint-disable-next-line react/no-unknown-property
<div align="center">
<div className="box" style={{width: Setting.PcBrowser ? "600px" : "auto"}}>
<Helmet>

View File

@ -365,6 +365,7 @@ class TopicBox extends React.Component {
renderMobileButtons() {
return (
<div className="inner">
{/* eslint-disable-next-line react/no-unknown-property */}
<div className="fr" align="right">
{this.props.account !== undefined && this.props.account !== null ? (
this.state.favoritesStatus ? (

View File

@ -50,23 +50,23 @@ class TopicList extends React.Component {
// return style according to whether it is a topped topic.
topStyle(nodeTopTime, tabTopTime, homePageTopTime) {
switch (this.props.topType) {
case "node":
if (nodeTopTime !== "") {
return this.topTopicStyle;
}
return null;
case "tab":
if (tabTopTime !== "" || homePageTopTime !== "") {
return this.topTopicStyle;
}
return null;
case "homePage":
if (homePageTopTime !== "") {
return this.topTopicStyle;
}
return null;
default:
return null;
case "node":
if (nodeTopTime !== "") {
return this.topTopicStyle;
}
return null;
case "tab":
if (tabTopTime !== "" || homePageTopTime !== "") {
return this.topTopicStyle;
}
return null;
case "homePage":
if (homePageTopTime !== "") {
return this.topTopicStyle;
}
return null;
default:
return null;
}
}

View File

@ -68,6 +68,7 @@ class RightCommunityHealthBox extends React.Component {
return (
<React.Fragment>
<div className="box">
{/* eslint-disable-next-line react/no-unknown-property */}
<div className="inner" align="center">
<a href={this.state.poster["link"]} target="_blank" rel="noopener noreferrer">
<img src={this.state.poster["picture_link"]} border="0" width="250" alt={this.state.poster["advertiser"]} style={{vertical: "bottom"}} />

View File

@ -36,6 +36,7 @@ class RightSigninBox extends React.Component {
</div>
<div className="inner">
<div className="sep5" />
{/* eslint-disable-next-line react/no-unknown-property */}
<div align="center">
<a href={Setting.getSignupUrl()} className="super normal button">
{i18next.t("bar:Sign Up Now")}

View File

@ -39,6 +39,7 @@ export function register(config) {
// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
// eslint-disable-next-line no-console
console.log("This web app is being served cache-first by a service " + "worker. To learn more, visit https://bit.ly/CRA-PWA");
});
} else {
@ -55,7 +56,7 @@ function registerValidSW(swUrl, config) {
.then((registration) => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
if (installingWorker == null) {
if (installingWorker === null) {
return;
}
installingWorker.onstatechange = () => {
@ -64,6 +65,7 @@ function registerValidSW(swUrl, config) {
// At this point, the updated precached content has been fetched,
// but the previous service worker will still serve the older
// content until all client tabs are closed.
// eslint-disable-next-line no-console
console.log("New content is available and will be used when all " + "tabs for this page are closed. See https://bit.ly/CRA-PWA.");
// Execute callback
@ -74,6 +76,7 @@ function registerValidSW(swUrl, config) {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
// eslint-disable-next-line no-console
console.log("Content is cached for offline use.");
// Execute callback
@ -86,6 +89,7 @@ function registerValidSW(swUrl, config) {
};
})
.catch((error) => {
// eslint-disable-next-line no-console
console.error("Error during service worker registration:", error);
});
}
@ -98,7 +102,7 @@ function checkValidServiceWorker(swUrl, config) {
.then((response) => {
// Ensure service worker exists, and that we really are getting a JS file.
const contentType = response.headers.get("content-type");
if (response.status === 404 || (contentType != null && contentType.indexOf("javascript") === -1)) {
if (response.status === 404 || (contentType !== null && contentType.indexOf("javascript") === -1)) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then((registration) => {
registration.unregister().then(() => {
@ -111,6 +115,7 @@ function checkValidServiceWorker(swUrl, config) {
}
})
.catch(() => {
// eslint-disable-next-line no-console
console.log("No internet connection found. App is running in offline mode.");
});
}
@ -122,6 +127,7 @@ export function unregister() {
registration.unregister();
})
.catch((error) => {
// eslint-disable-next-line no-console
console.error(error.message);
});
}

File diff suppressed because it is too large Load Diff