add about page

This commit is contained in:
Tao Bojlen 2018-09-03 13:36:14 +02:00
parent 62ed809ee0
commit 4a60a3f9b0
4 changed files with 119 additions and 12 deletions

View file

@ -55,7 +55,6 @@ class AppImpl extends React.Component<IAppProps> {
const description = `There are ${numInstances} known instances, so loading the graph might take a little while. Ready?` const description = `There are ${numInstances} known instances, so loading the graph might take a little while. Ready?`
return ( return (
<NonIdealState <NonIdealState
className="fediverse-welcome"
icon={IconNames.GLOBE_NETWORK} icon={IconNames.GLOBE_NETWORK}
title="Welcome to fediverse.space!" title="Welcome to fediverse.space!"
description={description} description={description}
@ -67,7 +66,6 @@ class AppImpl extends React.Component<IAppProps> {
private loadingState = (title?: string) => { private loadingState = (title?: string) => {
return ( return (
<NonIdealState <NonIdealState
className="fediverse-welcome"
icon={<Spinner />} icon={<Spinner />}
title={title || "Loading..."} title={title || "Loading..."}
/> />

View file

@ -1,15 +1,40 @@
import * as React from 'react'; import * as React from 'react';
import { Alignment, Navbar } from '@blueprintjs/core'; import { Alignment, Button, Classes, Dialog, Icon, Navbar } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
import { InstanceSearch } from './InstanceSearch'; import { InstanceSearch } from './InstanceSearch';
export class Nav extends React.Component { interface INavState {
aboutIsOpen: boolean;
}
export class Nav extends React.Component<{}, INavState> {
constructor(props: any) {
super(props);
this.state = {aboutIsOpen: false};
}
public render() { public render() {
return ( return (
<Navbar> <Navbar fixedToTop={true}>
<Navbar.Group align={Alignment.LEFT}> <Navbar.Group align={Alignment.LEFT}>
<Navbar.Heading>fediverse.space</Navbar.Heading> <Navbar.Heading>
<Icon
icon={IconNames.GLOBE_NETWORK}
iconSize={Icon.SIZE_LARGE}
className="fediverse-heading-icon"
/>
fediverse.space
</Navbar.Heading>
<Navbar.Divider />
<Button
icon={IconNames.INFO_SIGN}
text="About"
minimal={true}
onClick={this.handleAboutOpen}
/>
{this.renderAboutDialog()}
{/* <Button {/* <Button
icon={<Icon icon={IconNames.GLOBE_NETWORK} />} icon={<Icon icon={IconNames.GLOBE_NETWORK} />}
text="Network" text="Network"
@ -26,5 +51,85 @@ export class Nav extends React.Component {
</Navbar.Group> </Navbar.Group>
</Navbar> </Navbar>
) )
} }
private renderAboutDialog = () => {
return (
<Dialog
icon={IconNames.INFO_SIGN}
title="About"
onClose={this.handleAboutClose}
isOpen={this.state.aboutIsOpen}
className={Classes.DARK + ' fediverse-about-dialog'}
>
<div className={Classes.DIALOG_BODY}>
<p className={Classes.RUNNING_TEXT}>
fediverse.space is a tool to visualize networks and communities on the
{' '}<a href="https://en.wikipedia.org/wiki/Fediverse" target="_blank">fediverse</a>.
It works by scraping every instance it can find and aggregating statistics on communication
between these.
</p>
<h2>FAQ</h2>
<h4>Why can't I see details about my instance?</h4>
<p className={Classes.RUNNING_TEXT}>
Currently, fediverse.space only supports Mastodon and Pleroma instances. In addition, instances
with 5 or fewer users won't be scraped -- it's a tool for understanding communities, not
individuals.
</p>
<h4>How do you calculate the strength of relationships between instances?</h4>
<p className={Classes.RUNNING_TEXT}>
fediverse.space scrapes the last 2000 statuses from within the last month on the public
timeline of each instance. It looks at the ratio of
<code>mentions of an instance / total statuses</code>.
It uses a ratio rather than an absolute number of mentions to reflect that smaller instances
can play a large role in a community.
</p>
<h2>Credits</h2>
<p className={Classes.RUNNING_TEXT}>
This site is inspired by several other sites in the same vein:
<ul className={Classes.LIST}>
<li><a href="https://the-federation.info/" target="_blank">the-federation.info</a></li>
<li><a href="http://fediverse.network/" target="_blank">fediverse.network</a></li>
<li>
<a
href="https://lucahammer.at/vis/fediverse/2018-08-30-mastoverse_hashtags/"
target="_blank"
>
Mastodon hashtag network
</a>
{' by '}
<a href="https://vis.social/web/statuses/100634284168959187" target="_blank">
@Luca@vis.social
</a>
</li>
</ul>
fediverse.space is made by{' '}
<a href="https://sunbeam.city/@tao" target="_blank">@tao@sunbeam.city</a>.
The source code is available on{' '}
<a href="https://github.com/brortao/fediverse.space" target="_blank">GitHub</a>;{' '}
issues and pull requests are welcome!
</p>
</div>
<div className={Classes.DIALOG_FOOTER}>
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
<Button
icon={IconNames.THUMBS_UP}
text="OK!"
onClick={this.handleAboutClose}
/>
</div>
</div>
</Dialog>
)
}
private handleAboutOpen = () => {
this.setState({aboutIsOpen: true});
}
private handleAboutClose = () => {
this.setState({aboutIsOpen: false});
}
} }

View file

@ -1,14 +1,18 @@
html, body { html, body {
margin: 0; margin: 0;
padding: 0; padding: 50px 0 0 0;
font-family: sans-serif; font-family: sans-serif;
background-color: #30404D; background-color: #30404D;
height: 100%; height: 100%;
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,Icons16,sans-serif; font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,Icons16,sans-serif;
} }
.fediverse-welcome { .fediverse-heading-icon {
margin-top: 50px; margin-right: 8px;
}
.fediverse-about-dialog {
top: 100px;
} }
.fediverse-instance-search-popover { .fediverse-instance-search-popover {

View file

@ -30,7 +30,7 @@ from scraper.management.commands._util import require_lock, InvalidResponseExcep
# TODO: use the /api/v1/server/followers and /api/v1/server/following endpoints in peertube instances # TODO: use the /api/v1/server/followers and /api/v1/server/following endpoints in peertube instances
SEED = 'mastodon.social' SEED = 'mastodon.social'
TIMEOUT = 10 # seconds TIMEOUT = 20 # seconds
NUM_THREADS = 64 NUM_THREADS = 64
PERSONAL_INSTANCE_THRESHOLD = 5 # instances with <= this many users won't be scraped PERSONAL_INSTANCE_THRESHOLD = 5 # instances with <= this many users won't be scraped
@ -69,7 +69,7 @@ class Command(BaseCommand):
def get_statuses(instance_name: str): def get_statuses(instance_name: str):
"""Collect all statuses that mention users on other instances""" """Collect all statuses that mention users on other instances"""
mentions = [] mentions = []
datetime_threshold = datetime.now(timezone.utc) - timedelta(weeks=1) datetime_threshold = datetime.now(timezone.utc) - timedelta(months=1)
statuses_seen = 0 statuses_seen = 0
# We'll ask for 1000 statuses, but Mastodon never returns more than 40. Some Pleroma instances will ignore # We'll ask for 1000 statuses, but Mastodon never returns more than 40. Some Pleroma instances will ignore
# the limit and return 20. # the limit and return 20.