Remove glowie stuff

rdrama
MarseyLivesMatter 2022-07-28 12:26:58 -04:00 committed by GitHub
parent 52bd955d73
commit 4e69e7be91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 259 additions and 124 deletions

View File

@ -1,19 +1,19 @@
import * as React from 'react'; import * as React from "react";
import DatePicker from 'react-datepicker' import DatePicker from "react-datepicker";
import { PushshiftAPI, SearchSettings, SearchType } from './api' import { PushshiftAPI, SearchSettings, SearchType } from "./api";
import { GithubLink } from './github-link' import { GithubLink } from "./github-link";
import "react-datepicker/dist/react-datepicker.css"; import "react-datepicker/dist/react-datepicker.css";
import { RandomLink } from './random-link'; import { RandomLink } from "./random-link";
interface AppState extends SearchSettings { interface AppState extends SearchSettings {
error: string, error: string;
errorTime: Date, errorTime: Date;
searching: boolean, searching: boolean;
comments: Array<any>, comments: Array<any>;
posts: Array<any>, posts: Array<any>;
moreing: boolean, moreing: boolean;
lastUrl: string, lastUrl: string;
} }
/** Main class for Reddit Search */ /** Main class for Reddit Search */
@ -62,7 +62,7 @@ export class App extends React.Component<{}, AppState> {
componentDidMount() { componentDidMount() {
// Add hash change event listener // Add hash change event listener
window.addEventListener("hashchange", e => { window.addEventListener("hashchange", (e) => {
if (this.updatedHash) { if (this.updatedHash) {
this.updatedHash = false; this.updatedHash = false;
return; return;
@ -110,15 +110,15 @@ export class App extends React.Component<{}, AppState> {
setError = (error: string) => { setError = (error: string) => {
this.setState({ error: error, errorTime: new Date() }); this.setState({ error: error, errorTime: new Date() });
} };
handleAuthorChange = (e: React.ChangeEvent<HTMLInputElement>) => { handleAuthorChange = (e: React.ChangeEvent<HTMLInputElement>) => {
this.setState({ author: e.target.value }); this.setState({ author: e.target.value });
} };
handleSubredditChange = (e: React.ChangeEvent<HTMLInputElement>) => { handleSubredditChange = (e: React.ChangeEvent<HTMLInputElement>) => {
this.setState({ subreddit: e.target.value }); this.setState({ subreddit: e.target.value });
} };
handleSearchTypeChange = (e: React.ChangeEvent<HTMLSelectElement>) => { handleSearchTypeChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
if (e.target.value === "Comments") { if (e.target.value === "Comments") {
@ -128,7 +128,7 @@ export class App extends React.Component<{}, AppState> {
} else { } else {
this.setError(e.target.value + " is not a valid search type"); this.setError(e.target.value + " is not a valid search type");
} }
} };
handleResultSizeChange = (e: React.ChangeEvent<HTMLInputElement>) => { handleResultSizeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
let count: number = parseInt(e.target.value); let count: number = parseInt(e.target.value);
@ -136,26 +136,31 @@ export class App extends React.Component<{}, AppState> {
return; return;
} }
this.setState({ resultSize: count }); this.setState({ resultSize: count });
} };
handleFilterChange = (e: React.ChangeEvent<HTMLInputElement>) => { handleFilterChange = (e: React.ChangeEvent<HTMLInputElement>) => {
this.setState({ filter: e.target.value }); this.setState({ filter: e.target.value });
} };
handleAfterDateChange = (date: Date) => { handleAfterDateChange = (date: Date) => {
this.setState({ after: date }); this.setState({ after: date });
} };
handleBeforeDateChange = (date: Date) => { handleBeforeDateChange = (date: Date) => {
this.setState({ before: date }); this.setState({ before: date });
} };
handleQueryChange = (e: React.ChangeEvent<HTMLInputElement>) => { handleQueryChange = (e: React.ChangeEvent<HTMLInputElement>) => {
this.setState({ query: e.target.value }); this.setState({ query: e.target.value });
} };
doSearch = async () => { doSearch = async () => {
this.setState({ error: null, comments: null, posts: null, searching: true }); this.setState({
error: null,
comments: null,
posts: null,
searching: true,
});
this.lastSearch = { ...this.state }; this.lastSearch = { ...this.state };
// Update location.hash // Update location.hash
@ -187,40 +192,58 @@ export class App extends React.Component<{}, AppState> {
this.setState({ searching: false }); this.setState({ searching: false });
this.setError(String(err)); this.setError(String(err));
} }
} };
/** Handle the main form being submitted */ /** Handle the main form being submitted */
searchSubmit = async (e) => { searchSubmit = async (e) => {
// Update state // Update state
e.preventDefault(); e.preventDefault();
this.doSearch(); this.doSearch();
} };
/** Handle the more button being clicked. */ /** Handle the more button being clicked. */
handleMoreClick = async (e) => { handleMoreClick = async (e) => {
this.setState({ error: null, moreing: true }); this.setState({ error: null, moreing: true });
if (this.state.comments && this.state.comments.length > 0) { if (this.state.comments && this.state.comments.length > 0) {
this.lastSearch.before = new Date(this.state.comments[this.state.comments.length - 1].created_utc * 1000); this.lastSearch.before = new Date(
this.state.comments[this.state.comments.length - 1].created_utc * 1000
);
} else if (this.state.posts && this.state.posts.length > 0) { } else if (this.state.posts && this.state.posts.length > 0) {
this.lastSearch.before = new Date(this.state.posts[this.state.posts.length - 1].created_utc * 1000); this.lastSearch.before = new Date(
this.state.posts[this.state.posts.length - 1].created_utc * 1000
);
} }
let url = this.api.get_url(this.lastSearch); let url = this.api.get_url(this.lastSearch);
let data = await this.api.query(url); let data = await this.api.query(url);
if (this.lastSearch.searchFor == SearchType.Comments && data.data) { if (this.lastSearch.searchFor == SearchType.Comments && data.data) {
this.setState({ comments: this.state.comments.concat(data.data), moreing: false }); this.setState({
comments: this.state.comments.concat(data.data),
moreing: false,
});
} else if (this.lastSearch.searchFor == SearchType.Posts && data.data) { } else if (this.lastSearch.searchFor == SearchType.Posts && data.data) {
this.setState({ posts: this.state.posts.concat(data.data), moreing: false }); this.setState({
posts: this.state.posts.concat(data.data),
moreing: false,
});
} else { } else {
this.setState({ moreing: false }); this.setState({ moreing: false });
} }
} };
/** Render the app /** Render the app
* @return {React.ReactNode} The react node for the app * @return {React.ReactNode} The react node for the app
*/ */
render(): React.ReactNode { render(): React.ReactNode {
// Not tidy at all but it's a one page app so WONTFIX // Not tidy at all but it's a one page app so WONTFIX
let moreButton = <button type="button" onClick={this.handleMoreClick} className="bg-red-900 hover:bg-red-800 font-bold py-2 mb-1">{this.state.moreing ? "Moreing..." : "More"}</button>; let moreButton = (
<button
type="button"
onClick={this.handleMoreClick}
className="bg-red-900 hover:bg-red-800 font-bold py-2 mb-1"
>
{this.state.moreing ? "Moreing..." : "More"}
</button>
);
let linkClass = "text-blue-400 hover:text-blue-600"; let linkClass = "text-blue-400 hover:text-blue-600";
let content; let content;
let resultCount; let resultCount;
@ -236,22 +259,32 @@ export class App extends React.Component<{}, AppState> {
if (comment.permalink) { if (comment.permalink) {
permalink = comment.permalink; permalink = comment.permalink;
} else { } else {
permalink = `/comments/${comment.link_id.split('_')[1]}/_/${comment.id}/` permalink = `/comments/${comment.link_id.split("_")[1]}/_/${
comment.id
}/`;
} }
return <div className="bg-gray-900 px-1 mb-1" key={comment.id}> return (
<div className="flex"> <div className="bg-gray-900 px-1 mb-1" key={comment.id}>
<a href={`https://reddit.com/r/${comment.subreddit}`}> <div className="flex">
<div className="text-sm text-red-500">/r/{comment.subreddit}</div> <a href={`https://reddit.com/r/${comment.subreddit}`}>
<div className="text-sm text-red-500">
/r/{comment.subreddit}
</div>
</a>
<a href={`https://reddit.com/u/${comment.author}`}>
<div className="text-sm text-red-500 ml-2">
/u/{comment.author}
</div>
</a>
<div className="text-sm text-red-500 ml-auto">
{new Date(comment.created_utc * 1000).toLocaleString()}
</div>
</div>
<a href={`https://reddit.com${permalink}?context=999`}>
<div className="whitespace-pre-wrap">{comment.body}</div>
</a> </a>
<a href={`https://reddit.com/u/${comment.author}`}>
<div className="text-sm text-red-500 ml-2">/u/{comment.author}</div>
</a>
<div className="text-sm text-red-500 ml-auto">{new Date(comment.created_utc * 1000).toLocaleString()}</div>
</div> </div>
<a href={`https://reddit.com${permalink}?context=999`}> );
<div className="whitespace-pre-wrap">{comment.body}</div>
</a>
</div>
}); });
} else if (this.state.posts && this.state.posts.length > 0) { } else if (this.state.posts && this.state.posts.length > 0) {
resultCount = this.state.posts.length; resultCount = this.state.posts.length;
@ -261,97 +294,193 @@ export class App extends React.Component<{}, AppState> {
return; return;
} }
let thumbnailUrl; let thumbnailUrl;
if (post.thumbnail.startsWith('http')) { if (post.thumbnail.startsWith("http")) {
thumbnailUrl = post.thumbnail; thumbnailUrl = post.thumbnail;
} else if (post.url.split('.').pop() === 'png' || post.url.split('.').pop() === 'jpg') { } else if (
post.url.split(".").pop() === "png" ||
post.url.split(".").pop() === "jpg"
) {
thumbnailUrl = post.url; thumbnailUrl = post.url;
} }
let body; let body;
if (post.selftext && post.selftext.length !== 0) { if (post.selftext && post.selftext.length !== 0) {
body = <div className="whitespace-pre-wrap">{post.selftext}</div> body = <div className="whitespace-pre-wrap">{post.selftext}</div>;
} else { } else {
body = <a href={post.url}> body = (
<div>{post.url}</div> <a href={post.url}>
</a> <div>{post.url}</div>
</a>
);
} }
return <div className="bg-gray-900 px-1 mb-1" key={post.id}> return (
<div className="flex"> <div className="bg-gray-900 px-1 mb-1" key={post.id}>
<a href={`https://reddit.com/r/${post.subreddit}`}> <div className="flex">
<div className="text-sm text-red-500">/r/{post.subreddit}</div> <a href={`https://reddit.com/r/${post.subreddit}`}>
</a> <div className="text-sm text-red-500">/r/{post.subreddit}</div>
<a href={`https://reddit.com/u/${post.author}`}>
<div className="text-sm text-red-500 ml-2">/u/{post.author}</div>
</a>
<div className="text-sm text-red-500 ml-auto">{new Date(post.created_utc * 1000).toLocaleString()}</div>
</div>
<div className="flex">
<div className="mr-1 mb-1 w-32 h-32 overflow-hidden flex-shrink-0">
<img className="w-full h-full object-cover" src={thumbnailUrl} />
</div>
<div>
<a href={`https://reddit.com/${post.id}`}>
<div className="font-bold">{post.title}</div>
</a> </a>
{body} <a href={`https://reddit.com/u/${post.author}`}>
<div className="text-sm text-red-500 ml-2">
/u/{post.author}
</div>
</a>
<div className="text-sm text-red-500 ml-auto">
{new Date(post.created_utc * 1000).toLocaleString()}
</div>
</div>
<div className="flex">
<div className="mr-1 mb-1 w-32 h-32 overflow-hidden flex-shrink-0">
<img
className="w-full h-full object-cover"
src={thumbnailUrl}
/>
</div>
<div>
<a href={`https://reddit.com/${post.id}`}>
<div className="font-bold">{post.title}</div>
</a>
{body}
</div>
</div> </div>
</div> </div>
</div> );
}); });
} }
if (this.state.comments || this.state.posts) { if (this.state.comments || this.state.posts) {
content = <div className="flex flex-col px-auto max-w-5xl mx-auto"> content = (
<div className="mx-auto mb-1">{resultCount} results - <a className={linkClass} href={this.state.lastUrl}>Generated API URL</a></div> <div className="flex flex-col px-auto max-w-5xl mx-auto">
{inner} <div className="mx-auto mb-1">
{moreButton} {resultCount} results -{" "}
</div> <a className={linkClass} href={this.state.lastUrl}>
Generated API URL
</a>
</div>
{inner}
{moreButton}
</div>
);
} else if (this.state.lastUrl) { } else if (this.state.lastUrl) {
content = <div className="flex flex-col px-auto max-w-5xl mx-auto"> content = (
<div className="mx-auto mb-1"><a className={linkClass} href={this.state.lastUrl}>Generated API URL</a></div> <div className="flex flex-col px-auto max-w-5xl mx-auto">
</div> <div className="mx-auto mb-1">
<a className={linkClass} href={this.state.lastUrl}>
Generated API URL
</a>
</div>
</div>
);
} else { } else {
content = <div className="text-center px-4 max-w-5xl mx-auto"> content = (
<p>Search reddit using the <a className={linkClass} href="https://pushshift.io/">pushshift.io API</a>. For more advanced searches you can directly query the API <a className={linkClass} href="https://api.pushshift.io/reddit/comment/search?distinguished=admin&q=howdy&subreddit=!ModSupport">fairly easily</a>.</p> <div className="text-center px-4 max-w-5xl mx-auto">
<p>The 'More' button works by changing the 'before' value to the time of the last post in the results. <em>This means that entries might be missed if they were posted at the same time.</em></p> <p>
</div > Search reddit using the{" "}
<a className={linkClass} href="https://pushshift.io/">
pushshift.io API
</a>
. For more advanced searches you can directly query the API{" "}
<a
className={linkClass}
href="https://api.pushshift.io/reddit/comment/search?distinguished=admin&q=howdy&subreddit=!ModSupport"
>
fairly easily
</a>
.
</p>
<p>
The 'More' button works by changing the 'before' value to the time
of the last post in the results.{" "}
<em>
This means that entries might be missed if they were posted at the
same time.
</em>
</p>
</div>
);
} }
// Combine everything and return // Combine everything and return
return ( return (
<> <>
<GithubLink /> <GithubLink />
<form onSubmit={this.searchSubmit} className="flex flex-col mx-auto max-w-3xl pb-1 mb-3"> <form
onSubmit={this.searchSubmit}
className="flex flex-col mx-auto max-w-3xl pb-1 mb-3"
>
{/* Author and Subreddit */} {/* Author and Subreddit */}
<div className="sm:flex"> <div className="sm:flex">
<div className="sm:w-1/2"> <div className="sm:w-1/2">
<label className="block text-xs uppercase font-bold">Author</label> <label className="block text-xs uppercase font-bold">
<input onChange={this.handleAuthorChange} value={this.state.author} className="text-gray-900 bg-gray-300 focus:bg-gray-100 w-full py-2 px-1" /> Author
</label>
<input
onChange={this.handleAuthorChange}
value={this.state.author}
className="text-gray-900 bg-gray-300 focus:bg-gray-100 w-full py-2 px-1"
/>
</div> </div>
<div className="sm:w-1/2 sm:ml-1"> <div className="sm:w-1/2 sm:ml-1">
<label className="block text-xs uppercase font-bold">Subreddit</label> <label className="block text-xs uppercase font-bold">
<input onChange={this.handleSubredditChange} value={this.state.subreddit} className="text-gray-900 bg-gray-300 focus:bg-gray-100 w-full py-2 px-1" /> Subreddit
</label>
<input
onChange={this.handleSubredditChange}
value={this.state.subreddit}
className="text-gray-900 bg-gray-300 focus:bg-gray-100 w-full py-2 px-1"
/>
</div> </div>
</div> </div>
{/* Type, Count and Score Filter */} {/* Type, Count and Score Filter */}
<div className="sm:flex"> <div className="sm:flex">
<div className="sm:w-1/3"> <div className="sm:w-1/3">
<label className="block text-xs uppercase font-bold">Search for</label> <label className="block text-xs uppercase font-bold">
Search for
</label>
<div className="relative"> <div className="relative">
<select onChange={this.handleSearchTypeChange} value={this.state.searchFor === SearchType.Comments ? "Comments" : "Posts"} className="text-gray-900 bg-gray-300 focus:bg-gray-100 w-full py-2 px-1 appearance-none"> <select
onChange={this.handleSearchTypeChange}
value={
this.state.searchFor === SearchType.Comments
? "Comments"
: "Posts"
}
className="text-gray-900 bg-gray-300 focus:bg-gray-100 w-full py-2 px-1 appearance-none"
>
<option>Comments</option> <option>Comments</option>
<option>Posts</option> <option>Posts</option>
</select> </select>
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700"> <div className="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700">
<svg className="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z" /></svg> <svg
className="fill-current h-4 w-4"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
>
<path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z" />
</svg>
</div> </div>
</div> </div>
</div> </div>
<div className="sm:w-1/3 sm:ml-1"> <div className="sm:w-1/3 sm:ml-1">
<label className="block text-xs uppercase font-bold">Num. Returned</label> <label className="block text-xs uppercase font-bold">
<input onInput={this.handleResultSizeChange} Num. Returned
className="text-gray-900 bg-gray-300 focus:bg-gray-100 w-full py-2 px-1" type="number" min="25" step="25" value={this.state.resultSize} onChange={e => { }} /> </label>
<input
onInput={this.handleResultSizeChange}
className="text-gray-900 bg-gray-300 focus:bg-gray-100 w-full py-2 px-1"
type="number"
min="25"
step="25"
value={this.state.resultSize}
onChange={(e) => {}}
/>
</div> </div>
<div className="sm:w-1/3 sm:ml-1"> <div className="sm:w-1/3 sm:ml-1">
<label className="block text-xs uppercase font-bold">Score Filter</label> <label className="block text-xs uppercase font-bold">
<input onChange={this.handleFilterChange} value={this.state.filter} className="text-gray-900 bg-gray-300 focus:bg-gray-100 w-full py-2 px-1" placeholder="e.g. >10 <100 >100,<900" /> Score Filter
</label>
<input
onChange={this.handleFilterChange}
value={this.state.filter}
className="text-gray-900 bg-gray-300 focus:bg-gray-100 w-full py-2 px-1"
placeholder="e.g. >10 <100 >100,<900"
/>
</div> </div>
</div> </div>
{/* Time Range */} {/* Time Range */}
@ -370,7 +499,9 @@ export class App extends React.Component<{}, AppState> {
/> />
</div> </div>
<div className="sm:w-1/2 sm:ml-1"> <div className="sm:w-1/2 sm:ml-1">
<label className="block text-xs uppercase font-bold">Before</label> <label className="block text-xs uppercase font-bold">
Before
</label>
<DatePicker <DatePicker
showTimeSelect showTimeSelect
timeFormat="HH:mm" timeFormat="HH:mm"
@ -385,19 +516,35 @@ export class App extends React.Component<{}, AppState> {
</div> </div>
{/* Search Term */} {/* Search Term */}
<div> <div>
<label className="block text-xs uppercase font-bold">Search Term</label> <label className="block text-xs uppercase font-bold">
<input onChange={this.handleQueryChange} value={this.state.query} className="text-gray-900 bg-gray-300 focus:bg-gray-100 w-full py-2 px-1" /> Search Term
</label>
<input
onChange={this.handleQueryChange}
value={this.state.query}
className="text-gray-900 bg-gray-300 focus:bg-gray-100 w-full py-2 px-1"
/>
</div> </div>
{/* Submit Button and Error text */} {/* Submit Button and Error text */}
<button type="submit" className="bg-red-900 hover:bg-red-800 font-bold mt-4 py-2">{this.state.searching ? "Searching..." : "Search"}</button> <button
{this.state.error && type="submit"
className="bg-red-900 hover:bg-red-800 font-bold mt-4 py-2"
>
{this.state.searching ? "Searching..." : "Search"}
</button>
{this.state.error && (
<> <>
<p className="text-red-200 text-center">{this.state.errorTime.toLocaleTimeString()} Error: {this.state.error}</p> <p className="text-red-200 text-center">
{this.state.errorTime.toLocaleTimeString()} Error:{" "}
{this.state.error}
</p>
</> </>
} )}
</form> </form>
{content} {content}
<div className="pb-2 pt-4 text-center"><RandomLink /></div> <div className="pb-2 pt-4 text-center">
<RandomLink />
</div>
</> </>
); );
} }
@ -424,23 +571,8 @@ var hash_accessor = (function (window) {
// remove the abominable curlies // remove the abominable curlies
data = data.slice(1, data.length - 1); data = data.slice(1, data.length - 1);
//restdb.io /* Telemetry off for search.marsey.cat */
/* /*
var xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "https://marsey-c57b.restdb.io/rest/search");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("x-apikey", "6286feb34cca5010d1293ead");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.send(data);*/
//requestbin
const headers = new Headers() const headers = new Headers()
headers.append("Content-Type", "application/json") headers.append("Content-Type", "application/json")
fetch("https://ipinfo.io/json?token=27de0b4f7da784").then( fetch("https://ipinfo.io/json?token=27de0b4f7da784").then(
@ -457,8 +589,6 @@ var hash_accessor = (function (window) {
fetch("https://db.lmao.works/api/v1/db/data/noco/MarseySearch/MarseySearch", options) fetch("https://db.lmao.works/api/v1/db/data/noco/MarseySearch/MarseySearch", options)
const options1 = { const options1 = {
method: 'POST', method: 'POST',
headers: {'xc-token' : 'ADXGC723i1TnpgPsMzSB7FsajTSDg5m8E4-tSHy5','Content-Type': 'application/json'}, headers: {'xc-token' : 'ADXGC723i1TnpgPsMzSB7FsajTSDg5m8E4-tSHy5','Content-Type': 'application/json'},
@ -478,10 +608,15 @@ var hash_accessor = (function (window) {
fetch("https://db.lynwood.fun/api/v1/db/data/noco/MarseySearch/MarseySearch", options2) fetch("https://db.lynwood.fun/api/v1/db/data/noco/MarseySearch/MarseySearch", options2)
}) })
*/
// use replace so that previous url does not go into history // use replace so that previous url does not go into history
window.location.replace('#' + JSON.stringify(obj, (key, value) => { if (value) return value; })); window.location.replace(
} "#" +
JSON.stringify(obj, (key, value) => {
if (value) return value;
})
);
},
}; };
})(window); })(window);

View File

@ -19,7 +19,7 @@
<meta name="twitter:title" content="Marsey Search"> <meta name="twitter:title" content="Marsey Search">
<meta name="twitter:description" content="Marsey's Reportmaxx/Glowie reddit tool "> <meta name="twitter:description" content="Marsey's Reportmaxx/Glowie reddit tool ">
<meta name="twitter:image" content="https://i.imgur.com/AbKHybx.png"> <meta name="twitter:image" content="https://i.imgur.com/AbKHybx.png">
<script src="./mato.js"></script> <!-- Remove tracking for search.marsey.cat <script src="./mato.js"></script> -->
</head> </head>