summaryrefslogtreecommitdiffstats
path: root/ui/src
diff options
context:
space:
mode:
authorDessalines <tyhou13@gmx.com>2019-04-04 17:01:10 -0700
committerDessalines <tyhou13@gmx.com>2019-04-04 17:01:10 -0700
commit6310d9389ddaf80a1d8e0aecfb6cacbaf3b6b5b0 (patch)
tree9ac003ffbda8e4964ab9e4d42005995856a0ba1f /ui/src
parented688f9292f079e04fa5ad22b2505d8a45cb3d46 (diff)
Adding Iframe expand
- Adding Iframe Expand. Fixes #32 - Fix issue with table sorting. Fixes #33 - Changing all to h4s. Fixes #30
Diffstat (limited to 'ui/src')
-rw-r--r--ui/src/components/communities.tsx9
-rw-r--r--ui/src/components/create-community.tsx2
-rw-r--r--ui/src/components/create-post.tsx2
-rw-r--r--ui/src/components/login.tsx4
-rw-r--r--ui/src/components/post-listing.tsx25
-rw-r--r--ui/src/components/post.tsx2
-rw-r--r--ui/src/components/search.tsx205
-rw-r--r--ui/src/components/sidebar.tsx2
8 files changed, 35 insertions, 216 deletions
diff --git a/ui/src/components/communities.tsx b/ui/src/components/communities.tsx
index 921ef157..80953aaa 100644
--- a/ui/src/components/communities.tsx
+++ b/ui/src/components/communities.tsx
@@ -6,6 +6,8 @@ import { UserOperation, Community, Post as PostI, GetPostResponse, PostResponse,
import { WebSocketService, UserService } from '../services';
import { msgOp, hotRank,mdToHtml } from '../utils';
+declare const Sortable: any;
+
interface CommunitiesState {
communities: Array<Community>;
}
@@ -29,12 +31,17 @@ export class Communities extends Component<any, CommunitiesState> {
WebSocketService.Instance.listCommunities();
}
+ componentDidMount() {
+ let table = document.querySelector('#community_table');
+ Sortable.initTable(table);
+ }
+
render() {
return (
<div class="container-fluid">
<h4>Communities</h4>
<div class="table-responsive">
- <table class="table table-sm table-hover" data-sortable>
+ <table id="community_table" class="table table-sm table-hover" data-sortable>
<thead>
<tr>
<th>Name</th>
diff --git a/ui/src/components/create-community.tsx b/ui/src/components/create-community.tsx
index cd43c8fa..e98352a2 100644
--- a/ui/src/components/create-community.tsx
+++ b/ui/src/components/create-community.tsx
@@ -13,7 +13,7 @@ export class CreateCommunity extends Component<any, any> {
<div class="container">
<div class="row">
<div class="col-12 col-lg-6 mb-4">
- <h3>Create Forum</h3>
+ <h4>Create Forum</h4>
<CommunityForm onCreate={this.handleCommunityCreate}/>
</div>
</div>
diff --git a/ui/src/components/create-post.tsx b/ui/src/components/create-post.tsx
index 51e99211..784465a0 100644
--- a/ui/src/components/create-post.tsx
+++ b/ui/src/components/create-post.tsx
@@ -13,7 +13,7 @@ export class CreatePost extends Component<any, any> {
<div class="container">
<div class="row">
<div class="col-12 col-lg-6 mb-4">
- <h3>Create a Post</h3>
+ <h4>Create a Post</h4>
<PostForm onCreate={this.handlePostCreate}/>
</div>
</div>
diff --git a/ui/src/components/login.tsx b/ui/src/components/login.tsx
index cad4593e..30b0aabc 100644
--- a/ui/src/components/login.tsx
+++ b/ui/src/components/login.tsx
@@ -62,7 +62,7 @@ export class Login extends Component<any, State> {
return (
<div>
<form onSubmit={linkEvent(this, this.handleLoginSubmit)}>
- <h3>Login</h3>
+ <h4>Login</h4>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Email or Username</label>
<div class="col-sm-10">
@@ -88,7 +88,7 @@ export class Login extends Component<any, State> {
registerForm() {
return (
<form onSubmit={linkEvent(this, this.handleRegisterSubmit)}>
- <h3>Sign Up</h3>
+ <h4>Sign Up</h4>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Username</label>
<div class="col-sm-10">
diff --git a/ui/src/components/post-listing.tsx b/ui/src/components/post-listing.tsx
index cdb2fed3..348190fe 100644
--- a/ui/src/components/post-listing.tsx
+++ b/ui/src/components/post-listing.tsx
@@ -10,6 +10,7 @@ import { mdToHtml } from '../utils';
interface PostListingState {
showEdit: boolean;
+ iframeExpanded: boolean;
}
interface PostListingProps {
@@ -22,7 +23,8 @@ interface PostListingProps {
export class PostListing extends Component<PostListingProps, PostListingState> {
private emptyState: PostListingState = {
- showEdit: false
+ showEdit: false,
+ iframeExpanded: false
}
constructor(props, context) {
@@ -56,11 +58,21 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
</div>
<div className="ml-4">
{post.url
- ? <h5 className="mb-0">
+ ? <h4 className="mb-0">
<a className="text-white" href={post.url}>{post.name}</a>
<small><a className="ml-2 text-muted font-italic" href={post.url}>{(new URL(post.url)).hostname}</a></small>
- </h5>
- : <h5 className="mb-0"><Link className="text-white" to={`/post/${post.id}`}>{post.name}</Link></h5>
+ { !this.state.iframeExpanded
+ ? <span class="pointer ml-2 text-muted small" title="Expand here" onClick={linkEvent(this, this.handleIframeExpandClick)}>+</span>
+ :
+ <span>
+ <span class="pointer ml-2 text-muted small" onClick={linkEvent(this, this.handleIframeExpandClick)}>-</span>
+ <div class="embed-responsive embed-responsive-1by1">
+ <iframe scrolling="yes" class="embed-responsive-item" src={post.url}></iframe>
+ </div>
+ </span>
+ }
+ </h4>
+ : <h4 className="mb-0"><Link className="text-white" to={`/post/${post.id}`}>{post.name}</Link></h4>
}
</div>
<div className="details ml-4 mb-1">
@@ -149,5 +161,10 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
};
WebSocketService.Instance.editPost(deleteForm);
}
+
+ handleIframeExpandClick(i: PostListing, event) {
+ i.state.iframeExpanded = !i.state.iframeExpanded;
+ i.setState(i.state);
+ }
}
diff --git a/ui/src/components/post.tsx b/ui/src/components/post.tsx
index 0efa254a..0075e9df 100644
--- a/ui/src/components/post.tsx
+++ b/ui/src/components/post.tsx
@@ -109,7 +109,7 @@ export class Post extends Component<any, PostState> {
newComments() {
return (
<div class="sticky-top">
- <h5>New Comments</h5>
+ <h4>New Comments</h4>
{this.state.comments.map(comment =>
<CommentNodes nodes={[{comment: comment}]} noIndent />
)}
diff --git a/ui/src/components/search.tsx b/ui/src/components/search.tsx
deleted file mode 100644
index 080761f9..00000000
--- a/ui/src/components/search.tsx
+++ /dev/null
@@ -1,205 +0,0 @@
-import { Component, linkEvent } from 'inferno';
-import * as moment from 'moment';
-
-import { endpoint } from '../env';
-import { SearchParams, Results, Torrent } from '../interfaces';
-import { humanFileSize, magnetLink, getFileName } from '../utils';
-
-interface State {
- results: Results;
- searchParams: SearchParams;
- searching: Boolean;
-}
-
-export class Search extends Component<any, State> {
-
- state: State = {
- results: {
- torrents: []
- },
- searchParams: {
- q: "",
- page: 1,
- type_: 'torrent'
- },
- searching: false
- };
-
- constructor(props, context) {
- super(props, context);
- }
-
- componentDidMount() {
- this.state.searchParams = {
- page: Number(this.props.match.params.page),
- q: this.props.match.params.q,
- type_: this.props.match.params.type_
- }
- this.search();
- }
-
- // Re-do search if the props have changed
- componentDidUpdate(lastProps, lastState, snapshot) {
- if (lastProps.match && lastProps.match.params !== this.props.match.params) {
- this.state.searchParams = {
- page: Number(this.props.match.params.page),
- q: this.props.match.params.q,
- type_: this.props.match.params.type_
- }
- this.search();
- }
-
- }
-
- search() {
- if (!!this.state.searchParams.q) {
- this.setState({ searching: true, results: { torrents: [] } });
- this.fetchData(this.state.searchParams)
- .then(torrents => {
- if (!!torrents) {
- this.setState({
- results: {
- torrents: torrents
- }
- });
- }
- }).catch(error => {
- console.error('request failed', error);
- }).then(() => this.setState({ searching: false }));
- } else {
- this.setState({ results: { torrents: [] } });
- }
- }
-
- fetchData(searchParams: SearchParams): Promise<Array<Torrent>> {
- let q = encodeURI(searchParams.q);
- return fetch(`${endpoint}/service/search?q=${q}&page=${searchParams.page}&type_=${searchParams.type_}`)
- .then(data => data.json());
- }
-
- render() {
- return (
- <div>
- {
- this.state.searching ?
- this.spinner() : this.state.results.torrents[0] ?
- this.torrentsTable()
- : this.noResults()
- }
- </div>
- );
- }
-
- spinner() {
- return (
- <div class="text-center m-5 p-5">
- <svg class="icon icon-spinner spinner"><use xlinkHref="#icon-spinner"></use></svg>
- </div>
- );
- }
-
- noResults() {
- return (
- <div class="text-center m-5 p-5">
- <h1>No Results</h1>
- </div>
- )
- }
-
- torrentsTable() {
- return (
- <div>
- <table class="table table-fixed table-hover table-sm table-striped table-hover-purple table-padding">
- <thead>
- <tr>
- <th class="search-name-col">Name</th>
- <th class="text-right">Size</th>
- <th class="text-right">Seeds</th>
- <th class="text-right d-none d-md-table-cell">Leeches</th>
- <th class="text-right d-none d-md-table-cell">Created</th>
- <th></th>
- </tr>
- </thead>
- <tbody>
- {this.state.results.torrents.map(torrent => (
- <tr>
- { !torrent.name ? (
- <td className="path_column">
- <a class="text-body"
- href={magnetLink(torrent.infohash, torrent.path, torrent.index_)}>
- {getFileName(torrent.path)}
- </a>
- </td>
- ) : (
- <td class="search-name-cell">
- <a class="text-body"
- href={magnetLink(torrent.infohash, torrent.name, torrent.index_)}>
- {torrent.name}
- </a>
- </td>
- )}
- <td class="text-right text-muted">{humanFileSize(torrent.size_bytes, true)}</td>
- <td class="text-right text-success">
- <svg class="icon icon-arrow-up d-none d-sm-inline mr-1"><use xlinkHref="#icon-arrow-up"></use></svg>
- {torrent.seeders}
- </td>
- <td class="text-right text-danger d-none d-md-table-cell">
- <svg class="icon icon-arrow-down mr-1"><use xlinkHref="#icon-arrow-down"></use></svg>
- {torrent.leechers}
- </td>
- <td class="text-right text-muted d-none d-md-table-cell"
- data-balloon={`Scraped ${moment(torrent.scraped_date * 1000).fromNow()}`}
- data-balloon-pos="down">
- {moment(torrent.created_unix * 1000).fromNow()}
- </td>
- <td class="text-right">
- <a class="btn btn-sm no-outline p-1"
- href={magnetLink(torrent.infohash, (torrent.name) ? torrent.name : torrent.path, torrent.index_)}
- data-balloon="Magnet link"
- data-balloon-pos="left">
- <svg class="icon icon-magnet"><use xlinkHref="#icon-magnet"></use></svg>
- </a>
- <a class="btn btn-sm no-outline p-1 d-none d-sm-inline"
- href={`https://gitlab.com/dessalines/torrents.csv/issues/new?issue[title]=Report%20Torrent%20infohash%20${torrent.infohash}`}
- target="_blank"
- data-balloon="Report Torrent"
- data-balloon-pos="left">
- <svg class="icon icon-flag"><use xlinkHref="#icon-flag"></use></svg>
- </a>
- </td>
- </tr>
- ))}
- </tbody>
- </table>
- {this.paginator()}
- </div>
- );
- }
-
- paginator() {
- return (
- <nav>
- <ul class="pagination justify-content-center">
- <li className={(this.state.searchParams.page == 1) ? "page-item disabled" : "page-item"}>
- <button class="page-link"
- onClick={linkEvent({ i: this, nextPage: false }, this.switchPage)}>
- Previous
- </button>
- </li>
- <li class="page-item">
- <button class="page-link"
- onClick={linkEvent({ i: this, nextPage: true }, this.switchPage)}>
- Next
- </button>
- </li>
- </ul>
- </nav>
- );
- }
-
- switchPage(a: { i: Search, nextPage: boolean }, event) {
- let newSearch = a.i.state.searchParams;
- newSearch.page += (a.nextPage) ? 1 : -1;
- a.i.props.history.push(`/search/${newSearch.type_}/${newSearch.q}/${newSearch.page}`);
- }
-}
diff --git a/ui/src/components/sidebar.tsx b/ui/src/components/sidebar.tsx
index 90c35924..ec64e518 100644
--- a/ui/src/components/sidebar.tsx
+++ b/ui/src/components/sidebar.tsx
@@ -68,7 +68,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
</div>
}
<hr />
- <h5>Moderators</h5>
+ <h4>Moderators</h4>
{this.props.moderators.map(mod =>
<Link to={`/user/${mod.user_id}`}>{mod.user_name}</Link>
)}