Compare commits

...

3 Commits

Author SHA1 Message Date
e5be15c954 Fix warnings on the show page 2020-04-02 16:50:09 +02:00
bcadc48d5a Launch prettier with the --fix option
They've changed their default settings, this changes a lot of stuff in
our code base.
2020-04-01 17:55:34 +02:00
b3acd5067a Update js dependencies 2020-04-01 17:55:34 +02:00
88 changed files with 1302 additions and 879 deletions

View File

@ -2,8 +2,8 @@ export function addAlertError(message) {
return {
type: "ADD_ALERT_ERROR",
payload: {
message
}
message,
},
};
}
@ -11,13 +11,13 @@ export function addAlertOk(message) {
return {
type: "ADD_ALERT_OK",
payload: {
message
}
message,
},
};
}
export function dismissAlert() {
return {
type: "DISMISS_ALERT"
type: "DISMISS_ALERT",
};
}

View File

@ -7,8 +7,8 @@ export function updateLastMovieFetchUrl(url) {
return {
type: "UPDATE_LAST_MOVIE_FETCH_URL",
payload: {
url: url
}
url: url,
},
};
}
@ -16,8 +16,8 @@ export function selectMovie(imdbId) {
return {
type: "SELECT_MOVIE",
payload: {
imdbId
}
imdbId,
},
};
}
@ -25,8 +25,8 @@ export function updateFilter(filter) {
return {
type: "MOVIE_UPDATE_FILTER",
payload: {
filter
}
filter,
},
};
}
@ -43,7 +43,7 @@ export function getMovieDetails(imdbId) {
configureAxios().post(`/movies/${imdbId}/refresh`),
null,
{
imdbId
imdbId,
}
);
}
@ -51,7 +51,7 @@ export function getMovieDetails(imdbId) {
export function deleteMovie(imdbId, lastFetchUrl) {
return request("MOVIE_DELETE", configureAxios().delete(`/movies/${imdbId}`), [
fetchMovies(lastFetchUrl),
addAlertOk("Movie deleted")
addAlertOk("Movie deleted"),
]);
}
@ -84,26 +84,26 @@ export function updateMovieWishlistStore(imdbId, wishlisted) {
type: "MOVIE_UPDATE_STORE_WISHLIST",
payload: {
imdbId,
wishlisted
}
wishlisted,
},
};
}
export function fetchMovies(url) {
return request("MOVIE_LIST_FETCH", configureAxios().get(url), [
updateLastMovieFetchUrl(url)
updateLastMovieFetchUrl(url),
]);
}
export const newMovieEvent = data => {
return dispatch => {
export const newMovieEvent = (data) => {
return (dispatch) => {
dispatch(
sendNotification({
icon: "film",
autohide: true,
delay: 10000,
title: `${data.title} added to the library`,
imageUrl: data.thumb
imageUrl: data.thumb,
})
);
};

View File

@ -1,9 +1,9 @@
export const sendNotification = data => ({
export const sendNotification = (data) => ({
type: "ADD_NOTIFICATION",
payload: data
payload: data,
});
export const removeNotification = id => ({
export const removeNotification = (id) => ({
type: "REMOVE_NOTIFICATION",
payload: { id }
payload: { id },
});

View File

@ -11,10 +11,10 @@ export const getManagedPolochons = () =>
configureAxios().get("/users/polochons")
);
export const addPolochon = params =>
export const addPolochon = (params) =>
request("ADD_POLOCHON", configureAxios().post("/polochons", params), [
() => getPolochons(),
() => getManagedPolochons()
() => getManagedPolochons(),
]);
export const updatePolochon = ({ id, ...params }) =>
@ -24,10 +24,10 @@ export const updatePolochon = ({ id, ...params }) =>
[() => getPolochons(), () => getManagedPolochons()]
);
export const deletePolochon = id =>
export const deletePolochon = (id) =>
request("DELETE_POLOCHON", configureAxios().delete(`/polochons/${id}`), [
() => getPolochons(),
() => getManagedPolochons()
() => getManagedPolochons(),
]);
export const editPolochonUser = ({ polochonId, id, ...params }) =>

View File

@ -5,7 +5,7 @@ import { sendNotification } from "./notifications";
export function fetchShows(url) {
return request("SHOW_LIST_FETCH", configureAxios().get(url), [
updateLastShowsFetchUrl(url)
updateLastShowsFetchUrl(url),
]);
}
@ -28,7 +28,7 @@ export function getEpisodeDetails(imdbId, season, episode) {
{
imdbId,
season,
episode
episode,
}
);
}
@ -47,7 +47,7 @@ export function addShowToWishlist(imdbId, season = null, episode = null) {
"SHOW_ADD_TO_WISHLIST",
configureAxios().post(`/wishlist/shows/${imdbId}`, {
season: season,
episode: episode
episode: episode,
}),
[updateShowWishlistStore(imdbId, true, season, episode)]
);
@ -85,8 +85,8 @@ export function updateShowWishlistStore(
payload: {
imdbId,
season,
episode
}
episode,
},
};
}
@ -101,8 +101,8 @@ export function selectShow(imdbId) {
return {
type: "SELECT_SHOW",
payload: {
imdbId
}
imdbId,
},
};
}
@ -110,8 +110,8 @@ export function updateFilter(filter) {
return {
type: "SHOWS_UPDATE_FILTER",
payload: {
filter
}
filter,
},
};
}
@ -119,13 +119,13 @@ export function updateLastShowsFetchUrl(url) {
return {
type: "UPDATE_LAST_SHOWS_FETCH_URL",
payload: {
url: url
}
url: url,
},
};
}
export const newEpisodeEvent = data => {
return dispatch => {
export const newEpisodeEvent = (data) => {
return (dispatch) => {
dispatch(
sendNotification({
icon: "video-camera",
@ -136,7 +136,7 @@ export const newEpisodeEvent = data => {
data.season,
data.episode
)} added to the library`,
imageUrl: `img/shows/${data.show_imdb_id}-poster.jpg`
imageUrl: `img/shows/${data.show_imdb_id}-poster.jpg`,
})
);
};

View File

@ -1,6 +1,6 @@
import { configureAxios, request } from "../requests";
export const searchMovieSubtitles = imdbId => {
export const searchMovieSubtitles = (imdbId) => {
return request(
"MOVIE_SUBTITLES_UPDATE",
configureAxios().post(`/movies/${imdbId}/subtitles/refresh`),
@ -18,7 +18,7 @@ export const searchEpisodeSubtitles = (imdbId, season, episode) => {
{
imdbId: imdbId,
season: season,
episode: episode
episode: episode,
}
);
};

View File

@ -6,7 +6,7 @@ export function addTorrent(url) {
return request(
"ADD_TORRENT",
configureAxios().post("/torrents", {
url: url
url: url,
}),
[addAlertOk("Torrent added")]
);
@ -14,7 +14,7 @@ export function addTorrent(url) {
export function removeTorrent(id) {
return request("REMOVE_TORRENT", configureAxios().delete(`/torrents/${id}`), [
() => fetchTorrents()
() => fetchTorrents(),
]);
}
@ -31,8 +31,8 @@ export function setFetchedTorrents(torrents) {
type: "TORRENTS_FETCH_FULFILLED",
payload: {
response: {
data: torrents
}
}
data: torrents,
},
},
};
}

View File

@ -6,7 +6,7 @@ import { getManagedPolochons } from "./polochon";
export function userLogout() {
return {
type: "USER_LOGOUT"
type: "USER_LOGOUT",
};
}
@ -15,7 +15,7 @@ export function loginUser(username, password) {
"USER_LOGIN",
configureAxios().post("/users/login", {
username: username.trim(),
password: password
password: password,
}),
[() => dismissAlert()]
);
@ -24,7 +24,7 @@ export function loginUser(username, password) {
export function updateUser(config) {
return request("USER_UPDATE", configureAxios().post("/users/edit", config), [
addAlertOk("User updated"),
() => getManagedPolochons()
() => getManagedPolochons(),
]);
}
@ -48,8 +48,8 @@ export function setUserToken(token) {
return {
type: "USER_SET_TOKEN",
payload: {
token: token
}
token: token,
},
};
}

View File

@ -31,7 +31,7 @@ const protectedRoute = ({
return (
<Route
{...otherProps}
render={props => {
render={(props) => {
if (isAuthenticated()) {
if (isActivated) {
return <Component {...props} />;
@ -50,14 +50,14 @@ protectedRoute.propTypes = {
isLogged: PropTypes.bool.isRequired,
isActivated: PropTypes.bool.isRequired,
isTokenSet: PropTypes.bool.isRequired,
setUserToken: PropTypes.func.isRequired
setUserToken: PropTypes.func.isRequired,
};
export const ProtectedRoute = connect(
state => ({
(state) => ({
isLogged: state.userStore.get("isLogged"),
isAdmin: state.userStore.get("isLogged"),
isActivated: state.userStore.get("isActivated"),
isTokenSet: state.userStore.get("isTokenSet")
isTokenSet: state.userStore.get("isTokenSet"),
}),
{ setUserToken }
)(protectedRoute);
@ -66,7 +66,7 @@ const adminRoute = ({ component: Component, isAdmin, ...otherProps }) => {
return (
<Route
{...otherProps}
render={props => {
render={(props) => {
if (isAdmin) {
return <Component {...props} />;
} else {
@ -78,8 +78,8 @@ const adminRoute = ({ component: Component, isAdmin, ...otherProps }) => {
};
adminRoute.propTypes = {
component: PropTypes.func,
isAdmin: PropTypes.bool.isRequired
isAdmin: PropTypes.bool.isRequired,
};
export const AdminRoute = connect(state => ({
isAdmin: state.userStore.get("isLogged")
export const AdminRoute = connect((state) => ({
isAdmin: state.userStore.get("isLogged"),
}))(adminRoute);

View File

@ -15,12 +15,12 @@ const AdminModulesConnected = ({ modules, loading, getAdminModules }) => {
AdminModulesConnected.propTypes = {
modules: PropTypes.object,
loading: PropTypes.bool,
getAdminModules: PropTypes.func.isRequired
getAdminModules: PropTypes.func.isRequired,
};
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
loading: state.adminStore.get("fetchingModules"),
modules: state.adminStore.get("modules")
modules: state.adminStore.get("modules"),
});
export const AdminModules = connect(mapStateToProps, { getAdminModules })(

View File

@ -28,5 +28,5 @@ Stat.propTypes = {
name: PropTypes.string,
count: PropTypes.number,
torrentCount: PropTypes.number,
torrentCountById: PropTypes.number
torrentCountById: PropTypes.number,
};

View File

@ -36,11 +36,11 @@ const StatsConnected = ({ stats, getStats }) => {
};
StatsConnected.propTypes = {
stats: PropTypes.object,
getStats: PropTypes.func
getStats: PropTypes.func,
};
const mapStateToProps = state => ({
stats: state.adminStore.get("stats")
const mapStateToProps = (state) => ({
stats: state.adminStore.get("stats"),
});
export const Stats = connect(mapStateToProps, { getStats })(StatsConnected);

View File

@ -17,5 +17,5 @@ export const TorrentsStat = ({ count, torrentCount, torrentCountById }) => {
TorrentsStat.propTypes = {
count: PropTypes.number,
torrentCount: PropTypes.number,
torrentCountById: PropTypes.number
torrentCountById: PropTypes.number,
};

View File

@ -12,7 +12,7 @@ export const User = ({
polochonUrl,
polochonName,
polochonId,
token
token,
}) => {
return (
<tr>
@ -61,5 +61,5 @@ User.propTypes = {
token: PropTypes.string,
admin: PropTypes.bool,
activated: PropTypes.bool,
polochonActivated: PropTypes.bool
polochonActivated: PropTypes.bool,
};

View File

@ -21,7 +21,7 @@ const UserEditConnect = ({
polochonActivated: initPolochonActivated,
updateUser,
deleteUser,
publicPolochons
publicPolochons,
}) => {
const [modal, setModal] = useState(false);
const [admin, setAdmin] = useState(initAdmin);
@ -34,7 +34,7 @@ const UserEditConnect = ({
const [password, setPassword] = useState("");
const [confirmDelete, setConfirmDelete] = useState(false);
const handleSubmit = e => {
const handleSubmit = (e) => {
if (e) {
e.preventDefault();
}
@ -45,12 +45,12 @@ const UserEditConnect = ({
activated,
polochonId,
polochonActivated,
password
password,
});
setModal(false);
};
const handleDeleteUser = e => {
const handleDeleteUser = (e) => {
if (e) {
e.preventDefault();
}
@ -147,11 +147,11 @@ UserEditConnect.propTypes = {
polochonToken: PropTypes.string,
polochonId: PropTypes.string,
polochonActivated: PropTypes.bool,
publicPolochons: PropTypes.instanceOf(List)
publicPolochons: PropTypes.instanceOf(List),
};
const mapStateToProps = state => ({
publicPolochons: state.polochon.get("public")
const mapStateToProps = (state) => ({
publicPolochons: state.polochon.get("public"),
});
export const UserEdit = connect(mapStateToProps, { updateUser, deleteUser })(

View File

@ -8,8 +8,8 @@ import { User } from "./user";
import { getUsers } from "../../actions/admins";
import { getPolochons } from "../../actions/polochon";
const mapStateToProps = state => ({
users: state.adminStore.get("users")
const mapStateToProps = (state) => ({
users: state.adminStore.get("users"),
});
const mapDispatchToProps = { getUsers, getPolochons };
@ -57,7 +57,7 @@ const UserListConnect = ({ users, getUsers, getPolochons }) => {
UserListConnect.propTypes = {
getUsers: PropTypes.func,
getPolochons: PropTypes.func,
users: PropTypes.PropTypes.instanceOf(List)
users: PropTypes.PropTypes.instanceOf(List),
};
export const UserList = connect(

View File

@ -5,7 +5,7 @@ import { List } from "immutable";
import { Button, Modal } from "react-bootstrap";
import Toggle from "react-bootstrap-toggle";
export const UserList = props => (
export const UserList = (props) => (
<div className="table-responsive my-2">
<table className="table table-striped">
<thead className="table-secondary">
@ -29,10 +29,10 @@ export const UserList = props => (
);
UserList.propTypes = {
users: PropTypes.PropTypes.instanceOf(List),
updateUser: PropTypes.func
updateUser: PropTypes.func,
};
const User = function(props) {
const User = function (props) {
const polochonConfig = props.data.get("RawConfig").get("polochon");
const polochonUrl = polochonConfig ? polochonConfig.get("url") : "-";
const polochonToken = polochonConfig ? polochonConfig.get("token") : "-";
@ -61,15 +61,15 @@ const User = function(props) {
};
User.propTypes = {
data: PropTypes.object,
updateUser: PropTypes.func
updateUser: PropTypes.func,
};
const UserAdminStatus = props => (
const UserAdminStatus = (props) => (
<span className={props.admin ? "fa fa-check" : "fa fa-times"}></span>
);
UserAdminStatus.propTypes = { admin: PropTypes.bool.isRequired };
const UserActivationStatus = props => (
const UserActivationStatus = (props) => (
<span
className={props.activated ? "fa fa-check" : "fa fa-times text-danger"}
></span>
@ -83,7 +83,7 @@ function UserEdit(props) {
const [url, setUrl] = useState(props.polochonUrl);
const [token, setToken] = useState(props.polochonToken);
const handleSubmit = function(e) {
const handleSubmit = function (e) {
if (e) {
e.preventDefault();
}
@ -92,7 +92,7 @@ function UserEdit(props) {
admin: admin,
activated: activated,
polochonUrl: url,
polochonToken: token
polochonToken: token,
});
setModal(false);
};
@ -111,7 +111,7 @@ function UserEdit(props) {
</Modal.Title>
</Modal.Header>
<Modal.Body bsPrefix="modal-body admin-edit-user-modal">
<form className="form-horizontal" onSubmit={ev => handleSubmit(ev)}>
<form className="form-horizontal" onSubmit={(ev) => handleSubmit(ev)}>
<div className="form-group">
<label>Account status</label>
<Toggle
@ -141,7 +141,7 @@ function UserEdit(props) {
<input
className="form-control"
value={url}
onChange={e => setUrl(e.target.value)}
onChange={(e) => setUrl(e.target.value)}
/>
</div>
<div className="form-group">
@ -149,7 +149,7 @@ function UserEdit(props) {
<input
className="form-control"
value={token}
onChange={e => setToken(e.target.value)}
onChange={(e) => setToken(e.target.value)}
/>
</div>
</form>
@ -168,5 +168,5 @@ UserEdit.propTypes = {
data: PropTypes.object,
updateUser: PropTypes.func,
polochonUrl: PropTypes.string,
polochonToken: PropTypes.string
polochonToken: PropTypes.string,
};

View File

@ -5,14 +5,14 @@ import { connect } from "react-redux";
import { dismissAlert } from "../../actions/alerts";
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
show: state.alerts.get("show"),
title: state.alerts.get("message"),
type: state.alerts.get("type")
type: state.alerts.get("type"),
});
const mapDispatchToProps = { dismissAlert };
const Alert = props => {
const Alert = (props) => {
if (!props.show) {
return null;
}
@ -29,7 +29,7 @@ Alert.propTypes = {
show: PropTypes.bool.isRequired,
title: PropTypes.string.isRequired,
dismissAlert: PropTypes.func.isRequired,
type: PropTypes.string
type: PropTypes.string,
};
export default connect(mapStateToProps, mapDispatchToProps)(Alert);

View File

@ -19,7 +19,7 @@ export const DownloadAndStream = ({ url, name, subtitles }) => {
DownloadAndStream.propTypes = {
url: PropTypes.string,
name: PropTypes.string,
subtitles: PropTypes.instanceOf(List)
subtitles: PropTypes.instanceOf(List),
};
const DownloadButton = ({ url }) => (
@ -41,7 +41,7 @@ const StreamButton = ({ name, url, subtitles }) => {
<a
href="#"
className="btn btn-sm btn-primary m-1 clickable"
onClick={e => {
onClick={(e) => {
e.preventDefault();
setShowModal(true);
}}
@ -68,7 +68,7 @@ const StreamButton = ({ name, url, subtitles }) => {
StreamButton.propTypes = {
name: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
subtitles: PropTypes.instanceOf(List)
subtitles: PropTypes.instanceOf(List),
};
const Player = ({ url, subtitles }) => {
@ -95,8 +95,8 @@ const Player = ({ url, subtitles }) => {
};
Player.propTypes = {
subtitles: PropTypes.instanceOf(List),
url: PropTypes.string.isRequired
url: PropTypes.string.isRequired,
};
Player.defaultProps = {
subtitles: List()
subtitles: List(),
};

View File

@ -7,7 +7,7 @@ export const ImdbBadge = ({ imdbId }) => {
}
return (
<h5 className="d-inline">
<span className="d-inline">
<a
className="btn btn-sm btn-warning m-1"
href={`https://www.imdb.com/title/${imdbId}`}
@ -15,7 +15,7 @@ export const ImdbBadge = ({ imdbId }) => {
IMDb
<i className="ml-1 fa fa-external-link"></i>
</a>
</h5>
</span>
);
};
ImdbBadge.propTypes = { imdbId: PropTypes.string };

View File

@ -27,9 +27,9 @@ export const ShowMore = ({ children, id, inLibrary }) => {
ShowMore.propTypes = {
id: PropTypes.string,
inLibrary: PropTypes.bool.isRequired,
children: PropTypes.oneOfType([PropTypes.object, PropTypes.array])
children: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
};
ShowMore.defaultProps = {
id: "",
inLibrary: false
inLibrary: false,
};

View File

@ -8,7 +8,7 @@ export const SubtitlesButton = ({
subtitles,
inLibrary,
searching,
search
search,
}) => {
if (inLibrary === false) {
return null;
@ -17,7 +17,7 @@ export const SubtitlesButton = ({
const [show, setShow] = useState(false);
/* eslint-enable */
const onSelect = eventKey => {
const onSelect = (eventKey) => {
if (eventKey === null || eventKey != 1) {
setShow(false);
}
@ -68,5 +68,5 @@ SubtitlesButton.propTypes = {
subtitles: PropTypes.instanceOf(List),
inLibrary: PropTypes.bool.isRequired,
searching: PropTypes.bool.isRequired,
search: PropTypes.func.isRequired
search: PropTypes.func.isRequired,
};

View File

@ -13,7 +13,7 @@ function buildMenuItems(torrents) {
return [];
}
const t = torrents.groupBy(el => el.get("source"));
const t = torrents.groupBy((el) => el.get("source"));
// Build the array of entries
let entries = [];
@ -22,7 +22,7 @@ function buildMenuItems(torrents) {
// Push the title
entries.push({
type: "header",
value: source
value: source,
});
// Push the torrents
@ -31,7 +31,7 @@ function buildMenuItems(torrents) {
type: "entry",
quality: torrent.get("quality"),
url: torrent.get("url"),
size: torrent.get("size")
size: torrent.get("size"),
});
}
@ -52,7 +52,7 @@ const torrentsButton = ({ torrents, search, searching, addTorrent, url }) => {
const entries = buildMenuItems(torrents);
const count = torrents && torrents.size !== 0 ? torrents.size : 0;
const onSelect = eventKey => {
const onSelect = (eventKey) => {
// Close the dropdown if the eventkey is not specified
if (eventKey === null) {
setShow(false);
@ -116,10 +116,10 @@ torrentsButton.propTypes = {
searching: PropTypes.bool,
search: PropTypes.func.isRequired,
addTorrent: PropTypes.func.isRequired,
url: PropTypes.string
url: PropTypes.string,
};
torrentsButton.defaultProps = {
torrents: List()
torrents: List(),
};
export const TorrentsButton = connect(null, { addTorrent })(torrentsButton);

View File

@ -13,5 +13,5 @@ export const WishlistButton = ({ wishlisted, wishlist }) => {
};
WishlistButton.propTypes = {
wishlisted: PropTypes.bool.isRequired,
wishlist: PropTypes.func.isRequired
wishlist: PropTypes.func.isRequired,
};

View File

@ -10,7 +10,7 @@ export const Genres = ({ genres }) => {
// Uppercase first genres
const prettyGenres = genres
.toJS()
.map(word => word[0].toUpperCase() + word.substr(1))
.map((word) => word[0].toUpperCase() + word.substr(1))
.join(", ");
return (

View File

@ -6,14 +6,14 @@ export const PolochonMetadata = ({
container,
videoCodec,
audioCodec,
releaseGroup
releaseGroup,
}) => {
if (!quality || quality === "") {
return null;
}
const metadata = [quality, container, videoCodec, audioCodec, releaseGroup]
.filter(m => m && m !== "")
.filter((m) => m && m !== "")
.join(", ");
return (
@ -28,5 +28,5 @@ PolochonMetadata.propTypes = {
container: PropTypes.string,
videoCodec: PropTypes.string,
audioCodec: PropTypes.string,
releaseGroup: PropTypes.string
releaseGroup: PropTypes.string,
};

View File

@ -16,9 +16,9 @@ export const Rating = ({ rating, votes }) => {
};
Rating.propTypes = {
rating: PropTypes.number,
votes: PropTypes.number
votes: PropTypes.number,
};
Rating.defaultProps = {
rating: 0,
votes: 0
votes: 0,
};

View File

@ -2,7 +2,7 @@ import React from "react";
import PropTypes from "prop-types";
import moment from "moment";
const prettyDate = input => {
const prettyDate = (input) => {
switch (typeof input) {
case "string":
if (input === "") {
@ -46,6 +46,6 @@ export const ReleaseDate = ({ date }) => {
);
};
ReleaseDate.propTypes = {
date: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
date: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
};
ReleaseDate.defaultProps = { date: "" };

View File

@ -18,8 +18,8 @@ export const Title = ({ title, wishlist, wishlisted }) => {
Title.propTypes = {
title: PropTypes.string,
wishlist: PropTypes.func,
wishlisted: PropTypes.bool
wishlisted: PropTypes.bool,
};
Title.defaultProps = {
title: ""
title: "",
};

View File

@ -5,7 +5,7 @@ export const TrackingLabel = ({
wishlisted,
inLibrary,
trackedSeason,
trackedEpisode
trackedEpisode,
}) => {
if (wishlisted === false) {
return null;
@ -42,5 +42,5 @@ TrackingLabel.propTypes = {
wishlisted: PropTypes.bool,
inLibrary: PropTypes.bool,
trackedSeason: PropTypes.number,
trackedEpisode: PropTypes.number
trackedEpisode: PropTypes.number,
};

View File

@ -8,7 +8,7 @@ export const FormInput = ({ label, value, updateValue }) => {
<input
className="form-control"
value={value}
onChange={e => updateValue(e.target.value)}
onChange={(e) => updateValue(e.target.value)}
/>
</div>
);
@ -16,5 +16,5 @@ export const FormInput = ({ label, value, updateValue }) => {
FormInput.propTypes = {
label: PropTypes.string,
value: PropTypes.string,
updateValue: PropTypes.func
updateValue: PropTypes.func,
};

View File

@ -9,9 +9,9 @@ export const FormModal = ({
title,
icon,
handleSubmit,
children
children,
}) => {
const submit = function(e) {
const submit = function (e) {
if (e) {
e.preventDefault();
}
@ -27,7 +27,7 @@ export const FormModal = ({
</Modal.Title>
</Modal.Header>
<Modal.Body bsPrefix="modal-body">
<form className="form-horizontal" onSubmit={ev => submit(ev)}>
<form className="form-horizontal" onSubmit={(ev) => submit(ev)}>
{children}
</form>
</Modal.Body>
@ -48,5 +48,5 @@ FormModal.propTypes = {
icon: PropTypes.string,
title: PropTypes.string,
handleSubmit: PropTypes.func,
children: PropTypes.oneOfType([PropTypes.object, PropTypes.array])
children: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
};

View File

@ -16,7 +16,7 @@ import { ReleaseDate } from "../details/releaseDate";
import { Runtime } from "../details/runtime";
import { Title } from "../details/title";
const ListDetails = props => {
const ListDetails = (props) => {
if (props.data === undefined) {
return null;
}
@ -68,6 +68,6 @@ ListDetails.propTypes = {
data: PropTypes.instanceOf(Map),
wishlist: PropTypes.func,
loading: PropTypes.bool,
children: PropTypes.object
children: PropTypes.object,
};
export default ListDetails;

View File

@ -19,23 +19,23 @@ const ExplorerOptions = ({ display, params, options, type, history }) => {
return null;
}
const handleSourceChange = event => {
const handleSourceChange = (event) => {
let source = event.target.value;
let category = options.get(event.target.value).first();
history.push(`/${type}/explore/${source}/${category}`);
};
const handleCategoryChange = event => {
const handleCategoryChange = (event) => {
let source = params.source;
let category = event.target.value;
history.push(`/${type}/explore/${source}/${category}`);
};
const prettyName = name => {
const prettyName = (name) => {
return name
.replace("_", " ")
.split(" ")
.map(w => w[0].toUpperCase() + w.substr(1))
.map((w) => w[0].toUpperCase() + w.substr(1))
.join(" ");
};
@ -62,7 +62,7 @@ const ExplorerOptions = ({ display, params, options, type, history }) => {
onChange={handleSourceChange}
value={source}
>
{options.keySeq().map(function(source) {
{options.keySeq().map(function (source) {
return (
<option key={source} value={source}>
{prettyName(source)}
@ -81,7 +81,7 @@ const ExplorerOptions = ({ display, params, options, type, history }) => {
onChange={handleCategoryChange}
value={category}
>
{categories.map(function(category) {
{categories.map(function (category) {
return (
<option key={category} value={category}>
{prettyName(category)}
@ -102,7 +102,7 @@ ExplorerOptions.propTypes = {
history: PropTypes.object,
type: PropTypes.string,
options: PropTypes.object,
display: PropTypes.bool
display: PropTypes.bool,
};
export default withRouter(ExplorerOptions);

View File

@ -17,7 +17,7 @@ const ListFilter = ({ placeHolder, updateFilter }) => {
type="text"
className="form-control"
placeholder={placeHolder}
onChange={e => setFilter(e.target.value)}
onChange={(e) => setFilter(e.target.value)}
value={filter}
/>
<div className="input-group-append d-none d-md-block">
@ -28,6 +28,6 @@ const ListFilter = ({ placeHolder, updateFilter }) => {
};
ListFilter.propTypes = {
updateFilter: PropTypes.func.isRequired,
placeHolder: PropTypes.string.isRequired
placeHolder: PropTypes.string.isRequired,
};
export default ListFilter;

View File

@ -22,7 +22,7 @@ Poster.propTypes = {
url: PropTypes.string,
selected: PropTypes.bool.isRequired,
onClick: PropTypes.func,
onDoubleClick: PropTypes.func
onDoubleClick: PropTypes.func,
};
export default Poster;

View File

@ -10,7 +10,7 @@ import Poster from "./poster";
import Loader from "../loader/loader";
const ListPosters = props => {
const ListPosters = (props) => {
if (props.loading) {
return <Loader />;
}
@ -20,7 +20,7 @@ const ListPosters = props => {
// Filter the list of elements
if (props.filter !== "") {
elmts = elmts.filter(v => fuzzy.test(props.filter, v.get("title")));
elmts = elmts.filter((v) => fuzzy.test(props.filter, v.get("title")));
} else {
elmts = elmts.slice(0, listSize.items);
}
@ -80,7 +80,7 @@ ListPosters.propTypes = {
type: PropTypes.string.isRequired,
placeHolder: PropTypes.string.isRequired,
updateFilter: PropTypes.func.isRequired,
filter: PropTypes.string
filter: PropTypes.string,
};
export default ListPosters;
@ -90,7 +90,7 @@ const Posters = ({
onKeyEnter,
selectedImdbId,
selectPoster,
onDoubleClick
onDoubleClick,
}) => {
const addMoreCount = 20;
const [size, setSize] = useState(0);
@ -113,7 +113,7 @@ const Posters = ({
}, [elmts.size, loadMore]);
const move = useCallback(
event => {
(event) => {
// Only run the function if nothing else if actively focused
if (document.activeElement.tagName.toLowerCase() !== "body") {
return;
@ -144,7 +144,7 @@ const Posters = ({
}
// Get the index of the currently selected item
const idx = elmts.keySeq().findIndex(k => k === selectedImdbId);
const idx = elmts.keySeq().findIndex((k) => k === selectedImdbId);
var newIdx = idx + diff;
@ -170,11 +170,11 @@ const Posters = ({
posterHeight,
postersPerRow,
selectPoster,
selectedImdbId
selectedImdbId,
]
);
const posterCount = node => {
const posterCount = (node) => {
if (node === null) {
return;
}
@ -223,7 +223,7 @@ const Posters = ({
{elmts
.slice(0, size)
.toIndexedSeq()
.map(function(el, index) {
.map(function (el, index) {
const imdbId = el.get("imdb_id");
const selected = imdbId === selectedImdbId ? true : false;
@ -247,5 +247,5 @@ Posters.propTypes = {
loading: PropTypes.bool.isRequired,
onDoubleClick: PropTypes.func,
onKeyEnter: PropTypes.func,
selectPoster: PropTypes.func
selectPoster: PropTypes.func,
};

View File

@ -6,7 +6,7 @@ import { Map, List } from "immutable";
// TODO: udpate this
import { OverlayTrigger, Tooltip } from "react-bootstrap";
const Modules = props => {
const Modules = (props) => {
if (props.isLoading) {
return <Loader />;
}
@ -28,13 +28,13 @@ const Modules = props => {
};
Modules.propTypes = {
isLoading: PropTypes.bool.isRequired,
modules: PropTypes.instanceOf(Map)
modules: PropTypes.instanceOf(Map),
};
export default Modules;
const capitalize = string => string.charAt(0).toUpperCase() + string.slice(1);
const capitalize = (string) => string.charAt(0).toUpperCase() + string.slice(1);
const ModulesByVideoType = props => (
const ModulesByVideoType = (props) => (
<div className="col-12 col-md-6">
<div className="card mb-3">
<div className="card-header">
@ -50,15 +50,15 @@ const ModulesByVideoType = props => (
);
ModulesByVideoType.propTypes = {
videoType: PropTypes.string.isRequired,
data: PropTypes.instanceOf(Map)
data: PropTypes.instanceOf(Map),
};
const ModuleByType = props => (
const ModuleByType = (props) => (
<div>
<h4>{capitalize(props.type)}</h4>
<table className="table">
<tbody>
{props.data.map(function(value, key) {
{props.data.map(function (value, key) {
return <Module key={key} type={key} data={value} />;
})}
</tbody>
@ -67,10 +67,10 @@ const ModuleByType = props => (
);
ModuleByType.propTypes = {
type: PropTypes.string.isRequired,
data: PropTypes.instanceOf(List)
data: PropTypes.instanceOf(List),
};
const Module = props => {
const Module = (props) => {
let iconClass, prettyStatus, badgeClass;
const name = props.data.get("name");
@ -121,5 +121,5 @@ const Module = props => {
);
};
Module.propTypes = {
data: PropTypes.instanceOf(Map)
data: PropTypes.instanceOf(Map),
};

View File

@ -5,7 +5,7 @@ import { connect } from "react-redux";
import {
selectMovie,
updateFilter,
movieWishlistToggle
movieWishlistToggle,
} from "../../actions/movies";
import ListDetails from "../list/details";
@ -24,16 +24,16 @@ function mapStateToProps(state) {
movies: state.movieStore.get("movies"),
filter: state.movieStore.get("filter"),
selectedImdbId: state.movieStore.get("selectedImdbId"),
exploreOptions: state.movieStore.get("exploreOptions")
exploreOptions: state.movieStore.get("exploreOptions"),
};
}
const mapDispatchToProps = {
selectMovie,
updateFilter,
movieWishlistToggle
movieWishlistToggle,
};
const MovieList = props => {
const MovieList = (props) => {
let selectedMovie = Map();
if (props.movies !== undefined && props.movies.has(props.selectedImdbId)) {
selectedMovie = props.movies.get(props.selectedImdbId);
@ -50,10 +50,10 @@ const MovieList = props => {
updateFilter={props.updateFilter}
filter={props.filter}
onClick={props.selectMovie}
onDoubleClick={function() {
onDoubleClick={function () {
return;
}}
onKeyEnter={function() {
onKeyEnter={function () {
return;
}}
params={props.match.params}
@ -99,7 +99,7 @@ MovieList.propTypes = {
updateFilter: PropTypes.func,
movieWishlistToggle: PropTypes.func,
selectMovie: PropTypes.func,
match: PropTypes.object
match: PropTypes.object,
};
export default connect(mapStateToProps, mapDispatchToProps)(MovieList);

View File

@ -4,8 +4,8 @@ import { Route } from "react-router-dom";
import { connect } from "react-redux";
import { fetchMovies, getMovieExploreOptions } from "../../actions/movies";
const mapStateToProps = state => ({
isExplorerFetched: state.movieStore.get("exploreOptions").size !== 0
const mapStateToProps = (state) => ({
isExplorerFetched: state.movieStore.get("exploreOptions").size !== 0,
});
const mapDispatchToProps = { fetchMovies, getMovieExploreOptions };
@ -19,7 +19,7 @@ const MoviesRoute = ({
return (
<Route
{...otherProps}
render={props => {
render={(props) => {
let fetchUrl = "";
switch (props.match.path) {
case "/movies/polochon":
@ -59,7 +59,7 @@ MoviesRoute.propTypes = {
match: PropTypes.object,
isExplorerFetched: PropTypes.bool.isRequired,
fetchMovies: PropTypes.func.isRequired,
getMovieExploreOptions: PropTypes.func.isRequired
getMovieExploreOptions: PropTypes.func.isRequired,
};
export default connect(mapStateToProps, mapDispatchToProps)(MoviesRoute);

View File

@ -12,7 +12,7 @@ const movieSubtitlesButton = ({
imdbId,
searching,
searchMovieSubtitles,
subtitles
subtitles,
}) => (
<SubtitlesButton
inLibrary={inLibrary}
@ -27,7 +27,7 @@ movieSubtitlesButton.propTypes = {
inLibrary: PropTypes.bool,
imdbId: PropTypes.string,
searchMovieSubtitles: PropTypes.func,
subtitles: PropTypes.instanceOf(List)
subtitles: PropTypes.instanceOf(List),
};
export const MovieSubtitlesButton = connect(null, { searchMovieSubtitles })(

View File

@ -11,7 +11,7 @@ const movieTorrentsButton = ({
imdbId,
title,
searching,
getMovieDetails
getMovieDetails,
}) => (
<TorrentsButton
torrents={torrents}
@ -25,7 +25,7 @@ movieTorrentsButton.propTypes = {
imdbId: PropTypes.string,
title: PropTypes.string,
searching: PropTypes.bool,
getMovieDetails: PropTypes.func
getMovieDetails: PropTypes.func,
};
export const MovieTorrentsButton = connect(null, { getMovieDetails })(

View File

@ -8,7 +8,7 @@ import Nav from "react-bootstrap/Nav";
import Navbar from "react-bootstrap/Navbar";
import NavDropdown from "react-bootstrap/NavDropdown";
const mapStateToProps = state => {
const mapStateToProps = (state) => {
let torrentCount = 0;
if (
state.torrentStore.has("torrents") &&
@ -19,11 +19,11 @@ const mapStateToProps = state => {
return {
username: state.userStore.get("username"),
isAdmin: state.userStore.get("isAdmin"),
torrentCount: torrentCount
torrentCount: torrentCount,
};
};
const AppNavBar = props => {
const AppNavBar = (props) => {
const [expanded, setExpanded] = useState(false);
return (
@ -50,7 +50,7 @@ const AppNavBar = props => {
<Nav>
<Route
path="/movies"
render={props => (
render={(props) => (
<Search
placeholder="Search movies"
path="/movies/search"
@ -61,7 +61,7 @@ const AppNavBar = props => {
/>
<Route
path="/shows"
render={props => (
render={(props) => (
<Search
placeholder="Search shows"
path="/shows/search"
@ -80,7 +80,7 @@ AppNavBar.propTypes = {
torrentCount: PropTypes.number.isRequired,
username: PropTypes.string.isRequired,
isAdmin: PropTypes.bool.isRequired,
history: PropTypes.object
history: PropTypes.object,
};
export default connect(mapStateToProps)(AppNavBar);
@ -88,7 +88,7 @@ export default connect(mapStateToProps)(AppNavBar);
const Search = ({ path, placeholder, setExpanded, history }) => {
const [search, setSearch] = useState("");
const handleSearch = ev => {
const handleSearch = (ev) => {
ev.preventDefault();
history.push(`${path}/${encodeURI(search)}`);
setExpanded(false);
@ -96,12 +96,12 @@ const Search = ({ path, placeholder, setExpanded, history }) => {
return (
<div className="navbar-form navbar-right">
<form className="input-group" onSubmit={ev => handleSearch(ev)}>
<form className="input-group" onSubmit={(ev) => handleSearch(ev)}>
<input
className="form-control"
placeholder={placeholder}
value={search}
onChange={e => setSearch(e.target.value)}
onChange={(e) => setSearch(e.target.value)}
/>
</form>
</div>
@ -111,7 +111,7 @@ Search.propTypes = {
placeholder: PropTypes.string.isRequired,
setExpanded: PropTypes.func.isRequired,
path: PropTypes.string.isRequired,
history: PropTypes.object
history: PropTypes.object,
};
const MoviesDropdown = () => (
@ -136,7 +136,7 @@ const ShowsDropdown = () => (
</NavDropdown>
);
const UserDropdown = props => (
const UserDropdown = (props) => (
<Nav>
<NavDropdown title={props.username} alignRight>
{props.isAdmin && (
@ -158,7 +158,7 @@ const UserDropdown = props => (
);
UserDropdown.propTypes = {
username: PropTypes.string.isRequired,
isAdmin: PropTypes.bool.isRequired
isAdmin: PropTypes.bool.isRequired,
};
const WishlistDropdown = () => (
@ -172,7 +172,7 @@ const WishlistDropdown = () => (
</NavDropdown>
);
const TorrentsDropdown = props => {
const TorrentsDropdown = (props) => {
const title = <TorrentsDropdownTitle torrentsCount={props.torrentsCount} />;
return (
<NavDropdown title={title} id="navbar-wishlit-dropdown">
@ -187,7 +187,7 @@ const TorrentsDropdown = props => {
};
TorrentsDropdown.propTypes = { torrentsCount: PropTypes.number.isRequired };
const TorrentsDropdownTitle = props => {
const TorrentsDropdownTitle = (props) => {
if (props.torrentsCount === 0) {
return <span>Torrents</span>;
}
@ -206,5 +206,5 @@ const TorrentsDropdownTitle = props => {
);
};
TorrentsDropdownTitle.propTypes = {
torrentsCount: PropTypes.number.isRequired
torrentsCount: PropTypes.number.isRequired,
};

View File

@ -14,7 +14,7 @@ const NotificationConnected = ({
imageUrl,
autohide,
delay,
removeNotification
removeNotification,
}) => {
const [show, setShow] = useState(true);
@ -46,7 +46,7 @@ NotificationConnected.propTypes = {
imageUrl: PropTypes.string,
autohide: PropTypes.bool,
delay: PropTypes.number,
removeNotification: PropTypes.func
removeNotification: PropTypes.func,
};
NotificationConnected.defaultProps = {
@ -55,7 +55,7 @@ NotificationConnected.defaultProps = {
icon: "",
imageUrl: "",
title: "Info",
message: ""
message: "",
};
export const Notification = connect(null, { removeNotification })(

View File

@ -8,7 +8,7 @@ import { Notification } from "./notification";
const NotificationsConnected = ({ notifications }) => {
return (
<div className="notifications">
{notifications.map(el => (
{notifications.map((el) => (
<Notification
key={el.get("id")}
id={el.get("id")}
@ -24,11 +24,11 @@ const NotificationsConnected = ({ notifications }) => {
);
};
NotificationsConnected.propTypes = {
notifications: PropTypes.instanceOf(List)
notifications: PropTypes.instanceOf(List),
};
const mapStateToProps = state => ({
notifications: state.notifications
const mapStateToProps = (state) => ({
notifications: state.notifications,
});
export const Notifications = connect(mapStateToProps)(NotificationsConnected);

View File

@ -27,7 +27,7 @@ export const PolochonAddConnected = ({ addPolochon }) => {
);
};
PolochonAddConnected.propTypes = {
addPolochon: PropTypes.func
addPolochon: PropTypes.func,
};
export const PolochonAdd = connect(null, { addPolochon })(PolochonAddConnected);

View File

@ -13,7 +13,7 @@ export const PolochonEdit = ({
initialName,
initialUrl,
initialToken,
update
update,
}) => {
const [name, setName] = useState(initialName);
const [url, setUrl] = useState(initialUrl);
@ -53,7 +53,7 @@ PolochonEdit.propTypes = {
id: PropTypes.string,
initialName: PropTypes.string,
initialUrl: PropTypes.string,
initialToken: PropTypes.string
initialToken: PropTypes.string,
};
PolochonEdit.defaultProps = {
id: "",
@ -61,5 +61,5 @@ PolochonEdit.defaultProps = {
icon: "edit",
initialName: "",
initialUrl: "",
initialToken: ""
initialToken: "",
};

View File

@ -8,12 +8,12 @@ import { getManagedPolochons } from "../../actions/polochon";
import { Polochon } from "./polochon";
import { PolochonAdd } from "./add";
const mapStateToProps = state => ({
managedList: state.polochon.get("managed")
const mapStateToProps = (state) => ({
managedList: state.polochon.get("managed"),
});
const mapDispatchToProps = {
getManagedPolochons
getManagedPolochons,
};
const PolochonListConnected = ({ getManagedPolochons, managedList }) => {
@ -46,7 +46,7 @@ const PolochonListConnected = ({ getManagedPolochons, managedList }) => {
};
PolochonListConnected.propTypes = {
getManagedPolochons: PropTypes.func,
managedList: PropTypes.instanceOf(List)
managedList: PropTypes.instanceOf(List),
};
export const PolochonList = connect(

View File

@ -16,7 +16,7 @@ export const PolochonConnected = ({
authToken,
users,
updatePolochon,
deletePolochon
deletePolochon,
}) => {
const [edit, setEdit] = useState(false);
@ -66,7 +66,7 @@ PolochonConnected.propTypes = {
authToken: PropTypes.string,
users: PropTypes.instanceOf(List),
updatePolochon: PropTypes.func,
deletePolochon: PropTypes.func
deletePolochon: PropTypes.func,
};
export const Polochon = connect(null, { updatePolochon, deletePolochon })(

View File

@ -7,7 +7,7 @@ export const PolochonSelect = ({ value, changeValue, polochonList }) => {
<select
className="form-control"
value={value}
onChange={e =>
onChange={(e) =>
changeValue(e.target.options[e.target.selectedIndex].value)
}
>
@ -22,5 +22,5 @@ export const PolochonSelect = ({ value, changeValue, polochonList }) => {
PolochonSelect.propTypes = {
value: PropTypes.string,
changeValue: PropTypes.func,
polochonList: PropTypes.instanceOf(List)
polochonList: PropTypes.instanceOf(List),
};

View File

@ -15,7 +15,7 @@ export const PolochonUserConnected = ({
name,
initialToken,
initialActivated,
editPolochonUser
editPolochonUser,
}) => {
const [edit, setEdit] = useState(false);
const [token, setToken] = useState(initialToken);
@ -31,7 +31,7 @@ export const PolochonUserConnected = ({
polochonId,
id,
token,
activated
activated,
});
setEdit(false);
};
@ -73,7 +73,7 @@ PolochonUserConnected.propTypes = {
name: PropTypes.string,
initialToken: PropTypes.string,
initialActivated: PropTypes.bool,
editPolochonUser: PropTypes.func
editPolochonUser: PropTypes.func,
};
export const PolochonUser = connect(null, { editPolochonUser })(

View File

@ -35,5 +35,5 @@ export const PolochonUsers = ({ id, users }) => {
};
PolochonUsers.propTypes = {
id: PropTypes.string,
users: PropTypes.instanceOf(List)
users: PropTypes.instanceOf(List),
};

View File

@ -9,9 +9,9 @@ import { Fanart } from "./details/fanart";
import { Header } from "./details/header";
import { SeasonsList } from "./details/seasons";
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
loading: state.showStore.get("loading"),
show: state.showStore.get("show")
show: state.showStore.get("show"),
});
const showDetails = ({ show, loading }) => {
@ -31,6 +31,6 @@ const showDetails = ({ show, loading }) => {
};
showDetails.propTypes = {
loading: PropTypes.bool,
show: PropTypes.instanceOf(Map)
show: PropTypes.instanceOf(Map),
};
export const ShowDetails = connect(mapStateToProps)(showDetails);

View File

@ -8,7 +8,7 @@ import { showWishlistToggle } from "../../../actions/shows";
import {
inLibrary,
isEpisodeWishlisted,
prettyEpisodeName
prettyEpisodeName,
} from "../../../utils";
import { Plot } from "../../details/plot";
@ -24,12 +24,12 @@ import { EpisodeSubtitlesButton } from "./subtitlesButton";
import { EpisodeThumb } from "./episodeThumb";
import { EpisodeTorrentsButton } from "./torrentsButton";
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
trackedSeason: state.showStore.getIn(["show", "tracked_season"], null),
trackedEpisode: state.showStore.getIn(["show", "tracked_episode"], null)
trackedEpisode: state.showStore.getIn(["show", "tracked_episode"], null),
});
const episode = props => (
const episode = (props) => (
<div className="d-flex flex-column flex-lg-row mb-3 pb-3 border-bottom border-light">
<EpisodeThumb url={props.data.get("thumb")} />
<div className="d-flex flex-column">
@ -102,7 +102,7 @@ episode.propTypes = {
trackedSeason: PropTypes.number,
trackedEpisode: PropTypes.number,
showName: PropTypes.string.isRequired,
showWishlistToggle: PropTypes.func
showWishlistToggle: PropTypes.func,
};
export const Episode = connect(mapStateToProps, { showWishlistToggle })(

View File

@ -10,5 +10,5 @@ export const Fanart = ({ url }) => (
</div>
);
Fanart.propTypes = {
url: PropTypes.string
url: PropTypes.string,
};

View File

@ -15,7 +15,7 @@ import { TrackingLabel } from "../../details/tracking";
import { ImdbBadge } from "../../buttons/imdb";
export const header = props => (
export const header = (props) => (
<div className="card col-12 col-md-10 offset-md-1 mt-n3 mb-3">
<div className="d-flex flex-column flex-md-row">
<div className="d-flex justify-content-center">
@ -64,7 +64,7 @@ export const header = props => (
);
header.propTypes = {
data: PropTypes.instanceOf(Map),
showWishlistToggle: PropTypes.func
showWishlistToggle: PropTypes.func,
};
export const Header = connect(null, { showWishlistToggle })(header);

View File

@ -4,7 +4,7 @@ import { Map } from "immutable";
import { Episode } from "./episode";
export const Season = props => {
export const Season = (props) => {
const [show, setShow] = useState(false);
return (
@ -22,7 +22,7 @@ export const Season = props => {
</h5>
</div>
<div className={`card-body ${show ? "d-flex flex-column" : "d-none"}`}>
{props.data.toList().map(function(episode) {
{props.data.toList().map(function (episode) {
let key = `${episode.get("season")}-${episode.get("episode")}`;
return (
<Episode
@ -47,5 +47,5 @@ Season.propTypes = {
addToWishlist: PropTypes.func,
addTorrent: PropTypes.func,
refreshSubtitles: PropTypes.func,
getEpisodeDetails: PropTypes.func
getEpisodeDetails: PropTypes.func,
};

View File

@ -4,12 +4,12 @@ import { Map } from "immutable";
import { Season } from "./season";
export const SeasonsList = props => (
export const SeasonsList = (props) => (
<div className="col col-12 col-md-10 offset-md-1">
{props.data
.get("seasons")
.entrySeq()
.map(function([season, data]) {
.map(function ([season, data]) {
if (season === 0) {
return null;
}
@ -33,5 +33,5 @@ SeasonsList.propTypes = {
addToWishlist: PropTypes.func,
addTorrent: PropTypes.func,
refreshSubtitles: PropTypes.func,
getEpisodeDetails: PropTypes.func
getEpisodeDetails: PropTypes.func,
};

View File

@ -14,7 +14,7 @@ const episodeSubtitlesButton = ({
episode,
searching,
searchEpisodeSubtitles,
subtitles
subtitles,
}) => (
<SubtitlesButton
subtitles={subtitles}
@ -31,7 +31,7 @@ episodeSubtitlesButton.propTypes = {
season: PropTypes.number,
episode: PropTypes.number,
searchEpisodeSubtitles: PropTypes.func,
subtitles: PropTypes.instanceOf(List)
subtitles: PropTypes.instanceOf(List),
};
export const EpisodeSubtitlesButton = connect(null, { searchEpisodeSubtitles })(

View File

@ -14,7 +14,7 @@ const episodeTorrentsButton = ({
episode,
showName,
searching,
getEpisodeDetails
getEpisodeDetails,
}) => (
<TorrentsButton
torrents={torrents}
@ -32,7 +32,7 @@ episodeTorrentsButton.propTypes = {
episode: PropTypes.number.isRequired,
season: PropTypes.number.isRequired,
searching: PropTypes.bool.isRequired,
getEpisodeDetails: PropTypes.func.isRequired
getEpisodeDetails: PropTypes.func.isRequired,
};
export const EpisodeTorrentsButton = connect(null, { getEpisodeDetails })(

View File

@ -6,7 +6,7 @@ import {
selectShow,
showWishlistToggle,
getShowDetails,
updateFilter
updateFilter,
} from "../../actions/shows";
import { isWishlisted } from "../../utils";
@ -20,18 +20,18 @@ function mapStateToProps(state) {
shows: state.showsStore.get("shows"),
filter: state.showsStore.get("filter"),
selectedImdbId: state.showsStore.get("selectedImdbId"),
exploreOptions: state.showsStore.get("exploreOptions")
exploreOptions: state.showsStore.get("exploreOptions"),
};
}
const mapDispatchToProps = {
selectShow,
showWishlistToggle,
getShowDetails,
updateFilter
updateFilter,
};
const ShowList = props => {
const showDetails = imdbId => {
const ShowList = (props) => {
const showDetails = (imdbId) => {
props.history.push("/shows/details/" + imdbId);
};
@ -90,6 +90,6 @@ ShowList.propTypes = {
showWishlistToggle: PropTypes.func,
selectShow: PropTypes.func,
getShowDetails: PropTypes.func,
updateFilter: PropTypes.func
updateFilter: PropTypes.func,
};
export default connect(mapStateToProps, mapDispatchToProps)(ShowList);

View File

@ -5,16 +5,16 @@ import { connect } from "react-redux";
import {
fetchShows,
fetchShowDetails,
getShowExploreOptions
getShowExploreOptions,
} from "../../actions/shows";
const mapStateToProps = state => ({
isExplorerFetched: state.showsStore.get("exploreOptions").size !== 0
const mapStateToProps = (state) => ({
isExplorerFetched: state.showsStore.get("exploreOptions").size !== 0,
});
const mapDispatchToProps = {
fetchShows,
fetchShowDetails,
getShowExploreOptions
getShowExploreOptions,
};
const ShowsRoute = ({
@ -28,7 +28,7 @@ const ShowsRoute = ({
return (
<Route
{...otherProps}
render={props => {
render={(props) => {
let fetchUrl = "";
switch (props.match.path) {
case "/shows/polochon":
@ -65,12 +65,12 @@ const ShowsRoute = ({
);
};
ShowsRoute.propTypes = {
component: PropTypes.func,
component: PropTypes.object,
match: PropTypes.object,
isExplorerFetched: PropTypes.bool.isRequired,
fetchShows: PropTypes.func.isRequired,
fetchShowDetails: PropTypes.func.isRequired,
getShowExploreOptions: PropTypes.func.isRequired
getShowExploreOptions: PropTypes.func.isRequired,
};
export default connect(mapStateToProps, mapDispatchToProps)(ShowsRoute);

View File

@ -7,19 +7,19 @@ import { prettySize } from "../../utils";
import {
fetchTorrents,
addTorrent,
removeTorrent
removeTorrent,
} from "../../actions/torrents";
const mapStateToProps = state => ({
torrents: state.torrentStore.get("torrents")
const mapStateToProps = (state) => ({
torrents: state.torrentStore.get("torrents"),
});
const mapDispatchToProps = {
fetchTorrents,
addTorrent,
removeTorrent
removeTorrent,
};
const TorrentList = props => (
const TorrentList = (props) => (
<div className="row">
<div className="col-12">
<AddTorrent addTorrent={props.addTorrent} />
@ -31,14 +31,14 @@ TorrentList.propTypes = {
fetchTorrents: PropTypes.func.isRequired,
addTorrent: PropTypes.func.isRequired,
removeTorrent: PropTypes.func.isRequired,
torrents: PropTypes.instanceOf(List)
torrents: PropTypes.instanceOf(List),
};
export default connect(mapStateToProps, mapDispatchToProps)(TorrentList);
const AddTorrent = props => {
const AddTorrent = (props) => {
const [url, setUrl] = useState("");
const handleSubmit = e => {
const handleSubmit = (e) => {
e.preventDefault();
if (url === "") {
return;
@ -48,23 +48,23 @@ const AddTorrent = props => {
};
return (
<form onSubmit={e => handleSubmit(e)}>
<form onSubmit={(e) => handleSubmit(e)}>
<input
type="text"
className="form-control mb-3 w-100"
placeholder="Add torrent URL"
onSubmit={handleSubmit}
value={url}
onChange={e => setUrl(e.target.value)}
onChange={(e) => setUrl(e.target.value)}
/>
</form>
);
};
AddTorrent.propTypes = {
addTorrent: PropTypes.func.isRequired
addTorrent: PropTypes.func.isRequired,
};
const Torrents = props => {
const Torrents = (props) => {
if (props.torrents.size === 0) {
return (
<div className="jumbotron">
@ -83,10 +83,10 @@ const Torrents = props => {
};
Torrents.propTypes = {
removeTorrent: PropTypes.func.isRequired,
torrents: PropTypes.instanceOf(List)
torrents: PropTypes.instanceOf(List),
};
const Torrent = props => {
const Torrent = (props) => {
const handleClick = () => {
props.removeTorrent(props.data.get("id"));
};
@ -141,5 +141,5 @@ const Torrent = props => {
};
Torrent.propTypes = {
removeTorrent: PropTypes.func.isRequired,
data: PropTypes.instanceOf(Map)
data: PropTypes.instanceOf(Map),
};

View File

@ -9,9 +9,9 @@ import { OverlayTrigger, Tooltip } from "react-bootstrap";
import { prettySize } from "../../utils";
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
searching: state.torrentStore.get("searching"),
results: state.torrentStore.get("searchResults")
results: state.torrentStore.get("searchResults"),
});
const mapDispatchToProps = { addTorrent, searchTorrents };
@ -21,7 +21,7 @@ const TorrentSearch = ({
results,
addTorrent,
history,
match
match,
}) => {
const [search, setSearch] = useState(match.params.search || "");
const [type, setType] = useState(match.params.type || "");
@ -52,7 +52,7 @@ const TorrentSearch = ({
className="form-control mb-1 w-100 form-control-lg"
placeholder="Search torrents"
value={search}
onChange={e => setSearch(e.target.value)}
onChange={(e) => setSearch(e.target.value)}
/>
<div className="mb-3 w-100 d-flex">
<SearchButton
@ -93,10 +93,10 @@ TorrentSearch.propTypes = {
match: PropTypes.object,
history: PropTypes.object,
addTorrent: PropTypes.func.isRequired,
searchTorrents: PropTypes.func.isRequired
searchTorrents: PropTypes.func.isRequired,
};
const SearchButton = props => {
const SearchButton = (props) => {
const variant = props.type === props.typeFromURL ? "primary" : "secondary";
return (
<button
@ -112,10 +112,10 @@ SearchButton.propTypes = {
type: PropTypes.string,
typeFromURL: PropTypes.string,
text: PropTypes.string,
handleClick: PropTypes.func.isRequired
handleClick: PropTypes.func.isRequired,
};
const TorrentList = props => {
const TorrentList = (props) => {
if (props.searching) {
return <Loader />;
}
@ -134,7 +134,7 @@ const TorrentList = props => {
return (
<React.Fragment>
{props.results.map(function(el, index) {
{props.results.map(function (el, index) {
return <Torrent key={index} data={el} addTorrent={props.addTorrent} />;
})}
</React.Fragment>
@ -144,10 +144,10 @@ TorrentList.propTypes = {
searching: PropTypes.bool.isRequired,
results: PropTypes.instanceOf(List),
searchFromURL: PropTypes.string,
addTorrent: PropTypes.func.isRequired
addTorrent: PropTypes.func.isRequired,
};
const Torrent = props => (
const Torrent = (props) => (
<div className="alert d-flex border-bottom border-secondary align-items-center">
<TorrentHealth
url={props.data.get("url")}
@ -184,10 +184,10 @@ const Torrent = props => (
);
Torrent.propTypes = {
data: PropTypes.instanceOf(Map),
addTorrent: PropTypes.func.isRequired
addTorrent: PropTypes.func.isRequired,
};
const TorrentHealth = props => {
const TorrentHealth = (props) => {
const seeders = props.seeders || 0;
const leechers = props.leechers || 1;
@ -230,7 +230,7 @@ const TorrentHealth = props => {
TorrentHealth.propTypes = {
url: PropTypes.string,
seeders: PropTypes.number,
leechers: PropTypes.number
leechers: PropTypes.number,
};
export default connect(mapStateToProps, mapDispatchToProps)(TorrentSearch);

View File

@ -3,12 +3,12 @@ import PropTypes from "prop-types";
import { connect } from "react-redux";
import { Redirect, Link } from "react-router-dom";
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
isActivated: state.userStore.get("isActivated"),
isLogged: state.userStore.get("isLogged")
isLogged: state.userStore.get("isLogged"),
});
const UserActivation = props => {
const UserActivation = (props) => {
if (!props.isLogged) {
return <Redirect to="/users/login" />;
}
@ -33,7 +33,7 @@ const UserActivation = props => {
};
UserActivation.propTypes = {
isActivated: PropTypes.bool.isRequired,
isLogged: PropTypes.bool.isRequired
isLogged: PropTypes.bool.isRequired,
};
export default connect(mapStateToProps)(UserActivation);

View File

@ -9,17 +9,17 @@ import { getPolochons } from "../../actions/polochon";
import { PolochonSelect } from "../polochons/select";
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
loading: state.userStore.get("loading"),
publicPolochons: state.polochon.get("public"),
polochonId: state.userStore.get("polochonId"),
polochonActivated: state.userStore.get("polochonActivated")
polochonActivated: state.userStore.get("polochonActivated"),
});
const mapDispatchToProps = {
updateUser,
getPolochons,
getUserInfos
getUserInfos,
};
const UserEditConnect = ({
@ -29,7 +29,7 @@ const UserEditConnect = ({
updateUser,
getPolochons,
getUserInfos,
publicPolochons
publicPolochons,
}) => {
const [id, setId] = useState(polochonId);
const [password, setPassword] = useState("");
@ -44,12 +44,12 @@ const UserEditConnect = ({
setId(polochonId);
}, [polochonId]);
const handleSubmit = ev => {
const handleSubmit = (ev) => {
ev.preventDefault();
updateUser({
password: password,
password_confirm: passwordConfirm, // eslint-disable-line camelcase
polochon_id: id // eslint-disable-line camelcase
polochon_id: id, // eslint-disable-line camelcase
});
};
@ -62,7 +62,7 @@ const UserEditConnect = ({
<div className="col-12 col-md-8 offset-md-2">
<h2>Edit user</h2>
<hr />
<form className="form-horizontal" onSubmit={ev => handleSubmit(ev)}>
<form className="form-horizontal" onSubmit={(ev) => handleSubmit(ev)}>
<div className="form-group">
<label className="control-label">
Polochon
@ -88,7 +88,7 @@ const UserEditConnect = ({
type="password"
autoComplete="off"
value={password}
onChange={e => setPassword(e.target.value)}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
@ -99,7 +99,7 @@ const UserEditConnect = ({
type="password"
autoComplete="off"
value={passwordConfirm}
onChange={e => setPasswordConfirm(e.target.value)}
onChange={(e) => setPasswordConfirm(e.target.value)}
/>
</div>
@ -122,7 +122,7 @@ UserEditConnect.propTypes = {
updateUser: PropTypes.func,
getPolochons: PropTypes.func,
getUserInfos: PropTypes.func,
publicPolochons: PropTypes.instanceOf(List)
publicPolochons: PropTypes.instanceOf(List),
};
export const UserEdit = connect(

View File

@ -5,18 +5,18 @@ import { Redirect, Link } from "react-router-dom";
import { loginUser } from "../../actions/users";
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
isLogged: state.userStore.get("isLogged"),
isLoading: state.userStore.get("loading"),
error: state.userStore.get("error")
error: state.userStore.get("error"),
});
const mapDispatchToProps = { loginUser };
const UserLoginForm = props => {
const UserLoginForm = (props) => {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const handleSubmit = e => {
const handleSubmit = (e) => {
e.preventDefault();
if (!props.isLoading) {
props.loginUser(username, password);
@ -35,7 +35,7 @@ const UserLoginForm = props => {
{props.error && props.error !== "" && (
<div className="alert alert-danger">{props.error}</div>
)}
<form className="form-horizontal" onSubmit={e => handleSubmit(e)}>
<form className="form-horizontal" onSubmit={(e) => handleSubmit(e)}>
<div>
<label>Username</label>
<br />
@ -44,7 +44,7 @@ const UserLoginForm = props => {
type="username"
autoFocus
value={username}
onChange={e => setUsername(e.target.value)}
onChange={(e) => setUsername(e.target.value)}
/>
<p></p>
</div>
@ -56,7 +56,7 @@ const UserLoginForm = props => {
type="password"
autoComplete="new-password"
value={password}
onChange={e => setPassword(e.target.value)}
onChange={(e) => setPassword(e.target.value)}
/>
<p></p>
</div>
@ -91,7 +91,7 @@ UserLoginForm.propTypes = {
loginUser: PropTypes.func.isRequired,
isLoading: PropTypes.bool.isRequired,
isLogged: PropTypes.bool.isRequired,
error: PropTypes.string
error: PropTypes.string,
};
export default connect(mapStateToProps, mapDispatchToProps)(UserLoginForm);

View File

@ -5,12 +5,12 @@ import { Redirect } from "react-router-dom";
import { userLogout } from "../../actions/users";
const mapStateToProps = state => ({
isLogged: state.userStore.get("isLogged")
const mapStateToProps = (state) => ({
isLogged: state.userStore.get("isLogged"),
});
const mapDispatchToProps = { userLogout };
const UserLogout = props => {
const UserLogout = (props) => {
if (props.isLogged) {
props.userLogout();
}
@ -20,7 +20,7 @@ const UserLogout = props => {
UserLogout.propTypes = {
isLogged: PropTypes.bool.isRequired,
userLogout: PropTypes.func.isRequired,
history: PropTypes.object
history: PropTypes.object,
};
export default connect(mapStateToProps, mapDispatchToProps)(UserLogout);

View File

@ -9,9 +9,9 @@ import { UserEdit } from "./edit";
import { getUserModules } from "../../actions/users";
import Modules from "../modules/modules";
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
modules: state.userStore.get("modules"),
modulesLoading: state.userStore.get("modulesLoading")
modulesLoading: state.userStore.get("modulesLoading"),
});
const mapDispatchToProps = { getUserModules };
@ -32,7 +32,7 @@ const UserProfile = ({ modules, modulesLoading, getUserModules }) => {
UserProfile.propTypes = {
getUserModules: PropTypes.func.isRequired,
modules: PropTypes.instanceOf(Map),
modulesLoading: PropTypes.bool.isRequired
modulesLoading: PropTypes.bool.isRequired,
};
export default connect(mapStateToProps, mapDispatchToProps)(UserProfile);

View File

@ -5,14 +5,14 @@ import { Redirect } from "react-router-dom";
import { userSignUp } from "../../actions/users";
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
isLogged: state.userStore.get("isLogged"),
isLoading: state.userStore.get("loading"),
error: state.userStore.get("error")
error: state.userStore.get("error"),
});
const mapDispatchToProps = { userSignUp };
const UserSignUp = props => {
const UserSignUp = (props) => {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [passwordConfirm, setPasswordConfirm] = useState("");
@ -21,12 +21,12 @@ const UserSignUp = props => {
return <Redirect to="/" />;
}
const handleSubmit = e => {
const handleSubmit = (e) => {
e.preventDefault();
props.userSignUp({
username: username,
password: password,
password_confirm: passwordConfirm // eslint-disable-line camelcase
password_confirm: passwordConfirm, // eslint-disable-line camelcase
});
};
@ -39,14 +39,14 @@ const UserSignUp = props => {
<div className="alert alert-danger">{props.error}</div>
)}
<form className="form-horizontal" onSubmit={e => handleSubmit(e)}>
<form className="form-horizontal" onSubmit={(e) => handleSubmit(e)}>
<div className="form-group">
<label className="control-label">Username</label>
<input
autoFocus="autofocus"
className="form-control"
value={username}
onChange={e => setUsername(e.target.value)}
onChange={(e) => setUsername(e.target.value)}
/>
</div>
@ -56,7 +56,7 @@ const UserSignUp = props => {
className="form-control"
type="password"
value={password}
onChange={e => setPassword(e.target.value)}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
@ -66,7 +66,7 @@ const UserSignUp = props => {
className="form-control"
type="password"
value={passwordConfirm}
onChange={e => setPasswordConfirm(e.target.value)}
onChange={(e) => setPasswordConfirm(e.target.value)}
/>
</div>
<div>
@ -94,7 +94,7 @@ UserSignUp.propTypes = {
isLogged: PropTypes.bool.isRequired,
isLoading: PropTypes.bool.isRequired,
userSignUp: PropTypes.func.isRequired,
error: PropTypes.string
error: PropTypes.string,
};
export default connect(mapStateToProps, mapDispatchToProps)(UserSignUp);

View File

@ -7,12 +7,12 @@ import { Map, List } from "immutable";
import { getUserTokens, deleteUserToken } from "../../actions/users";
const mapStateToProps = state => ({
tokens: state.userStore.get("tokens")
const mapStateToProps = (state) => ({
tokens: state.userStore.get("tokens"),
});
const mapDispatchToProps = { getUserTokens, deleteUserToken };
const UserTokens = props => {
const UserTokens = (props) => {
const [fetched, setIsFetched] = useState(false);
if (!fetched) {
props.getUserTokens();
@ -33,10 +33,10 @@ UserTokens.propTypes = {
tokens: PropTypes.instanceOf(List),
isLoading: PropTypes.bool,
getUserTokens: PropTypes.func.isRequired,
deleteUserToken: PropTypes.func.isRequired
deleteUserToken: PropTypes.func.isRequired,
};
const Token = props => {
const Token = (props) => {
const ua = UAParser(props.data.get("user_agent"));
return (
<div className="card mt-3">
@ -69,10 +69,10 @@ const Token = props => {
);
};
Token.propTypes = {
data: PropTypes.instanceOf(Map).isRequired
data: PropTypes.instanceOf(Map).isRequired,
};
const Actions = props => {
const Actions = (props) => {
const handleClick = () => {
props.deleteToken(props.data.get("token"));
};
@ -86,7 +86,7 @@ const Actions = props => {
};
Actions.propTypes = {
data: PropTypes.instanceOf(Map).isRequired,
deleteToken: PropTypes.func.isRequired
deleteToken: PropTypes.func.isRequired,
};
const Logo = ({ ua, device, browser }) => {
@ -120,7 +120,7 @@ const Logo = ({ ua, device, browser }) => {
Logo.propTypes = {
ua: PropTypes.string,
device: PropTypes.object,
browser: PropTypes.object
browser: PropTypes.object,
};
const OS = ({ name, version }) => {
@ -138,7 +138,7 @@ const OS = ({ name, version }) => {
};
OS.propTypes = {
name: PropTypes.string,
version: PropTypes.string
version: PropTypes.string,
};
const Device = ({ model }) => {
@ -151,7 +151,7 @@ const Device = ({ model }) => {
return <span> {deviceName}</span>;
};
Device.propTypes = {
model: PropTypes.string
model: PropTypes.string,
};
const Browser = ({ name, version }) => {
@ -168,7 +168,7 @@ const Browser = ({ name, version }) => {
};
Browser.propTypes = {
name: PropTypes.string,
version: PropTypes.string
version: PropTypes.string,
};
export default connect(mapStateToProps, mapDispatchToProps)(UserTokens);

View File

@ -5,20 +5,20 @@ import { setFetchedTorrents } from "../actions/torrents";
import { newMovieEvent } from "../actions/movies";
import { newEpisodeEvent } from "../actions/shows";
const mapStateToProps = state => ({
isLogged: state.userStore.get("isLogged")
const mapStateToProps = (state) => ({
isLogged: state.userStore.get("isLogged"),
});
const mapDispatchToProps = {
setFetchedTorrents,
newMovieEvent,
newEpisodeEvent
newEpisodeEvent,
};
const WsHandler = ({
isLogged,
setFetchedTorrents,
newMovieEvent,
newEpisodeEvent
newEpisodeEvent,
}) => {
const [ws, setWs] = useState(null);
@ -45,18 +45,18 @@ const WsHandler = ({
socket.send(
JSON.stringify({
type: "subscribe",
message: "torrents"
message: "torrents",
})
);
socket.send(
JSON.stringify({
type: "subscribe",
message: "newVideo"
message: "newVideo",
})
);
};
socket.onmessage = event => {
socket.onmessage = (event) => {
if (!event.data) {
return;
}
@ -122,7 +122,7 @@ WsHandler.propTypes = {
isLogged: PropTypes.bool.isRequired,
setFetchedTorrents: PropTypes.func,
newMovieEvent: PropTypes.func,
newEpisodeEvent: PropTypes.func
newEpisodeEvent: PropTypes.func,
};
export default connect(mapStateToProps, mapDispatchToProps)(WsHandler);

View File

@ -4,7 +4,7 @@ export const defaultState = Map({
fetchingModules: false,
users: List(),
stats: Map({}),
modules: Map({})
modules: Map({}),
});
const handlers = {
@ -12,14 +12,14 @@ const handlers = {
state.set("users", fromJS(action.payload.response.data)),
ADMIN_GET_STATS_FULFILLED: (state, action) =>
state.set("stats", fromJS(action.payload.response.data)),
ADMIN_GET_MODULES_PENDING: state => state.set("fetchingModules", true),
ADMIN_GET_MODULES_PENDING: (state) => state.set("fetchingModules", true),
ADMIN_GET_MODULES_FULFILLED: (state, action) =>
state.merge(
fromJS({
modules: action.payload.response.data,
fetchingModules: false
fetchingModules: false,
})
)
),
};
export default (state = defaultState, action) =>

View File

@ -3,7 +3,7 @@ import { Map } from "immutable";
const defaultState = Map({
show: false,
message: "",
type: ""
type: "",
});
const handlers = {
@ -12,7 +12,7 @@ const handlers = {
Map({
message: action.payload.message,
show: true,
type: "error"
type: "error",
})
),
ADD_ALERT_OK: (state, action) =>
@ -20,17 +20,17 @@ const handlers = {
Map({
message: action.payload.message,
show: true,
type: "success"
type: "success",
})
),
DISMISS_ALERT: state =>
DISMISS_ALERT: (state) =>
state.merge(
Map({
message: "",
show: false,
type: ""
type: "",
})
)
),
};
export default (state = defaultState, action) =>

View File

@ -19,5 +19,5 @@ export default combineReducers({
torrentStore,
adminStore,
polochon,
notifications
notifications,
});

View File

@ -6,16 +6,16 @@ const defaultState = Map({
filter: "",
selectedImdbId: "",
lastFetchUrl: "",
exploreOptions: Map()
exploreOptions: Map(),
});
const handlers = {
MOVIE_LIST_FETCH_PENDING: state => state.set("loading", true),
MOVIE_LIST_FETCH_ERROR: state => state.set("loading", false),
MOVIE_LIST_FETCH_PENDING: (state) => state.set("loading", true),
MOVIE_LIST_FETCH_ERROR: (state) => state.set("loading", false),
MOVIE_LIST_FETCH_FULFILLED: (state, action) => {
let allMoviesInPolochon = true;
let movies = Map();
action.payload.response.data.map(function(movie) {
action.payload.response.data.map(function (movie) {
movie.fetchingDetails = false;
movie.fetchingSubtitles = false;
if (movie.polochon_url === "") {
@ -46,7 +46,7 @@ const handlers = {
movies: movies,
filter: "",
loading: false,
selectedImdbId: selectedImdbId
selectedImdbId: selectedImdbId,
})
);
},
@ -93,7 +93,7 @@ const handlers = {
SELECT_MOVIE: (state, action) =>
state.set("selectedImdbId", action.payload.imdbId),
MOVIE_UPDATE_FILTER: (state, action) =>
state.set("filter", action.payload.filter)
state.set("filter", action.payload.filter),
};
export default (state = defaultState, action) =>

View File

@ -6,14 +6,12 @@ const handlers = {
ADD_NOTIFICATION: (state, action) =>
state.push(
fromJS({
id: Math.random()
.toString(36)
.substring(7),
...action.payload
id: Math.random().toString(36).substring(7),
...action.payload,
})
),
REMOVE_NOTIFICATION: (state, action) =>
state.filter(e => e.get("id") !== action.payload.id)
state.filter((e) => e.get("id") !== action.payload.id),
};
export default (state = defaultState, action) =>

View File

@ -4,25 +4,26 @@ const defaultState = Map({
loadingPublic: false,
loadingManaged: false,
public: List(),
managed: List()
managed: List(),
});
const handlers = {
PUBLIC_POLOCHON_LIST_FETCH_PENDING: state => state.set("loadingPublic", true),
PUBLIC_POLOCHON_LIST_FETCH_PENDING: (state) =>
state.set("loadingPublic", true),
PUBLIC_POLOCHON_LIST_FETCH_FULFILLED: (state, action) => {
return state.merge({
loadingPublic: false,
public: List(fromJS(action.payload.response.data))
public: List(fromJS(action.payload.response.data)),
});
},
MANAGED_POLOCHON_LIST_FETCH_PENDING: state =>
MANAGED_POLOCHON_LIST_FETCH_PENDING: (state) =>
state.set("loadingManaged", true),
MANAGED_POLOCHON_LIST_FETCH_FULFILLED: (state, action) => {
return state.merge({
loadingManaged: false,
managed: List(fromJS(action.payload.response.data))
managed: List(fromJS(action.payload.response.data)),
});
}
},
};
export default (state = defaultState, action) =>

View File

@ -3,12 +3,12 @@ import { OrderedMap, Map, fromJS } from "immutable";
const defaultState = Map({
loading: false,
show: Map({
seasons: OrderedMap()
})
seasons: OrderedMap(),
}),
});
const handlers = {
SHOW_FETCH_DETAILS_PENDING: state => state.set("loading", true),
SHOW_FETCH_DETAILS_PENDING: (state) => state.set("loading", true),
SHOW_FETCH_DETAILS_FULFILLED: (state, action) =>
sortEpisodes(state, action.payload.response.data),
SHOW_UPDATE_STORE_WISHLIST: (state, action) => {
@ -16,8 +16,8 @@ const handlers = {
fromJS({
show: {
tracked_season: action.payload.season, // eslint-disable-line camelcase
tracked_episode: action.payload.episode // eslint-disable-line camelcase
}
tracked_episode: action.payload.episode, // eslint-disable-line camelcase
},
})
);
},
@ -28,7 +28,7 @@ const handlers = {
"seasons",
action.payload.main.season,
action.payload.main.episode,
"fetching"
"fetching",
],
true
),
@ -50,7 +50,7 @@ const handlers = {
"seasons",
action.payload.main.season,
action.payload.main.episode,
"fetchingSubtitles"
"fetchingSubtitles",
],
true
),
@ -62,7 +62,7 @@ const handlers = {
"seasons",
action.payload.main.season,
action.payload.main.episode,
"subtitles"
"subtitles",
],
fromJS(action.payload.response.data)
)
@ -72,10 +72,10 @@ const handlers = {
"seasons",
action.payload.main.season,
action.payload.main.episode,
"fetchingSubtitles"
"fetchingSubtitles",
],
false
)
),
};
const sortEpisodes = (state, show) => {
@ -97,15 +97,15 @@ const sortEpisodes = (state, show) => {
}
// Sort the episodes
ret = ret.updateIn(["show", "seasons"], function(seasons) {
return seasons.map(function(episodes) {
ret = ret.updateIn(["show", "seasons"], function (seasons) {
return seasons.map(function (episodes) {
return episodes.sort((a, b) => a.get("episode") - b.get("episode"));
});
});
// Sort the seasons
ret = ret.updateIn(["show", "seasons"], function(seasons) {
return seasons.sort(function(a, b) {
ret = ret.updateIn(["show", "seasons"], function (seasons) {
return seasons.sort(function (a, b) {
return a.first().get("season") - b.first().get("season");
});
});

View File

@ -6,14 +6,14 @@ const defaultState = Map({
filter: "",
selectedImdbId: "",
lastFetchUrl: "",
exploreOptions: Map()
exploreOptions: Map(),
});
const handlers = {
SHOW_LIST_FETCH_PENDING: state => state.set("loading", true),
SHOW_LIST_FETCH_PENDING: (state) => state.set("loading", true),
SHOW_LIST_FETCH_FULFILLED: (state, action) => {
let shows = Map();
action.payload.response.data.map(function(show) {
action.payload.response.data.map(function (show) {
show.fetchingDetails = false;
show.fetchingSubtitles = false;
shows = shows.set(show.imdb_id, fromJS(show));
@ -31,7 +31,7 @@ const handlers = {
shows: shows,
filter: "",
loading: false,
selectedImdbId: selectedImdbId
selectedImdbId: selectedImdbId,
})
);
},
@ -61,7 +61,7 @@ const handlers = {
["shows", action.payload.imdbId],
Map({
tracked_season: season,
tracked_episode: episode
tracked_episode: episode,
})
);
},
@ -70,7 +70,7 @@ const handlers = {
SELECT_SHOW: (state, action) =>
state.set("selectedImdbId", action.payload.imdbId),
SHOWS_UPDATE_FILTER: (state, action) =>
state.set("filter", action.payload.filter)
state.set("filter", action.payload.filter),
};
export default (state = defaultState, action) =>

View File

@ -4,26 +4,26 @@ const defaultState = Map({
fetching: false,
searching: false,
torrents: List(),
searchResults: List()
searchResults: List(),
});
const handlers = {
TORRENTS_FETCH_PENDING: state => state.set("fetching", true),
TORRENTS_FETCH_PENDING: (state) => state.set("fetching", true),
TORRENTS_FETCH_FULFILLED: (state, action) =>
state.merge(
fromJS({
fetching: false,
torrents: action.payload.response.data
torrents: action.payload.response.data,
})
),
TORRENTS_SEARCH_PENDING: state => state.set("searching", true),
TORRENTS_SEARCH_PENDING: (state) => state.set("searching", true),
TORRENTS_SEARCH_FULFILLED: (state, action) =>
state.merge(
fromJS({
searching: false,
searchResults: action.payload.response.data
searchResults: action.payload.response.data,
})
)
),
};
export default (state = defaultState, action) =>

View File

@ -18,7 +18,7 @@ const defaultState = Map({
polochonActivated: false,
tokens: List(),
modules: Map(),
modulesLoading: false
modulesLoading: false,
});
let initialState = defaultState;
@ -28,7 +28,7 @@ if (token && token !== "") {
}
const handlers = {
USER_LOGIN_PENDING: state => state.set("loading", true),
USER_LOGIN_PENDING: (state) => state.set("loading", true),
USER_LOGIN_ERROR: (state, action) => {
state.set("loading", false);
return logoutUser(action.payload.response.message);
@ -36,20 +36,20 @@ const handlers = {
USER_LOGIN_FULFILLED: (state, action) => {
return updateFromToken(state, action.payload.response.data.token);
},
USER_SIGNUP_PENDING: state => state.set("loading", true),
USER_SIGNUP_PENDING: (state) => state.set("loading", true),
USER_SIGNUP_ERROR: (state, action) =>
state.merge(
Map({
error: action.payload.response.message,
loading: false
loading: false,
})
),
USER_SIGNUP_FULFILLED: state =>
USER_SIGNUP_FULFILLED: (state) =>
state.merge(Map({ error: "", loading: false })),
USER_SET_TOKEN: (state, action) =>
updateFromToken(state, action.payload.token),
USER_LOGOUT: () => logoutUser(),
GET_USER_PENDING: state => state.set("loading", true),
GET_USER_PENDING: (state) => state.set("loading", true),
GET_USER_FULFILLED: (state, action) =>
state.merge(
Map({
@ -58,25 +58,25 @@ const handlers = {
polochonName: action.payload.response.data.name,
polochonId: action.payload.response.data.id,
polochonActivated: action.payload.response.data.activated,
loading: false
loading: false,
})
),
GET_USER_TOKENS_PENDING: state => state.set("loading", true),
GET_USER_TOKENS_PENDING: (state) => state.set("loading", true),
GET_USER_TOKENS_FULFILLED: (state, action) =>
state.merge(
Map({
tokens: fromJS(action.payload.response.data),
loading: false
loading: false,
})
),
GET_USER_MODULES_PENDING: state => state.set("modulesLoading", true),
GET_USER_MODULES_PENDING: (state) => state.set("modulesLoading", true),
GET_USER_MODULES_FULFILLED: (state, action) =>
state.merge(
Map({
modules: fromJS(action.payload.response.data),
modulesLoading: false
modulesLoading: false,
})
)
),
};
function logoutUser(error) {
@ -104,7 +104,7 @@ function updateFromToken(state, token) {
isTokenSet: true,
isAdmin: decodedToken.isAdmin,
isActivated: decodedToken.isActivated,
username: decodedToken.username
username: decodedToken.username,
})
);
}

View File

@ -10,7 +10,7 @@ export function configureAxios(headers = {}) {
}
return axios.create({
headers
headers,
});
}
@ -27,30 +27,30 @@ export function request(
const fulfilled = `${eventPrefix}_FULFILLED`;
const errored = `${eventPrefix}_ERROR`;
return function(dispatch) {
return function (dispatch) {
dispatch({
type: pending,
payload: {
main: mainPayload
}
main: mainPayload,
},
});
return promise
.then(response => {
.then((response) => {
if (response.data.status === "error") {
dispatch({
type: "ADD_ALERT_ERROR",
payload: {
message: response.data.message,
main: mainPayload
}
main: mainPayload,
},
});
dispatch({
type: errored,
payload: {
response: response.data,
main: mainPayload
}
main: mainPayload,
},
});
return;
}
@ -58,8 +58,8 @@ export function request(
type: fulfilled,
payload: {
response: response.data,
main: mainPayload
}
main: mainPayload,
},
});
if (callbackEvents) {
for (let event of callbackEvents) {
@ -70,19 +70,19 @@ export function request(
}
}
})
.catch(error => {
.catch((error) => {
// Unauthorized
if (error.response && error.response.status == 401) {
dispatch({
type: "USER_LOGOUT"
type: "USER_LOGOUT",
});
}
dispatch({
type: "ADD_ALERT_ERROR",
payload: {
message: error.response.data,
main: mainPayload
}
main: mainPayload,
},
});
});
};

View File

@ -1,4 +1,4 @@
export const prettyDurationFromMinutes = runtime => {
export const prettyDurationFromMinutes = (runtime) => {
const hours = Math.floor(runtime / 60);
const minutes = runtime % 60;
@ -16,14 +16,14 @@ export const prettyDurationFromMinutes = runtime => {
return duration;
};
const pad = d => (d < 10 ? "0" + d.toString() : d.toString());
const pad = (d) => (d < 10 ? "0" + d.toString() : d.toString());
export const prettyEpisodeName = (showName, season, episode) =>
`${showName} S${pad(season)}E${pad(episode)}`;
export const inLibrary = element => element.get("polochon_url", "") !== "";
export const inLibrary = (element) => element.get("polochon_url", "") !== "";
export const isWishlisted = element => {
export const isWishlisted = (element) => {
const wishlisted = element.get("wishlisted", undefined);
if (wishlisted !== undefined) {
return wishlisted;
@ -58,7 +58,7 @@ export const isEpisodeWishlisted = (element, trackedSeason, trackedEpisode) => {
}
};
export const prettySize = fileSizeInBytes => {
export const prettySize = (fileSizeInBytes) => {
var i = -1;
var byteUnits = [" kB", " MB", " GB", " TB", "PB", "EB", "ZB", "YB"];
do {

File diff suppressed because it is too large Load Diff

View File

@ -6,8 +6,8 @@
"lint": "./node_modules/eslint/bin/eslint.js ."
},
"dependencies": {
"bootstrap": "^4.3.1",
"bootswatch": "^4.3.1",
"bootstrap": "^4.4.1",
"bootswatch": "^4.4.1",
"font-awesome": "^4.7.0",
"fuzzy": "^0.1.3",
"history": "^4.9.0",
@ -17,47 +17,47 @@
"moment": "^2.20.1",
"popper.js": "^1.15.0",
"prop-types": "^15.6.0",
"react": "^16.13.0",
"react-bootstrap": "^1.0.0-beta.9",
"react": "^16.13.1",
"react-bootstrap": "^1.0.0",
"react-bootstrap-sweetalert": "^5.1.9",
"react-bootstrap-toggle": "^2.2.6",
"react-dom": "^16.13.0",
"react-dom": "^16.13.1",
"react-infinite-scroll-component": "^5.0.4",
"react-loading": "2.0.3",
"react-redux": "^7.2.0",
"react-router-bootstrap": "^0.25.0",
"react-router-dom": "^5.0.1",
"redux": "^4.0.1",
"react-router-dom": "^5.1.2",
"redux": "^4.0.5",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
"ua-parser-js": "^0.7.17"
},
"devDependencies": {
"@babel/core": "^7.5.0",
"@babel/preset-env": "^7.5.0",
"@babel/preset-react": "^7.0.0",
"autoprefixer": "^9.5.1",
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.0",
"@babel/preset-react": "^7.9.4",
"autoprefixer": "^9.7.5",
"axios": "^0.19.2",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.0.6",
"babel-loader": "^8.1.0",
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^3.4.2",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.0",
"eslint-plugin-import": "^2.20.1",
"eslint-config-prettier": "^6.10.1",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-prettier": "^3.1.2",
"eslint-plugin-react": "^7.6.1",
"eslint-plugin-react-hooks": "^2.5.0",
"eslint-plugin-react": "^7.19.0",
"eslint-plugin-react-hooks": "^2.5.1",
"file-loader": "^5.1.0",
"html-webpack-plugin": "^3.2.0",
"node-sass": "^4.12.0",
"postcss-loader": "^3.0.0",
"prettier": "^1.19.1",
"prettier": "^2.0.2",
"sass-loader": "^8.0.2",
"style-loader": "^1.1.3",
"universal-cookie": "^4.0.3",
"url-loader": "^3.0.0",
"webpack": "^4.31.0",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11",
"webpack-pwa-manifest": "^4.0.0"
}

View File

@ -1,3 +1,3 @@
module.exports = {
plugins: [require("autoprefixer")]
plugins: [require("autoprefixer")],
};

View File

@ -19,7 +19,7 @@ const config = {
entry: path.join(SRC_DIR, "js/app.js"),
output: {
path: BUILD_DIR,
filename: "[contenthash]-app.js"
filename: "[contenthash]-app.js",
},
optimization: {
runtimeChunk: "single",
@ -28,10 +28,10 @@ const config = {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
chunks: "all"
}
}
}
chunks: "all",
},
},
},
},
module: {
rules: [
@ -41,45 +41,45 @@ const config = {
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/preset-react"]
}
}
presets: ["@babel/preset-env", "@babel/preset-react"],
},
},
},
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader", "postcss-loader"]
use: ["style-loader", "css-loader", "sass-loader", "postcss-loader"],
},
{
test: /\.(png|jpg|svg|ico)$/,
use: ["file-loader?name=[hash]-[name].[ext]"]
use: ["file-loader?name=[hash]-[name].[ext]"],
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: ["url-loader?limit=10000&mimetype=application/font-woff"]
use: ["url-loader?limit=10000&mimetype=application/font-woff"],
},
{
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: ["file-loader"]
}
]
use: ["file-loader"],
},
],
},
plugins: [
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV)
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
}),
new webpack.HashedModuleIdsPlugin(),
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ["**/*", "!img/**/*", "!img"]
cleanOnceBeforeBuildPatterns: ["**/*", "!img/**/*", "!img"],
}),
new HtmlWebpackPlugin({
template: path.join(SRC_DIR, "index.html")
template: path.join(SRC_DIR, "index.html"),
}),
new WebpackPwaManifest({
fingerprints: true,
inject: true,
ios: {
"apple-mobile-web-app-status-bar-style": "default",
"apple-mobile-web-app-title": "Canapé"
"apple-mobile-web-app-title": "Canapé",
},
name: "Canapé",
short_name: "Canapé", // eslint-disable-line camelcase
@ -92,20 +92,20 @@ const config = {
icons: [
{
src: path.resolve(__dirname, "img/android-chrome-512x512.png"),
sizes: [96, 128, 192, 256, 384, 512]
sizes: [96, 128, 192, 256, 384, 512],
},
{
src: path.resolve(__dirname, "img/apple-touch-icon.png"),
sizes: [80, 120, 152, 167, 180],
ios: true
}
]
})
ios: true,
},
],
}),
],
resolve: {
extensions: [".js"]
extensions: [".js"],
},
devtool: mode === "production" ? "source-map" : "inline-source-map"
devtool: mode === "production" ? "source-map" : "inline-source-map",
};
module.exports = config;