2019-06-25 22:36:34 +02:00
|
|
|
import {React, WebpackModules, Strings} from "modules";
|
2020-10-24 08:13:16 +02:00
|
|
|
import Modals from "../modals";
|
2019-05-28 23:27:25 +02:00
|
|
|
import SettingsTitle from "../settings/title";
|
|
|
|
import ServerCard from "./card";
|
2020-11-04 01:45:36 +01:00
|
|
|
import EmptyResults from "../blankslates/noresults";
|
2019-06-22 06:37:19 +02:00
|
|
|
import Connection from "../../structs/psconnection";
|
2019-06-29 06:47:56 +02:00
|
|
|
import Search from "../settings/components/search";
|
2020-10-28 05:18:44 +01:00
|
|
|
import Previous from "../icons/previous";
|
|
|
|
import Next from "../icons/next";
|
2020-10-24 08:13:16 +02:00
|
|
|
|
2019-06-19 05:09:49 +02:00
|
|
|
const SettingsView = WebpackModules.getByDisplayName("SettingsView");
|
2020-10-24 08:13:16 +02:00
|
|
|
const GuildActions = WebpackModules.getByProps("transitionToGuildSync");
|
|
|
|
const LayerManager = WebpackModules.getByProps("popLayer");
|
|
|
|
|
2020-10-28 05:18:44 +01:00
|
|
|
const EMPTY_RESULTS = {
|
|
|
|
servers: [],
|
|
|
|
size: 0,
|
|
|
|
total: 0,
|
2020-11-07 07:03:29 +01:00
|
|
|
page: 1,
|
|
|
|
numPages: 1
|
2020-10-28 05:18:44 +01:00
|
|
|
};
|
|
|
|
|
2019-06-10 05:40:35 +02:00
|
|
|
export default class PublicServers extends React.Component {
|
2019-05-28 20:19:48 +02:00
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
2019-06-10 05:40:35 +02:00
|
|
|
this.state = {
|
2020-10-24 08:13:16 +02:00
|
|
|
tab: "Featured",
|
2019-06-21 06:32:59 +02:00
|
|
|
query: "",
|
2019-06-10 05:40:35 +02:00
|
|
|
loading: true,
|
2019-06-21 06:32:59 +02:00
|
|
|
user: null,
|
2020-10-28 05:18:44 +01:00
|
|
|
results: Object.assign({}, EMPTY_RESULTS)
|
2019-06-10 05:40:35 +02:00
|
|
|
};
|
2019-06-21 06:32:59 +02:00
|
|
|
|
2020-10-24 08:13:16 +02:00
|
|
|
this.featured = [];
|
|
|
|
this.popular = [];
|
|
|
|
this.keywords = [];
|
|
|
|
|
|
|
|
this.changeTab = this.changeTab.bind(this);
|
2019-05-28 20:19:48 +02:00
|
|
|
this.searchKeyDown = this.searchKeyDown.bind(this);
|
|
|
|
this.connect = this.connect.bind(this);
|
2020-10-28 05:18:44 +01:00
|
|
|
this.loadPreviousPage = this.loadPreviousPage.bind(this);
|
2019-06-21 06:32:59 +02:00
|
|
|
this.loadNextPage = this.loadNextPage.bind(this);
|
2020-07-16 23:17:02 +02:00
|
|
|
this.join = this.join.bind(this);
|
2020-10-24 08:13:16 +02:00
|
|
|
this.navigateTo = this.navigateTo.bind(this);
|
2019-05-28 20:19:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
componentDidMount() {
|
2020-10-24 08:13:16 +02:00
|
|
|
this.getDashboard();
|
2019-05-28 20:19:48 +02:00
|
|
|
this.checkConnection();
|
2019-06-20 20:03:48 +02:00
|
|
|
}
|
2019-05-28 20:19:48 +02:00
|
|
|
|
2019-06-21 06:32:59 +02:00
|
|
|
async checkConnection() {
|
2019-06-22 06:37:19 +02:00
|
|
|
const userData = await Connection.checkConnection();
|
2020-10-24 08:13:16 +02:00
|
|
|
if (!userData) return this.setState({user: null});
|
2019-06-21 06:32:59 +02:00
|
|
|
this.setState({user: userData});
|
2020-10-24 08:13:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
async getDashboard() {
|
|
|
|
const dashboardData = await Connection.getDashboard();
|
|
|
|
|
2020-10-27 19:42:49 +01:00
|
|
|
this.featured = dashboardData.featured;
|
|
|
|
this.popular = dashboardData.popular;
|
|
|
|
this.keywords = dashboardData.keywords;
|
2020-10-24 08:13:16 +02:00
|
|
|
|
|
|
|
this.setState({loading: false});
|
|
|
|
this.changeTab(this.state.tab);
|
2020-10-27 19:42:49 +01:00
|
|
|
|
2020-10-28 05:18:44 +01:00
|
|
|
if (!this.keywords || !this.keywords.length) Modals.showConfirmationModal(Strings.PublicServers.connectionError, Strings.PublicServers.connectionErrorMessage);
|
2019-05-28 20:19:48 +02:00
|
|
|
}
|
|
|
|
|
2019-06-21 06:32:59 +02:00
|
|
|
async connect() {
|
2019-06-22 06:37:19 +02:00
|
|
|
await Connection.connect();
|
2019-06-21 06:32:59 +02:00
|
|
|
this.checkConnection();
|
|
|
|
}
|
2019-05-28 20:19:48 +02:00
|
|
|
|
2019-06-21 06:32:59 +02:00
|
|
|
searchKeyDown(e) {
|
|
|
|
if (this.state.loading || e.which !== 13) return;
|
2020-10-24 08:13:16 +02:00
|
|
|
const term = e.target.value;
|
|
|
|
if (this.state.tab == "Featured" || this.state.tab == "Popular") this.setState({tab: "All"}, () => this.search(term));
|
|
|
|
else this.search(term);
|
2019-06-21 06:32:59 +02:00
|
|
|
}
|
|
|
|
|
2020-10-28 05:18:44 +01:00
|
|
|
async search(term = "", page = 1) {
|
2019-06-21 06:32:59 +02:00
|
|
|
this.setState({query: term, loading: true});
|
2020-10-28 05:18:44 +01:00
|
|
|
const results = await Connection.search({term, keyword: this.state.tab == "All" || this.state.tab == "Featured" || this.state.tab == "Popular" ? "" : this.state.tab, page});
|
|
|
|
if (!results) return this.setState({results: Object.assign({}, EMPTY_RESULTS)});
|
2020-10-24 08:13:16 +02:00
|
|
|
|
2019-06-21 06:32:59 +02:00
|
|
|
this.setState({loading: false, results});
|
|
|
|
}
|
2019-05-28 20:19:48 +02:00
|
|
|
|
2020-10-24 08:13:16 +02:00
|
|
|
async changeTab(id) {
|
2019-06-21 06:32:59 +02:00
|
|
|
if (this.state.loading) return;
|
2020-10-24 08:13:16 +02:00
|
|
|
await new Promise(resolve => this.setState({tab: id}, resolve));
|
|
|
|
if (this.state.tab === "Featured" || this.state.tab == "Popular") {
|
2021-04-12 07:07:00 +02:00
|
|
|
const fakeResults = {
|
2020-10-24 08:13:16 +02:00
|
|
|
servers: this[this.state.tab.toLowerCase()],
|
|
|
|
size: this[this.state.tab.toLowerCase()].length,
|
|
|
|
total: this[this.state.tab.toLowerCase()].length,
|
2020-10-28 05:18:44 +01:00
|
|
|
page: 1,
|
|
|
|
numPages: 1
|
2021-04-12 07:07:00 +02:00
|
|
|
};
|
|
|
|
return this.setState({results: fakeResults});
|
2020-10-24 08:13:16 +02:00
|
|
|
}
|
|
|
|
|
2019-06-21 06:32:59 +02:00
|
|
|
this.search();
|
|
|
|
}
|
2019-06-19 05:09:49 +02:00
|
|
|
|
2020-10-28 05:18:44 +01:00
|
|
|
get hasPrevious() {return this.state.results.page > 1;}
|
|
|
|
get hasNext() {return this.state.results.page < this.state.results.numPages;}
|
|
|
|
|
|
|
|
loadPreviousPage() {
|
|
|
|
if (this.state.loading || !this.hasPrevious) return;
|
|
|
|
this.search(this.state.query, this.state.results.page - 1);
|
|
|
|
}
|
|
|
|
|
2019-06-21 06:32:59 +02:00
|
|
|
loadNextPage() {
|
2020-10-28 05:18:44 +01:00
|
|
|
if (this.state.loading || !this.hasNext) return;
|
|
|
|
this.search(this.state.query, this.state.results.page + 1);
|
2019-06-21 06:32:59 +02:00
|
|
|
}
|
2019-05-28 20:19:48 +02:00
|
|
|
|
2019-06-21 17:16:49 +02:00
|
|
|
async join(id, native = false) {
|
2020-10-24 08:13:16 +02:00
|
|
|
if (!this.state.user && !native) {
|
|
|
|
return Modals.showConfirmationModal(Strings.PublicServers.notConnected, Strings.PublicServers.connectionRequired, {
|
|
|
|
cancelText: Strings.Modals.nevermind,
|
|
|
|
confirmText: Strings.Modals.okay,
|
|
|
|
onConfirm: () => {
|
|
|
|
this.connect().then(() => Connection.join(id, native));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2019-06-22 06:37:19 +02:00
|
|
|
return await Connection.join(id, native);
|
2019-06-21 17:16:49 +02:00
|
|
|
}
|
|
|
|
|
2020-10-24 08:13:16 +02:00
|
|
|
navigateTo(id) {
|
|
|
|
if (GuildActions) GuildActions.transitionToGuildSync(id);
|
|
|
|
if (LayerManager) LayerManager.popLayer();
|
|
|
|
}
|
|
|
|
|
2019-06-21 06:32:59 +02:00
|
|
|
get searchBox() {
|
2020-10-28 05:18:44 +01:00
|
|
|
return <Search onKeyDown={this.searchKeyDown} className="bd-server-search" placeholder={`${Strings.PublicServers.search}...`} value={this.state.query} />;
|
2019-06-21 06:32:59 +02:00
|
|
|
}
|
2019-05-28 20:19:48 +02:00
|
|
|
|
2019-06-21 06:32:59 +02:00
|
|
|
get title() {
|
2019-06-25 22:36:34 +02:00
|
|
|
if (this.state.loading) return `${Strings.PublicServers.loading}...`;
|
2020-10-28 05:18:44 +01:00
|
|
|
if (this.state.query) {
|
|
|
|
const start = ((this.state.results.page - 1) * this.state.results.size) + 1;
|
|
|
|
const total = this.state.results.total;
|
|
|
|
const end = this.hasNext ? (start - 1) + this.state.results.size : total;
|
|
|
|
let title = Strings.PublicServers.results.format({start, end, total, category: this.state.tab});
|
|
|
|
if (this.state.query) title += " " + Strings.PublicServers.query.format({query: this.state.query});
|
|
|
|
return title;
|
|
|
|
}
|
|
|
|
return this.state.tab;
|
2019-06-21 06:32:59 +02:00
|
|
|
}
|
2019-05-28 20:19:48 +02:00
|
|
|
|
2019-06-21 06:32:59 +02:00
|
|
|
get content() {
|
2019-06-25 22:36:34 +02:00
|
|
|
const connectButton = this.state.user ? null : {title: Strings.PublicServers.connect, onClick: this.connect};
|
2019-06-21 06:32:59 +02:00
|
|
|
const servers = this.state.results.servers.map((server) => {
|
2020-10-24 08:13:16 +02:00
|
|
|
return React.createElement(ServerCard, {key: server.identifier, server: server, joined: Connection.hasJoined(server.identifier), join: this.join, navigateTo: this.navigateTo, defaultAvatar: Connection.getDefaultAvatar});
|
2019-05-28 20:19:48 +02:00
|
|
|
});
|
|
|
|
|
2020-10-28 05:18:44 +01:00
|
|
|
let content = React.createElement(EmptyResults);
|
2020-11-05 09:28:58 +01:00
|
|
|
if (this.state.loading) content = this.loadingScreen;
|
2020-10-28 05:18:44 +01:00
|
|
|
else if (this.state.results.total) content = React.createElement("div", {className: "bd-card-list"}, servers);
|
|
|
|
|
|
|
|
return [React.createElement(SettingsTitle, {text: this.title, button: connectButton}),
|
2020-11-03 02:47:08 +01:00
|
|
|
this.state.results.numPages > 1 && this.pagination,
|
2020-10-28 05:18:44 +01:00
|
|
|
content,
|
2020-11-07 07:03:29 +01:00
|
|
|
this.state.results.numPages > 1 && this.pagination
|
2020-10-28 05:18:44 +01:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2020-11-05 09:28:58 +01:00
|
|
|
get loadingScreen() {
|
|
|
|
return <div className="bd-card-list">
|
|
|
|
<div className="bd-placeholder-card"></div>
|
|
|
|
<div className="bd-placeholder-card"></div>
|
|
|
|
<div className="bd-placeholder-card"></div>
|
|
|
|
<div className="bd-placeholder-card"></div>
|
|
|
|
<div className="bd-placeholder-card"></div>
|
|
|
|
<div className="bd-placeholder-card"></div>
|
2020-11-07 07:03:29 +01:00
|
|
|
<div className="bd-placeholder-card"></div>
|
|
|
|
<div className="bd-placeholder-card"></div>
|
2020-10-28 05:18:44 +01:00
|
|
|
</div>;
|
|
|
|
}
|
|
|
|
|
|
|
|
get pagination() {
|
|
|
|
return React.createElement("div", {className: "bd-pagination"},
|
|
|
|
React.createElement("button", {type: "button", className: "bd-button bd-pagination-previous", disabled: !this.hasPrevious, onClick: this.loadPreviousPage}, <Previous />),
|
|
|
|
React.createElement("span", {className: "bd-pagination-info"}, Strings.PublicServers.pagination.format({page: this.state.results.page, count: this.state.results.numPages})),
|
|
|
|
React.createElement("button", {type: "button", className: "bd-button bd-pagination-next", disabled: !this.hasNext, onClick: this.loadNextPage}, <Next />)
|
|
|
|
);
|
2019-05-28 20:19:48 +02:00
|
|
|
}
|
|
|
|
|
2019-06-21 06:32:59 +02:00
|
|
|
get connection() {
|
|
|
|
const {user} = this.state;
|
|
|
|
if (!user) return React.createElement("div", {id: "bd-connection"});
|
|
|
|
return React.createElement("div", {id: "bd-connection"},
|
2019-06-25 22:36:34 +02:00
|
|
|
React.createElement("div", {className: "bd-footnote"}, Strings.PublicServers.connection.format(user)),
|
|
|
|
React.createElement("button", {type: "button", className: "bd-button bd-button-reconnect", onClick: this.connect}, Strings.PublicServers.reconnect)
|
2019-06-21 06:32:59 +02:00
|
|
|
);
|
2019-05-28 20:19:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2020-10-24 08:13:16 +02:00
|
|
|
const keywords = this.keywords.map(name => ({
|
2019-06-20 20:03:48 +02:00
|
|
|
section: name,
|
2019-06-20 04:19:34 +02:00
|
|
|
label: name,
|
2019-06-20 20:03:48 +02:00
|
|
|
element: () => this.content
|
|
|
|
})
|
|
|
|
);
|
2019-06-19 05:09:49 +02:00
|
|
|
return React.createElement(SettingsView, {
|
2019-06-21 06:32:59 +02:00
|
|
|
onClose: this.props.close,
|
2020-10-24 08:13:16 +02:00
|
|
|
onSetSection: this.changeTab,
|
|
|
|
section: this.state.tab,
|
2019-06-19 05:09:49 +02:00
|
|
|
sections: [
|
2019-06-25 22:36:34 +02:00
|
|
|
{section: "HEADER", label: Strings.PublicServers.search},
|
2019-06-21 06:32:59 +02:00
|
|
|
{section: "CUSTOM", element: () => this.searchBox},
|
2020-10-24 08:13:16 +02:00
|
|
|
{section: "DIVIDER"},
|
2019-06-25 22:36:34 +02:00
|
|
|
{section: "HEADER", label: Strings.PublicServers.categories},
|
2020-10-24 08:13:16 +02:00
|
|
|
{section: "All", label: "All", element: () => this.content},
|
|
|
|
{section: "Featured", label: "Featured", element: () => this.content},
|
|
|
|
{section: "Popular", label: "Popular", element: () => this.content},
|
|
|
|
{section: "DIVIDER"},
|
|
|
|
{section: "HEADER", label: Strings.PublicServers.keywords},
|
|
|
|
...keywords,
|
2019-06-20 20:03:48 +02:00
|
|
|
{section: "DIVIDER"},
|
2019-06-25 22:36:34 +02:00
|
|
|
{section: "HEADER", label: React.createElement("a", {href: "https://discordservers.com", target: "_blank"}, "DiscordServers.com")},
|
2019-06-20 20:03:48 +02:00
|
|
|
{section: "DIVIDER"},
|
|
|
|
{section: "CUSTOM", element: () => this.connection}
|
2019-06-19 05:09:49 +02:00
|
|
|
],
|
|
|
|
theme: "dark"
|
|
|
|
});
|
2019-06-20 20:03:48 +02:00
|
|
|
}
|
2019-05-28 20:55:07 +02:00
|
|
|
}
|