Skip to content
This repository has been archived by the owner on Nov 10, 2020. It is now read-only.

Commit

Permalink
Merge pull request #164 from tahnik/patch3
Browse files Browse the repository at this point in the history
Patch3
  • Loading branch information
tahnik authored Aug 14, 2017
2 parents 5340e39 + b434ecf commit aa92383
Show file tree
Hide file tree
Showing 37 changed files with 483 additions and 137 deletions.
101 changes: 86 additions & 15 deletions app/src/main/js/actions/notifs.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,109 @@ const { ipcRenderer } = require('electron');
const currentWindow = require('electron').remote.getCurrentWindow();

// This is used to prevent notif being fetched when a notif clearing is in progress
let clearingNotif = false;
let clearingNotifs = false;
let fetching = false;

/**
* Fetches notifications
*
*/
const fetchNotifs = () => (dispatch, getState) => {
const fetchNotifs = (refresh = false) => (dispatch, getState) => {
if (clearingNotifs || fetching) {
return;
}
const auth = getState().auth;
if (!auth.user) {
return;
}
const stateNotifs = getState().notifs;
let lastCheckTime = 1;
let lastItems = [];
let lastUsers = {};
if (stateNotifs && stateNotifs.check_time) {
if (!refresh) {
lastItems = stateNotifs.items;
lastUsers = stateNotifs.username_map;
}
if (lastItems.length !== 0 && !refresh) {
lastCheckTime = stateNotifs.check_time;
}
}
fetching = true;
rantscript
.notifications(auth.user.authToken, 1)
.notifications(auth.user.authToken, lastCheckTime)
.then((res) => {
fetching = false;
/*
* We have got a successful response, let's dispatch to let
* redux store know about it
*/
if (res.data.items.length === 0) {
return;
}
let nextItems = [...lastItems];
const resItems = res.data.items;
if (!refresh) {
for (let i = (resItems.length - 1); i >= 0; i -= 1) {
const element = resItems[i];
const duplicate = lastItems.find(item => item.created_time === element.created_time);
if (typeof duplicate === 'undefined') {
if (lastCheckTime === 1) {
nextItems.push(element);
} else {
nextItems.unshift(element);
}
} else {
console.log('Leviosaaaaaaa');
}
}
} else {
nextItems = [...resItems];
}
const notifs = {
items: res.data.items,
items: nextItems.slice(0, 100),
check_time: res.data.check_time,
username_map: res.data.username_map,
username_map: { ...res.data.username_map, ...lastUsers },
num_unread: res.data.num_unread,
};
if (!clearingNotif) {
dispatch({
type: NOTIFS.FETCH,
notifs,
});
}
dispatch({
type: NOTIFS.FETCH,
notifs,
});
})
.catch(() => {
fetching = false;
});
};

/**
* Clears the notifications associated with a particular rant id
* @param {number} id id of a rant
*/
const clearNotif = id => (dispatch, getState) => {
const prevNotifs = { ...getState().notifs };
const nextItems = [...prevNotifs.items];
let nextNumUnread = prevNotifs.num_unread;
for (let i = 0; i < nextItems.length; i += 1) {
const item = nextItems[i];
if (item.rant_id === id) {
if (!item.read) {
item.read = 1;
if (nextNumUnread > 0) {
nextNumUnread -= 1;
}
}
}
}
const notifs = {
items: nextItems,
check_time: parseInt(Date.now() / 1000, 10),
username_map: prevNotifs.username_map,
num_unread: nextNumUnread,
};
dispatch({
type: NOTIFS.FETCH,
notifs,
});
};

Expand All @@ -54,14 +125,14 @@ const clearNotifs = () => (dispatch, getState) => {
if (!auth.user) {
return;
}
clearingNotif = true;
clearingNotifs = true;
rantscript
.clearNotifications(auth.user.authToken)
.then(() => {
clearingNotif = false;
clearingNotifs = false;
})
.catch(() => {
clearingNotif = false;
clearingNotifs = false;
});
};

Expand Down Expand Up @@ -115,4 +186,4 @@ const showNotifs = notif => (dispatch, getState) => {
}
};

export { fetchNotifs, clearNotifs, showNotifs };
export { fetchNotifs, clearNotifs, showNotifs, clearNotif };
13 changes: 13 additions & 0 deletions app/src/main/js/actions/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { SEARCH } from '../consts/types';

/**
* Adds a string to frequently searched terms
* @param {string} term term to add
*/
// eslint-disable-next-line
export const addToFreqTerms = term => (dispatch) => {
dispatch({
type: SEARCH.ADDTOFREQ,
term,
});
};
5 changes: 5 additions & 0 deletions app/src/main/js/actions/settings.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { SETTINGS } from '../consts/types';
import { fetchUser } from './user';
import { fetchNotifs } from './notifs';

const { ipcRenderer } = require('electron');

