Skip to content
This repository was archived by the owner on May 2, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25,900 changes: 25,482 additions & 418 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions src/common/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React from "react";
import { NavLink } from "react-router-dom";
import { arrayOfIds } from "../features/subscriptions/types";
import UserImage from "./UserImage";

interface CardProps {
id?: string;
image?: string;
username?: string;
followings?: string;
followers?: string;
followings?: arrayOfIds | null;
followers?: arrayOfIds | null;
children: React.ReactNode;
}

Expand Down
84 changes: 84 additions & 0 deletions src/common/InitializationCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React, { Component } from "react";
import { connect, ConnectedProps } from "react-redux";
import { fetchReadingsIfNeeded } from "../features/globalReadings/actions";
import { getReadings } from "../features/globalReadings/selectors";
import tags from "../features/tags/index";
import { RootState } from "../features/rootReducer";
import { match } from "react-router-dom";
import {
List,
AutoSizer,
CellMeasurer,
CellMeasurerCache,
WindowScroller,
ListRowRenderer,
} from "react-virtualized";
import ListItem from "../features/globalReadings/components/ListItem";
import VirtualizedList from "../features/globalReadings/components/VirtualizedList";

type OwnProps = {
readings: any;
list: any;
id?: any;
outdated?: any;
fav?: any;
tag_id?: any;
match: match;
};

type ReadingsListProps = PropsFromRedux & OwnProps;

class InitializationCard extends Component<ReadingsListProps> {
render() {
let { readings, list, outdated } = this.props;

if (readings === undefined) {
return (
<div className="col col--6-lg col--4-md">
<div className="newCard">
<div className="card_body">
<h3>Welcome</h3>
<p>You currently do not have any posted readings.</p>
</div>
</div>
</div>
);
} else if (readings === undefined && list === "subscriptions") {
return (
<div className="col col--6-lg col--4-md">
<div className="newCard">
<div className="card_body">
<h3>Welcome</h3>
<p>Your friends do not have posted readings.</p>
</div>
</div>
</div>
);
} else {
return (
<VirtualizedList readings={readings} list={list} outdated={outdated} />
);
}
}
}

function mapStateToProps(state: RootState, ownProps: OwnProps) {
return {
readings: getReadings(
state,
ownProps.list,
ownProps.fav,
ownProps.outdated,
ownProps.tag_id
),
};
}

const connector = connect(mapStateToProps, {
fetchReadingsIfNeeded,
...tags.actions,
});

type PropsFromRedux = ConnectedProps<typeof connector>;

