Add Page Populator from Sonarr

This commit is contained in:
Qstick 2017-10-07 02:47:28 -04:00
commit 023452e1c3
12 changed files with 244 additions and 69 deletions

View file

@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
import * as blacklistActions from 'Store/Actions/blacklistActions';
import { executeCommand } from 'Store/Actions/commandActions';
@ -35,6 +36,7 @@ class BlacklistConnector extends Component {
// Lifecycle
componentDidMount() {
registerPagePopulator(this.repopulate);
this.props.gotoBlacklistFirstPage();
}
@ -44,6 +46,17 @@ class BlacklistConnector extends Component {
}
}
componentWillUnmount() {
unregisterPagePopulator(this.repopulate);
}
//
// Control
repopulate = () => {
this.props.fetchBlacklist();
}
//
// Listeners

View file

@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
import selectUniqueIds from 'Utilities/Object/selectUniqueIds';
import * as historyActions from 'Store/Actions/historyActions';
@ -35,6 +36,7 @@ class HistoryConnector extends Component {
// Lifecycle
componentDidMount() {
registerPagePopulator(this.repopulate);
this.props.gotoHistoryFirstPage();
}
@ -46,10 +48,18 @@ class HistoryConnector extends Component {
}
componentWillUnmount() {
unregisterPagePopulator(this.repopulate);
this.props.clearHistory();
this.props.clearEpisodes();
}
//
// Control
repopulate = () => {
this.props.fetchHistory();
}
//
// Listeners

View file

@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
import selectUniqueIds from 'Utilities/Object/selectUniqueIds';
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
@ -44,6 +45,7 @@ class QueueConnector extends Component {
// Lifecycle
componentDidMount() {
registerPagePopulator(this.repopulate);
this.props.gotoQueueFirstPage();
}
@ -56,10 +58,18 @@ class QueueConnector extends Component {
}
componentWillUnmount() {
unregisterPagePopulator(this.repopulate);
this.props.clearQueue();
this.props.clearEpisodes();
}
//
// Control
repopulate = () => {
this.props.fetchQueue();
}
//
// Listeners

View file

@ -4,6 +4,7 @@ import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { findCommand } from 'Utilities/Command';
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
import createAllArtistSelector from 'Store/Selectors/createAllArtistSelector';
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
import { fetchEpisodes, clearEpisodes } from 'Store/Actions/episodeActions';
@ -86,7 +87,8 @@ class ArtistDetailsConnector extends Component {
// Lifecycle
componentDidMount() {
this._populate();
registerPagePopulator(this.populate);
this.populate();
}
componentDidUpdate(prevProps) {
@ -102,26 +104,27 @@ class ArtistDetailsConnector extends Component {
(prevProps.isRenamingFiles && !isRenamingFiles) ||
(prevProps.isRenamingArtist && !isRenamingArtist)
) {
this._populate();
this.populate();
}
// If the id has changed we need to clear the episodes/episode
// files and fetch from the server.
if (prevProps.id !== id) {
this._unpopulate();
this._populate();
this.unpopulate();
this.populate();
}
}
componentWillUnmount() {
this._unpopulate();
unregisterPagePopulator(this.populate);
this.unpopulate();
}
//
// Control
_populate() {
populate = () => {
const artistId = this.props.id;
this.props.fetchEpisodes({ artistId });
@ -129,7 +132,7 @@ class ArtistDetailsConnector extends Component {
this.props.fetchQueueDetails({ artistId });
}
_unpopulate() {
unpopulate = () => {
this.props.clearEpisodes();
this.props.clearTrackFiles();
this.props.clearQueueDetails();

View file

@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
import selectUniqueIds from 'Utilities/Object/selectUniqueIds';
import * as calendarActions from 'Store/Actions/calendarActions';
@ -40,6 +41,7 @@ class CalendarConnector extends Component {
}
componentDidMount() {
registerPagePopulator(this.repopulate);
this.props.gotoCalendarToday();
this.scheduleUpdate();
}
@ -67,6 +69,7 @@ class CalendarConnector extends Component {
}
componentWillUnmount() {
unregisterPagePopulator(this.repopulate);
this.props.clearCalendar();
this.props.clearQueueDetails();
this.props.clearTrackFiles();
@ -75,11 +78,20 @@ class CalendarConnector extends Component {
//
// Control
repopulate = () => {
const {
time,
view
} = this.props;
this.props.fetchQueueDetails({ time, view });
this.props.fetchCalendar({ time, view });
}
scheduleUpdate = () => {
this.clearUpdateTimeout();
this.updateTimeoutId = setTimeout(this.scheduleUpdate, UPDATE_DELAY);
this.updateTimeoutId = setTimeout(this.updateCalendar, UPDATE_DELAY);
}
clearUpdateTimeout = () => {
@ -130,12 +142,14 @@ class CalendarConnector extends Component {
CalendarConnector.propTypes = {
time: PropTypes.string,
view: PropTypes.string.isRequired,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
setCalendarView: PropTypes.func.isRequired,
gotoCalendarToday: PropTypes.func.isRequired,
gotoCalendarPreviousRange: PropTypes.func.isRequired,
gotoCalendarNextRange: PropTypes.func.isRequired,
clearCalendar: PropTypes.func.isRequired,
fetchCalendar: PropTypes.func.isRequired,
fetchTrackFiles: PropTypes.func.isRequired,
clearTrackFiles: PropTypes.func.isRequired,
fetchQueueDetails: PropTypes.func.isRequired,

View file

@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { repopulatePage } from 'Utilities/pagePopulator';
import { updateCommand, finishCommand } from 'Store/Actions/commandActions';
import { setAppValue, setVersion } from 'Store/Actions/appActions';
import { update, updateItem, removeItem } from 'Store/Actions/baseActions';
@ -28,10 +29,12 @@ function getState(status) {
function createMapStateToProps() {
return createSelector(
(state) => state.app.isReconnecting,
(state) => state.app.isDisconnected,
(state) => state.queue.paged.isPopulated,
(isReconnecting, isQueuePopulated) => {
(isReconnecting, isDisconnected, isQueuePopulated) => {
return {
isReconnecting,
isDisconnected,
isQueuePopulated
};
}
@ -170,7 +173,8 @@ class SignalRConnector extends Component {
this.props.updateItem({
section: 'calendar',
updateOnly: true,
...body.resource });
...body.resource
});
}
}
@ -193,7 +197,8 @@ class SignalRConnector extends Component {
this.props.updateItem({
section: 'episodes',
updateOnly: true,
...body.resource });
...body.resource
});
}
}
@ -202,7 +207,8 @@ class SignalRConnector extends Component {
this.props.updateItem({
section: 'tracks',
updateOnly: true,
...body.resource });
...body.resource
});
}
}
@ -210,7 +216,8 @@ class SignalRConnector extends Component {
if (body.action === 'updated') {
this.props.updateItem({
section: 'trackFiles',
...body.resource });
...body.resource
});
}
}
@ -254,7 +261,8 @@ class SignalRConnector extends Component {
this.props.updateItem({
section: 'cutoffUnmet',
updateOnly: true,
...body.resource });
...body.resource
});
}
}
@ -263,7 +271,8 @@ class SignalRConnector extends Component {
this.props.updateItem({
section: 'missing',
updateOnly: true,
...body.resource });
...body.resource
});
}
}
@ -275,6 +284,13 @@ class SignalRConnector extends Component {
console.log(`SignalR: [${state}]`);
if (state === 'connected') {
// Repopulate the page (if a repopulator is set) to ensure things
// are in sync after reconnecting.
if (this.props.isReconnecting || this.props.isDisconnected) {
repopulatePage();
}
this.props.setAppValue({
isConnected: true,
isReconnecting: false,
@ -329,6 +345,7 @@ class SignalRConnector extends Component {
SignalRConnector.propTypes = {
isReconnecting: PropTypes.bool.isRequired,
isDisconnected: PropTypes.bool.isRequired,
isQueuePopulated: PropTypes.bool.isRequired,
updateCommand: PropTypes.func.isRequired,
finishCommand: PropTypes.func.isRequired,

View file

@ -0,0 +1,17 @@
let currentPopulator = null;
export function registerPagePopulator(populator) {
currentPopulator = populator;
}
export function unregisterPagePopulator(populator) {
if (currentPopulator === populator) {
currentPopulator = null;
}
}
export function repopulatePage() {
if (currentPopulator) {
currentPopulator();
}
}

View file

@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
import selectUniqueIds from 'Utilities/Object/selectUniqueIds';
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
@ -46,6 +47,7 @@ class CutoffUnmetConnector extends Component {
// Lifecycle
componentDidMount() {
registerPagePopulator(this.repopulate);
this.props.gotoCutoffUnmetFirstPage();
}
@ -63,11 +65,19 @@ class CutoffUnmetConnector extends Component {
}
componentWillUnmount() {
unregisterPagePopulator(this.repopulate);
this.props.clearCutoffUnmet();
this.props.clearQueueDetails();
this.props.clearTrackFiles();
}
//
// Control
repopulate = () => {
this.props.fetchCutoffUnmet();
}
//
// Listeners

View file

@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
import selectUniqueIds from 'Utilities/Object/selectUniqueIds';
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
@ -43,6 +44,7 @@ class MissingConnector extends Component {
// Lifecycle
componentDidMount() {
registerPagePopulator(this.repopulate);
this.props.gotoMissingFirstPage();
}
@ -54,10 +56,18 @@ class MissingConnector extends Component {
}
componentWillUnmount() {
unregisterPagePopulator(this.repopulate);
this.props.clearMissing();
this.props.clearQueueDetails();
}
//
// Control
repopulate = () => {
this.props.fetchMissing();
}
//
// Listeners