add ability to mark all subscriptions as read
This commit is contained in:
parent
0562ed866b
commit
c07214ef7a
7 changed files with 108 additions and 21 deletions
|
@ -1,7 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
import type { Claim } from 'types/claim';
|
import type { Claim } from 'types/claim';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import * as React from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { normalizeURI } from 'lbry-redux';
|
import { normalizeURI } from 'lbry-redux';
|
||||||
import ToolTip from 'component/common/tooltip';
|
import ToolTip from 'component/common/tooltip';
|
||||||
import FileCard from 'component/fileCard';
|
import FileCard from 'component/fileCard';
|
||||||
|
|
10
src/renderer/component/subscribeMarkAsRead/index.js
Normal file
10
src/renderer/component/subscribeMarkAsRead/index.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { doRemoveUnreadSubscriptions } from 'redux/actions/subscriptions';
|
||||||
|
import MarkAsRead from './view';
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
doRemoveUnreadSubscriptions,
|
||||||
|
}
|
||||||
|
)(MarkAsRead);
|
40
src/renderer/component/subscribeMarkAsRead/view.jsx
Normal file
40
src/renderer/component/subscribeMarkAsRead/view.jsx
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
// @flow
|
||||||
|
import * as ICONS from 'constants/icons';
|
||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import Button from 'component/button';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
channel: ?string,
|
||||||
|
doRemoveUnreadSubscriptions: (?string) => void,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class MarkAsRead extends PureComponent<Props> {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
(this: any).handleClick = this.handleClick.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClick() {
|
||||||
|
const { channel, doRemoveUnreadSubscriptions } = this.props;
|
||||||
|
|
||||||
|
// If there is no channel, mark all as read
|
||||||
|
// If there is a channel, only mark that channel as read
|
||||||
|
if (channel) {
|
||||||
|
doRemoveUnreadSubscriptions(channel);
|
||||||
|
} else {
|
||||||
|
doRemoveUnreadSubscriptions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
noPadding
|
||||||
|
button="inverse"
|
||||||
|
icon={ICONS.CHECK_SIMPLE}
|
||||||
|
label={__('Mark as read')}
|
||||||
|
onClick={this.handleClick}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ import FileCard from 'component/fileCard';
|
||||||
import { parseURI } from 'lbry-redux';
|
import { parseURI } from 'lbry-redux';
|
||||||
import Native from 'native';
|
import Native from 'native';
|
||||||
import SuggestedSubscriptions from 'component/subscribeSuggested';
|
import SuggestedSubscriptions from 'component/subscribeSuggested';
|
||||||
|
import MarkAsRead from 'component/subscribeMarkAsRead';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
viewMode: ViewMode,
|
viewMode: ViewMode,
|
||||||
|
@ -90,7 +91,10 @@ export default (props: Props) => {
|
||||||
<div className="card__content">
|
<div className="card__content">
|
||||||
{viewMode === VIEW_ALL && (
|
{viewMode === VIEW_ALL && (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<div className="card__title">{__('Your subscriptions')}</div>
|
<div className="card__title card__actions card__actions--no-margin">
|
||||||
|
{__('Your subscriptions')}
|
||||||
|
{unreadSubscriptions.length > 0 && <MarkAsRead />}
|
||||||
|
</div>
|
||||||
<FileList hideFilter sortByHeight fileInfos={subscriptions} />
|
<FileList hideFilter sortByHeight fileInfos={subscriptions} />
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)}
|
)}
|
||||||
|
@ -102,13 +106,14 @@ export default (props: Props) => {
|
||||||
const { claimName } = parseURI(channel);
|
const { claimName } = parseURI(channel);
|
||||||
return (
|
return (
|
||||||
<section key={channel}>
|
<section key={channel}>
|
||||||
<div className="card__title">
|
<div className="card__title card__actions card__actions--no-margin">
|
||||||
<Button
|
<Button
|
||||||
button="link"
|
button="link"
|
||||||
navigate="/show"
|
navigate="/show"
|
||||||
navigateParams={{ uri: channel }}
|
navigateParams={{ uri: channel }}
|
||||||
label={claimName}
|
label={claimName}
|
||||||
/>
|
/>
|
||||||
|
<MarkAsRead channel={channel} />
|
||||||
</div>
|
</div>
|
||||||
<div className="card__list card__content">
|
<div className="card__list card__content">
|
||||||
{uris.map(uri => <FileCard key={uri} uri={uri} />)}
|
{uris.map(uri => <FileCard key={uri} uri={uri} />)}
|
||||||
|
|
|
@ -167,28 +167,44 @@ export const doUpdateUnreadSubscriptions = (
|
||||||
};
|
};
|
||||||
|
|
||||||
// Remove multiple files (or all) from a channels unread subscriptions
|
// Remove multiple files (or all) from a channels unread subscriptions
|
||||||
export const doRemoveUnreadSubscriptions = (channelUri: string, readUris: Array<string>) => (
|
export const doRemoveUnreadSubscriptions = (channelUri: ?string, readUris: ?Array<string>) => (
|
||||||
dispatch: ReduxDispatch,
|
dispatch: ReduxDispatch,
|
||||||
getState: GetState
|
getState: GetState
|
||||||
) => {
|
) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const unreadByChannel = selectUnreadByChannel(state);
|
const unreadByChannel = selectUnreadByChannel(state);
|
||||||
|
|
||||||
|
// If no channel is passed in, remove all unread subscriptions from all channels
|
||||||
|
if (!channelUri) {
|
||||||
|
return dispatch({
|
||||||
|
type: ACTIONS.REMOVE_SUBSCRIPTION_UNREADS,
|
||||||
|
data: { channel: null },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const currentChannelUnread = unreadByChannel[channelUri];
|
const currentChannelUnread = unreadByChannel[channelUri];
|
||||||
if (!currentChannelUnread || !currentChannelUnread.uris) {
|
if (!currentChannelUnread || !currentChannelUnread.uris) {
|
||||||
|
// Channel passed in doesn't have any unreads
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each uri passed in, remove it from the list of unread uris
|
// For each uri passed in, remove it from the list of unread uris
|
||||||
const urisToRemoveMap = readUris.reduce(
|
// If no uris are passed in, remove them all
|
||||||
(acc, val) => ({
|
let newUris;
|
||||||
...acc,
|
if (readUris) {
|
||||||
[val]: true,
|
const urisToRemoveMap = readUris.reduce(
|
||||||
}),
|
(acc, val) => ({
|
||||||
{}
|
...acc,
|
||||||
);
|
[val]: true,
|
||||||
|
}),
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
const filteredUris = currentChannelUnread.uris.filter(uri => !urisToRemoveMap[uri]);
|
const filteredUris = currentChannelUnread.uris.filter(uri => !urisToRemoveMap[uri]);
|
||||||
const newUris = filteredUris.length ? filteredUris : null;
|
newUris = filteredUris.length ? filteredUris : null;
|
||||||
|
} else {
|
||||||
|
newUris = null;
|
||||||
|
}
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.REMOVE_SUBSCRIPTION_UNREADS,
|
type: ACTIONS.REMOVE_SUBSCRIPTION_UNREADS,
|
||||||
|
|
|
@ -66,10 +66,11 @@ export default handleActions(
|
||||||
action: SetSubscriptionLatest
|
action: SetSubscriptionLatest
|
||||||
): SubscriptionState => ({
|
): SubscriptionState => ({
|
||||||
...state,
|
...state,
|
||||||
subscriptions: state.subscriptions.map(subscription =>
|
subscriptions: state.subscriptions.map(
|
||||||
subscription.channelName === action.data.subscription.channelName
|
subscription =>
|
||||||
? { ...subscription, latest: action.data.uri }
|
subscription.channelName === action.data.subscription.channelName
|
||||||
: subscription
|
? { ...subscription, latest: action.data.uri }
|
||||||
|
: subscription
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
[ACTIONS.UPDATE_SUBSCRIPTION_UNREADS]: (
|
[ACTIONS.UPDATE_SUBSCRIPTION_UNREADS]: (
|
||||||
|
@ -94,12 +95,19 @@ export default handleActions(
|
||||||
action: DoRemoveSubscriptionUnreads
|
action: DoRemoveSubscriptionUnreads
|
||||||
): SubscriptionState => {
|
): SubscriptionState => {
|
||||||
const { channel, uris } = action.data;
|
const { channel, uris } = action.data;
|
||||||
const newUnread = { ...state.unread };
|
|
||||||
|
|
||||||
if (!uris) {
|
// If no channel is passed in, remove all unreads
|
||||||
delete newUnread[channel];
|
let newUnread;
|
||||||
|
if (channel) {
|
||||||
|
newUnread = { ...state.unread };
|
||||||
|
|
||||||
|
if (!uris) {
|
||||||
|
delete newUnread[channel];
|
||||||
|
} else {
|
||||||
|
newUnread[channel].uris = uris;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
newUnread[channel].uris = uris;
|
newUnread = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -32,6 +32,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.btn--no-padding {
|
||||||
|
.btn__content {
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.btn--alt {
|
&.btn--alt {
|
||||||
&:not(:disabled) {
|
&:not(:disabled) {
|
||||||
background-color: $lbry-white;
|
background-color: $lbry-white;
|
||||||
|
|
Loading…
Add table
Reference in a new issue