,
+ user: User,
};
export default function NotificationsPage(props: Props) {
const {
notifications,
notificationsFiltered,
+ localNotifications,
fetching,
unreadCount,
unseenCount,
@@ -39,7 +42,10 @@ export default function NotificationsPage(props: Props) {
notificationCategories,
activeChannel,
doCommentReactList,
+ user,
} = props;
+ // const localCategories = [{ name: 'New Content', types: ['new_content'] }];
+ const legacyNotificationsEnabled = user && user.experimental_ui;
const initialFetchDone = useFetched(fetching);
const [name, setName] = usePersistedState('notifications--rule', NOTIFICATIONS.NOTIFICATION_NAME_ALL);
const isFiltered = name !== NOTIFICATIONS.NOTIFICATION_NAME_ALL;
@@ -113,7 +119,7 @@ export default function NotificationsPage(props: Props) {
{fetching && }
- {unreadCount > 0 && (
+ {legacyNotificationsEnabled && unreadCount > 0 && (
)}
- {notificationCategories && (
+ {!legacyNotificationsEnabled && unreadCount > 0 && (
+
- {list && list.length > 0 && !(isFiltered && fetching) ? (
+ {legacyNotificationsEnabled && list && list.length > 0 && !(isFiltered && fetching) && (
{list.map((notification) => {
@@ -148,7 +157,17 @@ export default function NotificationsPage(props: Props) {
})}
- ) : (
+ )}
+ {!legacyNotificationsEnabled && localNotifications && localNotifications.length > 0 && (
+
+
+ {localNotifications.map((notification) => {
+ return ;
+ })}
+
+
+ )}
+ {!(legacyNotificationsEnabled && list && list.length > 0 && !(isFiltered && fetching)) && (
{!fetching && (
{
+ dispatch({ type: ACTIONS.LOCAL_NOTIFICATION_DELETE_COMPLETED, data: { notificationId } });
+ };
+}
+
+export function doLocalSeeNotification(notificationIds: Array) {
+ return (dispatch: Dispatch) => {
+ dispatch({
+ type: ACTIONS.LOCAL_NOTIFICATION_SEEN_COMPLETED,
+ data: {
+ notificationIds,
+ },
+ });
+ };
+}
+
+export function doLocalSeeAllNotifications() {
+ return (dispatch: Dispatch, getState: GetState) => {
+ const state = getState();
+ const notifications = selectNotificationsLocal(state);
+
+ if (!notifications) {
+ return;
+ }
+
+ const getUnseenIds = (list) => list.filter((n) => !n.is_seen).map((n) => n.id);
+ const unseenIds = Array.from(new Set([...getUnseenIds(notifications)]));
+
+ dispatch(doLbryioNotificationsMarkSeen(unseenIds));
+ };
+}
diff --git a/ui/redux/reducers/notifications.js b/ui/redux/reducers/notifications.js
index 795acce79..d5c8df761 100644
--- a/ui/redux/reducers/notifications.js
+++ b/ui/redux/reducers/notifications.js
@@ -4,6 +4,7 @@ import { handleActions } from 'util/redux-utils';
const defaultState: NotificationState = {
notifications: [],
+ localNotifications: [],
notificationsFiltered: [],
notificationCategories: undefined,
fetchingNotifications: false,
@@ -133,6 +134,39 @@ export default handleActions(
};
},
+ [ACTIONS.LOCAL_NOTIFICATION_DELETE_COMPLETED]: (state, action) => {
+ const { localNotifications } = state;
+ const { notificationId } = action.data;
+
+ const deleteId = (list, id) => {
+ return localNotifications.filter((n) => n.id !== id);
+ };
+
+ return {
+ ...state,
+ localNotifications: deleteId(localNotifications, notificationId),
+ };
+ },
+
+ [ACTIONS.LOCAL_NOTIFICATION_SEEN_COMPLETED]: (state, action) => {
+ const { localNotifications } = state;
+ const { notificationIds } = action.data;
+
+ const markIdsAsSeen = (list, ids) => {
+ return list.map((n) => {
+ if (ids.includes(n.id)) {
+ return { ...n, is_seen: true };
+ }
+ return n;
+ });
+ };
+
+ return {
+ ...state,
+ localNotifications: markIdsAsSeen(localNotifications, notificationIds),
+ };
+ },
+
// Errors
[ACTIONS.CREATE_ERROR]: (state: NotificationState, action: DoError) => {
const error: ErrorNotification = action.data;
diff --git a/ui/redux/reducers/subscriptions.js b/ui/redux/reducers/subscriptions.js
index ffd358bcb..6017f856b 100644
--- a/ui/redux/reducers/subscriptions.js
+++ b/ui/redux/reducers/subscriptions.js
@@ -6,10 +6,17 @@ import { handleActions } from 'util/redux-utils';
const defaultState: SubscriptionState = {
subscriptions: [], // Deprecated
following: [],
+ autoDownloads: {},
loading: false,
firstRunCompleted: false,
};
+/*
+For each channel, track number to keep downloaded (number), downloads (Array<{id, releaseTime}>)
+ AutoDownloadById
+ { channel_id: { count: n, downloads: [ { claimId: xyz, releaseTime: 123 ], ... } }
+ */
+
export default handleActions(
{
[ACTIONS.CHANNEL_SUBSCRIBE]: (state: SubscriptionState, action): SubscriptionState => {
@@ -61,19 +68,6 @@ export default handleActions(
following: newFollowing,
};
},
- [ACTIONS.FETCH_SUBSCRIPTIONS_START]: (state: SubscriptionState): SubscriptionState => ({
- ...state,
- loading: true,
- }),
- [ACTIONS.FETCH_SUBSCRIPTIONS_FAIL]: (state: SubscriptionState): SubscriptionState => ({
- ...state,
- loading: false,
- }),
- [ACTIONS.FETCH_SUBSCRIPTIONS_SUCCESS]: (state: SubscriptionState, action): SubscriptionState => ({
- ...state,
- loading: false,
- subscriptions: action.data,
- }),
[ACTIONS.SET_VIEW_MODE]: (state: SubscriptionState, action): SubscriptionState => ({
...state,
viewMode: action.data,
diff --git a/ui/redux/selectors/notifications.js b/ui/redux/selectors/notifications.js
index 825a6e3f8..78600c0b5 100644
--- a/ui/redux/selectors/notifications.js
+++ b/ui/redux/selectors/notifications.js
@@ -3,6 +3,7 @@ import { createSelector } from 'reselect';
export const selectState = (state) => state.notifications || {};
export const selectNotifications = createSelector(selectState, (state) => state.notifications);
+export const selectNotificationsLocal = createSelector(selectState, (state) => state.localNotifications);
export const selectNotificationsFiltered = createSelector(selectState, (state) => state.notificationsFiltered);
@@ -31,6 +32,14 @@ export const selectUnseenNotificationCount = createSelector(selectNotifications,
return notifications ? notifications.filter((notification) => !notification.is_seen).length : 0;
});
+export const selectUnseenLocalNotificationCount = createSelector(selectNotificationsLocal, (notifications) => {
+ return notifications ? notifications.filter((notification) => !notification.is_seen).length : 0;
+});
+
+export const selectUnreadLocalNotificationCount = createSelector(selectNotificationsLocal, (notifications) => {
+ return notifications ? notifications.filter((notification) => !notification.is_read).length : 0;
+});
+
export const selectToast = createSelector(selectState, (state) => {
if (state.toasts.length) {
const { id, params } = state.toasts[0];
diff --git a/ui/scss/component/_button.scss b/ui/scss/component/_button.scss
index a8cfd3b36..2269e8567 100644
--- a/ui/scss/component/_button.scss
+++ b/ui/scss/component/_button.scss
@@ -710,14 +710,11 @@ svg + .button__label {
}
}
// bring back special button-following style later
-//.button-following {
-// color: var(--color-primary-contrast) !important;
-// //background-color: rgba(var(--color-primary-dynamic),0.5) !important;
-// background-color: rgba(125, 125, 125, 0.5) !important;
-// .icon {
-// stroke: var(--color-primary-contrast) !important;
-// }
-//}
+.button-following {
+ .icon {
+ stroke: var(--color-text) !important;
+ }
+}
.recommended-content__bubble {
// margin-top: var(--spacing-xs);
diff --git a/ui/scss/component/_channel.scss b/ui/scss/component/_channel.scss
index b5fc60ae0..9f0b79637 100644
--- a/ui/scss/component/_channel.scss
+++ b/ui/scss/component/_channel.scss
@@ -11,18 +11,14 @@ $actions-z-index: 2;
}
}
// bring back later
- //.button-following {
- // &.button--alt {
- // color: var(--color-text);
- // background-color: var(--color-button-alt-bg);
- // .icon {
- // stroke: var(--color-text);
- // }
- // &:hover {
- // color: var(--color-primary);
- // }
- // }
- //}
+ .button-following {
+ &.button--alt {
+ color: var(--color-text);
+ .icon {
+ stroke: var(--color-text);
+ }
+ }
+ }
.button-following:last-of-type {
margin-left: 2px;
}