Expand Down Expand Up @@ -36,6 +38,7 @@ const saveUserState = () => (dispatch, getState) => {
settings: state.settings,
notifs: state.notifs,
columns: customCols,
search: state.search,
};
// Use localStorage to save the state. Much better than a file
localStorage.setItem('savedState', JSON.stringify(savedState));
Expand Down Expand Up @@ -100,6 +103,8 @@ const setFirstLaunch = () => (dispatch) => {
*
*/
const setOnStartup = () => (dispatch, getState) => {
dispatch(fetchUser());
dispatch(fetchNotifs(true));
const generalSettings = getState().settings.general;
if (generalSettings.autoLaunch.value === true) {
setAutoLaunch(true);
Expand Down
8 changes: 7 additions & 1 deletion app/src/main/js/actions/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,14 @@ const fetchUser = () => (dispatch, getState) => {
});
return;
}
const authToken = user.authToken;
/**
* Normally fetching a user fetches a lot of contents with it
* we use collabs as most of the users don't have any and it uses
* the least bandwidth
*/
rantscript
.profile(userID)
.profile(userID, authToken, 'collabs', 0)
.then((res) => {
const profile = {
username: res.username,
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/js/components/columns/column.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class Column extends Component {
itemType={itemType}
auth={auth}
showToast={showToast}
history={this.props.history}
/>
))
}
Expand Down Expand Up @@ -150,6 +151,7 @@ Column.propTypes = {
auth: PropTypes.object.isRequired,
updateScrollHeight: PropTypes.func,
custom: PropTypes.bool,
history: PropTypes.object.isRequired,
};

export default Column;
1 change: 1 addition & 0 deletions app/src/main/js/components/comments/comment_post.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class CommentPost extends Component {
onPost={(text, image) => this.onPost(text, image)}
disabled={this.state.disabled || auth.user === null}
value={this.state.content}
maxChar={2000}
onChange={text => this.setState({ content: text })}
ref={(node) => { this.smartArea = node; }}
/>
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/js/components/comments/comments.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class Comments extends Component {
<div className="comments_container">
{
comments.length === 0 ?
<div style={{ width: `${theme.column.width}px` }}>
<div style={{ width: `${theme.column.width}px`, marginRight: '0.5rem' }}>
<h4>No comments</h4>
</div>
: null
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/js/components/item/item.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,16 @@ class Item extends Component {
* @memberof Item
*/
fetchitem(scrollToBottom = false) {
const { cardItem, auth, fetchNotifs } = this.props;
const { cardItem, auth, fetchNotifs, clearNotif } = this.props;
let authToken = null;
if (auth.user) {
authToken = auth.user.authToken;
}
rantscript
.rant(cardItem.id, authToken)
.then((res) => {
fetchNotifs();
clearNotif(cardItem.id);
const item = res;
this.setState({ item });
if (typeof cardItem.data.commentID !== 'undefined') {
Expand All @@ -97,7 +99,6 @@ class Item extends Component {
this.compactCol.scrollTop = this.compactCol.scrollHeight;
}
}
fetchNotifs();
})
.catch((err) => {
console.log(err);
Expand Down Expand Up @@ -223,6 +224,7 @@ Item.propTypes = {
open: PropTypes.func.isRequired,
showToast: PropTypes.func.isRequired,
fetchNotifs: PropTypes.func.isRequired,
clearNotif: PropTypes.func.isRequired,
};

export default Item;
13 changes: 9 additions & 4 deletions app/src/main/js/components/item/item_card.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,13 @@ class ItemCard extends Component {
if (isComment) {
content = parseUsers(content);
}
return parseLinks(content);
return parseLinks(content, item);
}
static openLink(url) {
let fURL = url;
if (
url.indexOf('http://') === -1
|| url.indexOf('https://') === -1
&& url.indexOf('https://') === -1
) {
fURL = `http://${url}`;
}
Expand All @@ -128,7 +128,11 @@ class ItemCard extends Component {
<div>
{item.tags.length !== 0 && <div className="tags">
{item.tags.map(object => (
<span key={object} className="tag">{object}</span>
<span
key={object}
className="tag"
onClick={() => this.props.history.replace(`/search/${object}`)}
>{object}</span>
))}
</div>}
</div>
Expand Down Expand Up @@ -240,8 +244,8 @@ class ItemCard extends Component {
{ this.renderCollab() }
</div>
{ image !== '' ? <img alt="" src={image.url} /> : null }
{this.getTags()}
</div>
{this.getTags()}
<BottomBar
item={item}
vote={vote}
Expand Down Expand Up @@ -272,6 +276,7 @@ ItemCard.propTypes = {
modal: PropTypes.bool,
addMention: PropTypes.func,
fetchitem: PropTypes.func,
history: PropTypes.object,
};


Expand Down
5 changes: 5 additions & 0 deletions app/src/main/js/components/navigation/sidenav.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ class SideNav extends Component {
}
componentDidMount() {
ipcRenderer.on('compose_rant', () => { this.props.open(); });
document.addEventListener('keydown', (e) => {
if (e.which === 13 && e.ctrlKey) {
this.props.open();
}
});
}
getUserCard() {
const { user, logout, login, fetchUser, open } = this.props;
Expand Down
9 changes: 6 additions & 3 deletions app/src/main/js/components/notifs/notif_bubbles.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,22 @@ class NotifBubbles extends Component {
}
render() {
const { data, open } = this.props;
if (!data) {
return <div />;
}
return (
<div className="notif_bubble_container">
{
data ? data.items.map((notif, index) =>
data.items.map((notif, index) =>
(<Notification
notif={notif}
index={index}
open={open}
unread={data.num_unread}
key={`${notif.uid}_${index}`} //eslint-disable-line
key={`${notif.uid}_${notif.created_time}_${notif.comment_id}_${notif.type}_${notif.rant_id}_${notif.read}`} //eslint-disable-line
user={data.username_map[notif.uid]}
/>),
) : null
)
}
</div>
);
Expand Down
Loading

0 comments on commit aa92383

Please sign in to comment.