diff --git a/jsclient/README.md b/jsclient/README.md
deleted file mode 100644
index d85e9e38c..000000000
--- a/jsclient/README.md
+++ /dev/null
@@ -1,68 +0,0 @@
-This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app), using the [Redux](https://redux.js.org/) and [Redux Toolkit](https://redux-toolkit.js.org/) template.
-
-## Available Scripts
-
-In the project directory, you can run:
-
-### `yarn start`
-
-Runs the app in the development mode.
-Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
-
-The page will reload if you make edits.
-You will also see any lint errors in the console.
-
-### `yarn test`
-
-Launches the test runner in the interactive watch mode.
-See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
-
-### `yarn build`
-
-Builds the app for production to the `build` folder.
-It correctly bundles React in production mode and optimizes the build for the best performance.
-
-The build is minified and the filenames include the hashes.
-Your app is ready to be deployed!
-
-See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
-
-### `yarn eject`
-
-**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
-
-If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
-
-Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
-
-You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
-
-## Learn More
-
-You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
-
-To learn React, check out the [React documentation](https://reactjs.org/).
-
-### Code Splitting
-
-This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
-
-### Analyzing the Bundle Size
-
-This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
-
-### Making a Progressive Web App
-
-This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
-
-### Advanced Configuration
-
-This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
-
-### Deployment
-
-This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
-
-### `yarn build` fails to minify
-
-This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
diff --git a/jsclient/src/Jarr.js b/jsclient/src/Jarr.js
index 254e4e826..dd897c9f6 100644
--- a/jsclient/src/Jarr.js
+++ b/jsclient/src/Jarr.js
@@ -1,26 +1,26 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { connect } from 'react-redux'
-import clsx from 'clsx';
+import React from "react";
+import PropTypes from "prop-types";
+import { connect } from "react-redux";
+import clsx from "clsx";
-import Drawer from '@material-ui/core/Drawer';
-import CssBaseline from '@material-ui/core/CssBaseline';
-import AppBar from '@material-ui/core/AppBar';
-import Toolbar from '@material-ui/core/Toolbar';
-import Typography from '@material-ui/core/Typography';
-import IconButton from '@material-ui/core/IconButton';
-import MenuIcon from '@material-ui/icons/Menu';
-import ChevronLeftIcon from '@material-ui/icons/ChevronLeft';
-import AddFeedIcon from '@material-ui/icons/Add';
-import AddCategoryIcon from '@material-ui/icons/LibraryAdd';
-import FoldAllCategoriesIcon from '@material-ui/icons/UnfoldLess';
-import UnFoldAllCategoriesIcon from '@material-ui/icons/UnfoldMore';
+import Drawer from "@material-ui/core/Drawer";
+import CssBaseline from "@material-ui/core/CssBaseline";
+import AppBar from "@material-ui/core/AppBar";
+import Toolbar from "@material-ui/core/Toolbar";
+import Typography from "@material-ui/core/Typography";
+import IconButton from "@material-ui/core/IconButton";
+import MenuIcon from "@material-ui/icons/Menu";
+import ChevronLeftIcon from "@material-ui/icons/ChevronLeft";
+import AddFeedIcon from "@material-ui/icons/Add";
+import AddCategoryIcon from "@material-ui/icons/LibraryAdd";
+import FoldAllCategoriesIcon from "@material-ui/icons/UnfoldLess";
+import UnFoldAllCategoriesIcon from "@material-ui/icons/UnfoldMore";
-import useStyles from './Jarr.styles.js';
-import Login from './features/login/Login';
-import FeedList from './features/feedlist/FeedList';
-import ClusterList from './features/clusterlist/ClusterList';
-import { toggleLeftMenu, toggleFolding } from './features/login/userSlice.js';
+import useStyles from "./Jarr.styles.js";
+import Login from "./features/login/Login";
+import FeedList from "./features/feedlist/FeedList";
+import ClusterList from "./features/clusterlist/ClusterList";
+import { toggleLeftMenu, toggleFolding } from "./features/login/userSlice.js";
function mapStateToProps(state) {
return { isLogged: !!state.login.token,
@@ -107,6 +107,6 @@ Jarr.propTypes = {
isLeftMenuFolded: PropTypes.bool.isRequired,
toggleDrawer: PropTypes.func.isRequired,
toggleFolder: PropTypes.func.isRequired,
-}
+};
export default connect(mapStateToProps, mapDispatchToProps)(Jarr);
diff --git a/jsclient/src/Jarr.styles.js b/jsclient/src/Jarr.styles.js
index 4b5fd7b55..67741ffa9 100644
--- a/jsclient/src/Jarr.styles.js
+++ b/jsclient/src/Jarr.styles.js
@@ -1,14 +1,14 @@
-import { makeStyles, Theme, createStyles } from '@material-ui/core/styles';
+import { makeStyles, Theme, createStyles } from "@material-ui/core/styles";
const drawerWidth = 240;
export default makeStyles((theme: Theme) =>
createStyles({
root: {
- display: 'flex',
+ display: "flex",
},
appBar: {
- transition: theme.transitions.create(['margin', 'width'], {
+ transition: theme.transitions.create(["margin", "width"], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
@@ -16,7 +16,7 @@ export default makeStyles((theme: Theme) =>
appBarShift: {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerWidth,
- transition: theme.transitions.create(['margin', 'width'], {
+ transition: theme.transitions.create(["margin", "width"], {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
@@ -25,7 +25,7 @@ export default makeStyles((theme: Theme) =>
marginRight: theme.spacing(2),
},
hide: {
- display: 'none',
+ display: "none",
},
drawer: {
width: drawerWidth,
@@ -35,18 +35,18 @@ export default makeStyles((theme: Theme) =>
width: drawerWidth,
},
drawerHeader: {
- display: 'flex',
- alignItems: 'center',
+ display: "flex",
+ alignItems: "center",
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar,
- justifyContent: 'flex-end',
+ justifyContent: "flex-end",
},
content: {
flexGrow: 1,
paddingTop: 88,
padding: theme.spacing(3),
- transition: theme.transitions.create('margin', {
+ transition: theme.transitions.create("margin", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
@@ -54,7 +54,7 @@ export default makeStyles((theme: Theme) =>
},
contentShift: {
paddingTop: 88,
- transition: theme.transitions.create('margin', {
+ transition: theme.transitions.create("margin", {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
diff --git a/jsclient/src/app/store.js b/jsclient/src/app/store.js
index 562243ee0..8ebd131b9 100644
--- a/jsclient/src/app/store.js
+++ b/jsclient/src/app/store.js
@@ -1,8 +1,8 @@
-import { configureStore, Action } from '@reduxjs/toolkit';
-import thunk, { ThunkAction }from 'redux-thunk';
-import userReducer from '../features/login/userSlice';
-import feedsReducer from '../features/feedlist/feedSlice';
-import clustersReducer from '../features/clusterlist/clusterSlice';
+import { configureStore, Action } from "@reduxjs/toolkit";
+import thunk, { ThunkAction }from "redux-thunk";
+import userReducer from "../features/login/userSlice";
+import feedsReducer from "../features/feedlist/feedSlice";
+import clustersReducer from "../features/clusterlist/clusterSlice";
export default configureStore({
reducer: {
@@ -13,4 +13,4 @@ export default configureStore({
middleware: [thunk],
});
-export type AppThunk = ThunkAction>
+export type AppThunk = ThunkAction>;
diff --git a/jsclient/src/const.js b/jsclient/src/const.js
index b1a253950..caa2b2083 100644
--- a/jsclient/src/const.js
+++ b/jsclient/src/const.js
@@ -1 +1 @@
-export const apiUrl = 'http://0.0.0.0:8000';
+export const apiUrl = "http://0.0.0.0:8000";
diff --git a/jsclient/src/features/clusterlist/Cluster.js b/jsclient/src/features/clusterlist/Cluster.js
index 84a6027e4..2b0a0b968 100644
--- a/jsclient/src/features/clusterlist/Cluster.js
+++ b/jsclient/src/features/clusterlist/Cluster.js
@@ -1,21 +1,22 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { connect } from 'react-redux'
-import Typography from '@material-ui/core/Typography';
-import Link from '@material-ui/core/Link';
-import ExpansionPanel from '@material-ui/core/ExpansionPanel';
-import ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary';
-import ExpansionPanelDetails from '@material-ui/core/ExpansionPanelDetails';
-import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
-import CircularProgress from '@material-ui/core/CircularProgress';
+import React from "react";
+import PropTypes from "prop-types";
+import { connect } from "react-redux";
-import { doReadCluster, doUnreadCluster } from './clusterSlice';
+import Typography from "@material-ui/core/Typography";
+import Link from "@material-ui/core/Link";
+import ExpansionPanel from "@material-ui/core/ExpansionPanel";
+import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary";
+import ExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails";
+import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
+import CircularProgress from "@material-ui/core/CircularProgress";
+
+import { doReadCluster, doUnreadCluster } from "./clusterSlice";
function mapStateToProps(state) {
return { requestedClusterId: state.clusters.requestedClusterId,
loadedCluster: state.clusters.loadedCluster,
};
-};
+}
const mapDispatchToProps = (dispatch) => ({
readCluster(clusterId) {
@@ -71,7 +72,7 @@ function Cluster({ id, mainFeedTitle, mainTitle, requestedClusterId, loadedClust
);
-};
+}
Cluster.propTypes = {
id: PropTypes.number.isRequired,
diff --git a/jsclient/src/features/clusterlist/ClusterList.js b/jsclient/src/features/clusterlist/ClusterList.js
index 6743d4a2a..9a0bb33f0 100644
--- a/jsclient/src/features/clusterlist/ClusterList.js
+++ b/jsclient/src/features/clusterlist/ClusterList.js
@@ -1,9 +1,9 @@
-import React, { useEffect, useState } from 'react';
-import PropTypes from 'prop-types';
-import { connect } from 'react-redux'
+import React, { useEffect, useState } from "react";
+import PropTypes from "prop-types";
+import { connect } from "react-redux"
-import Cluster from './Cluster';
-import { doListClusters } from './clusterSlice';
+import Cluster from "./Cluster";
+import { doListClusters } from "./clusterSlice";
function mapStateToProps(state) {
return { clusters: state.clusters.clusters,
diff --git a/jsclient/src/features/clusterlist/clusterSlice.js b/jsclient/src/features/clusterlist/clusterSlice.js
index 0a4365185..89ab5729e 100644
--- a/jsclient/src/features/clusterlist/clusterSlice.js
+++ b/jsclient/src/features/clusterlist/clusterSlice.js
@@ -1,10 +1,11 @@
-import axios from 'axios';
-import qs from 'qs';
-import { createSlice } from '@reduxjs/toolkit';
-import { apiUrl } from '../../const.js';
+import axios from "axios";
+import qs from "qs";
+import { createSlice } from "@reduxjs/toolkit";
+import { apiUrl } from "../../const.js";
+import { AppThunk } from "../../app/store";
const clusterSlice = createSlice({
- name: 'cluster',
+ name: "cluster",
initialState: { filters: {},
loadingClusterList: false,
clusters: [],
@@ -16,11 +17,11 @@ const clusterSlice = createSlice({
requestedClustersList(state, action) {
const selected = {};
const filters = {};
- if (!!action.payload.filters.feedId) {
- selected.feedId = filters.feed_id = action.payload.filters.feedId;
+ if (action.payload.filters.feedId) {
+ selected.feedId = filters['feed_id'] = action.payload.filters.feedId;
- } else if (!!action.payload.filters.categoryId) {
- selected.categoryId = filters.category_id = action.payload.filters.categoryId;
+ } else if (action.payload.filters.categoryId) {
+ selected.categoryId = filters['category_id'] = action.payload.filters.categoryId;
}
return { ...state, filters, selected, loadingClusterList: true };
@@ -58,35 +59,33 @@ export const { requestedClustersList, retrievedClustersList,
} = clusterSlice.actions;
export default clusterSlice.reducer;
-export const doListClusters = (
- filters: object,
-): AppThunk => async (dispatch, getState) => {
- dispatch(requestedClustersList({ filters: filters }));
+export const doListClusters = (filters): AppThunk => async (dispatch, getState) => {
+ dispatch(requestedClustersList({ filters }));
const params = qs.stringify(getState().clusters.filters);
const result = await axios({
- method: 'get',
- url: apiUrl + '/clusters?' + params,
- headers: { 'Authorization': getState().login.token },
+ method: "get",
+ url: apiUrl + "/clusters?" + params,
+ headers: { "Authorization": getState().login.token },
});
- dispatch(retrievedClustersList({ clusters: result.data }))
-}
+ dispatch(retrievedClustersList({ clusters: result.data }));
+};
-export const doReadCluster = (clusterId: number): AppThunk => async (dispatch, getState) => {
+export const doReadCluster = (clusterId): AppThunk => async (dispatch, getState) => {
dispatch(requestedCluster({ clusterId }));
const result = await axios({
- method: 'get',
- url: apiUrl + '/cluster/' + clusterId,
- headers: { 'Authorization': getState().login.token },
+ method: "get",
+ url: apiUrl + "/cluster/" + clusterId,
+ headers: { "Authorization": getState().login.token },
});
- dispatch(retrievedCluster({ cluster: result.data }))
-}
+ dispatch(retrievedCluster({ cluster: result.data }));
+};
-export const doUnreadCluster = (clusterId: number): AppThunk => async (dispatch, getState) => {
+export const doUnreadCluster = (clusterId): AppThunk => async (dispatch, getState) => {
dispatch(requestedUnreadCluster({ clusterId }));
await axios({
- method: 'put',
- url: apiUrl + '/cluster/' + clusterId + '?read=false',
- headers: { 'Authorization': getState().login.token },
+ method: "put",
+ url: apiUrl + "/cluster/" + clusterId + "?read=false",
+ headers: { "Authorization": getState().login.token },
});
- dispatch(retrievedUnreadCluster())
-}
+ dispatch(retrievedUnreadCluster());
+};
diff --git a/jsclient/src/features/feedlist/Category.js b/jsclient/src/features/feedlist/Category.js
index c76d13a36..29b650401 100644
--- a/jsclient/src/features/feedlist/Category.js
+++ b/jsclient/src/features/feedlist/Category.js
@@ -1,15 +1,15 @@
-import React, { useState } from 'react';
-import PropTypes from 'prop-types';
-import { connect } from 'react-redux'
+import React, { useState } from "react";
+import PropTypes from "prop-types";
+import { connect } from "react-redux";
-import Collapse from '@material-ui/core/Collapse';
-import List from '@material-ui/core/List';
-import ListItem from '@material-ui/core/ListItem';
-import ListItemText from '@material-ui/core/ListItemText';
-import ExpandLess from '@material-ui/icons/ExpandLess';
-import ExpandMore from '@material-ui/icons/ExpandMore';
+import Collapse from "@material-ui/core/Collapse";
+import List from "@material-ui/core/List";
+import ListItem from "@material-ui/core/ListItem";
+import ListItemText from "@material-ui/core/ListItemText";
+import ExpandLess from "@material-ui/icons/ExpandLess";
+import ExpandMore from "@material-ui/icons/ExpandMore";
-import { doListClusters } from '../clusterlist/clusterSlice';
+import { doListClusters } from "../clusterlist/clusterSlice";
const mapDispatchToProps = (dispatch) => ({
listClusters(e, filters) {
@@ -19,7 +19,7 @@ const mapDispatchToProps = (dispatch) => ({
});
function toKey(type, id, selectedId) {
- return type + '-' + id + '-' + (id === selectedId ? 'selected' : '');
+ return type + "-" + id + "-" + (id === selectedId ? "selected" : "");
}
function Category(props) {
@@ -40,9 +40,9 @@ function Category(props) {
return (
<>
(props.listClusters(e, { categoryId: props.id }))}>
-
+
{foldButton}
diff --git a/jsclient/src/features/feedlist/FeedList.js b/jsclient/src/features/feedlist/FeedList.js
index 116475eae..ad573c110 100644
--- a/jsclient/src/features/feedlist/FeedList.js
+++ b/jsclient/src/features/feedlist/FeedList.js
@@ -1,11 +1,11 @@
-import React, { useState, useEffect } from 'react';
-import PropTypes from 'prop-types';
-import { connect } from 'react-redux'
+import React, { useState, useEffect } from "react";
+import PropTypes from "prop-types";
+import { connect } from "react-redux";
-import List from '@material-ui/core/List';
-import Category from './Category';
+import List from "@material-ui/core/List";
+import Category from "./Category";
-import { doFetchFeeds } from './feedSlice';
+import { doFetchFeeds } from "./feedSlice";
function mapStateToProps(state) {
return { categories: state.feeds.categories,
@@ -13,7 +13,7 @@ function mapStateToProps(state) {
selectedFeedId: state.clusters.selected.feedId,
isFoldedFromParent: state.login.isLeftMenuFolded,
};
-};
+}
const mapDispatchToProps = (dispatch) => ({
fetchFeed() {
@@ -51,6 +51,6 @@ FeedList.propTypes = {
fetchFeed: PropTypes.func.isRequired,
selectedFeedId: PropTypes.number,
selectedCategoryId: PropTypes.number,
-}
+};
export default connect(mapStateToProps, mapDispatchToProps)(FeedList);
diff --git a/jsclient/src/features/feedlist/feedSlice.js b/jsclient/src/features/feedlist/feedSlice.js
index 36f4c6a63..2b887938a 100644
--- a/jsclient/src/features/feedlist/feedSlice.js
+++ b/jsclient/src/features/feedlist/feedSlice.js
@@ -1,9 +1,10 @@
-import axios from 'axios';
-import { createSlice } from '@reduxjs/toolkit';
-import { apiUrl } from '../../const.js';
+import axios from "axios";
+import { createSlice } from "@reduxjs/toolkit";
+import { apiUrl } from "../../const.js";
+import { AppThunk } from "../../app/store";
const feedSlice = createSlice({
- name: 'feed',
+ name: "feed",
initialState: { loading: false,
categories: [],
},
@@ -22,13 +23,12 @@ const feedSlice = createSlice({
export const { askedFeeds, loadedFeeds } = feedSlice.actions;
export default feedSlice.reducer;
-export const doFetchFeeds = (
-): AppThunk => async (dispatch, getState) => {
+export const doFetchFeeds = (): AppThunk => async (dispatch, getState) => {
dispatch(askedFeeds());
const result = await axios({
- method: 'get',
- url: apiUrl + '/list-feeds',
- headers: { 'Authorization': getState().login.token },
+ method: "get",
+ url: apiUrl + "/list-feeds",
+ headers: { "Authorization": getState().login.token },
});
- dispatch(loadedFeeds({ categories: result.data }))
-}
+ dispatch(loadedFeeds({ categories: result.data }));
+};
diff --git a/jsclient/src/features/login/Login.js b/jsclient/src/features/login/Login.js
index d52179cc8..4303f29dc 100644
--- a/jsclient/src/features/login/Login.js
+++ b/jsclient/src/features/login/Login.js
@@ -1,18 +1,23 @@
-import React, { useEffect } from 'react';
-import PropTypes from 'prop-types';
-import { connect } from 'react-redux'
-import { Grid, TextField, Button, CircularProgress } from '@material-ui/core';
-import styles from './Login.module.css';
-import { doLogin } from './userSlice.js';
+import React, { useEffect } from "react";
+import PropTypes from "prop-types";
+import { connect } from "react-redux";
+
+import Grid from "@material-ui/core/Grid";
+import TextField from "@material-ui/core/TextField";
+import Button from "@material-ui/core/Button";
+import CircularProgress from "@material-ui/core/CircularProgress";
+
+import styles from "./Login.module.css";
+import { doLogin } from "./userSlice.js";
function mapStateToProps(state) {
return { isLoading: state.login.loading,
- isLoginError: state.login.error !== undefined,
+ isLoginError: !!state.login.error,
noToken: !state.login.loading && state.login.login && state.login.password && !state.login.token,
savedLogin: state.login.login,
savedPassword: state.login.password,
loginError: state.login.error };
-};
+}
const mapDispatchToProps = (dispatch) => ({
onSubmit (e) {
@@ -73,6 +78,6 @@ Login.propTypes = {
onSubmit: PropTypes.func.isRequired,
hiddenLogin: PropTypes.func.isRequired,
loginError: PropTypes.string,
-}
+};
export default connect(mapStateToProps, mapDispatchToProps)(Login);
diff --git a/jsclient/src/features/login/storageUtils.js b/jsclient/src/features/login/storageUtils.js
index af1525bcf..a09a161bc 100644
--- a/jsclient/src/features/login/storageUtils.js
+++ b/jsclient/src/features/login/storageUtils.js
@@ -1,7 +1,7 @@
-const prefix = 'jarr-';
+const prefix = "jarr-";
function getStorage(storage) {
- if (!storage || storage === 'local') {
+ if (!storage || storage === "local") {
return localStorage;
} else {
return sessionStorage;
diff --git a/jsclient/src/features/login/userSlice.js b/jsclient/src/features/login/userSlice.js
index 0203ba6b8..fb57b1c3e 100644
--- a/jsclient/src/features/login/userSlice.js
+++ b/jsclient/src/features/login/userSlice.js
@@ -1,22 +1,23 @@
-import axios from 'axios';
-import { createSlice } from '@reduxjs/toolkit';
-import { apiUrl } from '../../const.js';
-import { storageGet, storageSet, storageRemove } from './storageUtils';
+import axios from "axios";
+import { createSlice } from "@reduxjs/toolkit";
+import { apiUrl } from "../../const";
+import { AppThunk } from "../../app/store":
+import { storageGet, storageSet, storageRemove } from "./storageUtils";
const userSlice = createSlice({
- name: 'user',
- initialState: { loading: false, error: undefined,
- login: storageGet('login'),
- password: storageGet('password'),
- token: storageGet('token', 'session'),
- isLeftMenuOpen: storageGet('left-menu-open') !== 'false',
- isLeftMenuFolded: storageGet('left-menu-folded') === 'true',
+ name: "user",
+ initialState: { loading: false, error: null,
+ login: storageGet("login"),
+ password: storageGet("password"),
+ token: storageGet("token", "session"),
+ isLeftMenuOpen: storageGet("left-menu-open") !== "false",
+ isLeftMenuFolded: storageGet("left-menu-folded") === "true",
},
reducers: {
attemptLogin(state, action) {
const { login, password } = action.payload;
- storageSet('login', login)
- storageSet('password', password)
+ storageSet("login", login);
+ storageSet("password", password);
return { ...state, login, password, loading: true };
},
loginFailed(state, action) {
@@ -25,30 +26,30 @@ const userSlice = createSlice({
},
tokenAcquired(state, action) {
const token = action.payload.data.access_token;
- storageSet('token', token, 'session');
+ storageSet("token", token, "session");
return { ...state, token, loading: false };
},
tokenExpire(state, action) {
- storageRemove('token', 'session');
+ storageRemove("token", "session");
return { ...state, loading: true, token: null};
},
toggleFolding(state, action) {
const newFolding = !state.isLeftMenuFolded;
- storageSet('left-menu-folded', newFolding);
+ storageSet("left-menu-folded", newFolding);
return { ...state, isLeftMenuFolded: newFolding };
},
toggleLeftMenu(state, action) {
const newState = !state.isLeftMenuOpen;
- storageSet('left-menu-open', newState);
+ storageSet("left-menu-open", newState);
return { ...state, isLeftMenuOpen: newState};
},
logout() {
- storageRemove('login');
- storageRemove('password');
- storageRemove('left-menu-open');
- storageRemove('left-menu-folded');
- storageRemove('token', 'session');
- return { loading: false, error: undefined,
+ storageRemove("login");
+ storageRemove("password");
+ storageRemove("left-menu-open");
+ storageRemove("left-menu-folded");
+ storageRemove("token", "session");
+ return { loading: false, error: null,
login: null, password: null, token: null,
isLeftMenuOpen: true,
};
@@ -65,16 +66,16 @@ export default userSlice.reducer;
export const doLogin = (
login: string,
password: string
-): AppThunk => async dispatch => {
+): AppThunk => async (dispatch) => {
try {
dispatch(attemptLogin({ login, password }));
const result = await axios.post(
- apiUrl + '/auth',
+ apiUrl + "/auth",
{ login, password },
- { responseType: 'json' },
+ { responseType: "json" },
);
- dispatch(tokenAcquired(result))
+ dispatch(tokenAcquired(result));
} catch (err) {
- dispatch(loginFailed({ error: err.toString() }))
+ dispatch(loginFailed({ error: err.toString() }));
}
-}
+};
diff --git a/jsclient/src/features/menus/Menus.js b/jsclient/src/features/menus/Menus.js
deleted file mode 100644
index 7029c01b4..000000000
--- a/jsclient/src/features/menus/Menus.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import React from 'react';
-// import PropTypes from 'prop-types';
-import { connect } from 'react-redux'
-
-function mapStateToProps(state) {
- return {};
-};
-
-function Menus({ feeds, handleDrawerOpen }) {
- return ();
-}
-
-Menus.propTypes = {
-}
-
-export default connect(mapStateToProps)(Menus);
diff --git a/jsclient/src/index.js b/jsclient/src/index.js
index eed8480bd..a07efdbd3 100644
--- a/jsclient/src/index.js
+++ b/jsclient/src/index.js
@@ -1,12 +1,12 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-import Jarr from './Jarr';
-import store from './app/store';
-import { Provider } from 'react-redux';
+import React from "react";
+import ReactDOM from "react-dom";
+import Jarr from "./Jarr";
+import store from "./app/store";
+import { Provider } from "react-redux";
ReactDOM.render(
,
- document.getElementById('root')
+ document.getElementById("root")
);
diff --git a/jsclient/src/setupTests.js b/jsclient/src/setupTests.js
index 35417dc8a..bde352f45 100644
--- a/jsclient/src/setupTests.js
+++ b/jsclient/src/setupTests.js
@@ -2,4 +2,4 @@
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
-import '@testing-library/jest-dom/extend-expect';
+import "@testing-library/jest-dom/extend-expect";
diff --git a/tests/api/feed_test.py b/tests/api/feed_test.py
index a68fa938c..f3c344016 100644
--- a/tests/api/feed_test.py
+++ b/tests/api/feed_test.py
@@ -112,13 +112,18 @@ def test_FeedResource_delete(self):
self.assertStatusCode(403, resp)
resp = self.jarr_client('get', 'list-feeds', user='user1')
- self.assertTrue(feed_id in {row['fid'] for row in resp.json})
+
+ feed_ids = set().union([{feed['id'] for feed in row['feeds']}
+ for row in resp.json])
+ self.assertTrue(feed_id in feed_ids)
resp = self.jarr_client('delete', 'feed', feed_id, user='user1')
self.assertStatusCode(204, resp)
resp = self.jarr_client('get', 'list-feeds', user='user1')
- self.assertFalse(feed_id in {row['fid'] for row in resp.json})
+ feed_ids = set().union([{feed['id'] for feed in row['feeds']}
+ for row in resp.json])
+ self.assertFalse(feed_id in feed_ids)
feeds = self.jarr_client('get', 'feeds', user='user1').json
self.assertTrue(feed_id in [feed['id'] for feed in feeds])
@@ -130,7 +135,9 @@ def test_FeedResource_delete(self):
self.assertFalse(feed_id in [feed['id'] for feed in feeds])
resp = self.jarr_client('get', 'list-feeds', user='user1')
- self.assertFalse(feed_id in {row['fid'] for row in resp.json})
+ feed_ids = set().union([{feed['id'] for feed in row['feeds']}
+ for row in resp.json])
+ self.assertFalse(feed_id in feed_ids)
def test_FeedBuilder_get(self):
resp = self.jarr_client('get', 'feed', 'build')
diff --git a/tests/api/one_page_app_test.py b/tests/api/one_page_app_test.py
index 7669b66e1..24fae0811 100644
--- a/tests/api/one_page_app_test.py
+++ b/tests/api/one_page_app_test.py
@@ -23,7 +23,8 @@ def assertClusterCount(self, count, filters=None):
def test_list_feeds(self):
resp = self.jarr_client('get', 'list-feeds', user=self.user.login)
- self.assertEqual(6, len(resp.json))
+ self.assertEqual(4, len(resp.json))
+ self.assertEqual(6, sum(len(cat['feeds']) for cat in resp.json))
def test_unreads(self):
resp = self.jarr_client('get', 'unreads', user=self.user.login)
diff --git a/tests/libs/feed_utils_test.py b/tests/libs/feed_utils_test.py
index 04b665b86..ceb37e840 100644
--- a/tests/libs/feed_utils_test.py
+++ b/tests/libs/feed_utils_test.py
@@ -87,7 +87,8 @@ def test_instagram(self):
'icon_url': 'https://www.instagram.com/static/'
'images/ico/favicon.ico/36b3ee2d91ed.ico',
'site_link': 'https://www.instagram.com/jaesivsm/',
- 'title': 'François (@jaesivsm) • Instagram photos and videos'},
+ 'title': 'François (@jaesivsm) '
+ 'Instagram profile • 124 photos and videos'},
insta)
def test_twitter(self):