export default connector(InitializationCard);
4 changes: 2 additions & 2 deletions src/common/services/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ export function setTokenHeader(token: string | boolean): void {
* @param {string} path - the route path/endpoint
* @param {object} data - (optional) data in JSON form for POST requests
*/
export const apiCall = (
export const apiCall = <T>(
method: Method,
url: string,
data?: any
): AxiosPromise<unknown> => {
): AxiosPromise<T> => {
return new Promise((resolve, reject) => {
return axios
.request({ method, url, data })
Expand Down
11 changes: 4 additions & 7 deletions src/features/actions.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { User, UserFollowers } from "./user/types";
import { RECEIVE_ENTITIES } from "./actionTypes";
import { Tags } from "./tags/types";

export interface Users {
id: number;
username: string;
image: string;
}

export interface Readings {
id: number;
title: string;
Expand All @@ -22,7 +17,7 @@ export interface Readings {
}

export interface Entities {
user?: Users;
users?: User[];
readings?: Readings;
tags?: Tags;
}
Expand All @@ -35,6 +30,8 @@ export interface ReceiveEntitiesAction {
list: any;
id?: any;
user_id?: number | null;
users?: User[];
userFollowers?: UserFollowers;
}

export const receiveEntities = (
Expand Down
7 changes: 1 addition & 6 deletions src/features/auth/types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { SET_CURRENT_USER } from "../actionTypes";
import { AlertActionTypes } from "../alerts/types";

export interface User {
id: number | null;
username: string | null;
image: string | null;
}
import { User } from "../user/types";

export interface AuthState {
isAuthenticated: boolean;
Expand Down
18 changes: 14 additions & 4 deletions src/features/globalReadings/components/GlobalReadingsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { fetchReadingsIfNeeded } from "../actions";
import { getReadings } from "../selectors";
import tags from "../../tags";
import VirtualizedList from "./VirtualizedList";
import InitializationCard from "../../../common/InitializationCard";
import { RootState } from "../../rootReducer";
import { match } from "react-router-dom";

Expand Down Expand Up @@ -33,10 +34,19 @@ class ReadingsList extends Component<ReadingsListProps> {

render() {
const { readings, list, outdated } = this.props;

return (
<VirtualizedList readings={readings} list={list} outdated={outdated} />
);
if (list === "global") {
return (
<VirtualizedList readings={readings} list={list} outdated={outdated} />
);
} else if (list === "subscriptions") {
return (
<InitializationCard readings={readings} list={list} match={outdated} />
);
} else {
return (
<InitializationCard readings={readings} list={list} match={outdated} />
);
}
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/features/globalReadings/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ const getTagReadings = (readings: any[], tag_id: number): any[] => {
export const getReadings = (
state: any,
list: string,
fav: any,
outdated: any,
tag_id: number
fav?: any,
outdated?: any,
tag_id?: number
): any[] | void => {
// give time for readingsByList items to load
if (
Expand Down Expand Up @@ -56,7 +56,7 @@ export const getReadingById = (state: any, list: string, id: number): any => {
export const getWebsites = (
state: any,
list: string,
tag_id: number
tag_id?: number
): { [k: string]: any } => {
let websiteCount: { [k: string]: any } = {};

Expand Down
17 changes: 11 additions & 6 deletions src/features/subscriptions/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@ import {
postingNewSubscription,
fetchingSubscriptionsIfNeeded,
} from "./types";
import { UserFollowers } from "../user/types";
import { AxiosResponse } from "axios";

const { addAlert } = alerts.actions;

export const loadSubscriptions = (users: any, id: number) => ({
export const loadSubscriptions = (
userFollowers: AxiosResponse<UserFollowers>,
id: string | number
) => ({
type: LOAD_SUBSCRIPTIONS,
users,
userFollowers,
id,
});

Expand All @@ -33,9 +38,9 @@ export const removeSubscriptions = (id: number, user_id: number | null) => ({
});

export const fetchSubscriptions =
(user_id: number): fetchingSubscriptions =>
(user_id: string | number): fetchingSubscriptions =>
async (dispatch) => {
return apiCall("get", `/users/${user_id}/subscriptions`)
return apiCall<UserFollowers>("get", `/users/${user_id}/subscriptions`)
.then((res) => dispatch(loadSubscriptions(res, user_id)))
.catch((err) =>
dispatch(addAlert({ message: err.message, type: "danger" }))
Expand Down Expand Up @@ -79,7 +84,7 @@ export const postNewSubscription =

const shouldFetchSubscriptions = (
state: any,
id: number
id: string | number
): boolean | undefined => {
const subscriptions = state.subscriptions[id];
const upToDate = state.subscriptions.upToDate;
Expand All @@ -89,7 +94,7 @@ const shouldFetchSubscriptions = (
};

export const fetchSubscriptionsIfNeeded = (
id: number
id: string | number
): fetchingSubscriptionsIfNeeded => {
return (dispatch, getState) => {
if (shouldFetchSubscriptions(getState(), id)) {
Expand Down
4 changes: 2 additions & 2 deletions src/features/subscriptions/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const getSubscriptions = (

export const getFollowers = (
state: any,
id: number
id: number | string
): arrayOfIds | undefined => {
if (state.subscriptions[id]) {
return state.subscriptions[id].followers;
Expand All @@ -18,7 +18,7 @@ export const getFollowers = (

export const getFollowings = (
state: any,
id: number
id: number | string
): arrayOfIds | undefined => {
if (state.subscriptions[id]) {
return state.subscriptions[id].following;
Expand Down
5 changes: 3 additions & 2 deletions src/features/subscriptions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import {
REMOVE_SUBSCRIPTIONS,
} from "../actionTypes";
import { RootState } from "../rootReducer";
import { UserFollowers } from "../user/types";

export type SubscriptionState = any;

interface LoadSubscriptionAction {
export interface LoadSubscriptionAction {
type: typeof LOAD_SUBSCRIPTIONS;
users: any;
id: number;
user_id: never;
userFollowers: UserFollowers;
}

interface AddSubscriptionAction {
Expand Down
4 changes: 2 additions & 2 deletions src/features/tags/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const loadTags = (tags: Tags) => ({
tags,
});

export const fetchTags = (list: string, id: number): fetchingTags => {
export const fetchTags = (list: string, id: string): fetchingTags => {
return (dispatch, getState) => {
if (list === "global") {
dispatch(addLoader("tags"));
Expand Down Expand Up @@ -121,7 +121,7 @@ const shouldFetchTags = (state: any, list: string) => {

export const fetchTagsIfNeeded = (
list: string,
id: number
id: string
): fetchingTagsIfNeeded => {
return (dispatch, getState) => {
if (shouldFetchTags(getState(), list)) {
Expand Down
2 changes: 1 addition & 1 deletion src/features/tags/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type TagsActionTypes =
| AddTagAction
| RemoveTagAction;

interface AddTagAction {
export interface AddTagAction {
type: typeof ADD_TAG;
id: number;
user_id: number | null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { ReceiveEntitiesAction } from "./../actions";
import { RECEIVE_ENTITIES, ADD_TAG } from "../actionTypes";
import { Tags, AddTagAction } from "./../tags/types";

const getIds = (tags) => {
const getIds = (tags: Tags): number[] => {
return Object.values(tags).map((tag) => tag.id);
};

const tagsByList = (state = {}, action) => {
export type TagsByListActionTypes = ReceiveEntitiesAction | AddTagAction;

const tagsByList = (state: any = {}, action: TagsByListActionTypes) => {
switch (action.type) {
case RECEIVE_ENTITIES:
const { entities } = action.payload;
Expand Down
Loading