diff --git a/CHANGELOG.md b/CHANGELOG.md index cb51eb2..b3d2b2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added - It's now shown in the front-end if an instance wasn't crawled because of its robots.txt. +- You can now link directly to instances at e.g. /instance/mastodon.social. +- Instance details now have a link to the corresponding fediverse.network page. ### Changed ### Deprecated ### Removed diff --git a/backend/config/dev.exs b/backend/config/dev.exs index 1f3c48b..c58a4ca 100644 --- a/backend/config/dev.exs +++ b/backend/config/dev.exs @@ -68,6 +68,6 @@ config :backend, :crawler, config :backend, Backend.Scheduler, jobs: [ - # Every 15 minutes - {"*/15 * * * *", {Backend.Scheduler, :prune_crawls, [12, "hour"]}} + # Every 5 minutes + {"*/5 * * * *", {Backend.Scheduler, :prune_crawls, [12, "month"]}} ] diff --git a/frontend/README.md b/frontend/README.md index 0652bb2..64c27a2 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -3,6 +3,7 @@ The React frontend for [fediverse.space](https://fediverse.space). Written in Typescript. - Set the environment variable `REACT_APP_STAGING=true` when building to use the staging backend. +- React components are organized into atoms, molecules, organisms, and screens according to [Atomic Design](http://bradfrost.com/blog/post/atomic-web-design/). # Default README diff --git a/frontend/package.json b/frontend/package.json index a08508e..3b2b09b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -32,6 +32,7 @@ "@blueprintjs/icons": "^3.9.1", "@blueprintjs/select": "^3.9.0", "classnames": "^2.2.6", + "connected-react-router": "^6.5.2", "cross-fetch": "^3.0.4", "cytoscape": "^3.8.1", "cytoscape-popper": "^1.0.4", diff --git a/frontend/src/AppRouter.tsx b/frontend/src/AppRouter.tsx index e78cd2b..a709401 100644 --- a/frontend/src/AppRouter.tsx +++ b/frontend/src/AppRouter.tsx @@ -3,11 +3,12 @@ import * as React from "react"; import { Button, Classes, Dialog } from "@blueprintjs/core"; import { IconNames } from "@blueprintjs/icons"; -import { BrowserRouter, Route } from "react-router-dom"; -import { Nav } from "./components/Nav"; -import { AboutScreen } from "./components/screens/AboutScreen"; -import { GraphScreen } from "./components/screens/GraphScreen"; -import { DESKTOP_WIDTH_THRESHOLD } from "./constants"; +import { ConnectedRouter } from "connected-react-router"; +import { Route, RouteComponentProps } from "react-router-dom"; +import { Nav } from "./components/organisms/"; +import { AboutScreen, GraphScreen } from "./components/screens/"; +import { DESKTOP_WIDTH_THRESHOLD, IInstanceDomainPath, INSTANCE_DOMAIN_PATH } from "./constants"; +import { history } from "./index"; interface IAppLocalState { mobileDialogOpen: boolean; @@ -20,14 +21,19 @@ export class AppRouter extends React.Component<{}, IAppLocalState> { public render() { return ( - +
-
+ ); } diff --git a/frontend/src/components/ErrorState.tsx b/frontend/src/components/ErrorState.tsx deleted file mode 100644 index a16db4f..0000000 --- a/frontend/src/components/ErrorState.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { NonIdealState } from "@blueprintjs/core"; -import { IconNames } from "@blueprintjs/icons"; -import * as React from "react"; - -export const ErrorState: React.SFC = () => ; diff --git a/frontend/src/components/Graph.tsx b/frontend/src/components/Graph.tsx deleted file mode 100644 index f213a5f..0000000 --- a/frontend/src/components/Graph.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import { get } from "lodash"; -import * as React from "react"; -import { connect } from "react-redux"; - -import { Dispatch } from "redux"; -import { selectAndLoadInstance } from "../redux/actions"; -import { IAppState, IGraph } from "../redux/types"; -import Cytoscape from "./Cytoscape"; -import { ErrorState } from "./ErrorState"; -import { FloatingResetButton } from "./FloatingResetButton"; - -interface IGraphProps { - graph?: IGraph; - currentInstanceName: string | null; - selectAndLoadInstance: (name: string) => void; -} -class GraphImpl extends React.Component { - private cytoscapeComponent: React.RefObject; - - public constructor(props: IGraphProps) { - super(props); - this.cytoscapeComponent = React.createRef(); - } - - public render() { - if (!this.props.graph) { - return ; - } - - return ( -
- - -
- ); - } - - public componentDidUpdate(prevProps: IGraphProps) { - const { currentInstanceName } = this.props; - if (prevProps.currentInstanceName !== currentInstanceName) { - const cy = this.getCytoscape(); - cy.$id(prevProps.currentInstanceName).unselect(); - if (currentInstanceName) { - // Select instance - cy.$id(`${currentInstanceName}`).select(); - // Center it - const selected = cy.$id(currentInstanceName); - cy.center(selected); - } - } - } - - private resetGraphPosition = () => { - const cy = this.getCytoscape(); - const { currentInstanceName } = this.props; - if (currentInstanceName) { - cy.zoom({ - level: 0.2, - position: cy.$id(currentInstanceName).position() - }); - } else { - cy.zoom({ - level: 0.2, - position: { x: 0, y: 0 } - }); - } - }; - - private onInstanceSelect = (domain: string) => { - this.props.selectAndLoadInstance(domain); - }; - - private onInstanceDeselect = () => { - this.props.selectAndLoadInstance(""); - }; - - private getCytoscape = () => { - const cy = get(this.cytoscapeComponent, "current.cy"); - if (!cy) { - throw new Error("Expected cytoscape component but did not find one."); - } - return cy; - }; -} -const mapStateToProps = (state: IAppState) => ({ - currentInstanceName: state.currentInstance.currentInstanceName, - graph: state.data.graph -}); -const mapDispatchToProps = (dispatch: Dispatch) => ({ - selectAndLoadInstance: (instanceName: string) => dispatch(selectAndLoadInstance(instanceName) as any) -}); -const Graph = connect( - mapStateToProps, - mapDispatchToProps -)(GraphImpl); -export default Graph; diff --git a/frontend/src/components/Nav.tsx b/frontend/src/components/Nav.tsx deleted file mode 100644 index 509b028..0000000 --- a/frontend/src/components/Nav.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import * as React from "react"; - -import { Alignment, Button, Navbar } from "@blueprintjs/core"; -import { IconNames } from "@blueprintjs/icons"; - -import { Link } from "react-router-dom"; -import styled from "styled-components"; -import { InstanceSearch } from "./InstanceSearch"; - -interface INavState { - aboutIsOpen: boolean; -} -export class Nav extends React.Component<{}, INavState> { - constructor(props: any) { - super(props); - this.state = { aboutIsOpen: false }; - } - - public render() { - const StyledLink = styled(Link)` - color: white !important; - `; - return ( - - - fediverse.space - - -