mirror of https://github.com/casbin/casnode.git
parent
8a9d12d7eb
commit
2b82984039
|
@ -0,0 +1,2 @@
|
|||
node_modules
|
||||
build
|
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"parser": "babel-eslint",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 12,
|
||||
"sourceType": "module",
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "detect"
|
||||
}
|
||||
},
|
||||
"extends": ["eslint:recommended", "plugin:react/recommended"],
|
||||
"rules": {
|
||||
// "eqeqeq": "error",
|
||||
"semi": ["error", "always"],
|
||||
// "indent": ["error", 2],
|
||||
// follow antd's style guide
|
||||
"quotes": ["error", "double"],
|
||||
"jsx-quotes": ["error", "prefer-double"],
|
||||
"space-in-parens": ["error", "never"],
|
||||
"object-curly-spacing": ["error", "never"],
|
||||
"array-bracket-spacing": ["error", "never"],
|
||||
"comma-spacing": ["error", { "before": false, "after": true }],
|
||||
"react/jsx-curly-spacing": [
|
||||
"error",
|
||||
{ "when": "never", "allowMultiline": true, "children": true }
|
||||
],
|
||||
"arrow-spacing": ["error", { "before": true, "after": true }],
|
||||
"space-before-blocks": ["error", "always"],
|
||||
"spaced-comment": ["error", "always"],
|
||||
"react/jsx-tag-spacing": ["error", { "beforeSelfClosing": "always" }],
|
||||
"block-spacing": ["error", "never"],
|
||||
"space-before-function-paren": ["error", "never"],
|
||||
"no-trailing-spaces": ["error", { "ignoreComments": true }],
|
||||
"eol-last": ["error", "always"],
|
||||
// "no-var": ["error"],
|
||||
"curly": ["error", "all"],
|
||||
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
|
||||
"no-mixed-spaces-and-tabs": "error",
|
||||
|
||||
"react/prop-types": "off",
|
||||
"react/display-name": "off",
|
||||
"react/react-in-jsx-scope": "off",
|
||||
|
||||
// don't use strict mod now, otherwise there are a lot of errors in the codebase
|
||||
"no-unused-vars": "warn",
|
||||
"react/no-deprecated": "warn",
|
||||
"no-case-declarations": "warn",
|
||||
"react/jsx-key": "warn"
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
const CracoLessPlugin = require('craco-less');
|
||||
const CracoLessPlugin = require("craco-less");
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
|
@ -7,7 +7,7 @@ module.exports = {
|
|||
options: {
|
||||
lessLoaderOptions: {
|
||||
lessOptions: {
|
||||
modifyVars: {'@primary-color': 'rgb(128,128,128)'},
|
||||
modifyVars: {"@primary-color": "rgb(128,128,128)"},
|
||||
javascriptEnabled: true,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -47,7 +47,8 @@
|
|||
"test": "craco test",
|
||||
"eject": "craco eject",
|
||||
"lint:all": "prettier --write \"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}\"",
|
||||
"crowdin:sync": "crowdin upload && crowdin download"
|
||||
"crowdin:sync": "crowdin upload && crowdin download",
|
||||
"lint": "eslint --fix ."
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
|
@ -67,7 +68,9 @@
|
|||
"devDependencies": {
|
||||
"husky": "^4.3.8",
|
||||
"lint-staged": "^10.5.3",
|
||||
"prettier": "^2.2.1"
|
||||
"prettier": "^2.2.1",
|
||||
"eslint": "^7.11.0",
|
||||
"eslint-plugin-react": "^7.30.1"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
|
@ -76,7 +79,8 @@
|
|||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
|
||||
"prettier --write --print-width 255"
|
||||
"prettier --write --print-width 255",
|
||||
"eslint --fix ."
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import React, { Component } from "react";
|
||||
import React, {Component} from "react";
|
||||
import classNames from "classnames";
|
||||
import "./App.less";
|
||||
import "codemirror/lib/codemirror.css";
|
||||
import { BackTop } from "antd";
|
||||
import {BackTop} from "antd";
|
||||
import * as Setting from "./Setting";
|
||||
import { Switch, Route } from "react-router-dom";
|
||||
import {Switch, Route} from "react-router-dom";
|
||||
import TopicPage from "./TopicPage";
|
||||
import Header from "./Header";
|
||||
import Footer from "./Footer";
|
||||
|
@ -102,7 +102,7 @@ class App extends Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
//Setting.SetLanguage();
|
||||
// Setting.SetLanguage();
|
||||
this.getAccount();
|
||||
this.getFavoriteNum();
|
||||
}
|
||||
|
@ -341,7 +341,7 @@ class App extends Component {
|
|||
<RankingPlayerBox />
|
||||
</div>
|
||||
</Route>
|
||||
{/*BACKSTAGE*/}
|
||||
{/* BACKSTAGE*/}
|
||||
<Route exact path="/admin">
|
||||
<div id={pcBrowser ? "Main" : ""}>
|
||||
{pcBrowser ? <div className="sep20" /> : null}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import React from "react";
|
||||
import { render } from "@testing-library/react";
|
||||
import {render} from "@testing-library/react";
|
||||
import App from "./App";
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
test("renders learn react link", () => {
|
||||
const { getByText } = render(<App />);
|
||||
const {getByText} = render(<App />);
|
||||
const linkElement = getByText(/learn react/i);
|
||||
// eslint-disable-next-line no-undef
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { Button, Result, Spin } from "antd";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import {Button, Result, Spin} from "antd";
|
||||
import {withRouter} from "react-router-dom";
|
||||
import * as Setting from "./Setting";
|
||||
import i18next from "i18next";
|
||||
|
||||
|
@ -46,11 +46,11 @@ class AuthCallback extends React.Component {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<div style={{ textAlign: "center" }}>
|
||||
<div style={{textAlign: "center"}}>
|
||||
{this.state.msg === null ? (
|
||||
<Spin size="large" tip={i18next.t("login:Signing in...")} style={{ paddingTop: "10%", paddingBottom: "10%" }} />
|
||||
<Spin size="large" tip={i18next.t("login:Signing in...")} style={{paddingTop: "10%", paddingBottom: "10%"}} />
|
||||
) : (
|
||||
<div style={{ display: "inline" }}>
|
||||
<div style={{display: "inline"}}>
|
||||
<Result
|
||||
status="error"
|
||||
title={i18next.t("login:Signing In Error")}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import {Link} from "react-router-dom";
|
||||
import * as Setting from "./Setting";
|
||||
import * as Conf from "./Conf";
|
||||
|
||||
|
@ -29,16 +29,16 @@ class Avatar extends React.Component {
|
|||
let style;
|
||||
switch (this.props.size) {
|
||||
case "small":
|
||||
style = { width: "24px", height: "24px" };
|
||||
style = {width: "24px", height: "24px"};
|
||||
break;
|
||||
case "middle":
|
||||
style = { width: "36px", height: "36px" };
|
||||
style = {width: "36px", height: "36px"};
|
||||
break;
|
||||
case "large":
|
||||
style = { width: "73px", height: "73px" };
|
||||
style = {width: "73px", height: "73px"};
|
||||
break;
|
||||
default:
|
||||
style = { width: "48px", height: "48px" };
|
||||
style = {width: "48px", height: "48px"};
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@ export const DefaultEditorType = "markdown";
|
|||
// attachment file can be no larger than 20MB by default
|
||||
export const AttachmentSizeLimitInMb = 20;
|
||||
|
||||
//Default search engine
|
||||
//Support: baidu(www.baidu.com) | google(www.google.com) | cn-bing(cn.bing.com)
|
||||
// Default search engine
|
||||
// Support: baidu(www.baidu.com) | google(www.google.com) | cn-bing(cn.bing.com)
|
||||
export const DefaultSearchSite = "google";
|
||||
|
||||
export const EnableNotificationAutoUpdate = false;
|
||||
|
|
|
@ -16,7 +16,7 @@ import React from "react";
|
|||
import * as Setting from "./Setting";
|
||||
import * as Conf from "./Conf";
|
||||
import * as BasicBackend from "./backend/BasicBackend";
|
||||
import { Link, withRouter } from "react-router-dom";
|
||||
import {Link, withRouter} from "react-router-dom";
|
||||
import moment from "moment";
|
||||
import i18next from "i18next";
|
||||
|
||||
|
@ -61,7 +61,7 @@ class Footer extends React.Component {
|
|||
return (
|
||||
<div id="Bottom">
|
||||
<div className="content">
|
||||
<div className="inner" style={{ textAlign: "center" }}>
|
||||
<div className="inner" style={{textAlign: "center"}}>
|
||||
© {date.getFullYear()} {Setting.getForumName()} · {loadingTime}ms ·{" "}
|
||||
<a href={`${Conf.GithubRepo}/commit/${this.state.version}`} target="_blank" rel="noopener noreferrer">
|
||||
{this.state.version.substring(0, 7)}
|
||||
|
@ -75,7 +75,7 @@ class Footer extends React.Component {
|
|||
<Link
|
||||
to={{
|
||||
pathname: "/select/language",
|
||||
query: { previous: this.props.location.pathname },
|
||||
query: {previous: this.props.location.pathname},
|
||||
}}
|
||||
title="Select Language"
|
||||
className="dark"
|
||||
|
@ -110,11 +110,11 @@ class Footer extends React.Component {
|
|||
/>
|
||||
</a>
|
||||
</div>
|
||||
{/*<div className="fr">*/}
|
||||
{/* <div className="fr">*/}
|
||||
{/* <a href="https://casbin.org" target="_blank">*/}
|
||||
{/* <div className="footer-logo" />*/}
|
||||
{/* </a>*/}
|
||||
{/*</div>*/}
|
||||
{/* </div>*/}
|
||||
<strong>
|
||||
<Link to="/about" className="dark" target="_self">
|
||||
{i18next.t("footer:About")}
|
||||
|
@ -153,7 +153,7 @@ class Footer extends React.Component {
|
|||
<Link
|
||||
to={{
|
||||
pathname: "/select/language",
|
||||
query: { previous: this.props.location.pathname },
|
||||
query: {previous: this.props.location.pathname},
|
||||
}}
|
||||
className="f11"
|
||||
>
|
||||
|
|
|
@ -17,9 +17,9 @@ import * as AccountBackend from "./backend/AccountBackend";
|
|||
import * as NodeBackend from "./backend/NodeBackend";
|
||||
import * as Setting from "./Setting";
|
||||
import * as Conf from "./Conf";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import i18next from "i18next";
|
||||
import { ServerUrl } from "./Setting";
|
||||
import {ServerUrl} from "./Setting";
|
||||
|
||||
class Header extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -141,12 +141,12 @@ class Header extends React.Component {
|
|||
{i18next.t("general:Timeline")}
|
||||
</Link>
|
||||
|
||||
<a target="_blank" className="top" href={Setting.getMyProfileUrl(this.props.account)}>
|
||||
<a target="_blank" className="top" href={Setting.getMyProfileUrl(this.props.account)} rel="noreferrer">
|
||||
{i18next.t("general:Setting")}
|
||||
</a>
|
||||
{/*<Link to="/settings" className="top">*/}
|
||||
{/* <Link to="/settings" className="top">*/}
|
||||
{/* {i18next.t("general:Setting")}*/}
|
||||
{/*</Link>*/}
|
||||
{/* </Link>*/}
|
||||
|
||||
{this.props.account?.isAdmin ? (
|
||||
<span>
|
||||
|
@ -176,17 +176,17 @@ class Header extends React.Component {
|
|||
return (
|
||||
<div id="Top">
|
||||
<div className="content">
|
||||
<div style={{ paddingTop: "6px" }}>
|
||||
<div style={{paddingTop: "6px"}}>
|
||||
<table cellPadding="0" cellSpacing="0" border="0" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="5" align="left"></td>
|
||||
<td width="80" align="left" style={{ paddingTop: "4px" }}>
|
||||
<td width="80" align="left" style={{paddingTop: "4px"}}>
|
||||
<Link to="/" name="top">
|
||||
<div id="logoMobile"></div>
|
||||
</Link>
|
||||
</td>
|
||||
<td width="auto" align="right" style={{ paddingTop: "2px" }}>
|
||||
<td width="auto" align="right" style={{paddingTop: "2px"}}>
|
||||
<Link to="/" className="top">
|
||||
{i18next.t("general:Home")}
|
||||
</Link>
|
||||
|
@ -226,7 +226,7 @@ class Header extends React.Component {
|
|||
src={this.props.account?.avatar !== "" ? this.props.account?.avatar : Setting.getUserAvatar(this.props.account?.name)}
|
||||
width={24}
|
||||
border={0}
|
||||
style={{ borderRadius: "32px", verticalAlign: "middle" }}
|
||||
style={{borderRadius: "32px", verticalAlign: "middle"}}
|
||||
height="32"
|
||||
align="absmiddle"
|
||||
alt={this.props.account?.name}
|
||||
|
@ -254,12 +254,12 @@ class Header extends React.Component {
|
|||
</Link>
|
||||
</div>
|
||||
<div>
|
||||
<a target="_blank" className="top" href={Setting.getMyProfileUrl(this.props.account)}>
|
||||
<a target="_blank" className="top" href={Setting.getMyProfileUrl(this.props.account)} rel="noreferrer">
|
||||
{i18next.t("general:Setting")}
|
||||
</a>
|
||||
{/*<Link to="/settings" className="top">*/}
|
||||
{/* <Link to="/settings" className="top">*/}
|
||||
{/* {i18next.t("general:Setting")}*/}
|
||||
{/*</Link>*/}
|
||||
{/* </Link>*/}
|
||||
</div>
|
||||
<div>
|
||||
<Link to="/admin" className="top">
|
||||
|
@ -268,7 +268,7 @@ class Header extends React.Component {
|
|||
</div>
|
||||
<div className="menu_sep"></div>
|
||||
<div>
|
||||
<a target="_blank" className="top" href={Setting.getMyResourcesUrl(this.props.account)}>
|
||||
<a target="_blank" className="top" href={Setting.getMyResourcesUrl(this.props.account)} rel="noreferrer">
|
||||
<img src={Setting.getStatic("/img/neue_image.png")} height="14" border="0" align="absmiddle" /> {i18next.t("bar:File library")}
|
||||
</a>
|
||||
</div>
|
||||
|
@ -291,13 +291,13 @@ class Header extends React.Component {
|
|||
<div className="menu_sep"></div>
|
||||
<div>
|
||||
<div className="top" onClick={Setting.toggleThemeMode}>
|
||||
<img src={Setting.getThemeBtnUrl()} align="absmiddle" height="10" alt="Light" style={{ verticalAlign: "middle" }} />
|
||||
<img src={Setting.getThemeBtnUrl()} align="absmiddle" height="10" alt="Light" style={{verticalAlign: "middle"}} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="menu_sep"></div>
|
||||
<div style={{ padding: "10px" }}>
|
||||
<div style={{padding: "10px"}}>
|
||||
<div className="member-activity-bar">
|
||||
<div className="member-activity-start" style={{ width: "5%" }}></div>
|
||||
<div className="member-activity-start" style={{width: "5%"}}></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="menu_sep"></div>
|
||||
|
@ -369,13 +369,13 @@ class Header extends React.Component {
|
|||
}}
|
||||
/>
|
||||
{this.state.searchResShow && this.state.searchValue ? (
|
||||
<div id="search-result" className="box" style={{ display: "block" }}>
|
||||
<div id="search-result" className="box" style={{display: "block"}}>
|
||||
<div className="cell">{i18next.t("search:Press Enter to search in site.")}</div>
|
||||
{this.state.matchNodes.length !== 0 ? (
|
||||
<div className="cell">
|
||||
<span className="fade">节点 / Nodes</span>
|
||||
{this.state.matchNodes.map((val) => {
|
||||
//TODO: maybe weshould add `active` iterm
|
||||
// TODO: maybe weshould add `active` iterm
|
||||
return (
|
||||
<a className="search-item" href={`/go/${val.id}`}>
|
||||
{val.name} / {val.id}
|
||||
|
@ -417,7 +417,7 @@ class Header extends React.Component {
|
|||
<div id="Top">
|
||||
<div className="content">
|
||||
<div className="site-nav">
|
||||
<Link to="/" name="top" style={{ fontSize: 0 }} title={Conf.FrontConfig.signinBoxSpan}>
|
||||
<Link to="/" name="top" style={{fontSize: 0}} title={Conf.FrontConfig.signinBoxSpan}>
|
||||
<div
|
||||
id="logo"
|
||||
style={{
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import {withRouter} from "react-router-dom";
|
||||
import * as SearchBackend from "./backend/SearchBackend";
|
||||
import TopicList from "./main/TopicList";
|
||||
import i18next from "i18next";
|
||||
|
@ -36,7 +36,9 @@ class SearchResultPage extends React.Component {
|
|||
componentWillMount() {
|
||||
this.props.history.listen((route) => {
|
||||
let params = route.search.split("=");
|
||||
if (params.length < 2) return;
|
||||
if (params.length < 2) {
|
||||
return;
|
||||
}
|
||||
this.setState(
|
||||
{
|
||||
keyword: params[1],
|
||||
|
@ -52,7 +54,7 @@ class SearchResultPage extends React.Component {
|
|||
if (res.status === "ok") {
|
||||
this.setState({
|
||||
topics: res.data,
|
||||
msg: i18next.t(`search:Search result of `) + this.state.keyword,
|
||||
msg: i18next.t("search:Search result of ") + this.state.keyword,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -60,13 +62,15 @@ class SearchResultPage extends React.Component {
|
|||
renderResult() {
|
||||
if (this.state.topics === null) {
|
||||
return (
|
||||
<div className="cell" id="SecondaryTabs" style={{ padding: "10px" }}>
|
||||
<div className="cell" id="SecondaryTabs" style={{padding: "10px"}}>
|
||||
{i18next.t("search:No topics found")}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.state.topics.length === 0) return null;
|
||||
if (this.state.topics.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <TopicList topics={this.state.topics} showNodeName={true} showAvatar={true} />;
|
||||
}
|
||||
|
@ -74,7 +78,7 @@ class SearchResultPage extends React.Component {
|
|||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div className="cell" id="SecondaryTabs" style={{ padding: "10px" }}>
|
||||
<div className="cell" id="SecondaryTabs" style={{padding: "10px"}}>
|
||||
{this.state.msg}
|
||||
</div>
|
||||
{this.renderResult()}
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { message } from "antd";
|
||||
import {Link} from "react-router-dom";
|
||||
import {message} from "antd";
|
||||
import moment from "moment";
|
||||
import { animateScroll as scroll } from "react-scroll";
|
||||
import {animateScroll as scroll} from "react-scroll";
|
||||
import md5 from "js-md5";
|
||||
import * as Conf from "./Conf";
|
||||
import * as MemberBackend from "./backend/MemberBackend";
|
||||
|
@ -25,7 +25,7 @@ import Zmage from "react-zmage";
|
|||
import Identicon from "identicon.js";
|
||||
import Sdk from "casdoor-js-sdk";
|
||||
import * as ConfBackend from "./backend/ConfBackend";
|
||||
import { FrontConfig } from "./Conf";
|
||||
import {FrontConfig} from "./Conf";
|
||||
|
||||
const pangu = require("pangu");
|
||||
|
||||
|
@ -79,11 +79,10 @@ export function signin() {
|
|||
return CasdoorSdk.signin(ServerUrl).then((res) => {
|
||||
if (res.status === "ok") {
|
||||
if (window !== window.parent) {
|
||||
const message = { tag: "Casdoor", type: "SilentSignin", data: "success" };
|
||||
const message = {tag: "Casdoor", type: "SilentSignin", data: "success"};
|
||||
window.parent.postMessage(message, "*");
|
||||
}
|
||||
showMessage("success", i18next.t("login:Logged in successfully"));
|
||||
} else {
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -216,7 +215,7 @@ export function changeMomentLanguage(language) {
|
|||
}
|
||||
|
||||
export function getFormattedContent(content, spacing) {
|
||||
let formattedContent = content.replace(/@(.*?)[ \n\t]|@([^ \n\t]*?)[^ \n\t]$/g, function (w) {
|
||||
let formattedContent = content.replace(/@(.*?)[ \n\t]|@([^ \n\t]*?)[^ \n\t]$/g, function(w) {
|
||||
if (w[w.length - 1] !== " ") {
|
||||
return `@[${w.substring(1, w.length)}](${ClientUrl}/member/${w.substring(1)})`;
|
||||
}
|
||||
|
@ -225,7 +224,7 @@ export function getFormattedContent(content, spacing) {
|
|||
if (spacing) {
|
||||
return pangu
|
||||
.spacing(formattedContent)
|
||||
.replace(/\[(.*?)]\((.*?)\)/g, function (w) {
|
||||
.replace(/\[(.*?)]\((.*?)\)/g, function(w) {
|
||||
return w.replace(/ /g, "");
|
||||
})
|
||||
.replace(/% /g, "%")
|
||||
|
@ -253,7 +252,7 @@ export function getFileType(fileName) {
|
|||
if (index < 0) {
|
||||
fileType = "file";
|
||||
}
|
||||
return { fileType: fileType, ext: ext };
|
||||
return {fileType: fileType, ext: ext};
|
||||
}
|
||||
|
||||
const unitSuffix = ["Bytes", "KB", "MB"];
|
||||
|
@ -304,8 +303,8 @@ export function checkPageLink(url) {
|
|||
return current === target;
|
||||
}
|
||||
|
||||
export function renderImage({ alt, src }) {
|
||||
return <Zmage src={src} alt={alt} style={{ maxWidth: "100%" }} />;
|
||||
export function renderImage({alt, src}) {
|
||||
return <Zmage src={src} alt={alt} style={{maxWidth: "100%"}} />;
|
||||
}
|
||||
|
||||
export function renderLink(props) {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import {withRouter} from "react-router-dom";
|
||||
import * as Setting from "./Setting";
|
||||
|
||||
class SigninPage extends React.Component {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import {withRouter} from "react-router-dom";
|
||||
import * as Setting from "./Setting";
|
||||
|
||||
class SilentSignin extends React.Component {
|
||||
|
@ -50,7 +50,7 @@ class SilentSignin extends React.Component {
|
|||
return null;
|
||||
}
|
||||
|
||||
return <iframe id="iframeTask" src={`${Setting.getSigninUrl()}&silentSignin=1`} style={{ display: "none" }} width={0} height={0} frameBorder="no" />;
|
||||
return <iframe id="iframeTask" src={`${Setting.getSigninUrl()}&silentSignin=1`} style={{display: "none"}} width={0} height={0} frameBorder="no" />;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,11 +19,11 @@ import * as TabBackend from "./backend/TabBackend";
|
|||
import * as NotificationBackend from "./backend/NotificationBackend";
|
||||
import Avatar from "./Avatar";
|
||||
import TopicList from "./main/TopicList";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import moment from "moment";
|
||||
import i18next from "i18next";
|
||||
import { scoreConverter } from "./main/Tools";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {scoreConverter} from "./main/Tools";
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
class TopicPage extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -87,7 +87,7 @@ class TopicPage extends React.Component {
|
|||
this.state.tab === undefined ? (tab = "") : (tab = this.state.tab);
|
||||
TabBackend.getTabWithNode(tab).then((res) => {
|
||||
if (res === null) {
|
||||
window.location.href = `/`;
|
||||
window.location.href = "/";
|
||||
}
|
||||
this.setState({
|
||||
tabInfo: res?.data,
|
||||
|
@ -126,7 +126,7 @@ class TopicPage extends React.Component {
|
|||
const newTopic = this.newTopic();
|
||||
TopicBackend.addTopic(newTopic)
|
||||
.then((res) => {
|
||||
Setting.showMessage("success", `Adding topic succeeded`);
|
||||
Setting.showMessage("success", "Adding topic succeeded");
|
||||
this.setState({
|
||||
topics: Setting.addRow(this.state.topics, newTopic),
|
||||
});
|
||||
|
@ -139,7 +139,7 @@ class TopicPage extends React.Component {
|
|||
deleteTopic(i) {
|
||||
TopicBackend.deleteTopic(this.state.topics[i].id)
|
||||
.then((res) => {
|
||||
Setting.showMessage("success", `Deleting topic succeeded`);
|
||||
Setting.showMessage("success", "Deleting topic succeeded");
|
||||
this.setState({
|
||||
topics: Setting.deleteRow(this.state.topics, i),
|
||||
});
|
||||
|
@ -170,10 +170,10 @@ class TopicPage extends React.Component {
|
|||
if (this.props.account === undefined || this.props.account === null) {
|
||||
return null;
|
||||
}
|
||||
const { goldCount, silverCount, bronzeCount } = scoreConverter(this.props.account.score);
|
||||
const {goldCount, silverCount, bronzeCount} = scoreConverter(this.props.account.score);
|
||||
return (
|
||||
<div class="cell">
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||
<div className="cell">
|
||||
<table cellPadding="0" cellSpacing="0" border="0" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="auto">
|
||||
|
@ -197,7 +197,7 @@ class TopicPage extends React.Component {
|
|||
</td>
|
||||
<td width="10"></td>
|
||||
<td width="150" align="right">
|
||||
<Link to="/balance" className="balance_area" style={{ margin: "0px" }}>
|
||||
<Link to="/balance" className="balance_area" style={{margin: "0px"}}>
|
||||
{goldCount ? (
|
||||
<span>
|
||||
{" "}
|
||||
|
@ -234,7 +234,7 @@ class TopicPage extends React.Component {
|
|||
return this.renderTab(tab);
|
||||
})}
|
||||
</div>
|
||||
<div className="cell" id="SecondaryTabs" style={{ padding: "10px" }}>
|
||||
<div className="cell" id="SecondaryTabs" style={{padding: "10px"}}>
|
||||
{this.props.account !== undefined && this.props.account !== null && this.state.tabInfo?.defaultNode !== undefined && this.state.tabInfo?.defaultNode !== null && this.state.tabInfo?.defaultNode !== "" ? (
|
||||
<div className="fr">
|
||||
<Link to={`/new/${this.state.tabInfo?.defaultNode}`}>{this.state.tab === "all" ? i18next.t("topic:Post a Question") : i18next.t("topic:Create a Post")}</Link>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import {Link} from "react-router-dom";
|
||||
import i18next from "i18next";
|
||||
|
||||
class UserLink extends React.Component {
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { Link, withRouter } from "react-router-dom";
|
||||
import {Link, withRouter} from "react-router-dom";
|
||||
import * as Setting from "../Setting";
|
||||
import i18next from "i18next";
|
||||
import * as ConfBackend from "../backend/ConfBackend";
|
||||
import * as Tools from "../main/Tools";
|
||||
import { Controlled as CodeMirrorsEditor } from "react-codemirror2";
|
||||
import {Controlled as CodeMirrorsEditor} from "react-codemirror2";
|
||||
|
||||
class AdminFrontConf extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -88,10 +88,10 @@ class AdminFrontConf extends React.Component {
|
|||
}
|
||||
|
||||
updateConf() {
|
||||
this.setState({ publishClicked: true });
|
||||
this.setState({publishClicked: true});
|
||||
let confs = [];
|
||||
for (const k in this.state.changeForm) {
|
||||
confs.push({ id: k, value: this.state.changeForm[k], field: this.state.field });
|
||||
confs.push({id: k, value: this.state.changeForm[k], field: this.state.field});
|
||||
}
|
||||
ConfBackend.updateFrontConfById(this.state.id, this.state.content).then((res) => {
|
||||
if (res.status === "ok") {
|
||||
|
@ -116,10 +116,10 @@ class AdminFrontConf extends React.Component {
|
|||
resize: "none",
|
||||
height: "auto",
|
||||
}}
|
||||
className={`mll`}
|
||||
className={"mll"}
|
||||
id="reply_content"
|
||||
>
|
||||
<div className={`cm-short-content`}>
|
||||
<div className={"cm-short-content"}>
|
||||
<CodeMirrorsEditor
|
||||
editorDidMount={(editor) => Tools.attachEditor(editor)}
|
||||
onPaste={() => Tools.uploadMdFile()}
|
||||
|
@ -129,7 +129,7 @@ class AdminFrontConf extends React.Component {
|
|||
mode: "markdown",
|
||||
lineNumbers: false,
|
||||
lineWrapping: true,
|
||||
extraKeys: { "Ctrl-Space": "autocomplete" },
|
||||
extraKeys: {"Ctrl-Space": "autocomplete"},
|
||||
hintOptions: {
|
||||
alignWithWord: false,
|
||||
closeOnUnfocus: false,
|
||||
|
@ -138,7 +138,7 @@ class AdminFrontConf extends React.Component {
|
|||
},
|
||||
}}
|
||||
onBeforeChange={(editor, data, value) => {
|
||||
this.setState({ content: value });
|
||||
this.setState({content: value});
|
||||
}}
|
||||
onChange={(editor, data, value) => {}}
|
||||
/>
|
||||
|
@ -148,7 +148,7 @@ class AdminFrontConf extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
let blurStyle = { color: "#ccc", pointerEvents: "none" };
|
||||
let blurStyle = {color: "#ccc", pointerEvents: "none"};
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -182,7 +182,7 @@ class AdminFrontConf extends React.Component {
|
|||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<button type="button" onClick={this.updateConf.bind(this)} type="submit" className="super normal button">
|
||||
<button onClick={this.updateConf.bind(this)} type="submit" className="super normal button">
|
||||
<li className={this.state.publishClicked ? "fa fa-circle-o-notch fa-spin" : "fa fa-paper-plane"} />
|
||||
{this.state.publishClicked ? i18next.t("new:Publishing...") : i18next.t("frontConf:Save")}
|
||||
</button>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { Link, withRouter } from "react-router-dom";
|
||||
import {Link, withRouter} from "react-router-dom";
|
||||
import * as Setting from "../Setting";
|
||||
import i18next from "i18next";
|
||||
import * as ConfBackend from "../backend/ConfBackend";
|
||||
|
@ -23,24 +23,24 @@ class AdminFrontConf extends React.Component {
|
|||
super(props);
|
||||
this.state = {
|
||||
classes: props,
|
||||
Management_LIST: [{ label: "Visual Conf", value: "visualConf" }],
|
||||
Management_LIST: [{label: "Visual Conf", value: "visualConf"}],
|
||||
field: "visualConf",
|
||||
conf: [
|
||||
{ id: "forumName", value: "" },
|
||||
{ id: "logoImage", value: "" },
|
||||
{ id: "signinBoxStrong", value: "" },
|
||||
{ id: "signinBoxSpan", value: "" },
|
||||
{ id: "footerAdvise", value: "" },
|
||||
{ id: "footerDeclaration", value: "" },
|
||||
{ id: "footerLogoImage", value: "" },
|
||||
{ id: "footerLogoUrl", value: "" },
|
||||
{id: "forumName", value: ""},
|
||||
{id: "logoImage", value: ""},
|
||||
{id: "signinBoxStrong", value: ""},
|
||||
{id: "signinBoxSpan", value: ""},
|
||||
{id: "footerAdvise", value: ""},
|
||||
{id: "footerDeclaration", value: ""},
|
||||
{id: "footerLogoImage", value: ""},
|
||||
{id: "footerLogoUrl", value: ""},
|
||||
],
|
||||
form: {},
|
||||
changeForm: {},
|
||||
message: "",
|
||||
memberId: props.match.params.memberId,
|
||||
};
|
||||
this.state.url = `/admin/frontconf`;
|
||||
this.state.url = "/admin/frontconf";
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -104,7 +104,7 @@ class AdminFrontConf extends React.Component {
|
|||
updateConf() {
|
||||
let confs = [];
|
||||
for (const k in this.state.changeForm) {
|
||||
confs.push({ id: k, value: this.state.changeForm[k], field: this.state.field });
|
||||
confs.push({id: k, value: this.state.changeForm[k], field: this.state.field});
|
||||
}
|
||||
|
||||
ConfBackend.updateFrontConfsByField(this.state.field, confs).then((res) => {
|
||||
|
@ -198,7 +198,7 @@ class AdminFrontConf extends React.Component {
|
|||
{this.convert(item.id)}
|
||||
</td>
|
||||
<td width="auto" align="left">
|
||||
<textarea rows="1" style={{ width: "80%" }} value={this.state.form[item.id]} onChange={(event) => this.inputChange(event, item.id)} />
|
||||
<textarea rows="1" style={{width: "80%"}} value={this.state.form[item.id]} onChange={(event) => this.inputChange(event, item.id)} />
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
import React from "react";
|
||||
import * as Setting from "../Setting";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import i18next from "i18next";
|
||||
import * as Conf from "../Conf";
|
||||
|
||||
|
@ -120,7 +120,7 @@ class AdminHomepage extends React.Component {
|
|||
renderManageItem(item) {
|
||||
if (item.value === "member") {
|
||||
return (
|
||||
<a className="grid_item" target="_blank" href={Setting.getMyProfileUrl(this.props.account)}>
|
||||
<a className="grid_item" target="_blank" href={Setting.getMyProfileUrl(this.props.account)} rel="noreferrer">
|
||||
{this.renderManageItemInternal(item)}
|
||||
</a>
|
||||
);
|
||||
|
|
|
@ -13,15 +13,15 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import * as PlaneBackend from "../backend/PlaneBackend.js";
|
||||
import * as TabBackend from "../backend/TabBackend.js";
|
||||
import * as NodeBackend from "../backend/NodeBackend";
|
||||
import * as Setting from "../Setting";
|
||||
import * as Tools from "../main/Tools";
|
||||
import * as FileBackend from "../backend/FileBackend";
|
||||
import { Controlled as CodeMirror } from "react-codemirror2";
|
||||
import { SketchPicker } from "react-color";
|
||||
import {Controlled as CodeMirror} from "react-codemirror2";
|
||||
import {SketchPicker} from "react-color";
|
||||
import Zmage from "react-zmage";
|
||||
import "../codemirrorSize.css";
|
||||
import Select2 from "react-select2-wrapper";
|
||||
|
@ -40,20 +40,20 @@ class AdminNode extends React.Component {
|
|||
errorMessage: "",
|
||||
form: {},
|
||||
nodeInfo: [],
|
||||
//event: props.match.params.event,
|
||||
// event: props.match.params.event,
|
||||
nodeId: props.match.params.nodeId,
|
||||
topicNum: 0,
|
||||
favoritesNum: 0,
|
||||
width: "",
|
||||
event: "basic",
|
||||
Management_LIST: [
|
||||
{ label: "Basic Info", value: "basic" },
|
||||
{ label: "Background", value: "background" },
|
||||
{label: "Basic Info", value: "basic"},
|
||||
{label: "Background", value: "background"},
|
||||
],
|
||||
Repeat_LIST: [
|
||||
{ label: "Repeat", value: "repeat" },
|
||||
{ label: "Repeat-x", value: "repeat-x" },
|
||||
{ label: "Repeat-y", value: "repeat-y" },
|
||||
{label: "Repeat", value: "repeat"},
|
||||
{label: "Repeat-x", value: "repeat-x"},
|
||||
{label: "Repeat-y", value: "repeat-y"},
|
||||
],
|
||||
color: "#386d97",
|
||||
displayColorPicker: false,
|
||||
|
@ -144,9 +144,13 @@ class AdminNode extends React.Component {
|
|||
let fileName,
|
||||
fileType = Setting.getFileType(file.name);
|
||||
|
||||
if (target === "headerImage") fileName = "header";
|
||||
else if (target === "backgroundImage") fileName = "background";
|
||||
else fileName = "other";
|
||||
if (target === "headerImage") {
|
||||
fileName = "header";
|
||||
} else if (target === "backgroundImage") {
|
||||
fileName = "background";
|
||||
} else {
|
||||
fileName = "other";
|
||||
}
|
||||
fileName += "." + fileType.ext;
|
||||
|
||||
let reader = new FileReader();
|
||||
|
@ -311,7 +315,7 @@ class AdminNode extends React.Component {
|
|||
|
||||
handleColorChange = (color) => {
|
||||
this.updateFormField("backgroundColor", color.hex);
|
||||
//this.setState({ color: color.hex });
|
||||
// this.setState({ color: color.hex });
|
||||
};
|
||||
|
||||
handleColorClick = () => {
|
||||
|
@ -372,8 +376,8 @@ class AdminNode extends React.Component {
|
|||
<div className="box">
|
||||
<div className="header">
|
||||
<Link to="/">{Setting.getForumName()}</Link> <span className="chevron"> › </span>
|
||||
<Link to={`/admin`}>{i18next.t("admin:Backstage management")}</Link> <span className="chevron"> › </span>
|
||||
<Link to={`/admin/node`}>{i18next.t("node:Node management")}</Link> <span className="chevron"> › </span>
|
||||
<Link to={"/admin"}>{i18next.t("admin:Backstage management")}</Link> <span className="chevron"> › </span>
|
||||
<Link to={"/admin/node"}>{i18next.t("node:Node management")}</Link> <span className="chevron"> › </span>
|
||||
{this.props.event === "new" ? <span>{i18next.t("node:New node")}</span> : <Link to={`/go/${encodeURIComponent(this.state.nodeId)}`}>{this.state.nodeInfo?.name}</Link>}
|
||||
</div>
|
||||
<div className="cell">
|
||||
|
@ -400,12 +404,12 @@ class AdminNode extends React.Component {
|
|||
<Link to={`/admin/node/edit/${encodeURIComponent(node?.nodeInfo.id)}`}>{i18next.t("node:Manage")}</Link>
|
||||
</td>
|
||||
<td width="10"></td>
|
||||
<td width={pcBrowser ? "auto" : "80"} valign="middle" style={{ textAlign: "center" }}>
|
||||
<span style={{ fontSize: "13px" }}>
|
||||
<td width={pcBrowser ? "auto" : "80"} valign="middle" style={{textAlign: "center"}}>
|
||||
<span style={{fontSize: "13px"}}>
|
||||
{node?.nodeInfo.hot} {i18next.t("node:hot")}
|
||||
</span>
|
||||
</td>
|
||||
<td width="100" align="left" style={{ textAlign: "center" }}>
|
||||
<td width="100" align="left" style={{textAlign: "center"}}>
|
||||
{node?.topicNum} {i18next.t("node:topics")}
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -425,28 +429,34 @@ class AdminNode extends React.Component {
|
|||
}
|
||||
|
||||
renderSelect(item) {
|
||||
if (this.state.nodes === null) return;
|
||||
if (this.state.tabs === null) return;
|
||||
if (this.state.planes === null) return;
|
||||
if (this.state.nodes === null) {
|
||||
return;
|
||||
}
|
||||
if (this.state.tabs === null) {
|
||||
return;
|
||||
}
|
||||
if (this.state.planes === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
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 };
|
||||
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 };
|
||||
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 };
|
||||
return {text: `${plane.name} / ${plane.id}`, id: i};
|
||||
});
|
||||
break;
|
||||
default:
|
||||
|
@ -495,7 +505,7 @@ class AdminNode extends React.Component {
|
|||
renderNodeModerators(moderators) {
|
||||
return (
|
||||
<span>
|
||||
<Link to={`/member/${moderators}`} style={{ fontWeight: "bolder" }} target="_blank">
|
||||
<Link to={`/member/${moderators}`} style={{fontWeight: "bolder"}} target="_blank">
|
||||
{moderators}
|
||||
</Link>
|
||||
|
||||
|
@ -528,20 +538,20 @@ class AdminNode extends React.Component {
|
|||
|
||||
if (this.state.nodeInfo === null) {
|
||||
return (
|
||||
<div class="box">
|
||||
<div class="header">
|
||||
<div className="box">
|
||||
<div className="header">
|
||||
<Link to="/">{Setting.getForumName()}</Link>
|
||||
<span className="chevron"> › </span> {i18next.t("error:Node not found")}
|
||||
</div>
|
||||
<div class="cell">
|
||||
<div className="cell">
|
||||
{i18next.t("error:The node you are trying to view does not exist, there are several possibilities")}
|
||||
<div class="sep10"></div>
|
||||
<div className="sep10"></div>
|
||||
<ul>
|
||||
<li>{i18next.t("error:You entered a node ID that does not exist.")}</li>
|
||||
<li>{i18next.t("error:The node is currently in invisible state.")}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="inner">
|
||||
<div className="inner">
|
||||
{this.props.account === null ? (
|
||||
<span className="gray">
|
||||
<span className="chevron">‹</span>
|
||||
|
@ -629,7 +639,7 @@ class AdminNode extends React.Component {
|
|||
{this.state.form?.image === undefined || this.state.form?.image === "" ? (
|
||||
<span className="gray">{i18next.t("node:Not set")}</span>
|
||||
) : (
|
||||
<Zmage src={this.state.form?.image} alt={this.state.form?.id} style={{ maxWidth: "48px", maxHeight: "48px" }} />
|
||||
<Zmage src={this.state.form?.image} alt={this.state.form?.id} style={{maxWidth: "48px", maxHeight: "48px"}} />
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -677,7 +687,7 @@ class AdminNode extends React.Component {
|
|||
</td>
|
||||
<td width="auto" align="left">
|
||||
<input type="range" min="1" max="1000" step="1" value={this.state.form?.sorter === undefined ? 1 : this.state.form?.sorter} onChange={(event) => this.updateFormField("sorter", parseInt(event.target.value))} />
|
||||
<input type="number" name="sorter" min="1" max="1000" step="1" value={this.state.form?.sorter} style={{ width: "50px" }} onChange={(event) => this.updateFormField("sorter", parseInt(event.target.value))} />
|
||||
<input type="number" name="sorter" min="1" max="1000" step="1" value={this.state.form?.sorter} style={{width: "50px"}} onChange={(event) => this.updateFormField("sorter", parseInt(event.target.value))} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -762,7 +772,7 @@ class AdminNode extends React.Component {
|
|||
{i18next.t("node:Moderators")}
|
||||
</td>
|
||||
<td width="auto" align="left">
|
||||
<span class="gray">{i18next.t("node:No moderators")}</span>
|
||||
<span className="gray">{i18next.t("node:No moderators")}</span>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
|
@ -791,7 +801,7 @@ class AdminNode extends React.Component {
|
|||
className="mle"
|
||||
id="node_description"
|
||||
>
|
||||
<div className={`cm-middle-unresizable-content`}>
|
||||
<div className={"cm-middle-unresizable-content"}>
|
||||
<CodeMirror
|
||||
editorDidMount={(editor) => Tools.attachEditor(editor)}
|
||||
onPaste={() => Tools.uploadMdFile()}
|
||||
|
@ -856,7 +866,7 @@ class AdminNode extends React.Component {
|
|||
{this.state.form?.headerImage === undefined || this.state.form?.headerImage === "" ? (
|
||||
<span className="gray">{i18next.t("node:Not set")}</span>
|
||||
) : (
|
||||
<Zmage src={this.state.form?.headerImage} alt={this.state.form?.id} style={{ maxWidth: "48px", maxHeight: "48px" }} />
|
||||
<Zmage src={this.state.form?.headerImage} alt={this.state.form?.id} style={{maxWidth: "48px", maxHeight: "48px"}} />
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -874,7 +884,7 @@ class AdminNode extends React.Component {
|
|||
onChange={(event) => this.updateFormField("headerImage", event.target.value)}
|
||||
autoComplete="off"
|
||||
/>{" "}
|
||||
<input type="file" accept=".jpg,.gif,.png,.JPG,.GIF,.PNG" onChange={(event) => this.handleUploadImage(event, "headerImage")} name="headerImage" style={{ width: "200px" }} />
|
||||
<input type="file" accept=".jpg,.gif,.png,.JPG,.GIF,.PNG" onChange={(event) => this.handleUploadImage(event, "headerImage")} name="headerImage" style={{width: "200px"}} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -885,7 +895,7 @@ class AdminNode extends React.Component {
|
|||
{this.state.form?.backgroundImage === undefined || this.state.form?.backgroundImage === "" ? (
|
||||
<span className="gray">{i18next.t("node:Not set")}</span>
|
||||
) : (
|
||||
<Zmage src={this.state.form?.backgroundImage} alt={this.state.form?.id} style={{ maxWidth: "48px", maxHeight: "48px" }} />
|
||||
<Zmage src={this.state.form?.backgroundImage} alt={this.state.form?.id} style={{maxWidth: "48px", maxHeight: "48px"}} />
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -903,7 +913,7 @@ class AdminNode extends React.Component {
|
|||
onChange={(event) => this.updateFormField("backgroundImage", event.target.value)}
|
||||
autoComplete="off"
|
||||
/>{" "}
|
||||
<input type="file" accept=".jpg,.gif,.png,.JPG,.GIF,.PNG" onChange={(event) => this.handleUploadImage(event, "backgroundImage")} name="backgroundImage" style={{ width: "200px" }} />
|
||||
<input type="file" accept=".jpg,.gif,.png,.JPG,.GIF,.PNG" onChange={(event) => this.handleUploadImage(event, "backgroundImage")} name="backgroundImage" style={{width: "200px"}} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import * as PlaneBackend from "../backend/PlaneBackend.js";
|
||||
import * as Setting from "../Setting";
|
||||
import Zmage from "react-zmage";
|
||||
import { SketchPicker } from "react-color";
|
||||
import {SketchPicker} from "react-color";
|
||||
import i18next from "i18next";
|
||||
import * as Conf from "../Conf";
|
||||
|
||||
|
@ -32,13 +32,13 @@ class AdminPlane extends React.Component {
|
|||
errorMessage: "",
|
||||
form: {},
|
||||
plane: [],
|
||||
//event: props.match.params.event,
|
||||
// event: props.match.params.event,
|
||||
planeId: props.match.params.planeId,
|
||||
width: "",
|
||||
event: "basic",
|
||||
Management_LIST: [
|
||||
{ label: "Basic Info", value: "basic" },
|
||||
{ label: "Display", value: "display" },
|
||||
{label: "Basic Info", value: "basic"},
|
||||
{label: "Display", value: "display"},
|
||||
],
|
||||
color: "",
|
||||
backgroundColor: "",
|
||||
|
@ -123,7 +123,7 @@ class AdminPlane extends React.Component {
|
|||
}
|
||||
|
||||
deletePlane(plane, planeId, nodesNum) {
|
||||
if (window.confirm(`${i18next.t(`plane:Are you sure to delete plane`)} ${plane} ?`)) {
|
||||
if (window.confirm(`${i18next.t("plane:Are you sure to delete plane")} ${plane} ?`)) {
|
||||
if (nodesNum !== 0) {
|
||||
alert(`
|
||||
${i18next.t("plane:Please delete all the nodes or move to another plane before deleting the plane")}
|
||||
|
@ -330,8 +330,8 @@ class AdminPlane extends React.Component {
|
|||
<div className="box">
|
||||
<div className="header">
|
||||
<Link to="/">{Setting.getForumName()}</Link> <span className="chevron"> › </span>
|
||||
<Link to={`/admin`}>{i18next.t("admin:Backstage management")}</Link> <span className="chevron"> › </span>
|
||||
<Link to={`/admin/plane`}>{i18next.t("plane:Plane management")}</Link> <span className="chevron"> › </span>
|
||||
<Link to={"/admin"}>{i18next.t("admin:Backstage management")}</Link> <span className="chevron"> › </span>
|
||||
<Link to={"/admin/plane"}>{i18next.t("plane:Plane management")}</Link> <span className="chevron"> › </span>
|
||||
<span>{this.props.event === "new" ? i18next.t("plane:New plane") : this.state.planeId}</span>
|
||||
</div>
|
||||
<div className="cell">
|
||||
|
@ -358,15 +358,15 @@ class AdminPlane extends React.Component {
|
|||
<Link to={`/admin/plane/edit/${plane?.id}`}>{i18next.t("plane:Manage")}</Link>
|
||||
</td>
|
||||
<td width="10"></td>
|
||||
<td width={pcBrowser ? "120" : "80"} valign="middle" style={{ textAlign: "center" }}>
|
||||
<span style={{ fontSize: "13px" }}>
|
||||
<td width={pcBrowser ? "120" : "80"} valign="middle" style={{textAlign: "center"}}>
|
||||
<span style={{fontSize: "13px"}}>
|
||||
{plane?.nodesNum} {i18next.t("plane:nodes")}
|
||||
</span>
|
||||
</td>
|
||||
<td width={pcBrowser ? "120" : "80"} align="left" style={{ textAlign: "center" }}>
|
||||
<td width={pcBrowser ? "120" : "80"} align="left" style={{textAlign: "center"}}>
|
||||
{plane?.visible ? <span className="positive">{i18next.t("plane:Visible")}</span> : <span className="gray">{i18next.t("plane:Invisible")}</span>}
|
||||
</td>
|
||||
<td width="50" align="left" style={{ textAlign: "right" }}>
|
||||
<td width="50" align="left" style={{textAlign: "right"}}>
|
||||
<a href="#" onClick={() => this.deletePlane(plane?.name, plane?.id, plane?.nodesNum)}>
|
||||
{i18next.t("plane:Delete")}
|
||||
</a>
|
||||
|
@ -403,12 +403,12 @@ class AdminPlane extends React.Component {
|
|||
|
||||
if (this.state.plane === null) {
|
||||
return (
|
||||
<div class="box">
|
||||
<div class="header">
|
||||
<div className="box">
|
||||
<div className="header">
|
||||
<Link to="/">{Setting.getForumName()}</Link>
|
||||
<span className="chevron"> › </span> {i18next.t("error:Plane not found")}
|
||||
</div>
|
||||
<div class="cell">{i18next.t("error:The plane you are trying to view does not exist")}</div>
|
||||
<div className="cell">{i18next.t("error:The plane you are trying to view does not exist")}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -485,7 +485,7 @@ class AdminPlane extends React.Component {
|
|||
</td>
|
||||
<td width="auto" align="left">
|
||||
<input type="range" min="1" max="1000" step="1" value={this.state.form?.sorter === undefined ? 1 : this.state.form?.sorter} onChange={(event) => this.updateFormField("sorter", parseInt(event.target.value))} />
|
||||
<input type="number" name="sorter" min="1" max="1000" step="1" value={this.state.form?.sorter} style={{ width: "50px" }} onChange={(event) => this.updateFormField("sorter", parseInt(event.target.value))} />
|
||||
<input type="number" name="sorter" min="1" max="1000" step="1" value={this.state.form?.sorter} style={{width: "50px"}} onChange={(event) => this.updateFormField("sorter", parseInt(event.target.value))} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -557,7 +557,7 @@ class AdminPlane extends React.Component {
|
|||
{this.state.form?.image === undefined || this.state.form?.image === "" ? (
|
||||
<span className="gray">{i18next.t("plane:Not set")}</span>
|
||||
) : (
|
||||
<Zmage src={this.state.form?.image} alt={this.state.form?.id} style={{ maxWidth: "48px", maxHeight: "48px" }} />
|
||||
<Zmage src={this.state.form?.image} alt={this.state.form?.id} style={{maxWidth: "48px", maxHeight: "48px"}} />
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import * as PosterBackend from "../backend/PosterBackend";
|
||||
import * as Setting from "../Setting";
|
||||
import i18next from "i18next";
|
||||
|
@ -36,7 +36,7 @@ class AdminPoster extends React.Component {
|
|||
memberId: props.match.params.memberId,
|
||||
};
|
||||
|
||||
this.state.url = `/admin/poster`;
|
||||
this.state.url = "/admin/poster";
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import * as SensitiveBackend from "../backend/SensitiveBackend.js";
|
||||
import * as Setting from "../Setting";
|
||||
import i18next from "i18next";
|
||||
|
@ -43,7 +43,9 @@ class AdminSensitive extends React.Component {
|
|||
sensitiveList: res,
|
||||
});
|
||||
});
|
||||
} else alert(res.msg);
|
||||
} else {
|
||||
alert(res.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -56,7 +58,7 @@ class AdminSensitive extends React.Component {
|
|||
>
|
||||
{item}
|
||||
</a>
|
||||
<a style={{ float: "right" }} onClick={() => this.delSensitive(item)}>
|
||||
<a style={{float: "right"}} onClick={() => this.delSensitive(item)}>
|
||||
delete
|
||||
</a>
|
||||
</div>
|
||||
|
@ -71,7 +73,9 @@ class AdminSensitive extends React.Component {
|
|||
sensitiveList: res,
|
||||
});
|
||||
});
|
||||
} else alert(res.msg);
|
||||
} else {
|
||||
alert(res.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -79,7 +83,7 @@ class AdminSensitive extends React.Component {
|
|||
return (
|
||||
<div className="cell">
|
||||
<input type="text" id="newsensitive" />
|
||||
<a style={{ float: "right" }} onClick={() => this.addSensitive()}>
|
||||
<a style={{float: "right"}} onClick={() => this.addSensitive()}>
|
||||
add
|
||||
</a>
|
||||
</div>
|
||||
|
@ -91,8 +95,8 @@ class AdminSensitive extends React.Component {
|
|||
<div className="box">
|
||||
<div className="header">
|
||||
<Link to="/">{Setting.getForumName()}</Link> <span className="chevron"> › </span>
|
||||
<Link to={`/admin`}>{i18next.t("admin:Backstage management")}</Link> <span className="chevron"> › </span>
|
||||
<Link to={`/admin/sensitive`}>{i18next.t("sensitive:sensitive management")}</Link> <span className="chevron"> › </span>
|
||||
<Link to={"/admin"}>{i18next.t("admin:Backstage management")}</Link> <span className="chevron"> › </span>
|
||||
<Link to={"/admin/sensitive"}>{i18next.t("sensitive:sensitive management")}</Link> <span className="chevron"> › </span>
|
||||
<span>{this.props.event === "new" ? i18next.t("sensitive:new sensitive") : ""}</span>
|
||||
</div>
|
||||
<div className="cell">
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import * as TabBackend from "../backend/TabBackend.js";
|
||||
import * as Setting from "../Setting";
|
||||
import Select2 from "react-select2-wrapper";
|
||||
|
@ -31,11 +31,11 @@ class AdminTab extends React.Component {
|
|||
errorMessage: "",
|
||||
form: {},
|
||||
tab: [],
|
||||
//event: props.match.params.event,
|
||||
// event: props.match.params.event,
|
||||
tabId: props.match.params.tabId,
|
||||
width: "",
|
||||
event: "basic",
|
||||
Management_LIST: [{ label: "Basic Info", value: "basic" }],
|
||||
Management_LIST: [{label: "Basic Info", value: "basic"}],
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,7 @@ class AdminTab extends React.Component {
|
|||
}
|
||||
|
||||
deleteTab(tab, topicsNum, nodesNum) {
|
||||
if (window.confirm(`${i18next.t(`tab:Are you sure to delete tab`)} ${tab} ?`)) {
|
||||
if (window.confirm(`${i18next.t("tab:Are you sure to delete tab")} ${tab} ?`)) {
|
||||
if (topicsNum !== 0 || nodesNum !== 0) {
|
||||
alert(`
|
||||
${i18next.t("tab:Please delete all the nodes and posts under the tab before deleting the tab")}
|
||||
|
@ -266,8 +266,8 @@ class AdminTab extends React.Component {
|
|||
<div className="box">
|
||||
<div className="header">
|
||||
<Link to="/">{Setting.getForumName()}</Link> <span className="chevron"> › </span>
|
||||
<Link to={`/admin`}>{i18next.t("admin:Backstage management")}</Link> <span className="chevron"> › </span>
|
||||
<Link to={`/admin/tab`}>{i18next.t("tab:Tab management")}</Link> <span className="chevron"> › </span>
|
||||
<Link to={"/admin"}>{i18next.t("admin:Backstage management")}</Link> <span className="chevron"> › </span>
|
||||
<Link to={"/admin/tab"}>{i18next.t("tab:Tab management")}</Link> <span className="chevron"> › </span>
|
||||
<span>{this.props.event === "new" ? i18next.t("tab:New tab") : this.state.tabId}</span>
|
||||
</div>
|
||||
<div className="cell">
|
||||
|
@ -294,15 +294,15 @@ class AdminTab extends React.Component {
|
|||
<Link to={`/admin/tab/edit/${tab?.id}`}>{i18next.t("tab:Manage")}</Link>
|
||||
</td>
|
||||
<td width="10"></td>
|
||||
<td width={pcBrowser ? "120" : "80"} valign="middle" style={{ textAlign: "center" }}>
|
||||
<span style={{ fontSize: "13px" }}>
|
||||
<td width={pcBrowser ? "120" : "80"} valign="middle" style={{textAlign: "center"}}>
|
||||
<span style={{fontSize: "13px"}}>
|
||||
{tab?.topicsNum} {i18next.t("tab:topics")}
|
||||
</span>
|
||||
</td>
|
||||
<td width={pcBrowser ? "120" : "80"} align="left" style={{ textAlign: "center" }}>
|
||||
<td width={pcBrowser ? "120" : "80"} align="left" style={{textAlign: "center"}}>
|
||||
{tab?.nodesNum} {i18next.t("tab:nodes")}
|
||||
</td>
|
||||
<td width="50" align="left" style={{ textAlign: "right" }}>
|
||||
<td width="50" align="left" style={{textAlign: "right"}}>
|
||||
<a href="#" onClick={() => this.deleteTab(tab?.id, tab?.topicsNum, tab?.nodesNum)}>
|
||||
{i18next.t("tab:Delete")}
|
||||
</a>
|
||||
|
@ -339,12 +339,12 @@ class AdminTab extends React.Component {
|
|||
|
||||
if (this.state.tab === null) {
|
||||
return (
|
||||
<div class="box">
|
||||
<div class="header">
|
||||
<div className="box">
|
||||
<div className="header">
|
||||
<Link to="/">{Setting.getForumName()}</Link>
|
||||
<span className="chevron"> › </span> {i18next.t("error:Tab not found")}
|
||||
</div>
|
||||
<div class="cell">{i18next.t("error:The tab you are trying to view does not exist")}</div>
|
||||
<div className="cell">{i18next.t("error:The tab you are trying to view does not exist")}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -420,7 +420,7 @@ class AdminTab extends React.Component {
|
|||
</td>
|
||||
<td width="auto" align="left">
|
||||
<input type="range" min="1" max="1000" step="1" value={this.state.form?.sorter === undefined ? 1 : this.state.form?.sorter} onChange={(event) => this.updateFormField("sorter", parseInt(event.target.value))} />
|
||||
<input type="number" name="sorter" min="1" max="1000" step="1" value={this.state.form?.sorter} style={{ width: "50px" }} onChange={(event) => this.updateFormField("sorter", parseInt(event.target.value))} />
|
||||
<input type="number" name="sorter" min="1" max="1000" step="1" value={this.state.form?.sorter} style={{width: "50px"}} onChange={(event) => this.updateFormField("sorter", parseInt(event.target.value))} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import * as TopicBackend from "../backend/TopicBackend.js";
|
||||
import * as Setting from "../Setting";
|
||||
import PageColumn from "../main/PageColumn";
|
||||
import Collapse, { Panel } from "rc-collapse";
|
||||
import Collapse, {Panel} from "rc-collapse";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import Zmage from "react-zmage";
|
||||
import i18next from "i18next";
|
||||
|
@ -31,7 +31,7 @@ class AdminTopic extends React.Component {
|
|||
message: "",
|
||||
errorMessage: "",
|
||||
form: {},
|
||||
//event: props.match.params.event,
|
||||
// event: props.match.params.event,
|
||||
width: "",
|
||||
p: "",
|
||||
topicId: props.match.params.topicId,
|
||||
|
@ -45,7 +45,7 @@ class AdminTopic extends React.Component {
|
|||
topicsNum: 0,
|
||||
topics: null,
|
||||
topic: [],
|
||||
//un, ti, cn, cs, lrs, us, rcs, hs, fcs
|
||||
// un, ti, cn, cs, lrs, us, rcs, hs, fcs
|
||||
un: "", // username search
|
||||
ti: "", // title search
|
||||
cn: "", // content search
|
||||
|
@ -57,13 +57,13 @@ class AdminTopic extends React.Component {
|
|||
hs: 0, // hot sort, default: None
|
||||
fcs: 0, // favorite count sort, default: None
|
||||
Status_LIST: [
|
||||
{ label: "Normal", value: 1 },
|
||||
{ label: "Deleted", value: 2 },
|
||||
{ label: "Topping", value: 3 },
|
||||
{label: "Normal", value: 1},
|
||||
{label: "Deleted", value: 2},
|
||||
{label: "Topping", value: 3},
|
||||
],
|
||||
Management_LIST: [
|
||||
{ label: "Basic Info", value: "basic" },
|
||||
{ label: "Content", value: "content" },
|
||||
{label: "Basic Info", value: "basic"},
|
||||
{label: "Content", value: "content"},
|
||||
],
|
||||
};
|
||||
const params = new URLSearchParams(this.props.location.search);
|
||||
|
@ -74,7 +74,7 @@ class AdminTopic extends React.Component {
|
|||
this.state.page = parseInt(this.state.p);
|
||||
}
|
||||
|
||||
this.state.url = `/admin/topic`;
|
||||
this.state.url = "/admin/topic";
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -109,7 +109,7 @@ class AdminTopic extends React.Component {
|
|||
return;
|
||||
}
|
||||
|
||||
//un, ti, cn, sdt, cs, lrs, us, rcs, hs, fcs
|
||||
// un, ti, cn, sdt, cs, lrs, us, rcs, hs, fcs
|
||||
TopicBackend.getTopicsAdmin(this.state.un, this.state.ti, this.state.cn, this.state.sdt, this.state.cs, this.state.lrs, this.state.us, this.state.rcs, this.state.hs, this.state.fcs, this.state.limit, this.state.page).then((res) => {
|
||||
this.setState({
|
||||
topics: res?.data,
|
||||
|
@ -154,7 +154,7 @@ class AdminTopic extends React.Component {
|
|||
getSearchResult() {
|
||||
TopicBackend.getTopicsAdmin(this.state.un, this.state.ti, this.state.cn, this.state.sdt, this.state.cs, this.state.lrs, this.state.us, this.state.rcs, this.state.hs, this.state.fcs, this.state.limit, 1).then((res) => {
|
||||
if (res.status === "ok") {
|
||||
window.history.pushState({}, 0, `/admin/topic`);
|
||||
window.history.pushState({}, 0, "/admin/topic");
|
||||
this.setState({
|
||||
message: i18next.t("admin:Get search result success"),
|
||||
topics: res?.data,
|
||||
|
@ -169,7 +169,7 @@ class AdminTopic extends React.Component {
|
|||
});
|
||||
}
|
||||
|
||||
renderImage = ({ alt, src }) => {
|
||||
renderImage = ({alt, src}) => {
|
||||
return <Zmage src={src} alt={alt} />;
|
||||
};
|
||||
|
||||
|
@ -218,62 +218,62 @@ class AdminTopic extends React.Component {
|
|||
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" />
|
||||
<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" />
|
||||
<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" />
|
||||
<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" />
|
||||
<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" />
|
||||
<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" />
|
||||
<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" />
|
||||
<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>
|
||||
);
|
||||
|
@ -293,7 +293,7 @@ class AdminTopic extends React.Component {
|
|||
<span className="gray">{i18next.t("topic:Author")}</span>
|
||||
</td>
|
||||
<td width={pcBrowser ? "100" : "auto"} align="left">
|
||||
<input value={this.state.un} onChange={(event) => this.setState({ un: event.target.value })} />
|
||||
<input value={this.state.un} onChange={(event) => this.setState({un: event.target.value})} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -301,7 +301,7 @@ class AdminTopic extends React.Component {
|
|||
<span className="gray">{i18next.t("topic:Title")}</span>
|
||||
</td>
|
||||
<td width={pcBrowser ? "100" : "auto"} align="left">
|
||||
<input value={this.state.ti} onChange={(event) => this.setState({ ti: event.target.value })} />
|
||||
<input value={this.state.ti} onChange={(event) => this.setState({ti: event.target.value})} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -309,7 +309,7 @@ class AdminTopic extends React.Component {
|
|||
<span className="gray">{i18next.t("topic:Content")}</span>
|
||||
</td>
|
||||
<td width={pcBrowser ? "100" : "auto"} align="left">
|
||||
<input value={this.state.cn} onChange={(event) => this.setState({ cn: event.target.value })} />
|
||||
<input value={this.state.cn} onChange={(event) => this.setState({cn: event.target.value})} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -459,7 +459,7 @@ class AdminTopic extends React.Component {
|
|||
<Link to={`/admin/topic/edit/${topic?.id}`}>{i18next.t("admin:Manage")}</Link>
|
||||
</td>
|
||||
<td width="10"></td>
|
||||
<td width="60" align="left" style={{ textAlign: "right" }}>
|
||||
<td width="60" align="left" style={{textAlign: "right"}}>
|
||||
{this.renderTopicStatus(topic?.deleted, topic?.homePageTopTime, topic?.tabTopTime, topic?.nodeTopTime)}
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -491,7 +491,7 @@ class AdminTopic extends React.Component {
|
|||
|
||||
if (this.state.topic === null) {
|
||||
return (
|
||||
<div class="box">
|
||||
<div className="box">
|
||||
<div className="box">
|
||||
<div className="header">
|
||||
<Link to="/">{Setting.getForumName()}</Link> <span className="chevron"> › </span> {i18next.t("error:Topic does not exist")}
|
||||
|
@ -554,7 +554,7 @@ class AdminTopic extends React.Component {
|
|||
</Link>
|
||||
</span>
|
||||
{" "}
|
||||
<Link to={`/move/topic/${topic?.id}`} style={{ fontWeight: "bolder" }} target="_blank">
|
||||
<Link to={`/move/topic/${topic?.id}`} style={{fontWeight: "bolder"}} target="_blank">
|
||||
{i18next.t("topic:Move topic")}
|
||||
</Link>
|
||||
</td>
|
||||
|
@ -702,7 +702,7 @@ class AdminTopic extends React.Component {
|
|||
<div className="box">
|
||||
<div className="header">
|
||||
<Link to="/">{Setting.getForumName()}</Link> <span className="chevron"> › </span>
|
||||
<Link to={`/admin`}>{i18next.t("admin:Backstage management")}</Link>
|
||||
<Link to={"/admin"}>{i18next.t("admin:Backstage management")}</Link>
|
||||
<span className="chevron"> › </span> {i18next.t("topic:Topic management")}
|
||||
<div className="fr f12">
|
||||
<span className="snow">{i18next.t("topic:Total Topics")} </span>
|
||||
|
@ -725,7 +725,7 @@ class AdminTopic extends React.Component {
|
|||
backgroundColor: "#ffffff",
|
||||
}}
|
||||
>
|
||||
<Panel header={<span style={{ color: "#666" }}>{i18next.t("admin:Condition search")}</span>}>{this.renderSearchList()}</Panel>
|
||||
<Panel header={<span style={{color: "#666"}}>{i18next.t("admin:Condition search")}</span>}>{this.renderSearchList()}</Panel>
|
||||
</Collapse>
|
||||
</div>
|
||||
{this.showPageColumn()}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import * as TranslatorBackend from "../backend/TranslatorBackend";
|
||||
import * as Setting from "../Setting";
|
||||
import i18next from "i18next";
|
||||
|
@ -37,9 +37,9 @@ class AdminTranslation extends React.Component {
|
|||
},
|
||||
event: "config",
|
||||
Management_LIST: [
|
||||
{ label: "Config Translator", value: "config" },
|
||||
{ label: "Create", value: "create" },
|
||||
{ label: "Manage", value: "manage" },
|
||||
{label: "Config Translator", value: "config"},
|
||||
{label: "Create", value: "create"},
|
||||
{label: "Manage", value: "manage"},
|
||||
],
|
||||
color: "",
|
||||
backgroundColor: "",
|
||||
|
@ -75,7 +75,9 @@ class AdminTranslation extends React.Component {
|
|||
}
|
||||
|
||||
renderSelectPlatform() {
|
||||
if (this.state.translators === null) return;
|
||||
if (this.state.translators === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
return (
|
||||
<Select2
|
||||
|
@ -109,7 +111,9 @@ class AdminTranslation extends React.Component {
|
|||
}
|
||||
|
||||
renderSelectAPI() {
|
||||
if (this.state.apis === null) return;
|
||||
if (this.state.apis === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
return (
|
||||
<Select2
|
||||
|
@ -119,7 +123,7 @@ class AdminTranslation extends React.Component {
|
|||
fontSize: "14px",
|
||||
}}
|
||||
data={this.state.apis.map((apiItem) => {
|
||||
return { text: apiItem, id: apiItem };
|
||||
return {text: apiItem, id: apiItem};
|
||||
})}
|
||||
onSelect={(event) => {
|
||||
const selected = event.target.value;
|
||||
|
@ -161,7 +165,7 @@ class AdminTranslation extends React.Component {
|
|||
}
|
||||
|
||||
if (this.state.form.key === "") {
|
||||
this.setState({ errMessage: i18next.t("translator:Please input key") });
|
||||
this.setState({errMessage: i18next.t("translator:Please input key")});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -196,12 +200,12 @@ class AdminTranslation extends React.Component {
|
|||
});
|
||||
|
||||
if (this.state.form.id === "") {
|
||||
this.setState({ errMessage: i18next.t("translator:Please input id") });
|
||||
this.setState({errMessage: i18next.t("translator:Please input id")});
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.state.form.name === "") {
|
||||
this.setState({ errMessage: i18next.t("translator:Please input name") });
|
||||
this.setState({errMessage: i18next.t("translator:Please input name")});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -213,7 +217,7 @@ class AdminTranslation extends React.Component {
|
|||
}
|
||||
|
||||
if (this.state.form.key === "") {
|
||||
this.setState({ errMessage: i18next.t("translator:Please input key") });
|
||||
this.setState({errMessage: i18next.t("translator:Please input key")});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -231,7 +235,7 @@ class AdminTranslation extends React.Component {
|
|||
}
|
||||
|
||||
deleteTranslator(translator) {
|
||||
if (window.confirm(`${i18next.t(`translator:Are you sure to delete translator`)} ${translator.name} ?`)) {
|
||||
if (window.confirm(`${i18next.t("translator:Are you sure to delete translator")} ${translator.name} ?`)) {
|
||||
if (translator.enable) {
|
||||
alert(i18next.t("translator:Please disable it first"));
|
||||
return;
|
||||
|
@ -422,7 +426,7 @@ class AdminTranslation extends React.Component {
|
|||
});
|
||||
}}
|
||||
value={this.state.form?.key}
|
||||
style={{ width: 300 }}
|
||||
style={{width: 300}}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -495,7 +499,7 @@ class AdminTranslation extends React.Component {
|
|||
});
|
||||
}}
|
||||
value={this.state.form.id}
|
||||
style={{ width: 300 }}
|
||||
style={{width: 300}}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -513,7 +517,7 @@ class AdminTranslation extends React.Component {
|
|||
});
|
||||
}}
|
||||
value={this.state.form.name}
|
||||
style={{ width: 300 }}
|
||||
style={{width: 300}}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -539,7 +543,7 @@ class AdminTranslation extends React.Component {
|
|||
});
|
||||
}}
|
||||
value={this.state.form.key}
|
||||
style={{ width: 300 }}
|
||||
style={{width: 300}}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -83,7 +83,7 @@ i18n.init({
|
|||
interpolation: {
|
||||
escapeValue: false,
|
||||
},
|
||||
//debug: true,
|
||||
// debug: true,
|
||||
saveMissing: true,
|
||||
});
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@ import "./i18n";
|
|||
import "./index.css";
|
||||
import App from "./App";
|
||||
import * as serviceWorker from "./serviceWorker";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import { loadTheme } from "./theme";
|
||||
import {BrowserRouter} from "react-router-dom";
|
||||
import {loadTheme} from "./theme";
|
||||
|
||||
let theme = localStorage.getItem("CASNODE_THEME");
|
||||
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import * as Setting from "../Setting";
|
||||
import i18next from "i18next";
|
||||
import * as BasicBackend from "../backend/BasicBackend";
|
||||
import * as Conf from "../Conf";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
class AboutForum extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -93,7 +93,7 @@ class AboutForum extends React.Component {
|
|||
{":"}
|
||||
</td>
|
||||
<td width="auto" align="left">
|
||||
<a href={`https://casnode.org/`} target="_blank" rel="noopener noreferrer">
|
||||
<a href={"https://casnode.org/"} target="_blank" rel="noopener noreferrer">
|
||||
Casnode official website
|
||||
</a>
|
||||
</td>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
import React from "react";
|
||||
import * as Setting from "../Setting";
|
||||
import * as TopicBackend from "../backend/TopicBackend";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import LatestReplyBox from "./LatestReplyBox";
|
||||
import PageColumn from "./PageColumn";
|
||||
import TopicList from "./TopicList";
|
||||
|
@ -41,12 +41,12 @@ class AllCreatedTopicsBox extends React.Component {
|
|||
member: [],
|
||||
url: "",
|
||||
TAB_LIST: [
|
||||
{ label: "Q&A", value: "qna" },
|
||||
{ label: "Tech", value: "tech" },
|
||||
{ label: "Play", value: "play" },
|
||||
{ label: "Jobs", value: "jobs" },
|
||||
{ label: "Deals", value: "deals" },
|
||||
{ label: "City", value: "city" },
|
||||
{label: "Q&A", value: "qna"},
|
||||
{label: "Tech", value: "tech"},
|
||||
{label: "Play", value: "play"},
|
||||
{label: "Jobs", value: "jobs"},
|
||||
{label: "Deals", value: "deals"},
|
||||
{label: "City", value: "city"},
|
||||
],
|
||||
};
|
||||
const params = new URLSearchParams(this.props.location.search);
|
||||
|
@ -189,7 +189,9 @@ class AllCreatedTopicsBox extends React.Component {
|
|||
this.props.history.push(`/member/${this.state.memberId}`);
|
||||
}
|
||||
|
||||
if (this.state.member.name) document.title = `${this.state.member.name}${i18next.t("member:'s more replies")} - ${Setting.getForumName()}`;
|
||||
if (this.state.member.name) {
|
||||
document.title = `${this.state.member.name}${i18next.t("member:'s more replies")} - ${Setting.getForumName()}`;
|
||||
}
|
||||
return <LatestReplyBox size={"large"} />;
|
||||
}
|
||||
|
||||
|
@ -198,7 +200,9 @@ class AllCreatedTopicsBox extends React.Component {
|
|||
this.props.history.push(`/member/${this.state.memberId}`);
|
||||
}
|
||||
|
||||
if (this.state.member.name) document.title = `${this.state.member.name}${i18next.t("member:'s more topics")} - ${Setting.getForumName()}`;
|
||||
if (this.state.member.name) {
|
||||
document.title = `${this.state.member.name}${i18next.t("member:'s more topics")} - ${Setting.getForumName()}`;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="box">
|
||||
|
@ -232,7 +236,7 @@ class AllCreatedTopicsBox extends React.Component {
|
|||
src={memberAvatar !== "" ? memberAvatar : Setting.getUserAvatar(this.state.memberId)}
|
||||
width={24}
|
||||
border={0}
|
||||
style={{ borderRadius: "24px", marginTop: "-2px" }}
|
||||
style={{borderRadius: "24px", marginTop: "-2px"}}
|
||||
alt={this.state.memberId}
|
||||
onError={(event) => {
|
||||
event.target.onerror = "";
|
||||
|
@ -255,7 +259,7 @@ class AllCreatedTopicsBox extends React.Component {
|
|||
</Link>
|
||||
)
|
||||
) : null}
|
||||
{!pcBrowser ? <div className="sep10" style={{ clear: "both" }} /> : null}
|
||||
{!pcBrowser ? <div className="sep10" style={{clear: "both"}} /> : null}
|
||||
{pcBrowser
|
||||
? this.state.TAB_LIST.map((tab) => {
|
||||
return this.renderTab(tab);
|
||||
|
|
|
@ -16,10 +16,10 @@ import React from "react";
|
|||
import * as Setting from "../Setting";
|
||||
import * as BalanceBackend from "../backend/BalanceBackend";
|
||||
import PageColumn from "./PageColumn";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import i18next from "i18next";
|
||||
import { scoreConverter } from "./Tools";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {scoreConverter} from "./Tools";
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
const pangu = require("pangu");
|
||||
|
||||
|
@ -47,7 +47,7 @@ class BalanceBox extends React.Component {
|
|||
this.state.page = parseInt(this.state.p);
|
||||
}
|
||||
|
||||
this.state.url = `/balance`;
|
||||
this.state.url = "/balance";
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -96,15 +96,15 @@ class BalanceBox extends React.Component {
|
|||
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
|
||||
</td>
|
||||
<td className="d">{i18next.t("balance:Checkin bonus")}</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
<span className="positive">
|
||||
<strong>{record?.amount + ".0"}</strong>
|
||||
</span>
|
||||
</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
{record?.balance + ".0"}
|
||||
</td>
|
||||
<td className="d" style={{ borderRight: "none" }}>
|
||||
<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>
|
||||
|
@ -118,15 +118,15 @@ class BalanceBox extends React.Component {
|
|||
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
|
||||
</td>
|
||||
<td className="d">{i18next.t("balance:Received thanks")}</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
<span className="positive">
|
||||
<strong>{record?.amount + ".0"}</strong>
|
||||
</span>
|
||||
</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
{record?.balance + ".0"}
|
||||
</td>
|
||||
<td className="d" style={{ borderRight: "none" }}>
|
||||
<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>
|
||||
|
@ -140,15 +140,15 @@ class BalanceBox extends React.Component {
|
|||
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
|
||||
</td>
|
||||
<td className="d">{i18next.t("balance:Received thanks")}</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
<span className="positive">
|
||||
<strong>{record?.amount + ".0"}</strong>
|
||||
</span>
|
||||
</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
{record?.balance + ".0"}
|
||||
</td>
|
||||
<td className="d" style={{ borderRight: "none" }}>
|
||||
<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>
|
||||
|
@ -162,15 +162,15 @@ class BalanceBox extends React.Component {
|
|||
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
|
||||
</td>
|
||||
<td className="d">{i18next.t("balance:Send thanks")}</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
<span className="negative">
|
||||
<strong>{record?.amount + ".0"}</strong>
|
||||
</span>
|
||||
</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
{record?.balance + ".0"}
|
||||
</td>
|
||||
<td className="d" style={{ borderRight: "none" }}>
|
||||
<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>
|
||||
|
@ -184,15 +184,15 @@ class BalanceBox extends React.Component {
|
|||
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
|
||||
</td>
|
||||
<td className="d">{i18next.t("balance:Send thanks")}</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
<span className="negative">
|
||||
<strong>{record?.amount + ".0"}</strong>
|
||||
</span>
|
||||
</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
{record?.balance + ".0"}
|
||||
</td>
|
||||
<td className="d" style={{ borderRight: "none" }}>
|
||||
<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>
|
||||
|
@ -206,15 +206,15 @@ class BalanceBox extends React.Component {
|
|||
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
|
||||
</td>
|
||||
<td className="d">{i18next.t("balance:Create reply")}</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
<span className="negative">
|
||||
<strong>{record?.amount + ".0"}</strong>
|
||||
</span>
|
||||
</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
{record?.balance + ".0"}
|
||||
</td>
|
||||
<td className="d" style={{ borderRight: "none" }}>
|
||||
<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>
|
||||
|
@ -228,15 +228,15 @@ class BalanceBox extends React.Component {
|
|||
<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" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
<span className="positive">
|
||||
<strong>{record?.amount + ".0"}</strong>
|
||||
</span>
|
||||
</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
{record?.balance + ".0"}
|
||||
</td>
|
||||
<td className="d" style={{ borderRight: "none" }}>
|
||||
<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>
|
||||
|
@ -250,15 +250,15 @@ class BalanceBox extends React.Component {
|
|||
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
|
||||
</td>
|
||||
<td className="d">{i18next.t("balance:Create topic")}</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
<span className="negative">
|
||||
<strong>{record?.amount + ".0"}</strong>
|
||||
</span>
|
||||
</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
{record?.balance + ".0"}
|
||||
</td>
|
||||
<td className="d" style={{ borderRight: "none" }}>
|
||||
<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>
|
||||
|
@ -272,15 +272,15 @@ class BalanceBox extends React.Component {
|
|||
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
|
||||
</td>
|
||||
<td className="d">{i18next.t("balance:Top topic")}</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
<span className="negative">
|
||||
<strong>{record?.amount + ".0"}</strong>
|
||||
</span>
|
||||
</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
{record?.balance + ".0"}
|
||||
</td>
|
||||
<td className="d" style={{ borderRight: "none" }}>
|
||||
<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>
|
||||
|
@ -294,15 +294,15 @@ class BalanceBox extends React.Component {
|
|||
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
|
||||
</td>
|
||||
<td className="d">{i18next.t("balance:Admin revision")}</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
<span className="positive">
|
||||
<strong>{record?.amount + ".0"}</strong>
|
||||
</span>
|
||||
</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
{record?.balance + ".0"}
|
||||
</td>
|
||||
<td className="d" style={{ borderRight: "none" }}>
|
||||
<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>
|
||||
|
@ -316,15 +316,15 @@ class BalanceBox extends React.Component {
|
|||
<small className="gray">{Setting.getFormattedDate(record?.createdTime)}</small>
|
||||
</td>
|
||||
<td className="d">{i18next.t("balance:Admin revision")}</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
<span className="negative">
|
||||
<strong>{record?.amount + ".0"}</strong>
|
||||
</span>
|
||||
</td>
|
||||
<td className="d" style={{ textAlign: "right" }}>
|
||||
<td className="d" style={{textAlign: "right"}}>
|
||||
{record?.balance + ".0"}
|
||||
</td>
|
||||
<td className="d" style={{ borderRight: "none" }}>
|
||||
<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>
|
||||
|
@ -337,7 +337,7 @@ class BalanceBox extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { goldCount, silverCount, bronzeCount } = scoreConverter(this.props.account?.score);
|
||||
const {goldCount, silverCount, bronzeCount} = scoreConverter(this.props.account?.score);
|
||||
|
||||
return (
|
||||
<div className="box">
|
||||
|
@ -345,7 +345,7 @@ class BalanceBox extends React.Component {
|
|||
<title>{`${i18next.t("balance:Account balance")} - ${Setting.getForumName()}`}</title>
|
||||
</Helmet>
|
||||
<div className="cell">
|
||||
<div className="fr" style={{ margin: "-3px -8px 0px 0px" }}>
|
||||
<div className="fr" style={{margin: "-3px -8px 0px 0px"}}>
|
||||
<Link to="/top/rich" className="tab">
|
||||
{i18next.t("balance:Wealth ranking")}
|
||||
</Link>
|
||||
|
@ -366,7 +366,7 @@ class BalanceBox extends React.Component {
|
|||
<span className="gray">{i18next.t("balance:Current account balance")}</span>
|
||||
<div className="sep10"></div>
|
||||
<div className="sep5"></div>
|
||||
<div className="balance_area bigger" style={{ fontSize: "24px", lineHeight: "24px" }}>
|
||||
<div className="balance_area bigger" style={{fontSize: "24px", lineHeight: "24px"}}>
|
||||
{goldCount !== 0 ? (
|
||||
<span>
|
||||
{" "}
|
||||
|
@ -400,7 +400,7 @@ class BalanceBox extends React.Component {
|
|||
<td width="60" className="h">
|
||||
{i18next.t("balance:Balance")}
|
||||
</td>
|
||||
<td width="auto" className="h" style={{ borderRight: "none" }}>
|
||||
<td width="auto" className="h" style={{borderRight: "none"}}>
|
||||
{i18next.t("balance:Description")}
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
import React from "react";
|
||||
import * as Setting from "../Setting";
|
||||
import * as BalanceBackend from "../backend/BalanceBackend";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import i18next from "i18next";
|
||||
|
||||
class CheckinBonusBox extends React.Component {
|
||||
|
@ -76,7 +76,7 @@ class CheckinBonusBox extends React.Component {
|
|||
) : null}
|
||||
<div className="cell">
|
||||
<span className="gray">
|
||||
<li className="fa fa-ok-sign" style={{ color: "#0c0" }}></li>
|
||||
<li className="fa fa-ok-sign" style={{color: "#0c0"}}></li>
|
||||
{i18next.t("mission:Daily checkin bonus has been received")}
|
||||
</span>
|
||||
<div className="sep10"></div>
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
|
||||
import React from "react";
|
||||
import * as Setting from "../Setting";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import * as TopicBackend from "../backend/TopicBackend";
|
||||
import * as ReplyBackend from "../backend/ReplyBackend";
|
||||
import { Controlled as CodeMirror } from "react-codemirror2";
|
||||
import {Controlled as CodeMirror} from "react-codemirror2";
|
||||
import TagsInput from "react-tagsinput";
|
||||
import "../tagsInput.css";
|
||||
import * as Tools from "./Tools";
|
||||
|
@ -147,9 +147,9 @@ class EditBox extends React.Component {
|
|||
{" "}
|
||||
<Select2
|
||||
value={this.state.form.editorType}
|
||||
style={{ width: "110px", fontSize: "14px" }}
|
||||
style={{width: "110px", fontSize: "14px"}}
|
||||
data={this.state.editor.map((node, i) => {
|
||||
return { text: `${node.text}`, id: i };
|
||||
return {text: `${node.text}`, id: i};
|
||||
})}
|
||||
onSelect={(event) => {
|
||||
const s = event.target.value;
|
||||
|
@ -169,7 +169,7 @@ class EditBox extends React.Component {
|
|||
});
|
||||
}
|
||||
}}
|
||||
options={{ placeholder: this.state.placeholder }}
|
||||
options={{placeholder: this.state.placeholder}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -190,7 +190,7 @@ class EditBox extends React.Component {
|
|||
className="mle tall"
|
||||
id="reply_content"
|
||||
>
|
||||
<div className={`cm-long-content`}>
|
||||
<div className={"cm-long-content"}>
|
||||
<CodeMirror
|
||||
editorDidMount={(editor) => Tools.attachEditor(editor)}
|
||||
onPaste={() => Tools.uploadMdFile()}
|
||||
|
@ -279,7 +279,7 @@ class EditBox extends React.Component {
|
|||
<td>{this.renderEditor()}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style={{ display: "flex", justifyContent: "space-between" }}>
|
||||
<td style={{display: "flex", justifyContent: "space-between"}}>
|
||||
<div>
|
||||
<input type="submit" value={i18next.t("edit:Save")} className="super normal button" onClick={() => this.editContent()} />
|
||||
</div>
|
||||
|
@ -332,7 +332,7 @@ class EditBox extends React.Component {
|
|||
value={this.state.tags}
|
||||
onChange={this.handleChange.bind(this)}
|
||||
/>
|
||||
<td style={{ display: "flex", justifyContent: "space-between" }}>
|
||||
<td style={{display: "flex", justifyContent: "space-between"}}>
|
||||
<div>
|
||||
<input type="submit" value={i18next.t("edit:Save")} className="super normal button" onClick={() => this.editContent()} />
|
||||
</div>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
import React from "react";
|
||||
import * as Setting from "../Setting";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import * as FavoritesBackend from "../backend/FavoritesBackend";
|
||||
import TopicList from "./TopicList";
|
||||
import PageColumn from "./PageColumn";
|
||||
|
|
|
@ -17,7 +17,7 @@ import * as FileBackend from "../backend/FileBackend";
|
|||
import * as Setting from "../Setting";
|
||||
import * as Tools from "./Tools";
|
||||
import PageColumn from "./PageColumn";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import "../deopzone.css";
|
||||
import Dropzone from "react-dropzone";
|
||||
import i18next from "i18next";
|
||||
|
@ -55,7 +55,7 @@ class FilesBox extends React.Component {
|
|||
this.state.page = parseInt(this.state.p);
|
||||
}
|
||||
|
||||
this.state.url = `/i`;
|
||||
this.state.url = "/i";
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -163,7 +163,7 @@ class FilesBox extends React.Component {
|
|||
}
|
||||
|
||||
uploadFile(file) {
|
||||
let fileInfo = { name: file[0].path, size: file[0].size, status: false };
|
||||
let fileInfo = {name: file[0].path, size: file[0].size, status: false};
|
||||
let files = this.state.files;
|
||||
files.push(fileInfo);
|
||||
this.setState({
|
||||
|
@ -254,7 +254,7 @@ class FilesBox extends React.Component {
|
|||
<td width="auto" valign="middle">
|
||||
<span className="item_hot_topic_title">{Setting.getFormattedSize(file.size)}</span>
|
||||
</td>
|
||||
<td width="auto" align="left" style={{ textAlign: "center" }}>
|
||||
<td width="auto" align="left" style={{textAlign: "center"}}>
|
||||
{file.status ? (
|
||||
<a href="javascript:void(0);" onClick={() => this.deleteFile(file)} className="delete">
|
||||
{i18next.t("file:Delete")}
|
||||
|
@ -286,9 +286,9 @@ class FilesBox extends React.Component {
|
|||
<div className="sep10"></div>
|
||||
<div id="uploader">
|
||||
<Dropzone onDrop={(acceptedFiles) => this.uploadFile(acceptedFiles)}>
|
||||
{({ getRootProps, getInputProps }) => (
|
||||
{({getRootProps, getInputProps}) => (
|
||||
<section className="container">
|
||||
<div {...getRootProps({ className: "dropzone" })}>
|
||||
<div {...getRootProps({className: "dropzone"})}>
|
||||
<input {...getInputProps()} />
|
||||
<p>{i18next.t("file:Drop files here, or click upload")}</p>
|
||||
</div>
|
||||
|
@ -304,7 +304,7 @@ class FilesBox extends React.Component {
|
|||
{this.state.files?.map((file) => this.renderUploadFile(file))}
|
||||
</div>
|
||||
<div className="cell">
|
||||
<div className="fr" style={{ paddingTop: "2px" }}>
|
||||
<div className="fr" style={{paddingTop: "2px"}}>
|
||||
<div
|
||||
style={{
|
||||
width: "400px",
|
||||
|
@ -365,13 +365,13 @@ class FilesBox extends React.Component {
|
|||
<div className="header">
|
||||
<Link to="/">{Setting.getForumName()}</Link> <span className="chevron"> › </span> <Link to="/i?p=1">Files</Link> <span className="chevron"> › </span> {file?.fileName}
|
||||
</div>
|
||||
<div className="cell" style={{ textAlign: "center", padding: "12px" }}>
|
||||
<div className="cell" style={{textAlign: "center", padding: "12px"}}>
|
||||
{file?.fileType === "image" ? (
|
||||
<a href={file?.fileUrl} className="img_view" target="_blank">
|
||||
<a href={file?.fileUrl} className="img_view" target="_blank" rel="noreferrer">
|
||||
<img src={file?.fileUrl} border="0" className="embedded_image" />
|
||||
</a>
|
||||
) : (
|
||||
<a href={file?.fileUrl} className="img_view" target="_blank">
|
||||
<a href={file?.fileUrl} className="img_view" target="_blank" rel="noreferrer">
|
||||
<div>{i18next.t("file:There is no preview for this type of file, click to download/view")}</div>
|
||||
</a>
|
||||
)}
|
||||
|
@ -426,7 +426,7 @@ class FilesBox extends React.Component {
|
|||
</Link>
|
||||
) : (
|
||||
<Link to={`/i/${file?.id}`} target="_blank">
|
||||
<div style={{ lineHeight: "100px" }}>{i18next.t("file:No preview for this type of file")}</div>
|
||||
<div style={{lineHeight: "100px"}}>{i18next.t("file:No preview for this type of file")}</div>
|
||||
</Link>
|
||||
)}
|
||||
<div className="inner">
|
||||
|
@ -449,11 +449,11 @@ class FilesBox extends React.Component {
|
|||
<td>
|
||||
{i18next.t("file:File title")}
|
||||
<div className="sep5"></div>
|
||||
<input type="text" className="sl" name="title" maxLength="64" style={{ width: "100%" }} value={this.state.form.fileName} onChange={(event) => this.updateFormField("fileName", event.target.value)} />
|
||||
<input type="text" className="sl" name="title" maxLength="64" style={{width: "100%"}} value={this.state.form.fileName} onChange={(event) => this.updateFormField("fileName", event.target.value)} />
|
||||
<div className="sep10"></div>
|
||||
{i18next.t("file:Description")}
|
||||
<div className="sep5"></div>
|
||||
<textarea className="ml" style={{ width: "100%" }} name="description" maxLength="1000" onChange={(event) => this.updateFormField("desc", event.target.value)} value={this.state.form.desc} />
|
||||
<textarea className="ml" style={{width: "100%"}} name="description" maxLength="1000" onChange={(event) => this.updateFormField("desc", event.target.value)} value={this.state.form.desc} />
|
||||
<div className="sep10"></div>
|
||||
<input type="submit" value={i18next.t("file:submit")} className="super normal button" onClick={() => this.editDesc()} />
|
||||
</td>
|
||||
|
@ -488,10 +488,10 @@ class FilesBox extends React.Component {
|
|||
<Link to={`/i/${file.id}`}>{file?.fileName}</Link>
|
||||
</td>
|
||||
<td width="10"></td>
|
||||
<td width={pcBrowser ? "auto" : "80"} valign="middle" style={{ textAlign: "center" }}>
|
||||
<span style={{ fontSize: "13px" }}>{Setting.getFormattedSize(file?.size)}</span>
|
||||
<td width={pcBrowser ? "auto" : "80"} valign="middle" style={{textAlign: "center"}}>
|
||||
<span style={{fontSize: "13px"}}>{Setting.getFormattedSize(file?.size)}</span>
|
||||
</td>
|
||||
<td width="100" align="left" style={{ textAlign: "center" }}>
|
||||
<td width="100" align="left" style={{textAlign: "center"}}>
|
||||
{Setting.getPrettyDate(file?.createdTime)}
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -580,7 +580,7 @@ class FilesBox extends React.Component {
|
|||
// url: /i?p=x
|
||||
return (
|
||||
<div className="box">
|
||||
<div className="cell" style={{ padding: "0px" }}>
|
||||
<div className="cell" style={{padding: "0px"}}>
|
||||
<table cellPadding="10" cellSpacing="0" border="0" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
|
@ -604,7 +604,7 @@ class FilesBox extends React.Component {
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div className="cell" style={{ padding: "0px", textAlign: "center" }}>
|
||||
<div className="cell" style={{padding: "0px", textAlign: "center"}}>
|
||||
{Setting.PcBrowser ? this.showPageColumn() : null}
|
||||
{this.state.files !== null && this.state.files.length !== 0 ? this.state.files.map((file) => this.renderFiles(file)) : null}
|
||||
{this.showPageColumn()}
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import * as Setting from "../Setting";
|
||||
import * as ConfBackend from "../backend/ConfBackend";
|
||||
import "./NoMatch.css";
|
||||
import i18next from "i18next";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {Helmet} from "react-helmet";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
|
||||
class NoMatch extends React.Component {
|
||||
|
@ -74,13 +74,8 @@ class NoMatch extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="main">
|
||||
{this.renderBox()}
|
||||
</div>
|
||||
)
|
||||
return <div className="main">{this.renderBox()}</div>;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default withRouter(NoMatch);
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
import React from "react";
|
||||
import * as Setting from "../Setting";
|
||||
import { Link } from "react-router-dom";
|
||||
import {Link} from "react-router-dom";
|
||||
import i18next from "i18next";
|
||||
|
||||
class Header extends React.Component {
|
||||
|
@ -32,7 +32,7 @@ class Header extends React.Component {
|
|||
{this.props.item !== "Sign In" ? (
|
||||
this.props.item
|
||||
) : (
|
||||
<div style={{ display: "inline" }}>
|
||||
<div style={{display: "inline"}}>
|
||||
{i18next.t("general:Sign In")}
|
||||
<li className="fa fa-lock" />
|
||||
</div>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
import React from "react";
|
||||
import * as Setting from "../Setting";
|
||||
import * as ReplyBackend from "../backend/ReplyBackend";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import PageColumn from "./PageColumn";
|
||||
import i18next from "i18next";
|
||||
|
||||
|
|
|
@ -16,14 +16,14 @@ import React from "react";
|
|||
import * as Setting from "../Setting";
|
||||
import * as MemberBackend from "../backend/MemberBackend";
|
||||
import * as FavoritesBackend from "../backend/FavoritesBackend";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import Avatar from "../Avatar";
|
||||
import AllCreatedTopicsBox from "./AllCreatedTopicsBox";
|
||||
import LatestReplyBox from "./LatestReplyBox";
|
||||
import i18next from "i18next";
|
||||
import { scoreConverter } from "./Tools";
|
||||
import {scoreConverter} from "./Tools";
|
||||
import * as Conf from "../Conf";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
class MemberBox extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -157,7 +157,7 @@ class MemberBox extends React.Component {
|
|||
}
|
||||
|
||||
const showWatch = this.props.account !== undefined && this.props.account !== null && this.state.memberId !== this.props.account?.name;
|
||||
const { goldCount, silverCount, bronzeCount } = scoreConverter(this.state.member.score);
|
||||
const {goldCount, silverCount, bronzeCount} = scoreConverter(this.state.member.score);
|
||||
return (
|
||||
<div className="box">
|
||||
<div className="cell">
|
||||
|
@ -171,7 +171,7 @@ class MemberBox extends React.Component {
|
|||
</td>
|
||||
<td width="10" />
|
||||
<td width="auto" valign="top" align="left">
|
||||
<div className="fr" style={{ display: showWatch ? "" : "none" }}>
|
||||
<div className="fr" style={{display: showWatch ? "" : "none"}}>
|
||||
{this.state.favoritesStatus ? (
|
||||
<input type="button" value={i18next.t("member:Cancel Following")} onClick={() => this.deleteFavorite(this.state.member?.name)} className="super inverse button" />
|
||||
) : (
|
||||
|
@ -180,7 +180,7 @@ class MemberBox extends React.Component {
|
|||
<div className="sep10" />
|
||||
<input type="button" value="Block" onClick={this.block(this.state.memberId)} className="super normal button" />
|
||||
</div>
|
||||
<h1 style={{ marginBottom: "5px" }}>{this.state.member?.name}</h1>
|
||||
<h1 style={{marginBottom: "5px"}}>{this.state.member?.name}</h1>
|
||||
<span className="bigger">{this.state.member?.tagline}</span>
|
||||
<div className="sep10" />
|
||||
{this.state.member?.affiliation?.length !== 0 || this.state.member?.title?.length !== 0 ? (
|
||||
|
@ -191,13 +191,13 @@ class MemberBox extends React.Component {
|
|||
<div className={Setting.PcBrowser ? "sep10" : "sep5"} />
|
||||
<span className="gray">
|
||||
{Setting.getForumName()} {i18next.t("member:No.")} {this.state.member?.ranking} {i18next.t("member:member, joined on")} {Setting.getFormattedDate(this.state.member?.createdTime)}
|
||||
{/*{Setting.PcBrowser ? (*/}
|
||||
{/* {Setting.PcBrowser ? (*/}
|
||||
{/* <span>*/}
|
||||
{/* <div className="sep5" />*/}
|
||||
{/* {i18next.t("member:Today's ranking")}{" "}*/}
|
||||
{/* <Link to="/top/dau">{this.state.member?.ranking}</Link>*/}
|
||||
{/* </span>*/}
|
||||
{/*) : null}*/}
|
||||
{/* ) : null}*/}
|
||||
<div className="sep5" />
|
||||
{this.state.member?.isModerator ? <img src={Setting.getStatic("/img/mod@2x.png")} height="14px" align="absmiddle" /> : null} {this.state.member?.isModerator ? i18next.t("member:authorized to manage the community") : null}
|
||||
</span>
|
||||
|
@ -260,7 +260,7 @@ class MemberBox extends React.Component {
|
|||
return null;
|
||||
}
|
||||
|
||||
const provider = { type: providerType };
|
||||
const provider = {type: providerType};
|
||||
|
||||
const linkedValue = user[provider.type.toLowerCase()];
|
||||
const id = this.getUserProperty(user, provider.type, "id");
|
||||
|
@ -290,8 +290,8 @@ class MemberBox extends React.Component {
|
|||
}
|
||||
|
||||
return (
|
||||
<a href={profileUrl} style={profileUrl !== "" ? null : { pointerEvents: "none" }} className="social_label" target="_blank" rel="nofollow noopener noreferrer">
|
||||
<img src={avatarUrl} width="24" style={{ borderRadius: "24px" }} alt={providerType} align="absmiddle" /> {name}
|
||||
<a href={profileUrl} style={profileUrl !== "" ? null : {pointerEvents: "none"}} className="social_label" target="_blank" rel="nofollow noopener noreferrer">
|
||||
<img src={avatarUrl} width="24" style={{borderRadius: "24px"}} alt={providerType} align="absmiddle" /> {name}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
@ -306,21 +306,21 @@ class MemberBox extends React.Component {
|
|||
<tbody>
|
||||
<tr>
|
||||
<td width="33%" valign="center" align="center">
|
||||
<Link to="/my/nodes" className="dark" style={{ display: "block" }}>
|
||||
<Link to="/my/nodes" className="dark" style={{display: "block"}}>
|
||||
<span className="bigger">{this.state.nodeFavoriteNum}</span>
|
||||
<div className="sep3" />
|
||||
<span className="fade small">{i18next.t("bar:Nodes")}</span>
|
||||
</Link>
|
||||
</td>
|
||||
<td width="33%" valign="center" align="center" style={{ borderLeft: "1px solid rgba(100, 100, 100, 0.25)" }}>
|
||||
<Link to="/my/topics" className="dark" style={{ display: "block" }}>
|
||||
<td width="33%" valign="center" align="center" style={{borderLeft: "1px solid rgba(100, 100, 100, 0.25)"}}>
|
||||
<Link to="/my/topics" className="dark" style={{display: "block"}}>
|
||||
<span className="bigger">{this.state.topicFavoriteNum}</span>
|
||||
<div className="sep3" />
|
||||
<span className="fade small">{i18next.t("bar:Topics")}</span>
|
||||
</Link>
|
||||
</td>
|
||||
<td width="33%" valign="center" align="center" style={{ borderLeft: "1px solid rgba(100, 100, 100, 0.25)" }}>
|
||||
<Link to="/my/following" className="dark" style={{ display: "block" }}>
|
||||
<td width="33%" valign="center" align="center" style={{borderLeft: "1px solid rgba(100, 100, 100, 0.25)"}}>
|
||||
<Link to="/my/following" className="dark" style={{display: "block"}}>
|
||||
<span className="bigger">{this.state.followingNum}</span>
|
||||
<div className="sep3" />
|
||||
<span className="fade small">{i18next.t("bar:Watch")}</span>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
import React from "react";
|
||||
import * as Setting from "../Setting";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import * as NodeBackend from "../backend/NodeBackend";
|
||||
import * as TopicBackend from "../backend/TopicBackend";
|
||||
import Select2 from "react-select2-wrapper";
|
||||
|
@ -178,7 +178,7 @@ class MoveTopicNodeBox extends React.Component {
|
|||
fontSize: "14px",
|
||||
}}
|
||||
data={this.state.nodes.map((node, i) => {
|
||||
return { text: `${node.name} / ${node.id}`, id: i };
|
||||
return {text: `${node.name} / ${node.id}`, id: i};
|
||||
})}
|
||||
onSelect={(event) => {
|
||||
const s = event.target.value;
|
||||
|
|
|
@ -21,15 +21,15 @@ import * as Setting from "../Setting";
|
|||
import * as Tools from "./Tools";
|
||||
import NewNodeTopicBox from "./NewNodeTopicBox";
|
||||
import "../codemirrorSize.css";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import {withRouter} from "react-router-dom";
|
||||
import i18next from "i18next";
|
||||
import Select2 from "react-select2-wrapper";
|
||||
import { Controlled as CodeMirror } from "react-codemirror2";
|
||||
import {Controlled as CodeMirror} from "react-codemirror2";
|
||||
import Editor from "./richTextEditor";
|
||||
import * as Conf from "../Conf";
|
||||
import TagsInput from "react-tagsinput";
|
||||
import "../tagsInput.css";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
require("codemirror/mode/markdown/markdown");
|
||||
|
||||
|
@ -189,9 +189,9 @@ class NewBox extends React.Component {
|
|||
{" "}
|
||||
<Select2
|
||||
value={this.state.form.editorType}
|
||||
style={{ width: "110px", fontSize: "14px" }}
|
||||
style={{width: "110px", fontSize: "14px"}}
|
||||
data={this.state.editor.map((node, i) => {
|
||||
return { text: `${node.text}`, id: i };
|
||||
return {text: `${node.text}`, id: i};
|
||||
})}
|
||||
onSelect={(event) => {
|
||||
const s = event.target.value;
|
||||
|
@ -211,7 +211,7 @@ class NewBox extends React.Component {
|
|||
});
|
||||
}
|
||||
}}
|
||||
options={{ placeholder: this.state.placeholder }}
|
||||
options={{placeholder: this.state.placeholder}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -263,7 +263,7 @@ class NewBox extends React.Component {
|
|||
</div>
|
||||
{i18next.t("new:Topic Title")}
|
||||
</div>
|
||||
<div className="cell" style={{ padding: "0px" }}>
|
||||
<div className="cell" style={{padding: "0px"}}>
|
||||
<textarea
|
||||
onChange={(event) => {
|
||||
this.updateFormField("title", event.target.value);
|
||||
|
@ -296,8 +296,8 @@ class NewBox extends React.Component {
|
|||
lineHeight: "120%",
|
||||
}}
|
||||
>
|
||||
<textarea style={{ visibility: "hidden", display: "none" }} maxLength="20000" id="editor" name="content" />
|
||||
<div className={`cm-long-content`}>
|
||||
<textarea style={{visibility: "hidden", display: "none"}} maxLength="20000" id="editor" name="content" />
|
||||
<div className={"cm-long-content"}>
|
||||
<CodeMirror
|
||||
editorDidMount={(editor) => Tools.attachEditor(editor)}
|
||||
onPaste={() => Tools.uploadMdFile()}
|
||||
|
@ -316,7 +316,7 @@ class NewBox extends React.Component {
|
|||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ display: "block", height: "100%" }}>
|
||||
<div style={{display: "block", height: "100%"}}>
|
||||
<Editor
|
||||
language={i18next.language}
|
||||
height="400px"
|
||||
|
@ -329,7 +329,7 @@ class NewBox extends React.Component {
|
|||
)}
|
||||
</div>
|
||||
{/* select node */}
|
||||
<div className="cell" style={{ display: "flex", justifyContent: "space-between" }}>
|
||||
<div className="cell" style={{display: "flex", justifyContent: "space-between"}}>
|
||||
<Select2
|
||||
value={this.getIndexFromNodeId(this.state.form.nodeId)}
|
||||
style={{
|
||||
|
@ -337,7 +337,7 @@ class NewBox extends React.Component {
|
|||
fontSize: "14px",
|
||||
}}
|
||||
data={this.state.nodes.map((node, i) => {
|
||||
return { text: `${node.name} / ${node.id}`, id: i };
|
||||
return {text: `${node.name} / ${node.id}`, id: i};
|
||||
})}
|
||||
onSelect={(event) => {
|
||||
const s = event.target.value;
|
||||
|
@ -357,11 +357,11 @@ class NewBox extends React.Component {
|
|||
/>
|
||||
{this.renderEditorSelect()}
|
||||
</div>
|
||||
<div className="cell" style={{ lineHeight: "190%" }}>
|
||||
<div className="cell" style={{lineHeight: "190%"}}>
|
||||
{i18next.t("new:Hottest Nodes")} {" "}
|
||||
{this.state.nodes.map((node, i) => {
|
||||
return (
|
||||
<div key={node.name} style={{ display: "inline" }}>
|
||||
<div key={node.name} style={{display: "inline"}}>
|
||||
<a
|
||||
href="#"
|
||||
onClick={() => {
|
||||
|
@ -380,8 +380,8 @@ class NewBox extends React.Component {
|
|||
</div>
|
||||
</form>
|
||||
<div style={{}}>
|
||||
<div style={{ height: 1, borderTop: "1px solid black" }}></div>
|
||||
<div style={{ height: 3 }}></div>
|
||||
<div style={{height: 1, borderTop: "1px solid black"}}></div>
|
||||
<div style={{height: 3}}></div>
|
||||
<TagsInput
|
||||
inputProps={{
|
||||
maxLength: "8",
|
||||
|
|
|
@ -18,13 +18,13 @@ import * as TopicBackend from "../backend/TopicBackend";
|
|||
import * as MemberBackend from "../backend/MemberBackend";
|
||||
import * as Setting from "../Setting";
|
||||
import * as Tools from "./Tools";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import "./node-casbin.css";
|
||||
import "../codemirrorSize.css";
|
||||
import i18next from "i18next";
|
||||
import Select2 from "react-select2-wrapper";
|
||||
import Editor from "./richTextEditor";
|
||||
import { Controlled as CodeMirror } from "react-codemirror2";
|
||||
import {Controlled as CodeMirror} from "react-codemirror2";
|
||||
import TagsInput from "react-tagsinput";
|
||||
import "../tagsInput.css";
|
||||
import * as Conf from "../Conf";
|
||||
|
@ -250,7 +250,7 @@ class NewNodeTopicBox extends React.Component {
|
|||
className={`mll ${this.state.nodeInfo.id}`}
|
||||
id="topic_content"
|
||||
>
|
||||
<div className={`cm-short-content`}>
|
||||
<div className={"cm-short-content"}>
|
||||
<CodeMirror
|
||||
className={`${this.state.nodeInfo.id}`}
|
||||
editorDidMount={(editor) => Tools.attachEditor(editor)}
|
||||
|
@ -292,7 +292,7 @@ class NewNodeTopicBox extends React.Component {
|
|||
</div>
|
||||
)}
|
||||
<div className="sep10"></div>
|
||||
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
||||
<div style={{display: "flex", justifyContent: "space-between"}}>
|
||||
<input type="submit" value={i18next.t("node:Publish")} className="super normal button" onClick={this.publishTopic.bind(this)} />
|
||||
{this.renderEditorSelect()}
|
||||
</div>
|
||||
|
@ -317,9 +317,9 @@ class NewNodeTopicBox extends React.Component {
|
|||
{" "}
|
||||
<Select2
|
||||
value={this.state.form.editorType}
|
||||
style={{ width: "110px", fontSize: "14px" }}
|
||||
style={{width: "110px", fontSize: "14px"}}
|
||||
data={this.state.editor.map((node, i) => {
|
||||
return { text: `${node.text}`, id: i };
|
||||
return {text: `${node.text}`, id: i};
|
||||
})}
|
||||
onSelect={(event) => {
|
||||
const s = event.target.value;
|
||||
|
@ -339,7 +339,7 @@ class NewNodeTopicBox extends React.Component {
|
|||
});
|
||||
}
|
||||
}}
|
||||
options={{ placeholder: this.state.placeholder }}
|
||||
options={{placeholder: this.state.placeholder}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -394,7 +394,7 @@ class NewNodeTopicBox extends React.Component {
|
|||
className="mle"
|
||||
id="topic_content"
|
||||
>
|
||||
<div className={`cm-long-content`}>
|
||||
<div className={"cm-long-content"}>
|
||||
<CodeMirror
|
||||
editorDidMount={(editor) => Tools.attachEditor(editor)}
|
||||
onPaste={() => Tools.uploadMdFile()}
|
||||
|
@ -456,7 +456,7 @@ class NewNodeTopicBox extends React.Component {
|
|||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
<td style={{ display: "flex", justifyContent: "space-between" }}>
|
||||
<td style={{display: "flex", justifyContent: "space-between"}}>
|
||||
<div>
|
||||
<input type="hidden" name="once" />
|
||||
<button type="button" className="super normal button" onClick={this.enablePreview.bind(this)}>
|
||||
|
|
|
@ -17,7 +17,7 @@ import * as Setting from "../Setting";
|
|||
import * as MemberBackend from "../backend/MemberBackend";
|
||||
import * as ReplyBackend from "../backend/ReplyBackend";
|
||||
import * as FavoritesBackend from "../backend/FavoritesBackend";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import "../Reply.css";
|
||||
import * as Tools from "./Tools";
|
||||
import "../codemirrorSize.css";
|
||||
|
@ -26,7 +26,7 @@ import "./node-casbin.css";
|
|||
import * as CodeMirror from "codemirror";
|
||||
import "codemirror/addon/hint/show-hint";
|
||||
import "./show-hint.css";
|
||||
import { Controlled as CodeMirrorsEditor } from "react-codemirror2";
|
||||
import {Controlled as CodeMirrorsEditor} from "react-codemirror2";
|
||||
import i18next from "i18next";
|
||||
import Editor from "./richTextEditor";
|
||||
import Select2 from "react-select2-wrapper";
|
||||
|
@ -182,7 +182,7 @@ class NewReplyBox extends React.Component {
|
|||
});
|
||||
}
|
||||
if (value.substring(value.length - 1) === "@") {
|
||||
CodeMirror.commands.autocomplete(editor, null, { completeSingle: false });
|
||||
CodeMirror.commands.autocomplete(editor, null, {completeSingle: false});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,19 +197,24 @@ class NewReplyBox extends React.Component {
|
|||
synonyms(cm, option) {
|
||||
let comp = this.props.memberList;
|
||||
let res = [];
|
||||
return new Promise(function (accept) {
|
||||
setTimeout(function () {
|
||||
return new Promise(function(accept) {
|
||||
setTimeout(function() {
|
||||
let cursor = cm.getCursor(),
|
||||
line = cm.getLine(cursor.line);
|
||||
let start = cursor.ch,
|
||||
end = cursor.ch;
|
||||
while (start && line.charAt(start - 1) !== "@") --start;
|
||||
while (end < line.length && /\w/.test(line.charAt(end))) ++end;
|
||||
while (start && line.charAt(start - 1) !== "@") {
|
||||
--start;
|
||||
}
|
||||
while (end < line.length && /\w/.test(line.charAt(end))) {
|
||||
++end;
|
||||
}
|
||||
let word = line.slice(start, end).toLowerCase();
|
||||
for (let i = 0; i < comp.length; i++)
|
||||
for (let i = 0; i < comp.length; i++) {
|
||||
if (comp[i].includes(word)) {
|
||||
res.push(comp[i]);
|
||||
}
|
||||
}
|
||||
return accept({
|
||||
list: res,
|
||||
from: CodeMirror.Pos(cursor.line, start + 1),
|
||||
|
@ -223,10 +228,10 @@ class NewReplyBox extends React.Component {
|
|||
if (needLogin) {
|
||||
if (Conf.ShowEmbedButtons) {
|
||||
return (
|
||||
<div style={{ width: "100%", textAlign: "center" }}>
|
||||
<div style={{ marginTop: 30, marginBottom: 30 }}>
|
||||
<div style={{width: "100%", textAlign: "center"}}>
|
||||
<div style={{marginTop: 30, marginBottom: 30}}>
|
||||
<input
|
||||
style={{ marginRight: 20 }}
|
||||
style={{marginRight: 20}}
|
||||
onClick={() => {
|
||||
let encodedUrl = encodeURIComponent(window.location.href);
|
||||
localStorage.setItem("loginCallbackUrl", encodedUrl);
|
||||
|
@ -251,8 +256,8 @@ class NewReplyBox extends React.Component {
|
|||
);
|
||||
} else {
|
||||
return (
|
||||
<div style={{ width: "100%", textAlign: "center" }}>
|
||||
<div style={{ marginTop: 30, marginBottom: 30 }}>
|
||||
<div style={{width: "100%", textAlign: "center"}}>
|
||||
<div style={{marginTop: 30, marginBottom: 30}}>
|
||||
<input
|
||||
onClick={() => {
|
||||
const data = {
|
||||
|
@ -283,7 +288,7 @@ class NewReplyBox extends React.Component {
|
|||
className={`mll ${this.props.nodeId}`}
|
||||
id="reply_content"
|
||||
>
|
||||
<div className={`cm-short-content`}>
|
||||
<div className={"cm-short-content"}>
|
||||
<CodeMirrorsEditor
|
||||
editorDidMount={(editor) => Tools.attachEditor(editor)}
|
||||
onPaste={() => Tools.uploadMdFile()}
|
||||
|
@ -295,7 +300,7 @@ class NewReplyBox extends React.Component {
|
|||
lineNumbers: false,
|
||||
lineWrapping: true,
|
||||
theme: `${this.props.nodeId}`,
|
||||
extraKeys: { "Ctrl-Space": "autocomplete" },
|
||||
extraKeys: {"Ctrl-Space": "autocomplete"},
|
||||
hintOptions: {
|
||||
hint: this.synonyms,
|
||||
alignWithWord: false,
|
||||
|
@ -346,9 +351,9 @@ class NewReplyBox extends React.Component {
|
|||
{" "}
|
||||
<Select2
|
||||
value={this.state.form.editorType}
|
||||
style={{ width: "110px", fontSize: "14px" }}
|
||||
style={{width: "110px", fontSize: "14px"}}
|
||||
data={this.state.editor.map((node, i) => {
|
||||
return { text: `${node.text}`, id: i };
|
||||
return {text: `${node.text}`, id: i};
|
||||
})}
|
||||
onSelect={(event) => {
|
||||
const s = event.target.value;
|
||||
|
@ -368,7 +373,7 @@ class NewReplyBox extends React.Component {
|
|||
});
|
||||
}
|
||||
}}
|
||||
options={{ placeholder: this.state.placeholder }}
|
||||
options={{placeholder: this.state.placeholder}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -384,19 +389,19 @@ class NewReplyBox extends React.Component {
|
|||
return null;
|
||||
}
|
||||
|
||||
let blurStyle = needLogin ? { color: "#ccc", pointerEvents: "none" } : null;
|
||||
let blurStyle = needLogin ? {color: "#ccc", pointerEvents: "none"} : null;
|
||||
|
||||
return (
|
||||
<div className={["box", this.props.sticky ? "sticky" : "", `${this.props.nodeId}`].join(" ")} id="reply-box">
|
||||
<div style={blurStyle} className={`cell ${this.props.nodeId}`}>
|
||||
<div className="fr">
|
||||
{this.props.parent?.id > 0 ? (
|
||||
<a onClick={this.props.cancelReply.bind(this)} style={{ display: this.props.sticky ? "" : "none" }} id="cancel-button" className={`${this.props.nodeId}`}>
|
||||
<a onClick={this.props.cancelReply.bind(this)} style={{display: this.props.sticky ? "" : "none"}} id="cancel-button" className={`${this.props.nodeId}`}>
|
||||
{i18next.t("reply:Cancel reply to {username}").replace("{username}", this.props.parent.username)}
|
||||
</a>
|
||||
) : null}{" "}
|
||||
{" "}
|
||||
<a onClick={this.undockBox.bind(this)} style={{ display: this.props.sticky ? "" : "none" }} id="undock-button" className={`${this.props.nodeId}`}>
|
||||
<a onClick={this.undockBox.bind(this)} style={{display: this.props.sticky ? "" : "none"}} id="undock-button" className={`${this.props.nodeId}`}>
|
||||
{i18next.t("reply:Undock")}
|
||||
</a>{" "}
|
||||
{" "}
|
||||
|
@ -422,7 +427,7 @@ class NewReplyBox extends React.Component {
|
|||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<button type="button" style={blurStyle} onClick={this.publishReply.bind(this)} type="submit" className="super normal button">
|
||||
<button style={blurStyle} onClick={this.publishReply.bind(this)} type="submit" className="super normal button">
|
||||
<li className={this.state.publishClicked ? "fa fa-circle-o-notch fa-spin" : "fa fa-paper-plane"} />
|
||||
{this.state.publishClicked ? i18next.t("new:Publishing...") : i18next.t("reply:Reply")}
|
||||
</button>
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import * as Setting from "../Setting";
|
||||
import "./NoMatch.css";
|
||||
import i18next from "i18next";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
class NoMatch extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -42,7 +42,7 @@ class NoMatch extends React.Component {
|
|||
<div className="box-transparent">
|
||||
<div className="cell-translucent">The object you were looking for is not found on the {Setting.getForumName()} Space Station.</div>
|
||||
<div className="cell-translucent">你要寻找的物件不存在于 {Setting.getForumName()} 空间站上。</div>
|
||||
<div className="cell-translucent">L'objet que vous cherchiez ne se trouve pas sur la station spatiale {Setting.getForumName()}.</div>
|
||||
<div className="cell-translucent">L'objet que vous cherchiez ne se trouve pas sur la station spatiale {Setting.getForumName()}.</div>
|
||||
<div className="cell-translucent">
|
||||
Das von Ihnen gesuchte Objekt wird auf der {Setting.getForumName()}
|
||||
-Raumstation nicht gefunden.
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
import React from "react";
|
||||
import * as Setting from "../Setting";
|
||||
import * as NodeBackend from "../backend/NodeBackend";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import * as TopicBackend from "../backend/TopicBackend";
|
||||
import * as FavoritesBackend from "../backend/FavoritesBackend";
|
||||
import PageColumn from "./PageColumn";
|
||||
|
@ -25,7 +25,7 @@ import "../node.css";
|
|||
import ReactMarkdown from "react-markdown";
|
||||
import i18next from "i18next";
|
||||
import * as Conf from "../Conf";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
class NodeBox extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -63,7 +63,7 @@ class NodeBox extends React.Component {
|
|||
componentDidMount() {
|
||||
this.getTopics();
|
||||
this.getNodeInfo();
|
||||
//this.props.getNodeId(this.state.nodeId);
|
||||
// this.props.getNodeId(this.state.nodeId);
|
||||
NodeBackend.addNodeBrowseCount(this.state.nodeId);
|
||||
}
|
||||
|
||||
|
@ -275,7 +275,7 @@ class NodeBox extends React.Component {
|
|||
<div className="sep5"></div>
|
||||
{this.props.account !== null ? (
|
||||
<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" }} />
|
||||
<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>
|
||||
) : null}
|
||||
</div>
|
||||
|
@ -283,7 +283,7 @@ class NodeBox extends React.Component {
|
|||
}
|
||||
|
||||
renderDesktopHeader() {
|
||||
const { nodeInfo, nodeId } = this.state;
|
||||
const {nodeInfo, nodeId} = this.state;
|
||||
|
||||
return (
|
||||
<div
|
||||
|
@ -364,7 +364,7 @@ class NodeBox extends React.Component {
|
|||
<div className="sep20" />
|
||||
<div className="sep5" />
|
||||
{this.props.account !== null ? (
|
||||
<div className="fr" style={{ paddingLeft: "10px" }}>
|
||||
<div className="fr" style={{paddingLeft: "10px"}}>
|
||||
<input
|
||||
type="button"
|
||||
className="super normal button"
|
||||
|
@ -400,7 +400,7 @@ class NodeBox extends React.Component {
|
|||
}
|
||||
|
||||
renderNode() {
|
||||
const { page, limit } = this.state;
|
||||
const {page, limit} = this.state;
|
||||
let from, end;
|
||||
if (this.state.topicNum !== 0) {
|
||||
from = (page - 1) * limit + 1;
|
||||
|
@ -428,7 +428,7 @@ class NodeBox extends React.Component {
|
|||
<tr>
|
||||
<td width="120" align="right"></td>
|
||||
<td width="auto" align="left">
|
||||
<Link to={`/member/${moderators}`} style={{ fontWeight: "bolder" }} target="_blank">
|
||||
<Link to={`/member/${moderators}`} style={{fontWeight: "bolder"}} target="_blank">
|
||||
{moderators}
|
||||
</Link>
|
||||
</td>
|
||||
|
@ -472,21 +472,21 @@ class NodeBox extends React.Component {
|
|||
if (this.state.nodeInfo === null) {
|
||||
return (
|
||||
<div id={pcBrowser ? "Main" : ""}>
|
||||
<div class="sep20"></div>
|
||||
<div class="box">
|
||||
<div class="header">
|
||||
<div className="sep20"></div>
|
||||
<div className="box">
|
||||
<div className="header">
|
||||
<Link to="/">{Setting.getForumName()}</Link>
|
||||
<span className="chevron"> › </span> {i18next.t("error:Node not found")}
|
||||
</div>
|
||||
<div class="cell">
|
||||
<div className="cell">
|
||||
{i18next.t("error:The node you are trying to view does not exist, there are several possibilities")}
|
||||
<div class="sep10"></div>
|
||||
<div className="sep10"></div>
|
||||
<ul>
|
||||
<li>{i18next.t("error:You entered a node ID that does not exist.")}</li>
|
||||
<li>{i18next.t("error:The node is currently in invisible state.")}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="inner">
|
||||
<div className="inner">
|
||||
{this.props.account === null ? (
|
||||
<span className="gray">
|
||||
<span className="chevron">‹</span>
|
||||
|
@ -539,7 +539,7 @@ class NodeBox extends React.Component {
|
|||
{i18next.t("node:Moderators")}
|
||||
</td>
|
||||
<td width="auto" align="left">
|
||||
<Link to={`/member/${this.state.nodeInfo?.moderators[0]}`} style={{ fontWeight: "bolder" }} target="_blank">
|
||||
<Link to={`/member/${this.state.nodeInfo?.moderators[0]}`} style={{fontWeight: "bolder"}} target="_blank">
|
||||
{this.state.nodeInfo?.moderators[0]}
|
||||
</Link>
|
||||
</td>
|
||||
|
@ -560,7 +560,7 @@ class NodeBox extends React.Component {
|
|||
{i18next.t("node:Moderators")}
|
||||
</td>
|
||||
<td width="auto" align="left">
|
||||
<span class="gray">{i18next.t("node:No moderators")}</span>
|
||||
<span className="gray">{i18next.t("node:No moderators")}</span>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
import React from "react";
|
||||
import * as BasicBackend from "../backend/BasicBackend";
|
||||
import * as Setting from "../Setting";
|
||||
import { Link } from "react-router-dom";
|
||||
import {Link} from "react-router-dom";
|
||||
import i18next from "i18next";
|
||||
|
||||
class NodeNavigationBox extends React.Component {
|
||||
|
@ -42,7 +42,7 @@ class NodeNavigationBox extends React.Component {
|
|||
renderNode(node) {
|
||||
return (
|
||||
<span key={node?.id}>
|
||||
<Link to={`/go/${encodeURIComponent(node?.id)}`} style={{ fontSize: "14px" }}>
|
||||
<Link to={`/go/${encodeURIComponent(node?.id)}`} style={{fontSize: "14px"}}>
|
||||
{node?.name}
|
||||
</Link>
|
||||
|
||||
|
|
|
@ -18,11 +18,11 @@ import * as NotificationBackend from "../backend/NotificationBackend";
|
|||
import PageColumn from "./PageColumn";
|
||||
import Avatar from "../Avatar";
|
||||
import "../Notification.css";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import Zmage from "react-zmage";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import i18next from "i18next";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
const pangu = require("pangu");
|
||||
|
||||
|
@ -49,7 +49,7 @@ class NotificationBox extends React.Component {
|
|||
this.state.page = parseInt(this.state.p);
|
||||
}
|
||||
|
||||
this.state.url = `/notifications`;
|
||||
this.state.url = "/notifications";
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -120,8 +120,8 @@ class NotificationBox extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
renderImage = ({ alt, src }) => {
|
||||
return <Zmage src={src} alt={alt} style={{ maxWidth: "100%" }} />;
|
||||
renderImage = ({alt, src}) => {
|
||||
return <Zmage src={src} alt={alt} style={{maxWidth: "100%"}} />;
|
||||
};
|
||||
|
||||
renderLink = (props) => {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
import React from "react";
|
||||
import * as Setting from "../Setting";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import "../Bottom.css";
|
||||
import "./node-casbin.css";
|
||||
import i18next from "i18next";
|
||||
|
@ -60,8 +60,12 @@ class PageColumn extends React.Component {
|
|||
maxPage: this.handleMaxPage(this.props.total),
|
||||
},
|
||||
() => {
|
||||
if (this.props.page > this.state.maxPage) this.gotoPage(this.props.url, this.state.maxPage);
|
||||
if (this.props.page < this.state.minPage) this.gotoPage(this.props.url, this.state.minPage);
|
||||
if (this.props.page > this.state.maxPage) {
|
||||
this.gotoPage(this.props.url, this.state.maxPage);
|
||||
}
|
||||
if (this.props.page < this.state.minPage) {
|
||||
this.gotoPage(this.props.url, this.state.minPage);
|
||||
}
|
||||
this.getPages();
|
||||
}
|
||||
);
|
||||
|
@ -82,7 +86,7 @@ class PageColumn extends React.Component {
|
|||
return 1;
|
||||
}
|
||||
|
||||
//Get an array of page number, and there always should have 10 elements except '...'.
|
||||
// Get an array of page number, and there always should have 10 elements except '...'.
|
||||
getShowPages(page, total) {
|
||||
let pages = [];
|
||||
|
||||
|
@ -157,12 +161,12 @@ class PageColumn extends React.Component {
|
|||
if (this.state.maxPage <= 1) {
|
||||
return null;
|
||||
}
|
||||
const { page, url } = this.props;
|
||||
const {page, url} = this.props;
|
||||
|
||||
if (!Setting.PcBrowser) {
|
||||
return (
|
||||
<div class="inner">
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||
<div className="inner">
|
||||
<table cellPadding="0" cellSpacing="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td width="120" align="left">
|
||||
<Link to={`${url}?p=${page - 1}`}>
|
||||
|
@ -173,12 +177,12 @@ class PageColumn extends React.Component {
|
|||
}}
|
||||
value={`‹ ${i18next.t("topic:Last")}`}
|
||||
className="super normal button"
|
||||
style={{ display: page > 1 ? "block" : "none" }}
|
||||
style={{display: page > 1 ? "block" : "none"}}
|
||||
/>
|
||||
</Link>
|
||||
</td>
|
||||
<td width="auto" align="center">
|
||||
<strong class="fade">
|
||||
<strong className="fade">
|
||||
{page}/{this.state.maxPage}
|
||||
</strong>
|
||||
</td>
|
||||
|
|
|
@ -16,9 +16,9 @@ import React from "react";
|
|||
import * as PlaneBackend from "../backend/PlaneBackend";
|
||||
import * as NodeBackend from "../backend/NodeBackend";
|
||||
import * as Setting from "../Setting";
|
||||
import { Link } from "react-router-dom";
|
||||
import {Link} from "react-router-dom";
|
||||
import i18next from "i18next";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
class PlaneBox extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -72,7 +72,7 @@ class PlaneBox extends React.Component {
|
|||
}}
|
||||
>
|
||||
<img src={plane?.image} border="0" align="absmiddle" width="24" /> {plane?.name}
|
||||
<span className="fr" style={{ color: plane?.color, lineHeight: "20px" }}>
|
||||
<span className="fr" style={{color: plane?.color, lineHeight: "20px"}}>
|
||||
{plane?.id} •{" "}
|
||||
<span className="small">
|
||||
{plane?.nodes.length} {i18next.t("plane:nodes")}
|
||||
|
@ -96,7 +96,7 @@ class PlaneBox extends React.Component {
|
|||
<Helmet>
|
||||
<title>{`${i18next.t("plane:Plane list")} - ${Setting.getForumName()}`}</title>
|
||||
</Helmet>
|
||||
<div className="cell" style={{ padding: "0px" }}>
|
||||
<div className="cell" style={{padding: "0px"}}>
|
||||
<table cellPadding="10" cellSpacing="0" border="0" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import React from "react";
|
||||
import i18next from "i18next";
|
||||
import * as Setting from "../Setting";
|
||||
import Avatar from "../Avatar";
|
||||
import * as MemberBackend from "../backend/MemberBackend";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
class RankingPlayerBox extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -38,7 +38,7 @@ class RankingPlayerBox extends React.Component {
|
|||
|
||||
renderPlayerBox(karma) {
|
||||
return (
|
||||
<div className="balance_area" style={{ fontSize: "24px", lineHeight: "24px", width: "70%", background: "#f5f5f5" }}>
|
||||
<div className="balance_area" style={{fontSize: "24px", lineHeight: "24px", width: "70%", background: "#f5f5f5"}}>
|
||||
${karma}
|
||||
</div>
|
||||
);
|
||||
|
@ -52,7 +52,7 @@ class RankingPlayerBox extends React.Component {
|
|||
<meta name="keywords" content={Setting.getForumName()} />
|
||||
</Helmet>
|
||||
<div className="cell">
|
||||
<div className="fr" style={{ margin: "-1px -8px 0px 0px" }}>
|
||||
<div className="fr" style={{margin: "-1px -8px 0px 0px"}}>
|
||||
<Link to="/top/rich" className="tab">
|
||||
{i18next.t("balance:Wealth ranking")}
|
||||
</Link>
|
||||
|
@ -75,8 +75,8 @@ class RankingPlayerBox extends React.Component {
|
|||
<Avatar username={member.name} avatar={member.avatar} key={key} />
|
||||
</td>
|
||||
<td width="auto" align="left">
|
||||
<h2 style={{ marginBottom: "10px", marginTop: "0px", fontSize: "20px" }}>
|
||||
<span class="gray">{key + 1}.</span> <a href={`/member/${member.name}`}>{member.name}</a>
|
||||
<h2 style={{marginBottom: "10px", marginTop: "0px", fontSize: "20px"}}>
|
||||
<span className="gray">{key + 1}.</span> <a href={`/member/${member.name}`}>{member.name}</a>
|
||||
</h2>
|
||||
<div className="sep5"></div>
|
||||
<span className="gray f12">
|
||||
|
@ -89,13 +89,13 @@ class RankingPlayerBox extends React.Component {
|
|||
<a href={member.homepage}>{member.homepage}</a>{" "}
|
||||
</span>
|
||||
<div className="sep5"></div>
|
||||
<span style={{ fontSize: "18px", color: "#bbbbbb" }}>
|
||||
<span style={{fontSize: "18px", color: "#bbbbbb"}}>
|
||||
{i18next.t("member:No.")} {member.ranking} {i18next.t("member:member")}
|
||||
</span>
|
||||
<div className="sep5"></div>
|
||||
</td>
|
||||
<td width="200px" align="center">
|
||||
<div class="sep20"></div>
|
||||
<div className="sep20"></div>
|
||||
<div>{this.renderPlayerBox(member.karma)}</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -12,14 +12,14 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import React from "react";
|
||||
import i18next from "i18next";
|
||||
import * as Setting from "../Setting";
|
||||
import Avatar from "../Avatar";
|
||||
import * as MemberBackend from "../backend/MemberBackend";
|
||||
import { scoreConverter } from "./Tools";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {scoreConverter} from "./Tools";
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
class RankingRichBox extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -38,9 +38,9 @@ class RankingRichBox extends React.Component {
|
|||
}
|
||||
|
||||
renderRichBox(score) {
|
||||
const { goldCount, silverCount, bronzeCount } = scoreConverter(score);
|
||||
const {goldCount, silverCount, bronzeCount} = scoreConverter(score);
|
||||
return (
|
||||
<div className="balance_area bigger" style={{ fontSize: "24px", lineHeight: "24px", width: "100%" }}>
|
||||
<div className="balance_area bigger" style={{fontSize: "24px", lineHeight: "24px", width: "100%"}}>
|
||||
{goldCount}
|
||||
<img src={Setting.getStatic("/img/gold@2x.png")} height="16" alt="G" border="0" />
|
||||
{silverCount}
|
||||
|
@ -56,10 +56,10 @@ class RankingRichBox extends React.Component {
|
|||
<div className="box">
|
||||
<Helmet>
|
||||
<title>{`${i18next.t("balance:Rich ranking")} - ${Setting.getForumName()}`}</title>
|
||||
<meta name="keywords" content={`${i18next.t("balance:Rich ranking")},${Setting.getForumName()}`} />} />
|
||||
<meta name="keywords" content={`${i18next.t("balance:Rich ranking")},${Setting.getForumName()}`} />
|
||||
</Helmet>
|
||||
<div className="cell">
|
||||
<div className="fr" style={{ margin: "-3px -8px 0px 0px" }}>
|
||||
<div className="fr" style={{margin: "-3px -8px 0px 0px"}}>
|
||||
<Link to="/top/rich" className="tab">
|
||||
{i18next.t("balance:Wealth ranking")}
|
||||
</Link>
|
||||
|
@ -82,8 +82,8 @@ class RankingRichBox extends React.Component {
|
|||
<Avatar username={member.name} avatar={member.avatar} key={key} />
|
||||
</td>
|
||||
<td width="auto" align="left">
|
||||
<h2 style={{ marginBottom: "10px", marginTop: "0px" }}>
|
||||
<span class="gray">{key + 1}.</span> <a href={`/member/${member.name}`}>{member.name}</a>
|
||||
<h2 style={{marginBottom: "10px", marginTop: "0px"}}>
|
||||
<span className="gray">{key + 1}.</span> <a href={`/member/${member.name}`}>{member.name}</a>
|
||||
</h2>
|
||||
<span className="gray f12"> {member.tag} </span>
|
||||
<div className="sep5"></div>
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
|
||||
import React from "react";
|
||||
import * as Setting from "../Setting";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import * as TopicBackend from "../backend/TopicBackend";
|
||||
import TopicList from "./TopicList";
|
||||
import PageColumn from "./PageColumn";
|
||||
import i18next from "i18next";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
class RecentTopicsBox extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -44,7 +44,7 @@ class RecentTopicsBox extends React.Component {
|
|||
this.state.page = parseInt(this.state.p);
|
||||
}
|
||||
|
||||
this.state.url = `/recent`;
|
||||
this.state.url = "/recent";
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
|
|
@ -17,7 +17,7 @@ import * as Setting from "../Setting";
|
|||
import * as Conf from "../Conf";
|
||||
import * as ReplyBackend from "../backend/ReplyBackend";
|
||||
import * as BalanceBackend from "../backend/BalanceBackend";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import Avatar from "../Avatar";
|
||||
import NewReplyBox from "./NewReplyBox";
|
||||
import PageColumn from "./PageColumn";
|
||||
|
@ -68,7 +68,7 @@ class ReplyBox extends React.Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
//this.getTopic();
|
||||
// this.getTopic();
|
||||
let lastIndex = window.location.href.lastIndexOf("#");
|
||||
if (lastIndex >= 0) {
|
||||
let idString = window.location.href.substring(lastIndex + 1);
|
||||
|
@ -85,7 +85,7 @@ class ReplyBox extends React.Component {
|
|||
|
||||
componentDidUpdate(prevProps, prevState, snapshot) {
|
||||
if (prevState.fullUrl !== window.location.href) {
|
||||
this.setState({ fullUrl: window.location.href });
|
||||
this.setState({fullUrl: window.location.href});
|
||||
let lastIndex = window.location.href.lastIndexOf("#");
|
||||
if (lastIndex >= 0) {
|
||||
let idString = window.location.href.substring(lastIndex + 1);
|
||||
|
@ -213,7 +213,7 @@ class ReplyBox extends React.Component {
|
|||
list.push(this.state.replies[i].author + " ");
|
||||
}
|
||||
}
|
||||
//console.log(list)
|
||||
// console.log(list)
|
||||
this.setState({
|
||||
memberList: list,
|
||||
});
|
||||
|
@ -232,7 +232,7 @@ class ReplyBox extends React.Component {
|
|||
}
|
||||
|
||||
deleteReply(id) {
|
||||
if (window.confirm(`Are you sure to delete this reply?`)) {
|
||||
if (window.confirm("Are you sure to delete this reply?")) {
|
||||
ReplyBackend.deleteReply(id).then((res) => {
|
||||
if (res?.status === "ok") {
|
||||
this.getReplies(false);
|
||||
|
@ -275,8 +275,8 @@ class ReplyBox extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
renderImage = ({ alt, src }) => {
|
||||
return <Zmage src={src} alt={alt} style={{ maxWidth: "100%" }} />;
|
||||
renderImage = ({alt, src}) => {
|
||||
return <Zmage src={src} alt={alt} style={{maxWidth: "100%"}} />;
|
||||
};
|
||||
|
||||
renderLink = (props) => {
|
||||
|
@ -292,27 +292,27 @@ class ReplyBox extends React.Component {
|
|||
|
||||
return (
|
||||
<div id={`r_${reply.id}`}>
|
||||
<div style={{ minHeight: isChild ? "48px" : "60px" }}>
|
||||
<div style={{ width: isChild ? "36px" : "48px", float: "left" }}>
|
||||
<div style={{minHeight: isChild ? "48px" : "60px"}}>
|
||||
<div style={{width: isChild ? "36px" : "48px", float: "left"}}>
|
||||
<Avatar username={reply.author} avatar={reply.avatar} size={isChild ? "middle" : ""} />
|
||||
</div>
|
||||
<div style={{ marginLeft: isChild ? "48px" : "60px" }}>
|
||||
<div style={{marginLeft: isChild ? "48px" : "60px"}}>
|
||||
<div className="fr">
|
||||
{this.props.account !== null && this.props.account !== undefined && this.props.account.id !== reply?.author ? (
|
||||
reply?.thanksStatus === false ? (
|
||||
<div id={`thank_area__${reply.id}`} className="thank_area" style={{ marginRight: "10px" }}>
|
||||
{/*<a*/}
|
||||
<div id={`thank_area__${reply.id}`} className="thank_area" style={{marginRight: "10px"}}>
|
||||
{/* <a*/}
|
||||
{/* className="thank"*/}
|
||||
{/* style={{*/}
|
||||
{/* color: "#ccc",*/}
|
||||
{/* display: Setting.PcBrowser ? "" : "none",*/}
|
||||
{/* marginRight: "10px",*/}
|
||||
{/* }}*/}
|
||||
{/*>*/}
|
||||
{/* >*/}
|
||||
{/* {i18next.t("reply:ignore")}*/}
|
||||
{/*</a>*/}
|
||||
{/* </a>*/}
|
||||
<a onClick={() => this.thanksReply(reply.id, reply.author)} className="thank link-btn">
|
||||
{Setting.PcBrowser ? i18next.t("reply:thank") : <img src={Setting.getStatic("/img/heart_neue.png")} width="16" style={{ verticalAlign: "bottom" }} alt={i18next.t("reply:thank")} />}
|
||||
{Setting.PcBrowser ? i18next.t("reply:thank") : <img src={Setting.getStatic("/img/heart_neue.png")} width="16" style={{verticalAlign: "bottom"}} alt={i18next.t("reply:thank")} />}
|
||||
</a>
|
||||
</div>
|
||||
) : (
|
||||
|
@ -322,8 +322,8 @@ class ReplyBox extends React.Component {
|
|||
)
|
||||
) : null}
|
||||
{reply?.deletable ? (
|
||||
<div id={`thank_area__${reply.id}`} className="thank_area" style={{ marginRight: "10px" }}>
|
||||
<a className="delete link-btn" style={{ marginRight: "10px" }} onClick={() => this.deleteReply(reply.id)}>
|
||||
<div id={`thank_area__${reply.id}`} className="thank_area" style={{marginRight: "10px"}}>
|
||||
<a className="delete link-btn" style={{marginRight: "10px"}} onClick={() => this.deleteReply(reply.id)}>
|
||||
{i18next.t("reply:Delete")}
|
||||
</a>
|
||||
<a href={`/edit/reply/${reply.id}`} className="edit link-btn">
|
||||
|
@ -336,10 +336,10 @@ class ReplyBox extends React.Component {
|
|||
onClick={() => {
|
||||
this.handleClick(`@${reply.author} `);
|
||||
this.setState({
|
||||
parent: { id: reply.id, username: reply.author },
|
||||
parent: {id: reply.id, username: reply.author},
|
||||
});
|
||||
}}
|
||||
style={{ marginRight: "10px" }}
|
||||
style={{marginRight: "10px"}}
|
||||
>
|
||||
<img src={Setting.getStatic("/img/reply_neue.png")} align="absmiddle" border="0" alt="Reply" width="20" />
|
||||
</a>
|
||||
|
@ -356,7 +356,7 @@ class ReplyBox extends React.Component {
|
|||
<Link
|
||||
className="ago"
|
||||
to={`#r_${reply.id}`}
|
||||
style={{ marginLeft: "10px" }}
|
||||
style={{marginLeft: "10px"}}
|
||||
onClick={() => {
|
||||
this.scrollToAnchor(`r_${reply?.id}`);
|
||||
}}
|
||||
|
@ -371,9 +371,9 @@ class ReplyBox extends React.Component {
|
|||
) : null}
|
||||
<div className={`reply_content ${this.props.topic.nodeId}`}>
|
||||
{reply.deleted ? (
|
||||
<span style={{ color: "#ccc" }}>This reply has been deleted</span>
|
||||
<span style={{color: "#ccc"}}>This reply has been deleted</span>
|
||||
) : (
|
||||
<ReactMarkdown escapeHtml={false} renderers={{ image: this.renderImage, link: this.renderLink }} source={Setting.getFormattedContent(reply.content, true)} />
|
||||
<ReactMarkdown escapeHtml={false} renderers={{image: this.renderImage, link: this.renderLink}} source={Setting.getFormattedContent(reply.content, true)} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -389,7 +389,7 @@ class ReplyBox extends React.Component {
|
|||
result.push(this.renderReplyBox(reply, no));
|
||||
}
|
||||
result.push(
|
||||
<div style={{ paddingLeft: depth < maxReplyDepth ? "40px" : "", marginTop: 16 }}>
|
||||
<div style={{paddingLeft: depth < maxReplyDepth ? "40px" : "", marginTop: 16}}>
|
||||
{reply.child?.map((childItem) => {
|
||||
let childResult = [];
|
||||
if (!(childItem.deleted && childItem.child === null)) {
|
||||
|
@ -410,7 +410,7 @@ class ReplyBox extends React.Component {
|
|||
return (
|
||||
<div className={`box ${this.props.topic.nodeId}`}>
|
||||
<div className={`cell ${this.props.topic.nodeId}`}>
|
||||
<div className="fr" style={{ margin: "-3px -5px 0px 0px" }}>
|
||||
<div className="fr" style={{margin: "-3px -5px 0px 0px"}}>
|
||||
{this.props.topic?.tags?.map((tag, i) => {
|
||||
return (
|
||||
<Link key={i} to={`/tag/${tag}`} className={`tag ${this.props.topic.nodeId}`}>
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
import React from "react";
|
||||
import * as Setting from "../Setting";
|
||||
import * as TopicBackend from "../backend/TopicBackend";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import PageColumn from "./PageColumn";
|
||||
import i18next from "i18next";
|
||||
import TopicList from "./TopicList";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
class SearchTag extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -56,11 +56,11 @@ class SearchTag extends React.Component {
|
|||
renderTag() {
|
||||
return (
|
||||
<div className={`box ${this.state.tagId}`}>
|
||||
<div className="cell" align="center" style={{ border: 0 }}>
|
||||
<div className="cell" align="center" style={{border: 0}}>
|
||||
<div className="header">
|
||||
<Link to="/">{Setting.getForumName()}</Link> <span className="chevron"> › </span>
|
||||
<span className="chevron">{this.state.tagId}</span>{" "}
|
||||
<span className="gray" style={{ float: "right" }}>
|
||||
<span className="gray" style={{float: "right"}}>
|
||||
{`${i18next.t("node:all")} ${this.state.topicNum} ${i18next.t("node:topics")}`}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
|
||||
import React from "react";
|
||||
import * as Setting from "../Setting";
|
||||
import { Link } from "react-router-dom";
|
||||
import {Link} from "react-router-dom";
|
||||
import i18next from "i18next";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
class SelectLanguageBox extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -29,7 +29,7 @@ class SelectLanguageBox extends React.Component {
|
|||
render() {
|
||||
return (
|
||||
<div align="center">
|
||||
<div className="box" style={{ width: Setting.PcBrowser ? "600px" : "auto" }}>
|
||||
<div className="box" style={{width: Setting.PcBrowser ? "600px" : "auto"}}>
|
||||
<Helmet>
|
||||
<title>{`${i18next.t("footer:Select Editor")} - ${Setting.getForumName()}`}</title>
|
||||
</Helmet>
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
|
||||
import React from "react";
|
||||
import * as Setting from "../Setting";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import i18next from "i18next";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
class SelectLanguageBox extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -39,7 +39,7 @@ class SelectLanguageBox extends React.Component {
|
|||
render() {
|
||||
return (
|
||||
<div align="center">
|
||||
<div className="box" style={{ width: Setting.PcBrowser ? "600px" : "auto" }}>
|
||||
<div className="box" style={{width: Setting.PcBrowser ? "600px" : "auto"}}>
|
||||
<Helmet>
|
||||
<title>{`${i18next.t("general:Language")} - ${Setting.getForumName()}`}</title>
|
||||
</Helmet>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
import React from "react";
|
||||
import Header from "./Header";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import {withRouter} from "react-router-dom";
|
||||
import * as AccountBackend from "../backend/AccountBackend";
|
||||
import i18next from "i18next";
|
||||
import * as Setting from "../Setting";
|
||||
|
|
|
@ -16,11 +16,11 @@ import React from "react";
|
|||
import * as Setting from "../Setting";
|
||||
import * as ReplyBackend from "../backend/ReplyBackend";
|
||||
import * as TopicBackend from "../backend/TopicBackend";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import {withRouter} from "react-router-dom";
|
||||
import Avatar from "../Avatar";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import UserLink from "../UserLink";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {Helmet} from "react-helmet";
|
||||
import Zmage from "react-zmage";
|
||||
|
||||
class SingleReplyBox extends React.Component {
|
||||
|
@ -54,7 +54,7 @@ class SingleReplyBox extends React.Component {
|
|||
});
|
||||
}
|
||||
|
||||
renderImage = ({ alt, src }) => {
|
||||
renderImage = ({alt, src}) => {
|
||||
return <Zmage src={src} alt={alt} />;
|
||||
};
|
||||
|
||||
|
@ -65,15 +65,15 @@ class SingleReplyBox extends React.Component {
|
|||
renderSingleReplyBox(reply) {
|
||||
return (
|
||||
<div id={`r_${reply.id}`}>
|
||||
<div style={{ width: "48px", float: "left" }}>
|
||||
<div style={{width: "48px", float: "left"}}>
|
||||
<Avatar username={reply.author} avatar={reply.avatar} />
|
||||
</div>
|
||||
<div style={{ marginLeft: "60px" }}>
|
||||
<div style={{marginLeft: "60px"}}>
|
||||
<strong>
|
||||
<UserLink username={reply.author} classNameText={"dark"} />
|
||||
</strong>
|
||||
<div className={`reply_content ${this.state.topic?.nodeId}`}>
|
||||
{reply.delete ? "" : <ReactMarkdown escapeHtml={false} renderers={{ image: this.renderImage, link: this.renderLink }} source={Setting.getFormattedContent(reply?.content, true)} />}
|
||||
{reply.delete ? "" : <ReactMarkdown escapeHtml={false} renderers={{image: this.renderImage, link: this.renderLink}} source={Setting.getFormattedContent(reply?.content, true)} />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -16,7 +16,7 @@ import React from "react";
|
|||
import * as Setting from "../Setting";
|
||||
import * as TopicBackend from "../backend/TopicBackend";
|
||||
import * as NodeBackend from "../backend/NodeBackend";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import {withRouter} from "react-router-dom";
|
||||
import Avatar from "../Avatar";
|
||||
import ReplyBox from "./ReplyBox";
|
||||
import * as FavoritesBackend from "../backend/FavoritesBackend";
|
||||
|
@ -24,11 +24,11 @@ import * as BalanceBackend from "../backend/BalanceBackend";
|
|||
import * as TranslatorBackend from "../backend/TranslatorBackend";
|
||||
import "../node.css";
|
||||
import Zmage from "react-zmage";
|
||||
import { Link } from "react-router-dom";
|
||||
import {Link} from "react-router-dom";
|
||||
import i18next from "i18next";
|
||||
import UserLink from "../UserLink";
|
||||
import * as Conf from "../Conf";
|
||||
import { Helmet } from "react-helmet";
|
||||
import {Helmet} from "react-helmet";
|
||||
|
||||
require("codemirror/mode/markdown/markdown");
|
||||
|
||||
|
@ -111,7 +111,7 @@ class TopicBox extends React.Component {
|
|||
}
|
||||
|
||||
this.getNodeInfo();
|
||||
//this.props.getNodeId(this.state.topic?.nodeId);
|
||||
// this.props.getNodeId(this.state.topic?.nodeId);
|
||||
NodeBackend.addNodeBrowseCount(this.state.topic?.nodeId);
|
||||
}
|
||||
);
|
||||
|
@ -229,8 +229,8 @@ class TopicBox extends React.Component {
|
|||
ignoreTopic() {}
|
||||
|
||||
translateTopic() {
|
||||
//https://html.spec.whatwg.org/multipage/system-state.html#language-preferences
|
||||
//Use navigator.languages to get an array of language tags representing the user's preferred languages
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#language-preferences
|
||||
// Use navigator.languages to get an array of language tags representing the user's preferred languages
|
||||
|
||||
if (!this.state.translation.translated) {
|
||||
TopicBackend.translateTopic(this.state.topicId, navigator.language).then((res) => {
|
||||
|
@ -251,7 +251,7 @@ class TopicBox extends React.Component {
|
|||
}
|
||||
|
||||
deleteTopic() {
|
||||
if (window.confirm(`Are you sure to delete this topic?`)) {
|
||||
if (window.confirm("Are you sure to delete this topic?")) {
|
||||
TopicBackend.deleteTopic(this.state.topicId).then((res) => {
|
||||
if (res) {
|
||||
this.props.history.push(this.state.from);
|
||||
|
@ -276,7 +276,7 @@ class TopicBox extends React.Component {
|
|||
|
||||
topTopic(topType) {
|
||||
if (this.props.account?.isAdmin || this.state.topic?.nodeModerator) {
|
||||
//let time = prompt(i18next.t("topic:How long do you want to top this topic? (minute)"), this.state.defaultTopTopicTime)
|
||||
// let time = prompt(i18next.t("topic:How long do you want to top this topic? (minute)"), this.state.defaultTopTopicTime)
|
||||
if (window.confirm(`${i18next.t("topic:Are you sure to top this topic?")}`)) {
|
||||
TopicBackend.topTopic(this.state.topic?.id, "", topType).then((res) => {
|
||||
if (res?.status === "ok") {
|
||||
|
@ -350,7 +350,7 @@ class TopicBox extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
renderImage = ({ alt, src }) => {
|
||||
renderImage = ({alt, src}) => {
|
||||
return <Zmage src={src} alt={alt} />;
|
||||
};
|
||||
|
||||
|
@ -364,8 +364,8 @@ class TopicBox extends React.Component {
|
|||
|
||||
renderMobileButtons() {
|
||||
return (
|
||||
<div class="inner">
|
||||
<div class="fr" align="right">
|
||||
<div className="inner">
|
||||
<div className="fr" align="right">
|
||||
{this.props.account !== undefined && this.props.account !== null ? (
|
||||
this.state.favoritesStatus ? (
|
||||
<a href="javascript:void(0)" onClick={() => this.deleteFavorite()} className="op">
|
||||
|
@ -398,7 +398,7 @@ class TopicBox extends React.Component {
|
|||
Tweet
|
||||
</a>{" "}
|
||||
|
||||
<a href="javascript:void(0)" onclick="shareTopic(``);" class="op">
|
||||
<a href="javascript:void(0)" onClick="shareTopic(``);" className="op">
|
||||
Share
|
||||
</a>{" "}
|
||||
|
||||
|
@ -441,7 +441,7 @@ class TopicBox extends React.Component {
|
|||
renderDesktopButtons() {
|
||||
return (
|
||||
<div className="topic_buttons">
|
||||
<div className="fr topic_stats" style={{ paddingTop: "4px" }}>
|
||||
<div className="fr topic_stats" style={{paddingTop: "4px"}}>
|
||||
{this.state.topic?.hitCount} {i18next.t("topic:hits")} ∙ {this.state.topic?.favoriteCount} {i18next.t("topic:favorites")}
|
||||
</div>
|
||||
{this.props.account !== undefined && this.props.account !== null ? (
|
||||
|
@ -543,14 +543,14 @@ class TopicBox extends React.Component {
|
|||
|
||||
if (this.state.topic === null) {
|
||||
return (
|
||||
<div class="box">
|
||||
<div class="header">
|
||||
{Setting.getHomeLink()} <span class="chevron"> › </span> {i18next.t("error:Topic not found")}
|
||||
<div className="box">
|
||||
<div className="header">
|
||||
{Setting.getHomeLink()} <span className="chevron"> › </span> {i18next.t("error:Topic not found")}
|
||||
</div>
|
||||
<div class="cell">
|
||||
<span class="gray bigger">404 Topic Not Found</span>
|
||||
<div className="cell">
|
||||
<span className="gray bigger">404 Topic Not Found</span>
|
||||
</div>
|
||||
<div class="inner">← {Setting.getHomeLink(i18next.t("error:Back to Home Page"))}</div>
|
||||
<div className="inner">← {Setting.getHomeLink(i18next.t("error:Back to Home Page"))}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -560,12 +560,12 @@ class TopicBox extends React.Component {
|
|||
this.props.history.push(`/t/${this.state.topic?.id}`);
|
||||
}
|
||||
return (
|
||||
<div class="box">
|
||||
<div class="header">
|
||||
{Setting.getHomeLink()} <span class="chevron"> › </span> <Link to={`/go/${encodeURIComponent(this.state.topic?.nodeId)}`}>{this.state.topic?.nodeName}</Link>
|
||||
<span class="chevron"> › </span> <Link to={`/t/${this.state.topic?.id}`}>{pangu.spacing(this.state.topic?.title)}</Link> <span class="chevron"> › </span> Review
|
||||
<div className="box">
|
||||
<div className="header">
|
||||
{Setting.getHomeLink()} <span className="chevron"> › </span> <Link to={`/go/${encodeURIComponent(this.state.topic?.nodeId)}`}>{this.state.topic?.nodeName}</Link>
|
||||
<span className="chevron"> › </span> <Link to={`/t/${this.state.topic?.id}`}>{pangu.spacing(this.state.topic?.title)}</Link> <span className="chevron"> › </span> Review
|
||||
</div>
|
||||
<div class="cell topic_content markdown_body">
|
||||
<div className="cell topic_content markdown_body">
|
||||
<p>
|
||||
{i18next.t("topic:The new topic has been successfully created on the")} <Link to={`/go/${encodeURIComponent(this.state.topic?.nodeId)}`}>{this.state.topic?.nodeName}</Link>{" "}
|
||||
{i18next.t("topic:node, you can click on the title below to continue to view")}
|
||||
|
@ -588,9 +588,9 @@ class TopicBox extends React.Component {
|
|||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="cell topic_content markdown_body">
|
||||
<div className="cell topic_content markdown_body">
|
||||
<h3>{i18next.t("topic:Topic meta information")}</h3>
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||
<table cellPadding="0" cellSpacing="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="right" width="120">
|
||||
ID
|
||||
|
@ -643,7 +643,7 @@ class TopicBox extends React.Component {
|
|||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="cell topic_content markdown_body">
|
||||
<div className="cell topic_content markdown_body">
|
||||
<h3>{i18next.t("topic:Related resources")}</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
@ -669,7 +669,7 @@ class TopicBox extends React.Component {
|
|||
<meta name="keywords" content={this.state.topic?.tags} />
|
||||
<meta name="description" content={this.state.topic?.content} />
|
||||
</Helmet>
|
||||
<div className={`box ${this.state.topic.nodeId}`} style={{ borderBottom: "0px" }}>
|
||||
<div className={`box ${this.state.topic.nodeId}`} style={{borderBottom: "0px"}}>
|
||||
<div className={`header ${this.state.topic.nodeId}`}>
|
||||
<div className="fr">
|
||||
<Avatar username={this.state.topic?.author} size={pcBrowser ? "large" : "middle"} avatar={this.state.topic?.avatar} />
|
||||
|
@ -800,7 +800,7 @@ class TopicBox extends React.Component {
|
|||
/>
|
||||
{this.state.showTranslateBtn ? (
|
||||
<a href="javascript:void(0)" onClick={() => this.translateTopic()}>
|
||||
<p style={{ margin: 15 }}>
|
||||
<p style={{margin: 15}}>
|
||||
{this.state.translation.translated ? (
|
||||
<span>
|
||||
{`Translate from ${this.state.translation.from} by `}
|
||||
|
|
|
@ -18,7 +18,7 @@ import * as TopicBackend from "../backend/TopicBackend";
|
|||
import Avatar from "../Avatar";
|
||||
import "../node.css";
|
||||
import i18next from "i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
import {Link} from "react-router-dom";
|
||||
import UserLink from "../UserLink";
|
||||
|
||||
const pangu = require("pangu");
|
||||
|
@ -36,7 +36,7 @@ class TopicList extends React.Component {
|
|||
if (res?.status === "fail") {
|
||||
Setting.showMessage("error", res?.msg);
|
||||
}
|
||||
//goToLink(`/t/${topicId}?from=${encodeURIComponent(window.location.href)}`)
|
||||
// goToLink(`/t/${topicId}?from=${encodeURIComponent(window.location.href)}`)
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ class TopicList extends React.Component {
|
|||
</strong>{" "}
|
||||
• {topic.lastReplyTime === "" || this.props.timeStandard === "createdTime" ? Setting.getPrettyDate(topic.createdTime) : Setting.getPrettyDate(topic.lastReplyTime)}
|
||||
{topic.lastReplyUser === "" ? null : (
|
||||
<div style={{ display: "inline" }}>
|
||||
<div style={{display: "inline"}}>
|
||||
{" "}
|
||||
• {i18next.t("topic:last reply from")}{" "}
|
||||
<strong>
|
||||
|
@ -136,7 +136,7 @@ class TopicList extends React.Component {
|
|||
<span>
|
||||
{topic.lastReplyTime === "" || this.props.timeStandard === "createdTime" ? Setting.getPrettyDate(topic.createdTime) : Setting.getPrettyDate(topic.lastReplyTime)}
|
||||
{topic.lastReplyUser === "" ? null : (
|
||||
<div style={{ display: "inline" }}>
|
||||
<div style={{display: "inline"}}>
|
||||
{" "}
|
||||
• {i18next.t("topic:last reply from")}{" "}
|
||||
<strong>
|
||||
|
|
|
@ -13,20 +13,20 @@
|
|||
// limitations under the License.
|
||||
|
||||
export const Area_Code = [
|
||||
{ label: "+86 中国 CN", value: "+86" },
|
||||
{ label: "+1 美国 US", value: "+1" },
|
||||
{ label: "+81 日本 JP", value: "+81" },
|
||||
{ label: "+852 香港 HK", value: "+852" },
|
||||
{ label: "+886 台湾 TW", value: "+886" },
|
||||
{ label: "+65 新加坡 SG", value: "+65" },
|
||||
{ label: "+61 澳大利亚 AU", value: "+61" },
|
||||
{ label: "+1 加拿大 CA", value: "+1" },
|
||||
{ label: "+44 英国 GB", value: "+44" },
|
||||
{ label: "+49 德国 DE", value: "+49" },
|
||||
{ label: "+31 荷兰 NL", value: "+31" },
|
||||
{ label: "+32 比利时 BE", value: "+32" },
|
||||
{ label: "+33 法国 FR", value: "+33" },
|
||||
{ label: "+372 爱沙尼亚 EE", value: "+372" },
|
||||
{ label: "+64 新西兰 NZ", value: "+64" },
|
||||
{ label: "+82 韩国 KR", value: "+82" },
|
||||
{label: "+86 中国 CN", value: "+86"},
|
||||
{label: "+1 美国 US", value: "+1"},
|
||||
{label: "+81 日本 JP", value: "+81"},
|
||||
{label: "+852 香港 HK", value: "+852"},
|
||||
{label: "+886 台湾 TW", value: "+886"},
|
||||
{label: "+65 新加坡 SG", value: "+65"},
|
||||
{label: "+61 澳大利亚 AU", value: "+61"},
|
||||
{label: "+1 加拿大 CA", value: "+1"},
|
||||
{label: "+44 英国 GB", value: "+44"},
|
||||
{label: "+49 德国 DE", value: "+49"},
|
||||
{label: "+31 荷兰 NL", value: "+31"},
|
||||
{label: "+32 比利时 BE", value: "+32"},
|
||||
{label: "+33 法国 FR", value: "+33"},
|
||||
{label: "+372 爱沙尼亚 EE", value: "+372"},
|
||||
{label: "+64 新西兰 NZ", value: "+64"},
|
||||
{label: "+82 韩国 KR", value: "+82"},
|
||||
];
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from "react";
|
||||
import BraftEditor from "braft-editor";
|
||||
import "braft-editor/dist/index.css";
|
||||
import { myUploadFn } from "./Tools";
|
||||
import {myUploadFn} from "./Tools";
|
||||
|
||||
const _ = require("lodash");
|
||||
|
||||
|
@ -38,7 +38,7 @@ export default class Editor extends React.Component {
|
|||
}
|
||||
|
||||
handleEditorValueSend(text) {
|
||||
//call father compoents function
|
||||
// call father compoents function
|
||||
this.props.onBeforeChange(text);
|
||||
}
|
||||
|
||||
|
@ -51,12 +51,12 @@ export default class Editor extends React.Component {
|
|||
};
|
||||
|
||||
ValidateFn = (file) => {
|
||||
//file should be less than 6MB
|
||||
// file should be less than 6MB
|
||||
return file.size < 1024 * 1024 * 6;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { editorState, contentStyle, language } = this.state;
|
||||
const {editorState, contentStyle, language} = this.state;
|
||||
const UploadFn = myUploadFn;
|
||||
// add debounce function && decrease call fucntion times.
|
||||
return (
|
||||
|
|
|
@ -17,10 +17,10 @@ import * as Setting from "../Setting";
|
|||
import Avatar from "../Avatar";
|
||||
import * as FavoritesBackend from "../backend/FavoritesBackend";
|
||||
import * as NotificationBackend from "../backend/NotificationBackend";
|
||||
import { Link } from "react-router-dom";
|
||||
import {Link} from "react-router-dom";
|
||||
import "../node.css";
|
||||
import i18next from "i18next";
|
||||
import { scoreConverter } from "../main/Tools";
|
||||
import {scoreConverter} from "../main/Tools";
|
||||
import * as Conf from "../Conf";
|
||||
|
||||
class RightAccountBox extends React.Component {
|
||||
|
@ -39,7 +39,7 @@ class RightAccountBox extends React.Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
//this.getFavoriteNum();
|
||||
// this.getFavoriteNum();
|
||||
this.getUnreadNotificationNum();
|
||||
if (Conf.EnableNotificationAutoUpdate) {
|
||||
setInterval(() => {
|
||||
|
@ -87,7 +87,7 @@ class RightAccountBox extends React.Component {
|
|||
const avatar = this.props.account?.avatar;
|
||||
const tagline = this.props.account?.tagline;
|
||||
const favorites = this.props.favorites;
|
||||
const { goldCount, silverCount, bronzeCount } = scoreConverter(this.props.account.score);
|
||||
const {goldCount, silverCount, bronzeCount} = scoreConverter(this.props.account.score);
|
||||
|
||||
return (
|
||||
<div className={`box ${this.props.nodeId}`}>
|
||||
|
@ -100,7 +100,7 @@ class RightAccountBox extends React.Component {
|
|||
</td>
|
||||
<td width="10" valign="top" />
|
||||
<td width="auto" align="left">
|
||||
<div className="fr light-toggle" style={{ cursor: "pointer" }} onClick={Setting.toggleThemeMode}>
|
||||
<div className="fr light-toggle" style={{cursor: "pointer"}} onClick={Setting.toggleThemeMode}>
|
||||
<img src={Setting.getThemeBtnUrl()} align="absmiddle" height="10" alt="Light" />
|
||||
</div>
|
||||
<span className="bigger">
|
||||
|
@ -119,7 +119,7 @@ class RightAccountBox extends React.Component {
|
|||
<tbody>
|
||||
<tr>
|
||||
<td width="33%" align="center">
|
||||
<Link to="/my/nodes" className="dark" style={{ display: "block" }}>
|
||||
<Link to="/my/nodes" className="dark" style={{display: "block"}}>
|
||||
<span className="bigger">{favorites === undefined ? this.state.nodeFavoriteNum : favorites[3]}</span>
|
||||
<div className="sep3" />
|
||||
<span className="fade">{i18next.t("bar:Nodes")}</span>
|
||||
|
@ -133,14 +133,14 @@ class RightAccountBox extends React.Component {
|
|||
}}
|
||||
align="center"
|
||||
>
|
||||
<Link to="/my/topics" className="dark" style={{ display: "block" }}>
|
||||
<Link to="/my/topics" className="dark" style={{display: "block"}}>
|
||||
<span className="bigger">{favorites === undefined ? this.state.topicFavoriteNum + this.state.topicSubscribeNum : favorites[1] + favorites[4]}</span>
|
||||
<div className="sep3" />
|
||||
<span className="fade">{i18next.t("bar:Topics")}</span>
|
||||
</Link>
|
||||
</td>
|
||||
<td width="33%" align="center">
|
||||
<Link to="/my/following" className="dark" style={{ display: "block" }}>
|
||||
<Link to="/my/following" className="dark" style={{display: "block"}}>
|
||||
<span className="bigger">{favorites === undefined ? this.state.followingNum : favorites[2]}</span>
|
||||
<div className="sep3" />
|
||||
<span className="fade">{i18next.t("bar:Watch")}</span>
|
||||
|
@ -152,21 +152,21 @@ class RightAccountBox extends React.Component {
|
|||
</div>
|
||||
<div className={`cell ${this.props.nodeId}`} id="member-activity">
|
||||
<div className="member-activity-bar">
|
||||
<div className="member-activity-start" style={{ width: "80px" }} />
|
||||
<div className="member-activity-start" style={{width: "80px"}} />
|
||||
</div>
|
||||
</div>
|
||||
<div className={`cell ${this.props.nodeId}`} style={{ padding: "8px", lineHeight: "100%" }}>
|
||||
<div className={`cell ${this.props.nodeId}`} style={{padding: "8px", lineHeight: "100%"}}>
|
||||
<table cellPadding="0" cellSpacing="0" border="0" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="28">
|
||||
<Link to="/i">
|
||||
<img src={Setting.getStatic("/img/essentials/images.png")} width="28" border="0" style={{ verticalAlign: "bottom" }} />
|
||||
<img src={Setting.getStatic("/img/essentials/images.png")} width="28" border="0" style={{verticalAlign: "bottom"}} />
|
||||
</Link>
|
||||
</td>
|
||||
<td width="10"></td>
|
||||
<td width="auto" valign="middle" align="left">
|
||||
<a target="_blank" href={Setting.getMyResourcesUrl(this.props.account)}>
|
||||
<a target="_blank" href={Setting.getMyResourcesUrl(this.props.account)} rel="noreferrer">
|
||||
{i18next.t("bar:File library")}
|
||||
</a>
|
||||
</td>
|
||||
|
@ -174,13 +174,13 @@ class RightAccountBox extends React.Component {
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div className={`cell ${this.props.nodeId}`} style={{ padding: "8px", lineHeight: "100%" }}>
|
||||
<div className={`cell ${this.props.nodeId}`} style={{padding: "8px", lineHeight: "100%"}}>
|
||||
<table cellPadding="0" cellSpacing="0" border="0" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="28">
|
||||
<Link to="/new">
|
||||
<img src={Setting.getStatic("/img/essentials/compose.png")} width="28" border="0" style={{ verticalAlign: "bottom" }} />
|
||||
<img src={Setting.getStatic("/img/essentials/compose.png")} width="28" border="0" style={{verticalAlign: "bottom"}} />
|
||||
</Link>
|
||||
</td>
|
||||
<td width="10" />
|
||||
|
@ -194,7 +194,7 @@ class RightAccountBox extends React.Component {
|
|||
</table>
|
||||
</div>
|
||||
<div className="inner">
|
||||
<div className="fr" id="money" style={{ margin: "-3px 0px 0px 0px" }}>
|
||||
<div className="fr" id="money" style={{margin: "-3px 0px 0px 0px"}}>
|
||||
<Link to="/balance" className="balance_area">
|
||||
{goldCount !== 0 ? (
|
||||
<span>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
import React from "react";
|
||||
import * as BalanceBackend from "../backend/BalanceBackend";
|
||||
import * as Setting from "../Setting";
|
||||
import { Link } from "react-router-dom";
|
||||
import {Link} from "react-router-dom";
|
||||
import "./rightFavourite.css";
|
||||
import i18next from "i18next";
|
||||
|
||||
|
@ -50,7 +50,7 @@ class RightCheckinBonusBox extends React.Component {
|
|||
{Setting.PcBrowser ? <div className="sep20" /> : null}
|
||||
<div className={`box ${this.props.nodeId}`}>
|
||||
<div className={`inner ${this.props.nodeId}`}>
|
||||
<li className="fa fa-gift" style={{ color: "#f90" }}></li>
|
||||
<li className="fa fa-gift" style={{color: "#f90"}}></li>
|
||||
|
||||
<Link to="/mission/daily">{i18next.t("bar:Receive today's checkin bonus")}</Link>
|
||||
</div>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import {Link} from "react-router-dom";
|
||||
import * as BasicBackend from "../backend/BasicBackend";
|
||||
import * as PosterBackend from "../backend/PosterBackend";
|
||||
import i18next from "i18next";
|
||||
|
@ -70,10 +70,10 @@ class RightCommunityHealthBox extends React.Component {
|
|||
<div className="box">
|
||||
<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" }} />
|
||||
<img src={this.state.poster["picture_link"]} border="0" width="250" alt={this.state.poster["advertiser"]} style={{vertical: "bottom"}} />
|
||||
</a>
|
||||
</div>
|
||||
<div className="sidebar_compliance flex-one-row" style={{ display: "flex", justifyContent: "space-between" }}>
|
||||
<div className="sidebar_compliance flex-one-row" style={{display: "flex", justifyContent: "space-between"}}>
|
||||
<div>
|
||||
<a href={this.state.poster["link"]} target="_blank" rel="noopener noreferrer">
|
||||
{this.state.poster["advertiser"]}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
import React from "react";
|
||||
import * as Setting from "../Setting";
|
||||
import * as FavoritesBackend from "../backend/FavoritesBackend";
|
||||
import { Link } from "react-router-dom";
|
||||
import {Link} from "react-router-dom";
|
||||
import "./rightFavourite.css";
|
||||
import i18next from "i18next";
|
||||
|
||||
|
@ -49,7 +49,7 @@ class RightFavouriteBox extends React.Component {
|
|||
</Link>
|
||||
</div>
|
||||
<Link to={`/go/${encodeURIComponent(node?.id)}`} id="linkAvatar">
|
||||
<div id="avatar" style={{ backgroundImage: `url(${node?.image})` }} className="rightFavorite" />
|
||||
<div id="avatar" style={{backgroundImage: `url(${node?.image})`}} className="rightFavorite" />
|
||||
</Link>
|
||||
{" "}
|
||||
<linkTitle to={`/go/${encodeURIComponent(node?.id)}`} id="linkTitle">
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
import React from "react";
|
||||
import * as Setting from "../Setting";
|
||||
import * as NodeBackend from "../backend/NodeBackend";
|
||||
import { Link } from "react-router-dom";
|
||||
import {Link} from "react-router-dom";
|
||||
import i18next from "i18next";
|
||||
|
||||
class RightHotNodeBox extends React.Component {
|
||||
|
@ -64,7 +64,7 @@ class RightHotNodeBox extends React.Component {
|
|||
</div>
|
||||
<div className="inner">
|
||||
<a href="/index.xml" target="_blank" rel="noopener noreferrer">
|
||||
<img src={Setting.getStatic("/img/rss.png")} align="absmiddle" border="0" style={{ marginTop: "-3px" }} />
|
||||
<img src={Setting.getStatic("/img/rss.png")} align="absmiddle" border="0" style={{marginTop: "-3px"}} />
|
||||
</a>
|
||||
|
||||
<a href="/index.xml" target="_blank" rel="noopener noreferrer">
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
import React from "react";
|
||||
import * as TopicBackend from "../backend/TopicBackend";
|
||||
import { Link } from "react-router-dom";
|
||||
import {Link} from "react-router-dom";
|
||||
import Avatar from "../Avatar";
|
||||
import i18next from "i18next";
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
import React from "react";
|
||||
import * as NodeBackend from "../backend/NodeBackend";
|
||||
import { Link } from "react-router-dom";
|
||||
import {Link} from "react-router-dom";
|
||||
import "./rightFavourite.css";
|
||||
import i18next from "i18next";
|
||||
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
import React from "react";
|
||||
import * as Setting from "../Setting";
|
||||
import * as NodeBackend from "../backend/NodeBackend";
|
||||
import { withRouter, Link } from "react-router-dom";
|
||||
import {withRouter, Link} from "react-router-dom";
|
||||
import "../node.css";
|
||||
import "./rightNodeRelation.css";
|
||||
import Collapse, { Panel } from "rc-collapse";
|
||||
import Collapse, {Panel} from "rc-collapse";
|
||||
import i18next from "i18next";
|
||||
|
||||
class RightNodeBox extends React.Component {
|
||||
|
@ -66,7 +66,7 @@ class RightNodeBox extends React.Component {
|
|||
</Link>
|
||||
</div>
|
||||
<Link to={`/go/${encodeURIComponent(node?.id)}`} id="linkAvatar">
|
||||
<div id="avatar" style={{ backgroundImage: `url(${node?.image})` }} className="rightFavorite" />
|
||||
<div id="avatar" style={{backgroundImage: `url(${node?.image})`}} className="rightFavorite" />
|
||||
</Link>
|
||||
{" "}
|
||||
<Link to={`/go/${encodeURIComponent(node?.id)}`} id="linkTitle">
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import {withRouter} from "react-router-dom";
|
||||
import * as Conf from "../Conf";
|
||||
import i18next from "i18next";
|
||||
import * as Setting from "../Setting";
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
import React from "react";
|
||||
import i18next from "i18next";
|
||||
import { loadTheme, THEME_OPTIONS } from "../theme";
|
||||
import {loadTheme, THEME_OPTIONS} from "../theme";
|
||||
import "./rightTheme.css";
|
||||
|
||||
class RightThemeBox extends React.Component {
|
||||
|
@ -39,7 +39,7 @@ class RightThemeBox extends React.Component {
|
|||
}
|
||||
|
||||
loadThemeFile() {
|
||||
let { theme } = this.state;
|
||||
let {theme} = this.state;
|
||||
loadTheme(theme);
|
||||
}
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ function registerValidSW(swUrl, config) {
|
|||
function checkValidServiceWorker(swUrl, config) {
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl, {
|
||||
headers: { "Service-Worker": "script" },
|
||||
headers: {"Service-Worker": "script"},
|
||||
})
|
||||
.then((response) => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
|
|
201
web/yarn.lock
201
web/yarn.lock
|
@ -2572,6 +2572,17 @@ array-includes@^3.1.3, array-includes@^3.1.4:
|
|||
get-intrinsic "^1.1.1"
|
||||
is-string "^1.0.7"
|
||||
|
||||
array-includes@^3.1.5:
|
||||
version "3.1.5"
|
||||
resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.5.tgz#2c320010db8d31031fd2a5f6b3bbd4b1aad31bdb"
|
||||
integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.4"
|
||||
es-abstract "^1.19.5"
|
||||
get-intrinsic "^1.1.1"
|
||||
is-string "^1.0.7"
|
||||
|
||||
array-tree-filter@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/array-tree-filter/-/array-tree-filter-2.1.0.tgz#873ac00fec83749f255ac8dd083814b4f6329190"
|
||||
|
@ -2617,6 +2628,16 @@ array.prototype.flatmap@^1.2.5:
|
|||
define-properties "^1.1.3"
|
||||
es-abstract "^1.19.0"
|
||||
|
||||
array.prototype.flatmap@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz#a7e8ed4225f4788a70cd910abcf0791e76a5534f"
|
||||
integrity sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.19.2"
|
||||
es-shim-unscopables "^1.0.0"
|
||||
|
||||
arrify@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa"
|
||||
|
@ -4318,6 +4339,14 @@ define-properties@^1.1.2, define-properties@^1.1.3:
|
|||
dependencies:
|
||||
object-keys "^1.0.12"
|
||||
|
||||
define-properties@^1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1"
|
||||
integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==
|
||||
dependencies:
|
||||
has-property-descriptors "^1.0.0"
|
||||
object-keys "^1.1.1"
|
||||
|
||||
define-property@^0.2.5:
|
||||
version "0.2.5"
|
||||
resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116"
|
||||
|
@ -4764,6 +4793,42 @@ es-abstract@^1.17.2, es-abstract@^1.19.0, es-abstract@^1.19.1:
|
|||
string.prototype.trimstart "^1.0.4"
|
||||
unbox-primitive "^1.0.1"
|
||||
|
||||
es-abstract@^1.19.2, es-abstract@^1.19.5:
|
||||
version "1.20.1"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814"
|
||||
integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
es-to-primitive "^1.2.1"
|
||||
function-bind "^1.1.1"
|
||||
function.prototype.name "^1.1.5"
|
||||
get-intrinsic "^1.1.1"
|
||||
get-symbol-description "^1.0.0"
|
||||
has "^1.0.3"
|
||||
has-property-descriptors "^1.0.0"
|
||||
has-symbols "^1.0.3"
|
||||
internal-slot "^1.0.3"
|
||||
is-callable "^1.2.4"
|
||||
is-negative-zero "^2.0.2"
|
||||
is-regex "^1.1.4"
|
||||
is-shared-array-buffer "^1.0.2"
|
||||
is-string "^1.0.7"
|
||||
is-weakref "^1.0.2"
|
||||
object-inspect "^1.12.0"
|
||||
object-keys "^1.1.1"
|
||||
object.assign "^4.1.2"
|
||||
regexp.prototype.flags "^1.4.3"
|
||||
string.prototype.trimend "^1.0.5"
|
||||
string.prototype.trimstart "^1.0.5"
|
||||
unbox-primitive "^1.0.2"
|
||||
|
||||
es-shim-unscopables@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241"
|
||||
integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==
|
||||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
es-to-primitive@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
|
||||
|
@ -4936,6 +5001,26 @@ eslint-plugin-react@^7.21.5:
|
|||
semver "^6.3.0"
|
||||
string.prototype.matchall "^4.0.6"
|
||||
|
||||
eslint-plugin-react@^7.30.1:
|
||||
version "7.30.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.30.1.tgz#2be4ab23ce09b5949c6631413ba64b2810fd3e22"
|
||||
integrity sha512-NbEvI9jtqO46yJA3wcRF9Mo0lF9T/jhdHqhCHXiXtD+Zcb98812wvokjWpU7Q4QH5edo6dmqrukxVvWWXHlsUg==
|
||||
dependencies:
|
||||
array-includes "^3.1.5"
|
||||
array.prototype.flatmap "^1.3.0"
|
||||
doctrine "^2.1.0"
|
||||
estraverse "^5.3.0"
|
||||
jsx-ast-utils "^2.4.1 || ^3.0.0"
|
||||
minimatch "^3.1.2"
|
||||
object.entries "^1.1.5"
|
||||
object.fromentries "^2.0.5"
|
||||
object.hasown "^1.1.1"
|
||||
object.values "^1.1.5"
|
||||
prop-types "^15.8.1"
|
||||
resolve "^2.0.0-next.3"
|
||||
semver "^6.3.0"
|
||||
string.prototype.matchall "^4.0.7"
|
||||
|
||||
eslint-plugin-testing-library@^3.9.2:
|
||||
version "3.10.2"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-3.10.2.tgz#609ec2b0369da7cf2e6d9edff5da153cc31d87bd"
|
||||
|
@ -5602,11 +5687,26 @@ function-bind@^1.1.1:
|
|||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||
|
||||
function.prototype.name@^1.1.5:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621"
|
||||
integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.19.0"
|
||||
functions-have-names "^1.2.2"
|
||||
|
||||
functional-red-black-tree@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
|
||||
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
|
||||
|
||||
functions-have-names@^1.2.2:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
|
||||
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
|
||||
|
||||
gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2:
|
||||
version "1.0.0-beta.2"
|
||||
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
|
||||
|
@ -5786,6 +5886,11 @@ has-bigints@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113"
|
||||
integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==
|
||||
|
||||
has-bigints@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa"
|
||||
integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==
|
||||
|
||||
has-flag@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||
|
@ -5796,11 +5901,23 @@ has-flag@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
|
||||
|
||||
has-property-descriptors@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861"
|
||||
integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==
|
||||
dependencies:
|
||||
get-intrinsic "^1.1.1"
|
||||
|
||||
has-symbols@^1.0.1, has-symbols@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423"
|
||||
integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==
|
||||
|
||||
has-symbols@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
|
||||
integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
|
||||
|
||||
has-tostringtag@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25"
|
||||
|
@ -6559,7 +6676,7 @@ is-module@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
|
||||
integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=
|
||||
|
||||
is-negative-zero@^2.0.1:
|
||||
is-negative-zero@^2.0.1, is-negative-zero@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150"
|
||||
integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==
|
||||
|
@ -6657,6 +6774,13 @@ is-shared-array-buffer@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6"
|
||||
integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==
|
||||
|
||||
is-shared-array-buffer@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79"
|
||||
integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
|
||||
is-stream@^1.0.1, is-stream@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
|
@ -6691,7 +6815,7 @@ is-unicode-supported@^0.1.0:
|
|||
resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
|
||||
integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==
|
||||
|
||||
is-weakref@^1.0.1:
|
||||
is-weakref@^1.0.1, is-weakref@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2"
|
||||
integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==
|
||||
|
@ -8000,6 +8124,13 @@ minimatch@3.0.4, minimatch@^3.0.4:
|
|||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimatch@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
|
@ -8366,6 +8497,11 @@ object-inspect@^1.11.0, object-inspect@^1.9.0:
|
|||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0"
|
||||
integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==
|
||||
|
||||
object-inspect@^1.12.0:
|
||||
version "1.12.2"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
|
||||
integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==
|
||||
|
||||
object-is@^1.0.1:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac"
|
||||
|
@ -8436,6 +8572,14 @@ object.hasown@^1.1.0:
|
|||
define-properties "^1.1.3"
|
||||
es-abstract "^1.19.1"
|
||||
|
||||
object.hasown@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.1.tgz#ad1eecc60d03f49460600430d97f23882cf592a3"
|
||||
integrity sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==
|
||||
dependencies:
|
||||
define-properties "^1.1.4"
|
||||
es-abstract "^1.19.5"
|
||||
|
||||
object.pick@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747"
|
||||
|
@ -9702,7 +9846,7 @@ prompts@^2.0.1:
|
|||
kleur "^3.0.3"
|
||||
sisteransi "^1.0.5"
|
||||
|
||||
prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
|
||||
version "15.8.1"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||
|
@ -10695,6 +10839,15 @@ regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.1:
|
|||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
|
||||
regexp.prototype.flags@^1.4.1, regexp.prototype.flags@^1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac"
|
||||
integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
functions-have-names "^1.2.2"
|
||||
|
||||
regexpp@^3.1.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
|
||||
|
@ -11699,6 +11852,20 @@ string.prototype.matchall@^4.0.6:
|
|||
regexp.prototype.flags "^1.3.1"
|
||||
side-channel "^1.0.4"
|
||||
|
||||
string.prototype.matchall@^4.0.7:
|
||||
version "4.0.7"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz#8e6ecb0d8a1fb1fda470d81acecb2dba057a481d"
|
||||
integrity sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.19.1"
|
||||
get-intrinsic "^1.1.1"
|
||||
has-symbols "^1.0.3"
|
||||
internal-slot "^1.0.3"
|
||||
regexp.prototype.flags "^1.4.1"
|
||||
side-channel "^1.0.4"
|
||||
|
||||
string.prototype.trimend@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80"
|
||||
|
@ -11707,6 +11874,15 @@ string.prototype.trimend@^1.0.4:
|
|||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
|
||||
string.prototype.trimend@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0"
|
||||
integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.4"
|
||||
es-abstract "^1.19.5"
|
||||
|
||||
string.prototype.trimstart@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed"
|
||||
|
@ -11715,6 +11891,15 @@ string.prototype.trimstart@^1.0.4:
|
|||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
|
||||
string.prototype.trimstart@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef"
|
||||
integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.4"
|
||||
es-abstract "^1.19.5"
|
||||
|
||||
string_decoder@^1.0.0, string_decoder@^1.1.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
|
||||
|
@ -12292,6 +12477,16 @@ unbox-primitive@^1.0.1:
|
|||
has-symbols "^1.0.2"
|
||||
which-boxed-primitive "^1.0.2"
|
||||
|
||||
unbox-primitive@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
|
||||
integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
has-bigints "^1.0.2"
|
||||
has-symbols "^1.0.3"
|
||||
which-boxed-primitive "^1.0.2"
|
||||
|
||||
unherit@^1.0.4:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.3.tgz#6c9b503f2b41b262330c80e91c8614abdaa69c22"
|
||||
|
|
Loading…
Reference in New Issue