diff --git a/src/features/gameboard/types.ts b/src/features/gameboard/types.ts index 44042ce..4429331 100644 --- a/src/features/gameboard/types.ts +++ b/src/features/gameboard/types.ts @@ -15,6 +15,11 @@ export enum EGrip { none, } +export type Credentials = { + login: string + api_key: string +} + export type PornList = string[] export type GameEvent = ( diff --git a/src/features/settings/SettingsControls/PornSetting/PornSetting.css b/src/features/settings/SettingsControls/PornSetting/PornSetting.css index 80d28d2..29b0bc0 100644 --- a/src/features/settings/SettingsControls/PornSetting/PornSetting.css +++ b/src/features/settings/SettingsControls/PornSetting/PornSetting.css @@ -3,4 +3,13 @@ flex-wrap: wrap; width: 100%; margin-top: 10px; -} \ No newline at end of file +} + +.PornSetting__error { + color: #cc0000; +} + +.PornSetting__textarea { + width: 100%; + min-height: 6.25em; +} diff --git a/src/features/settings/SettingsControls/PornSetting/PornSetting.tsx b/src/features/settings/SettingsControls/PornSetting/PornSetting.tsx index 373bf7d..6fff1e0 100644 --- a/src/features/settings/SettingsControls/PornSetting/PornSetting.tsx +++ b/src/features/settings/SettingsControls/PornSetting/PornSetting.tsx @@ -1,14 +1,17 @@ import React from 'react' import '../settings.css' import './PornSetting.css' -import { PornList } from '../../../gameboard/types' -import { E621Posts } from '../../types' -import axios, { AxiosResponse } from 'axios' +import { Credentials, PornList } from '../../../gameboard/types' +import { E621Post, E621User } from '../../types' +import axios, { AxiosRequestConfig, AxiosResponse } from 'axios' import { PornThumbnail } from './PornThumbnail' import { debounce } from 'lodash' import reactGA from '../../../../analytics' +import { Blacklist } from '../../../../helpers/blacklist' interface IPornSettingProps { + credentials: Credentials | null + setCredentials: (newCredentials: Credentials | null) => void pornList: PornList setPornList: (newPornList: PornList) => void } @@ -20,6 +23,10 @@ interface IPornSettingState { flags: { highRes: boolean } + credentials: Credentials + addCredentials: boolean + credentialsError: string | null + blacklistTagsString: string | null } export class PornSetting extends React.Component { @@ -33,18 +40,84 @@ export class PornSetting extends React.Component) { this.setState({ tags: event.target.value, }) } + updateLogin(event: React.ChangeEvent) { + const login = event.target.value + this.setState(prevState => ({ + credentials: { + ...prevState.credentials!, + login, + }, + credentialsError: null, + })) + } + + updateApiKey(event: React.ChangeEvent) { + const api_key = event.target.value + this.setState(prevState => ({ + credentials: { + ...prevState.credentials!, + api_key, + }, + credentialsError: null, + })) + } + + saveCredentials() { + // Check to see if these credentials are valid + const config: AxiosRequestConfig = { + params: this.state.credentials, + responseType: 'json', + } + axios + .get(`https://e621.net/users/${this.state.credentials.login}.json`, config) + .then(() => this.props.setCredentials(this.state.credentials)) + .catch(() => this.setState({ credentialsError: 'Invalid credentials' })) + } + + clearCredentials() { + this.props.setCredentials(null) + this.setState({ addCredentials: false }) + } + + loadBlacklist() { + const config: AxiosRequestConfig = { + params: this.props.credentials, + responseType: 'json', + } + axios.get(`https://e621.net/users/${this.props.credentials!.login}.json`, config).then((response: AxiosResponse) => { + this.setState({ blacklistTagsString: response.data.blacklisted_tags }) + }) + } + downloadFromTags() { debounce(() => { if (localStorage.getItem('allowCookies') !== 'true' || localStorage.getItem('allowCookies') !== null) return @@ -54,15 +127,21 @@ export class PornSetting extends React.Component=${this.state.minScore}` : '')) axios - .get(`https://e621.net/posts.json?tags=${tags}&limit=${this.state.count}&callback=callback`, { - responseType: 'json', - }) - .then((response: AxiosResponse<{ posts: E621Posts }>) => { + .get(`https://e621.net/posts.json?tags=${tags}&limit=${this.state.count}&callback=callback`, config) + .then((response: AxiosResponse<{ posts: E621Post[] }>) => { this.props.setPornList( (response.data.posts .filter(post => /(jpg|png|bmp|jpeg|webp|gif)$/g.test(post.file.ext)) + .filter(blacklist.shouldKeepPost) .map(post => (this.state.flags.highRes ? post.file.url : post.sample.url)) .filter(url => url !== null) as string[]) .filter(url => this.props.pornList.indexOf(url) === -1) @@ -92,6 +171,81 @@ export class PornSetting extends React.ComponentImport from e621 +
+ {this.props.credentials ? ( + <> + +
+ + Logged in. +
+ You can now use votedup:me, private sets, & your blacklist. +
+ + ) : ( + <> + + Login to use votedup:me, private sets, & your blacklist. + {this.state.addCredentials ? ( + <> + +
+
+ + + (found in your account under "Manage API Access") + + + {this.state.credentialsError != null ? {this.state.credentialsError} : null} + + ) : null} + + )} +
+
+ + {this.state.blacklistTagsString !== null ? ( + <> +
+
+ + + ) : null} +