prepare past logs

This commit is contained in:
gempir 2020-02-08 17:12:36 +01:00
parent a86f9e5baa
commit 1b15372891
8 changed files with 36 additions and 61 deletions

View file

@ -4,6 +4,11 @@ import setLoading from "./setLoading";
export default function (channel, username, year, month) { export default function (channel, username, year, month) {
return function (dispatch, getState) { return function (dispatch, getState) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
channel = channel || getState().channel;
username = username || getState().username;
year = year || getState().year;
month = month || getState().month;
dispatch(setLoading(true)); dispatch(setLoading(true));

View file

@ -1,7 +1,7 @@
export default (channel, username) => (dispatch) => { export default (channel, username) => (dispatch) => {
dispatch({ dispatch({
type: 'SET_CURRENT', type: 'SET_CURRENT',
currentChannel: channel, channel: channel,
currentUsername: username username: username
}); });
} }

View file

@ -2,38 +2,27 @@ import React, { Component } from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import setCurrent from "./../actions/setCurrent"; import setCurrent from "./../actions/setCurrent";
import AutocompleteInput from "./AutocompleteInput"; import AutocompleteInput from "./AutocompleteInput";
import loadLogs from "../actions/loadLogs";
class Filter extends Component { class Filter extends Component {
constructor(props) {
super(props);
const date = new Date();
this.state = {
year: date.getFullYear(),
month: date.getMonth() + 1,
}
}
username; username;
componentDidMount() { componentDidMount() {
if (this.props.currentChannel && this.props.currentUsername) { if (this.props.channel && this.props.username) {
this.props.searchLogs(this.props.currentChannel, this.props.currentUsername, this.state.year, this.state.month); this.props.dispatch(loadLogs());
} }
} }
render() { render() {
return ( return (
<form className="filter" autoComplete="off" onSubmit={this.onSubmit}> <form className="filter" autoComplete="off" onSubmit={this.onSubmit}>
<AutocompleteInput placeholder="pajlada" onChange={this.onChannelChange} value={this.props.currentChannel} onAutocompletionClick={() => this.username.focus()} autocompletions={this.props.channels.map(channel => channel.name)} /> <AutocompleteInput placeholder="pajlada" onChange={this.onChannelChange} value={this.props.channel} onAutocompletionClick={() => this.username.focus()} autocompletions={this.props.channels.map(channel => channel.name)} />
<input <input
ref={el => this.username = el} ref={el => this.username = el}
type="text" type="text"
placeholder="gempir" placeholder="gempir"
onChange={this.onUsernameChange} onChange={this.onUsernameChange}
value={this.props.currentUsername} value={this.props.username}
/> />
<button type="submit" className="show-logs">Show logs</button> <button type="submit" className="show-logs">Show logs</button>
</form> </form>
@ -41,19 +30,11 @@ class Filter extends Component {
} }
onChannelChange = (channel) => { onChannelChange = (channel) => {
this.props.dispatch(setCurrent(channel, this.props.currentUsername)); this.props.dispatch(setCurrent(channel, this.props.username));
} }
onUsernameChange = (e) => { onUsernameChange = (e) => {
this.props.dispatch(setCurrent(this.props.currentChannel, e.target.value)); this.props.dispatch(setCurrent(this.props.channel, e.target.value));
}
onYearChange = (e) => {
this.setState({ year: e.target.value });
}
onMonthChange = (e) => {
this.setState({ month: e.target.value });
} }
onSubmit = (e) => { onSubmit = (e) => {
@ -61,18 +42,18 @@ class Filter extends Component {
const url = new URL(window.location.href); const url = new URL(window.location.href);
const params = new URLSearchParams(url.search); const params = new URLSearchParams(url.search);
params.set('channel', this.props.currentChannel); params.set('channel', this.props.channel);
params.set('username', this.props.currentUsername); params.set('username', this.props.username);
window.location.search = params.toString(); window.location.search = params.toString();
this.props.searchLogs(this.props.currentChannel, this.props.currentUsername, this.state.year, this.state.month); this.props.dispatch(loadLogs());
} }
} }
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
channels: state.channels, channels: state.channels,
currentChannel: state.currentChannel, channel: state.channel,
currentUsername: state.currentUsername username: state.username
}); });
export default connect(mapStateToProps)(Filter); export default connect(mapStateToProps)(Filter);

View file

@ -20,18 +20,11 @@ class LogSearch extends Component {
<ToastContainer /> <ToastContainer />
<Filter <Filter
channels={this.props.channels} channels={this.props.channels}
searchLogs={this.searchLogs}
/> />
<LogView /> <LogView />
</div> </div>
); );
} }
searchLogs = (channel, username, year, month) => {
this.props.dispatch(loadLogs(channel, username, year, month)).catch((error) => {
toast.error("Failed to load logs: " + error);
});
}
} }
const mapStateToProps = (state) => { const mapStateToProps = (state) => {

View file

@ -5,34 +5,27 @@ import reactStringReplace from "react-string-replace";
class LogView extends Component { class LogView extends Component {
static LOAD_LIMIT = 100;
state = {
limitLoad: true,
};
render() { render() {
const oldLogs = [];
for (let month = this.props.month - 1; month >= 1; month--) {
oldLogs.push(month)
}
console.log(oldLogs);
return ( return (
<div className={"log-view"}> <div className={"log-view"}>
{this.getLogs().map((value, key) => {this.props.messages.reverse().map((value, key) =>
<div key={key} className="line" onClick={() => this.setState({})}> <div key={key} className="line" onClick={() => this.setState({})}>
<span id={value.timestamp} className="timestamp">{this.formatDate(value.timestamp)}</span>{this.renderMessage(value.text)} <span id={value.timestamp} className="timestamp">{this.formatDate(value.timestamp)}</span>{this.renderMessage(value.text)}
</div> </div>
)} )}
{this.getLogs().length > this.constructor.LOAD_LIMIT && this.state.limitLoad && <button className={"load-all"} onClick={() => this.setState({limitLoad: false })}>Load all</button>}
{this.props.loading && <div>loading</div>} {this.props.loading && <div>loading</div>}
</div> </div>
); );
} }
getLogs = () => {
if (this.state.limitLoad) {
return this.props.messages.slice(this.props.messages.length - LogView.LOAD_LIMIT, this.props.messages.length).reverse();
} else {
return this.props.messages.reverse();
}
};
renderMessage = (message) => { renderMessage = (message) => {
for (let emoteCode in twitchEmotes) { for (let emoteCode in twitchEmotes) {
const regex = new RegExp(`(?:^|\ )(${emoteCode})(?:$|\ )`); const regex = new RegExp(`(?:^|\ )(${emoteCode})(?:$|\ )`);
@ -60,6 +53,7 @@ class LogView extends Component {
const mapStateToProps = (state) => { const mapStateToProps = (state) => {
return { return {
month: state.month,
messages: state.logs.messages, messages: state.logs.messages,
loading: state.loading loading: state.loading
}; };

View file

@ -1,6 +1,8 @@
export default () => { export default () => {
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
const date = new Date();
return { return {
apiBaseUrl: process.env.apiBaseUrl, apiBaseUrl: process.env.apiBaseUrl,
channels: [], channels: [],
@ -9,7 +11,9 @@ export default () => {
}, },
loading: false, loading: false,
twitchEmotes: {}, twitchEmotes: {},
currentChannel: urlParams.get("channel") || "", month: date.getMonth() + 1,
currentUsername: urlParams.get("username") || "", year: date.getFullYear(),
channel: urlParams.get("channel") || "",
username: urlParams.get("username") || "",
} }
} }

View file

@ -7,7 +7,7 @@ export default (state, action) => {
case "SET_LOGS": case "SET_LOGS":
return { ...state, logs: action.logs }; return { ...state, logs: action.logs };
case "SET_CURRENT": case "SET_CURRENT":
return { ...state, currentChannel: action.currentChannel, currentUsername: action.currentUsername }; return { ...state, channel: action.channel, username: action.username };
case "SET_TWITCH_EMOTES": case "SET_TWITCH_EMOTES":
return { ...state, twitchEmotes: action.twitchEmotes }; return { ...state, twitchEmotes: action.twitchEmotes };
default: default:

View file

@ -4,8 +4,6 @@ body {
background: $grey-dark; background: $grey-dark;
font-family: Helvetica, Arial, sans-serif; font-family: Helvetica, Arial, sans-serif;
height: 100%; height: 100%;
overflow: hidden;
position: absolute;
width: 100%; width: 100%;
} }